aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:35 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:35 -0800
commitf721e3ac031f892af46f255a47d7f54a91317b30 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904
parentbae1bc39312d5019bd9a5b8d840a529213a69a17 (diff)
downloadexternal_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip
external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz
external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2
auto import from //depot/cupcake/@135843
-rw-r--r--Android.mk10
-rw-r--r--CHANGES.TXT648
-rw-r--r--COPYING339
-rw-r--r--COPYING.LIB504
-rw-r--r--Changelog395
-rw-r--r--INSTALL119
-rw-r--r--LICENSE12
-rw-r--r--MODULE_LICENSE_GPL0
-rw-r--r--Makefile73
-rw-r--r--Makefile.android537
-rw-r--r--NOTICE339
-rw-r--r--README23
-rw-r--r--a.out.h431
-rw-r--r--aes.c1320
-rw-r--r--aes.h26
-rw-r--r--alpha.ld128
-rwxr-xr-xandroid-configure.sh646
-rwxr-xr-xandroid-rebuild.sh12
-rw-r--r--android/android.h100
-rw-r--r--android/avd/hardware-properties.ini158
-rw-r--r--android/avd/hw-config-defs.h165
-rw-r--r--android/avd/hw-config.c39
-rw-r--r--android/avd/hw-config.h46
-rw-r--r--android/avd/info.c1585
-rw-r--r--android/avd/info.h161
-rw-r--r--android/build/binary.make34
-rw-r--r--android/build/clear_vars.make30
-rw-r--r--android/build/definitions.make109
-rw-r--r--android/build/getdir.make19
-rw-r--r--android/build/host_executable.make34
-rw-r--r--android/build/host_static_library.make35
-rwxr-xr-xandroid/build/mkdeps.sh51
-rw-r--r--android/charmap.c148
-rw-r--r--android/charmap.h133
-rw-r--r--android/cmdline-option.c255
-rw-r--r--android/cmdline-option.h42
-rw-r--r--android/cmdline-options.h131
-rw-r--r--android/config.c467
-rw-r--r--android/config.h57
-rw-r--r--android/config/Linux/config-host.h10
-rw-r--r--android/config/check-alsa.c107
-rw-r--r--android/config/check-esd.c67
-rw-r--r--android/config/config.h14
-rw-r--r--android/config/darwin-ppc/config-host.h13
-rw-r--r--android/config/darwin-x86/config-host.h13
-rw-r--r--android/config/linux-x86/config-host.h10
-rw-r--r--android/config/windows/config-host.h10
-rw-r--r--android/console.c2190
-rw-r--r--android/globals.h33
-rw-r--r--android/gps.c37
-rw-r--r--android/gps.h23
-rw-r--r--android/help.c1432
-rw-r--r--android/help.h36
-rw-r--r--android/hw-control.c204
-rw-r--r--android/hw-control.h38
-rw-r--r--android/hw-events.c223
-rw-r--r--android/hw-events.h184
-rw-r--r--android/hw-kmsg.c70
-rw-r--r--android/hw-kmsg.h31
-rw-r--r--android/icons.h984
-rw-r--r--android/main.c2889
-rw-r--r--android/qemud.c456
-rw-r--r--android/qemud.h72
-rw-r--r--android/resource.c64
-rw-r--r--android/resource.h26
-rw-r--r--android/skin/argb.h856
-rw-r--r--android/skin/composer.c401
-rw-r--r--android/skin/composer.h102
-rw-r--r--android/skin/default.h7414
-rw-r--r--android/skin/file.c693
-rw-r--r--android/skin/file.h132
-rw-r--r--android/skin/image.c742
-rw-r--r--android/skin/image.h92
-rw-r--r--android/skin/keyboard.c783
-rw-r--r--android/skin/keyboard.h59
-rw-r--r--android/skin/keyset.c542
-rw-r--r--android/skin/keyset.h122
-rw-r--r--android/skin/rect.c241
-rw-r--r--android/skin/rect.h71
-rw-r--r--android/skin/region.c1448
-rw-r--r--android/skin/region.h103
-rw-r--r--android/skin/scaler.c135
-rw-r--r--android/skin/scaler.h39
-rw-r--r--android/skin/surface.c613
-rw-r--r--android/skin/surface.h101
-rw-r--r--android/skin/trackball.c625
-rw-r--r--android/skin/trackball.h43
-rw-r--r--android/skin/window.c1516
-rw-r--r--android/skin/window.h65
-rwxr-xr-xandroid/tools/gen-hw-config.py141
-rw-r--r--android/utils/bufprint.c230
-rw-r--r--android/utils/bufprint.h76
-rw-r--r--android/utils/debug.c141
-rw-r--r--android/utils/debug.h91
-rw-r--r--android/utils/dirscanner.c203
-rw-r--r--android/utils/dirscanner.h51
-rw-r--r--android/utils/display-quartz.m111
-rw-r--r--android/utils/display.c245
-rw-r--r--android/utils/display.h31
-rw-r--r--android/utils/filelock.c414
-rw-r--r--android/utils/filelock.h38
-rw-r--r--android/utils/ini.c386
-rw-r--r--android/utils/ini.h126
-rw-r--r--android/utils/misc.c193
-rw-r--r--android/utils/misc.h67
-rw-r--r--android/utils/path.c430
-rw-r--r--android/utils/path.h122
-rw-r--r--android/utils/reflist.c203
-rw-r--r--android/utils/reflist.h129
-rw-r--r--android/utils/stralloc.c300
-rw-r--r--android/utils/stralloc.h60
-rw-r--r--android/utils/system.c172
-rw-r--r--android/utils/system.h161
-rw-r--r--android/utils/tempfile.c198
-rw-r--r--android/utils/tempfile.h52
-rw-r--r--android/utils/timezone.c721
-rw-r--r--android/utils/timezone.h31
-rw-r--r--arm-dis.c4165
-rw-r--r--arm-semi.c469
-rw-r--r--arm.ld154
-rw-r--r--audio/alsaaudio.c1067
-rw-r--r--audio/audio.c2172
-rw-r--r--audio/audio.h185
-rw-r--r--audio/audio_int.h287
-rw-r--r--audio/audio_pt_int.c148
-rw-r--r--audio/audio_pt_int.h22
-rw-r--r--audio/audio_template.h577
-rw-r--r--audio/coreaudio.c821
-rw-r--r--audio/dsound_template.h291
-rw-r--r--audio/dsoundaudio.c1086
-rw-r--r--audio/esdaudio.c682
-rw-r--r--audio/fmodaudio.c685
-rw-r--r--audio/mixeng.c336
-rw-r--r--audio/mixeng.h51
-rw-r--r--audio/mixeng_template.h177
-rw-r--r--audio/noaudio.c172
-rw-r--r--audio/ossaudio.c773
-rw-r--r--audio/rate_template.h111
-rw-r--r--audio/sdlaudio.c660
-rw-r--r--audio/sys-queue.h241
-rw-r--r--audio/wavaudio.c482
-rw-r--r--audio/wavcapture.c166
-rw-r--r--audio/winaudio.c666
-rw-r--r--block-bochs.c254
-rw-r--r--block-cloop.c169
-rw-r--r--block-cow.c267
-rw-r--r--block-dmg.c297
-rw-r--r--block-nbd.c189
-rw-r--r--block-parallels.c176
-rw-r--r--block-qcow.c904
-rw-r--r--block-qcow2.c2620
-rw-r--r--block-raw-posix.c1210
-rw-r--r--block-raw-win32.c526
-rw-r--r--block-vmdk.c834
-rw-r--r--block-vpc.c239
-rw-r--r--block-vvfat.c2847
-rw-r--r--block.c1433
-rw-r--r--block.h158
-rw-r--r--block_int.h150
-rw-r--r--bswap.h209
-rw-r--r--cbuffer.c231
-rw-r--r--cbuffer.h61
-rw-r--r--charpipe.c273
-rw-r--r--charpipe.h26
-rw-r--r--compatfd.c128
-rw-r--r--compatfd.h28
-rw-r--r--console.c1345
-rw-r--r--console.h195
-rw-r--r--cpu-all.h1090
-rw-r--r--cpu-defs.h198
-rw-r--r--cpu-exec.c1487
-rw-r--r--curses.c374
-rw-r--r--curses_keys.h484
-rw-r--r--cutils.c137
-rw-r--r--d3des.c434
-rw-r--r--d3des.h51
-rw-r--r--dcache.c349
-rw-r--r--dcache.h31
-rw-r--r--dis-asm.h478
-rw-r--r--disas.c431
-rw-r--r--disas.h21
-rw-r--r--distrib/Makefile8
-rw-r--r--distrib/README50
-rwxr-xr-xdistrib/build-emulator.sh39
-rwxr-xr-xdistrib/build_gcc_qemu_darwin.sh482
-rw-r--r--distrib/libpng-1.2.19/Makefile25
-rw-r--r--distrib/libpng-1.2.19/png.c895
-rw-r--r--distrib/libpng-1.2.19/png.h3525
-rw-r--r--distrib/libpng-1.2.19/pngconf.h1535
-rw-r--r--distrib/libpng-1.2.19/pngerror.c326
-rw-r--r--distrib/libpng-1.2.19/pnggccrd.c6041
-rw-r--r--distrib/libpng-1.2.19/pngget.c962
-rw-r--r--distrib/libpng-1.2.19/pngmem.c608
-rw-r--r--distrib/libpng-1.2.19/pngpread.c1585
-rw-r--r--distrib/libpng-1.2.19/pngread.c1478
-rw-r--r--distrib/libpng-1.2.19/pngrio.c167
-rw-r--r--distrib/libpng-1.2.19/pngrtran.c4284
-rw-r--r--distrib/libpng-1.2.19/pngrutil.c4189
-rw-r--r--distrib/libpng-1.2.19/pngset.c1284
-rw-r--r--distrib/libpng-1.2.19/pngtrans.c662
-rw-r--r--distrib/libpng-1.2.19/pngvcrd.c3922
-rw-r--r--distrib/libpng-1.2.19/pngwio.c234
-rw-r--r--distrib/libpng-1.2.19/pngwrite.c1530
-rw-r--r--distrib/libpng-1.2.19/pngwtran.c572
-rw-r--r--distrib/libpng-1.2.19/pngwutil.c2782
-rw-r--r--distrib/libpng-1.2.19/sources.make14
-rwxr-xr-xdistrib/make-distrib.sh110
-rwxr-xr-xdistrib/update-audio.sh95
-rw-r--r--distrib/zlib-1.2.3/Makefile15
-rw-r--r--distrib/zlib-1.2.3/adler32.c149
-rw-r--r--distrib/zlib-1.2.3/compress.c79
-rwxr-xr-xdistrib/zlib-1.2.3/configure459
-rw-r--r--distrib/zlib-1.2.3/crc32.c423
-rw-r--r--distrib/zlib-1.2.3/crc32.h441
-rw-r--r--distrib/zlib-1.2.3/deflate.c1736
-rw-r--r--distrib/zlib-1.2.3/deflate.h331
-rw-r--r--distrib/zlib-1.2.3/gzio.c1026
-rw-r--r--distrib/zlib-1.2.3/infback.c623
-rw-r--r--distrib/zlib-1.2.3/inffast.c318
-rw-r--r--distrib/zlib-1.2.3/inffast.h11
-rw-r--r--distrib/zlib-1.2.3/inffixed.h94
-rw-r--r--distrib/zlib-1.2.3/inflate.c1368
-rw-r--r--distrib/zlib-1.2.3/inflate.h115
-rw-r--r--distrib/zlib-1.2.3/inftrees.c329
-rw-r--r--distrib/zlib-1.2.3/inftrees.h55
-rw-r--r--distrib/zlib-1.2.3/sources.make4
-rw-r--r--distrib/zlib-1.2.3/trees.c1219
-rw-r--r--distrib/zlib-1.2.3/trees.h128
-rw-r--r--distrib/zlib-1.2.3/uncompr.c61
-rw-r--r--distrib/zlib-1.2.3/zconf.h332
-rw-r--r--distrib/zlib-1.2.3/zlib.h1357
-rw-r--r--distrib/zlib-1.2.3/zutil.c318
-rw-r--r--distrib/zlib-1.2.3/zutil.h269
-rw-r--r--dyngen-exec.h305
-rw-r--r--dynlink.h110
-rw-r--r--elf.h1172
-rw-r--r--elf_ops.h217
-rw-r--r--exec-all.h392
-rw-r--r--exec.c3201
-rw-r--r--fpu/softfloat-macros.h720
-rw-r--r--fpu/softfloat-native.c505
-rw-r--r--fpu/softfloat-native.h425
-rw-r--r--fpu/softfloat-specialize.h569
-rw-r--r--fpu/softfloat.c5541
-rw-r--r--fpu/softfloat.h444
-rw-r--r--framebuffer.c243
-rw-r--r--framebuffer.h205
-rw-r--r--gdbstub.c1593
-rw-r--r--gdbstub.h19
-rw-r--r--gen-charmap.py180
-rw-r--r--gen-icount.h56
-rwxr-xr-xgen-skin.py78
-rw-r--r--host-defs.h18
-rw-r--r--host-utils.c104
-rw-r--r--host-utils.h204
-rw-r--r--hostregs_helper.h98
-rw-r--r--hpet.h22
-rw-r--r--hw/android_arm.c175
-rw-r--r--hw/arm-misc.h49
-rw-r--r--hw/arm_boot.c251
-rw-r--r--hw/arm_gic.c747
-rw-r--r--hw/arm_pic.c48
-rw-r--r--hw/arm_pic.h25
-rw-r--r--hw/armv7m.c206
-rw-r--r--hw/armv7m_nvic.c407
-rw-r--r--hw/audiodev.h17
-rw-r--r--hw/baum.h29
-rw-r--r--hw/boards.h122
-rw-r--r--hw/cdrom.c157
-rw-r--r--hw/devices.h74
-rw-r--r--hw/dma.c548
-rw-r--r--hw/goldfish_audio.c533
-rw-r--r--hw/goldfish_battery.c261
-rw-r--r--hw/goldfish_device.c200
-rw-r--r--hw/goldfish_device.h58
-rw-r--r--hw/goldfish_events_device.c423
-rw-r--r--hw/goldfish_fb.c405
-rw-r--r--hw/goldfish_interrupt.c190
-rw-r--r--hw/goldfish_memlog.c78
-rw-r--r--hw/goldfish_mmc.c468
-rw-r--r--hw/goldfish_nand.c636
-rw-r--r--hw/goldfish_nand.h28
-rw-r--r--hw/goldfish_nand_reg.h54
-rw-r--r--hw/goldfish_switch.c172
-rw-r--r--hw/goldfish_timer.c256
-rw-r--r--hw/goldfish_trace.c251
-rw-r--r--hw/goldfish_trace.h79
-rw-r--r--hw/goldfish_tty.c226
-rw-r--r--hw/hw.h110
-rw-r--r--hw/irq.c71
-rw-r--r--hw/irq.h34
-rw-r--r--hw/isa.h27
-rw-r--r--hw/mmc.h214
-rw-r--r--hw/pc.h148
-rw-r--r--hw/pci.c701
-rw-r--r--hw/pci.h142
-rw-r--r--hw/pci_host.h93
-rw-r--r--hw/pcmcia.h50
-rw-r--r--hw/power_supply.h109
-rw-r--r--hw/pxa.h227
-rw-r--r--hw/scsi-disk.c809
-rw-r--r--hw/scsi-disk.h36
-rw-r--r--hw/sd.h83
-rw-r--r--hw/smc91c111.c715
-rw-r--r--hw/usb-hid.c896
-rw-r--r--hw/usb-hub.c554
-rw-r--r--hw/usb-msd.c578
-rw-r--r--hw/usb-ohci.c1684
-rw-r--r--hw/usb.c231
-rw-r--r--hw/usb.h291
-rw-r--r--i386-dis.c4120
-rw-r--r--i386-vl.ld140
-rw-r--r--i386.ld142
-rw-r--r--ia64.ld211
-rw-r--r--images/android_icon.icobin300318 -> 0 bytes
-rw-r--r--images/android_icon.rc3
-rw-r--r--images/android_icon_16.pngbin460 -> 0 bytes
-rw-r--r--images/android_icon_256.pngbin13369 -> 0 bytes
-rw-r--r--images/android_icon_32.pngbin1321 -> 0 bytes
-rw-r--r--keymaps.c207
-rw-r--r--kqemu.c1025
-rw-r--r--kqemu.h154
-rw-r--r--linux_keycodes.h452
-rw-r--r--loader.c412
-rw-r--r--loadpng.c275
-rw-r--r--m68k.ld177
-rw-r--r--monitor.c2736
-rw-r--r--net.h58
-rwxr-xr-xoffset_layout.py111
-rw-r--r--osdep.c288
-rw-r--r--osdep.h90
-rw-r--r--ppc-dis.c3246
-rw-r--r--ppc.ld228
-rw-r--r--proxy/proxy_common.c532
-rw-r--r--proxy/proxy_common.h88
-rw-r--r--proxy/proxy_http.c186
-rw-r--r--proxy/proxy_http.h24
-rw-r--r--proxy/proxy_http_connector.c203
-rw-r--r--proxy/proxy_http_int.h38
-rw-r--r--proxy/proxy_http_rewriter.c1125
-rw-r--r--proxy/proxy_int.h201
-rw-r--r--qemu-char.h90
-rw-r--r--qemu-common.h142
-rw-r--r--qemu-lock.h249
-rw-r--r--qemu-log.h7
-rw-r--r--qemu-timer.h50
-rw-r--r--qemu_debug.h5
-rw-r--r--qemu_file.h52
-rw-r--r--qemu_socket.h8
-rw-r--r--qemu_timers.h7
-rw-r--r--readline.c488
-rw-r--r--sdl_keysym.h278
-rw-r--r--shaper.c590
-rw-r--r--shaper.h51
-rw-r--r--slirp2/COPYRIGHT64
-rw-r--r--slirp2/bootp.c263
-rw-r--r--slirp2/bootp.h113
-rw-r--r--slirp2/cksum.c141
-rw-r--r--slirp2/ctl.h10
-rw-r--r--slirp2/debug.c352
-rw-r--r--slirp2/debug.h50
-rw-r--r--slirp2/helper.h111
-rw-r--r--slirp2/icmp_var.h69
-rw-r--r--slirp2/if.c322
-rw-r--r--slirp2/if.h50
-rw-r--r--slirp2/ip.h297
-rw-r--r--slirp2/ip_icmp.c377
-rw-r--r--slirp2/ip_icmp.h166
-rw-r--r--slirp2/ip_input.c702
-rw-r--r--slirp2/ip_output.c205
-rw-r--r--slirp2/libslirp.h50
-rw-r--r--slirp2/main.h57
-rw-r--r--slirp2/mbuf.c287
-rw-r--r--slirp2/mbuf.h121
-rw-r--r--slirp2/misc.c277
-rw-r--r--slirp2/misc.h64
-rw-r--r--slirp2/sbuf.c172
-rw-r--r--slirp2/sbuf.h37
-rw-r--r--slirp2/slirp.c762
-rw-r--r--slirp2/slirp.h276
-rw-r--r--slirp2/slirp_config.h200
-rw-r--r--slirp2/socket.c732
-rw-r--r--slirp2/socket.h107
-rw-r--r--slirp2/tcp.h175
-rw-r--r--slirp2/tcp_input.c1714
-rw-r--r--slirp2/tcp_output.c605
-rw-r--r--slirp2/tcp_subr.c1010
-rw-r--r--slirp2/tcp_timer.c326
-rw-r--r--slirp2/tcp_timer.h142
-rw-r--r--slirp2/tcp_var.h232
-rw-r--r--slirp2/tcpip.h81
-rw-r--r--slirp2/tftp.c430
-rw-r--r--slirp2/tftp.h33
-rw-r--r--slirp2/udp.c495
-rw-r--r--slirp2/udp.h115
-rw-r--r--sockets.c1269
-rw-r--r--sockets.h339
-rw-r--r--softmmu-semi.h70
-rw-r--r--softmmu_defs.h22
-rw-r--r--softmmu_exec.h115
-rw-r--r--softmmu_header.h345
-rw-r--r--softmmu_template.h333
-rw-r--r--sparc.ld131
-rw-r--r--sysemu.h184
-rw-r--r--tap-win32.c688
-rw-r--r--target-arm/cpu.h420
-rw-r--r--target-arm/exec.h63
-rw-r--r--target-arm/helper.c2553
-rw-r--r--target-arm/helpers.h548
-rw-r--r--target-arm/iwmmxt_helper.c682
-rw-r--r--target-arm/machine.c218
-rw-r--r--target-arm/neon_helper.c1457
-rw-r--r--target-arm/op_addsub.h103
-rw-r--r--target-arm/op_helper.c688
-rw-r--r--target-arm/translate.c8963
-rw-r--r--tcg/LICENSE3
-rw-r--r--tcg/README425
-rw-r--r--tcg/TODO15
-rw-r--r--tcg/arm/tcg-target.c1584
-rw-r--r--tcg/arm/tcg-target.h76
-rw-r--r--tcg/hppa/tcg-target.c973
-rw-r--r--tcg/hppa/tcg-target.h204
-rw-r--r--tcg/i386/tcg-target.c1185
-rw-r--r--tcg/i386/tcg-target.h55
-rw-r--r--tcg/ppc/tcg-target.c1492
-rw-r--r--tcg/ppc/tcg-target.h105
-rw-r--r--tcg/ppc64/tcg-target.c1491
-rw-r--r--tcg/ppc64/tcg-target.h105
-rw-r--r--tcg/sparc/tcg-target.c1206
-rw-r--r--tcg/sparc/tcg-target.h122
-rw-r--r--tcg/tcg-dyngen.c431
-rw-r--r--tcg/tcg-op.h1713
-rw-r--r--tcg/tcg-opc.h238
-rw-r--r--tcg/tcg-runtime.c68
-rw-r--r--tcg/tcg.c2081
-rw-r--r--tcg/tcg.h421
-rw-r--r--tcg/x86_64/tcg-target.c1307
-rw-r--r--tcg/x86_64/tcg-target.h77
-rw-r--r--tcpdump.c147
-rw-r--r--tcpdump.h36
-rw-r--r--telephony/Jamfile13
-rw-r--r--telephony/android_modem.c1870
-rw-r--r--telephony/android_modem.h137
-rw-r--r--telephony/gsm.c1220
-rw-r--r--telephony/gsm.h196
-rw-r--r--telephony/modem_driver.c148
-rw-r--r--telephony/modem_driver.h29
-rw-r--r--telephony/remote_call.c430
-rw-r--r--telephony/remote_call.h55
-rw-r--r--telephony/sim_card.c439
-rw-r--r--telephony/sim_card.h54
-rw-r--r--telephony/simulator.c195
-rw-r--r--telephony/sms.c1655
-rw-r--r--telephony/sms.h117
-rw-r--r--telephony/sysdeps.h80
-rw-r--r--telephony/sysdeps_posix.c645
-rw-r--r--telephony/sysdeps_qemu.c376
-rw-r--r--telephony/test1.c49
-rw-r--r--telephony/test2.c215
-rw-r--r--thunk.c288
-rw-r--r--thunk.h161
-rw-r--r--trace.c1879
-rw-r--r--trace.h162
-rw-r--r--trace_common.h139
-rw-r--r--translate-all.c195
-rw-r--r--translate-op.c81
-rw-r--r--translate.make37
-rw-r--r--uboot_image.h160
-rw-r--r--usb-linux.c1506
-rw-r--r--varint.c118
-rw-r--r--varint.h15
-rw-r--r--vgafont.h4611
-rw-r--r--vl.c9803
-rw-r--r--vnc.c2446
-rw-r--r--vnc_keysym.h302
-rw-r--r--vnchextile.h209
-rw-r--r--x86_64.ld171
477 files changed, 0 insertions, 252937 deletions
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 0b02fdb..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# the following test is made to detect that we were called
-# through the 'm' or 'mm' build commands. if not, we use the
-# standard QEMU Makefile
-#
-ifeq ($(DEFAULT_GOAL),droid)
- LOCAL_PATH:= $(call my-dir)
- include $(LOCAL_PATH)/Makefile.android
-else
- include Makefile.qemu
-endif
diff --git a/CHANGES.TXT b/CHANGES.TXT
deleted file mode 100644
index c437e0c..0000000
--- a/CHANGES.TXT
+++ /dev/null
@@ -1,648 +0,0 @@
-Android Emulator changes:
-=========================
-
-Versions:
-
- 1.0 => SDK M3 release
- 1.1 => SDK M5 release
- 1.2 => Internal release (build 72264)
- 1.3 => Internal release (build 77780)
- 1.4 => Internal release (build 84853)
- 1.5 => SDK 0.9_r1
- 1.6 => SDK 1.0_r1
- 1.7 => SDK 1.0_r2
- 1.8 => SDK 1.1
- 1.9 => (unreleased, planned, named likely to change)
-
-==============================================================================
-Changes between 1.8 and 1.9
-
-IMPORTANT CHANGES:
-
-- Many features have been integrated from upstream QEMU sources, including
- the new TCG code generator used by the ARM translator. This should result
- in slightly faster execution speed on all supported platforms.
-
-- The emulator now requires that you specify a virtual device name when
- starting the emulator, prefixed with the '@' sign. For example, to start
- the 'foo' virtual device, type:
-
- emulator @foo
-
- Each AVD (Android Virtual Device) corresponds to a directory used to store
- mutable disk images, an optional system image/kernel/sdcard, plus some
- configuration file(s).
-
- The command-line tool 'android' that comes with the SDK can be used to
- create/list/remove virtual devices on your system.
-
- Note that the '@<name>' form is a convenience shortcut for '-avd <name>'.
- It is thus possible to place options after the AVD name on your command
- line, as in:
-
- emulator @foo -verbose -shell
-
- Finally, when building the Android platform source tree, an AVD name is not
- required and 'emulator' will start a new emulator instance exactly as
- previously.
-
-- Hardware emulation is now limited to the corresponding Android Virtual
- Device's configuration. This means it is now possible to not emulate
- a touch-screen, trackball, dpad, keyboard, modem, etc...
-
- Note that in the case of the Android build system, all hardware properties
- are enabled by default, so this only affects "normal" virtual devices
- created with the 'android' tool.
-
-- The emulator now supports capturing network packets to a file.
- You can either use the new -tcpdump <file> command-line option, or use
- the new console 'network capture start <file>' command (then use
- 'network capture stop' to stop it).
-
- This captures all ethernet packets on the virtual LAN, so this includes
- ARP, UDP, TCP, etc... The file is in libpcap format and can be opened with
- external tools like WireShark for analysis.
-
-OTHER:
-
-- The file in ~/.android/default.keyset was ignored, unless you used
- '-keyset default' explicitely. It is now loaded automatically when
- available.
-
-- Environment variable ANDROID_SDK_ROOT can be used to specifiy the location
- of the SDK.
-
-- Environment variable ANDROID_SDK_HOME can be used to specify the location
- of the '.android' data directory.
-
-- A new console command 'avd name' can be used to query the name of the
- virtual device running in the emulator. Note that it will be '<build>'
- if you run from the Android build system.
-
- Also, the emulator's window title also displays the AVD name now.
-
-- The option '-memory <size>' has been added. <memory> must be an integer
- specifying the amount of physical RAM in the emulated device in megabytes.
- The default value is 96.
-
-- The '-skindir <path>' option now requires that you specify a '-skin <name>'
- option as well.
-
-- Better handling of Audio on Linux for the EsounD and Alsa backends
-
-- Fullscreen toggle should now work on Windows and OS X. On Linux, the
- toggle will not switch the display resolution anymore (which resulted
- in distorted images).
-
-==============================================================================
-Changes between 1.6 and 1.7
-
-IMPORTANT BUG FIXES:
-
-- Properly create ~/.android directory when needed.
-
-- Do not leave temporary files in Android app-specific directory on Win32
-
-- Support for HTTP/HTTPS proxies has been considerably improved and should now
- "just work" with a lot more HTTP proxies. In case of problem, use the
- -debug-proxy option to dump debugging data to stderr.
-
-OTHER:
-
-- Trackball emulation has changed. First, the awkward "Control-T" keybinding
- is gone. Instead, you can now:
-
- - press 'Delete' to show the trackball and have it disappear as soon
- as your release the key.
-
- - press 'F6' to perform a persistent trackball mode toggle.
-
- Also, trackball emulation is fixed in rotated/landscape mode now.
-
-- New option '-nand-limits <limits>' allows you to send a signal to a remote
- process when a read or write threshold on flash storage is reached. This is
- only useful for hardcore Android system hackers.
-
-- Fix emulator build on recent Cygwin releases (the -mno-cygwin headers do not
- tolerate the _GNU_SOURCE macro definition anymore)
-
-- Fix Win32 emulator to support SD Card images larger than 2 GiB
-
-- The non-Android build system has been completely rewritten to allow building
- the emulator on Linux x86_64. Also, there is now a single Makefile that
- drives the build in both Android and non-Android modes.
-
-- '-qemu <other-options>' works again
-
-==============================================================================
-Changes between 1.5 and 1.6
-
-IMPORTANT CHANGES:
-
-- Emulator now saves the user image in <android>/SDK1.0/
-
-OTHER:
-
-- Get rid of EsounD-related freezes on Linux (again)
-
-- Fix the documentation in -help-audio. '-audio list' doesn't work, one
- needs to call -help-audio-out and -help-audio-in to get the list of valid
- audio backends
-
-- Fix scrollwheel Dpad emulation in rotated mode. before that, using the
- scroll-wheel would always generated Dpad Up/Down events, even when in
- landscape mode.
-
-- Re-enable CPU fault emulation in case of unaligned data access. this was
- previously disabled because it crashed the emulated kernel in previous
- releases.
-
-- The emulator no longer prints an obscure warning when it doesn't find
- the emulator.cfg configuration file in ~/.android.
-
- 'broken configuration file doesn't have a 'window' element'
-
-- Removed a bunch of obsolete options (e.g. -console, -adb-port, etc...)
-
-- Setting the network speed through the console or the -netspeed option will
- properly modify the connectivity icon on the device.
-
-- Setting the GSM voice registration state to 'roaming' in the console will
- properly modify the voice icon on the device
-
-==============================================================================
-Changes between 1.4 and 1.5
-
-IMPORTANT BUG FIXES:
-
-- Fix spurious discards of SMS messages when using two emulators.
-
-OTHER:
-
-- Get rid of EsounD-related freezes on Linux (again)
-
-- Fix the documentation in -help-audio. '-audio list' doesn't work; one
- needs to call -help-audio-out and -help-audio-in to get the list of valid
- audio backends
-
-- Fix scrollwheel Dpad emulation in rotated mode. before that, using the
- scroll-wheel would always generated Dpad Up/Down events, even when in
- landscape mode.
-
-- Re-enable CPU fault emulation in case of unaligned data access. This was
- previously disabled because it crashed the emulated kernel in previous
- releases.
-
-==============================================================================
-Changes between 1.3 and 1.4
-
-IMPORTANT BUG FIXES:
-
-- fix for audio-related Linux startup freezes when using the 'esd' and 'alsa'
- backends
-
-- the number of audio buffers in the Windows backend has been incremented.
- this gets rid of audio chopiness issues on Vista (and sometimes on XP too)
-
-NEW FEATURES:
-
-NEW CONSOLE COMMANDS:
-
-- new 'geo fix <lontitude> <latitude> [<altitude>]' command allows you to
- send a simple GPS fix to the emulated system, without the headaches of
- NMEA 1083 formatting.
-
-OTHER BUG FIXES:
-
-- fixed the -audio, -audio-in and -audio-out options (the <backend> values
- were sometimes ignored)
-
-REGRESSIONS:
-
-OTHER:
-
-- the transitional '-qemud' option introduced in 1.3 is now gone. its
- behaviour is now the default.
-
-- use the new '-old-system' option if you need to use a 1.4+ emulator binary
- with older system images. if you don't use it, GSM and GPS emulation will
- not work correctly (among other things).
-
-- the obsolete '-oldradio' option is now gone
-
-- on some Unix systems, SIGALRM is blocked by default, so unblock it when
- creating the alarm timer
-
-- the 'esd' and 'alsa' libraries dump a lot of error messages to the console
- by default on Linux. these are now disabled unless you use '-debug audio'
-
-- added the '-help-char-devices' help topic that describe the specification
- of the <device> parameter of options like -serial, -gps, -shell-serial,
- etc...
-
-KNOWN ISSUES:
-
-- no support for video input
-- no support for mutable SIM Card emulation yet
-- no support for bluetooth
-- no support for WiFi
-
-- on some Linux machines, the emulator might get stuck at startup. this
- seems to be related to audio input support. try starting with
- '-audio-in none' or even '-noaudio' to disable sound, or choose a
- different audio backend by defining QEMU_AUDIO_DRV to an appropriate
- value (read below).
-
- you can also select different audio backends for both output and input
- by defining QEMU_AUDIO_OUT_DRV and QEMU_AUDIO_IN_DRV independently.
-
-- on Windows, the emulator takes about 10-15% of the CPU even when the
- emulated system is idle. this is a known issue related to QEMU's internal
- event loop and Winsock. this should be fixed in a future emulator release.
-
-- GPS emulation only if you use the '-qemud' option. this is an experimental
- option that is soon going to be the default. without this option, the
- emulated system will start but GPS emulation will not work.
-
- for the record, 'qemud' is a serial port multiplexer that is used to
- multiplex several communication channels between the emulator and the
- emulated system, though a single serial port.
-
-==============================================================================
-Changes between 1.2 and 1.3
-
-IMPORTANT BUG FIXES:
-
-NEW FEATURES:
-
-- '-audio-in <backend>' allows you to select the audio input backend from the
- command line. this is equivalent to defining QEMU_AUDIO_IN_DRV=<backend>
-
- '-audio-out <backend>' works for the audio output, and '-audio <backend>'
- will select both input and output at the same time
-
-- '-debug <tags>' has replaced the old '-verbose-<tag1> -verbose-<tag2> ...'
- debugging option. <tags> is a comma-separated list of debug tags
- (see -help-debug-tags for a complete list). you can also use the special
- value 'all' to indicate all debug tags, or prefix a '-' before a tag
- name to disable it. for example:
-
- -debug all,-audio
-
- enables all debugging except audio. '-debug-<tag>' still works though.
-
- note that while '-verbose-<tag>' is deprecated, '-verbose' is still supported
- as an alias to '-debug-init'
-
-- '-keyset <file>' allows you to specific the keyset file to use. the default
- is still ~/.android/default.keyset on Unix. for Windows, use -help-keyset
- to get its default location (which differs between XP and Vista)
-
-
-NEW CONSOLE COMMANDS:
-
-- the 'geo nmea <sentence>' can be used to send a NMEA 1083 sentence as if
- it came from an emulated GPS unit. NOTE: this doesn't work unless you
- also use the '-qemud' option (see KNOWN ISSUES below)
-
-OTHER BUG FIXES:
-
-- severe color artefact issues when scaling the emulator window < 1.0 were
- fixed.
-
-- fix rare random emulator freezes on Linux by disabling the 'dynticks' timer.
-
-REGRESSIONS:
-
-OTHER:
-
-- the ambiguous '-console' option is now obsolete. use '-shell' instead
-
-- the new '-shell-serial <device>' allows you to specify a device to
- connect a root shell session to the emulated system.
-
-- the '-debug-kernel' option is now known as '-show-kernel' (the -debug-
- prefix is reserved for strict emulator debugging features)
-
-- '-adb-port' has been removed from the list of options. similarly
- '-port <port>' will accept an odd port number, but will print a warning
- that it is using <port>-1 instead.
-
-- MMX is used on x86 to speed up window rescaling.
-
-- a new '-qemud' option is required to have GPS support work in this
- SDK (either through '-gps <device>' or the 'geo nmea <sentence>'
- console command)
-
- this option is purely experimental and will soon become the default.
-
-KNOWN ISSUES:
-
-- no support for video input
-- no support for mutable SIM Card emulation yet
-- no support for bluetooth
-- no support for WiFi
-
-- on some Linux machines, the emulator might get stuck at startup. this
- seems to be related to audio input support. try starting with
- '-audio-in none' or even '-noaudio' to disable sound, or choose a
- different audio backend by defining QEMU_AUDIO_DRV to an appropriate
- value (read below).
-
- you can also select different audio backends for both output and input
- by defining QEMU_AUDIO_OUT_DRV and QEMU_AUDIO_IN_DRV independently.
-
-- on Windows, the emulator takes about 10-15% of the CPU even when the
- emulated system is idle. this is a known issue related to QEMU's internal
- event loop and Winsock. this should be fixed in a future emulator release.
-
-- GPS emulation only if you use the '-qemud' option. this is an experimental
- option that is soon going to be the default. without this option, the
- emulated system will start but GPS emulation will not work.
-
- for the record, 'qemud' is a serial port multiplexer that is used to
- multiplex several communication channels between the emulator and the
- emulated system, though a single serial port.
-
-==============================================================================
-Changes between 1.1 and 1.2
-
-
-IMPORTANT BUG FIXES:
-
-- fixed a typo that prevented the F9/F10 keyboard shortcuts from working
- properly, making non-programatically tracing unusable.
-
-- halve the emulator's memory requirements, saving around 130 megabytes
- of memory by changing the way flash images are accessed (we now use
- temporary files instead)
-
-- this emulator binary should be 10% to 20% faster than previous ones on
- the Windows and OS X platforms. for faster boots, you may also want to
- use the -no-boot-anim option described below to speed up the initial
- boot sequence as well on slow machines.
-
-- proper rotation support when using Keypad 7/9 to switch between layouts
- in the default HVGA skin. no need to use Ctrl-PageDown anymore
-
-- the -http-proxy <proxy> option didn't work correctly on Windows (unless
- you were very lucky).
-
-- general socket handling code on Windows has been significantly improved.
-
-
-NEW FEATURES:
-
-- the console port number of a given emulator instance is now displayed in
- its window's title bar.
-
-- voice/sms are automatically forwarded to other emulator instances running
- on the same machine, as long as you use their console port number as the
- destination phone number.
-
- for example, if you have two emulator running, the first one will usually
- use console port 5554, and the second one will use port 5556
-
- then dialing 5556 on the 1st emulator will generate an incoming call on
- the 2nd emulator. you can also hold/unhold calls as well.
-
- this also works when sending SMS messages from one emulator to the other
-
-- the help system has been totally revamped:
-
- * -help prints a summary of all options and help topics
- * -help-<option> prints option-specific help
- * -help-<topic> prints various topical help text
- * -help-all prints *all* help content at once
-
-- the emulator now tries to automatically detect the host time zone and sends
- it to the emulated system at startup (through the GSM modem). there is also
- a new '-timezone <timezone>' option to be able to specify a different one.
-
- IMPORTANT: the <timezone> name must be in zoneinfo format, i.e.
- Area/Location, human-friendly abbreviations like "PST" or "CET"
- will not work. examples are:
-
- America/Los_Angeles
- Europe/Paris
-
-- the emulator can now use up to 4 distinct DNS servers (instead of only one).
- by default, they are taken from your system's list, which is obtained by
- calling GetNetworkParams() on Win32, and parsing /etc/resolv.conf on
- Unix.
-
-- a new '-dns-server <server>' option can be used to specify a comma-separated
- list of alternative DNS servers to be used by the emulated system, instead of
- the system's default.
-
-- a new '-scale <fraction>' option allows you to scale the emulator
- window. <fraction> can be a number between 0.1 and 3.0.
-
- you can also use '-scale <value>dpi', (e.g. '-scale 110dpi') to indicate the
- resolution of your host monitor screen. it will be divided by the emulated
- device's resolution to get an absolute scale.
-
-- a new '-dpi-device <dpi>' option allows you to specific the resolution of
- the emulated device's screen. Note that this is not required: the default
- used is 165, which is the average of several prototypes we've been working
- with.
-
-- add a new '-port <port>' option to specify which port the emulator should
- bind to for the console, instead of letting it guess. <port> must be an
- *even* integer between 5554 and 5584 included. the corresponding ADB port
- will be <port>+1
-
-- [DEPRECATED] add a new '-adb-port <port>' option to specify which port the
- emulator should bind to, instead of letting it guess. <port> must be an odd
- integer between 5555 and 5585 included. the corresponding control console
- will be on <port>-1
-
- NOTE: -adb-port is deprecated, don't use it, it will probably disappear
- NOTE2: you cannot use both -port and -adb-port at the same time.
-
-- a new '-no-boot-anim' options tells the emulated system to disable the boot
- animation. on slow systems, this can *significantly* reduce the time to
- boot the system in the emulator.
-
-- you can now redefine the emulator's keybinding by writing a 'keyset' file
- and use '-keyset <filename>' to use it when starting the emulator. use
- -help-keyset and -help-keyset-file for all details.
-
- this allows you to use the emulator effectively on keyboards which don't
- have a keypad, by using different keys..
-
-- you can now toggle between windowed and fullscreen mode at runtime by
- pressing Alt-Enter (only works on Linux at the moment !!)
-
-- use '-audio-out <backend>' and '-audio-in <backend>' to change the output
- and input audio backends used by the emulator. see -help-audio-out and
- -help-audio-in for a list of valid values.
-
- this is equivalent to setting the QEMU_AUDIO_OUT_DRV and QEMU_AUDIO_IN_DRV
- environment variables.
-
- use '-audio <backend>' to set both the input and output backends at the
- same time. this is equivalent to setting the QEMU_AUDIO_DRV environment
- variable.
-
-
-NEW CONSOLE COMMANDS:
-
-- the new 'power' command can be used to control the power/battery state of
- the emulated device.
-
-- the new 'event send' command can be used to send simulated hardware events
- to the Android Linux kernel. each event must be in the form
- <type>:<code>:<value> where:
-
- <type> is either an integer or a corresponding string alias
- (use "event types" to see a list of aliases)
-
- <code> is either an integer or a corresponding string alias
- that depends on the value of <type> (use "event codes <type>"
- to see a list of these aliases)
-
- <value> is an integer
-
- NOTE: Be warned that it is very easy to confuse the kernel about the state
- of emulated hardware by sending the wrong event. An *excellent*
- knowledge of the Linux kernel internals is encouraged before playing
- with "event send".
-
-- the new 'event text <textMessage>' command can be used to simulate
- keypresses of small text messages, where <textMessage> is an utf-8 string.
-
-- the new 'avd stop' and 'avd start' command can be used to stop/start the
- emulation. you can also use 'avd status' to query the current state.
-
-- the new 'window scale <scale>' command allows you to change the scale of
- the emulator window dynamically. <scale> is either an integer followed by
- the 'dpi' suffix (e.g. '120dpi') or a real number between 0.1 and 3.0.
-
- in the first case, <scale> specifies your monitor dpi; in the second one,
- the new window scale itself.
-
-
-OTHER BUG FIXES:
-
-- in case of SDL_Init() failure, print the SDL error message.
-- disable networking code's logging to /tmp/slirp.log
-- the emulator now works with 2GB SD Card files
-- the emulator doesn't prevent the screensaver to kick in on OS X anymore
-- the -onion and -onion-alpha options now work properly
-- a second emulator instance trying to use the same SD Card instance than a
- first one will no longer crash
-- it's now possible to properly start the emulator in the background on all
- Unix shells (e.g. "emulator &") without being interrupted/stopped by a
- SIGTTIN or SIGTTOU signal.
-- fixed a bug in the SMS emulation that happened when using GSM 7-bit escaped
- characters, i.e. anything in the following: [|]~\{}^
-- fixed a small regression where -data <foo> would fail if the file <foo>
- did not exist.
-
-
-REGRESSIONS:
-
-- the -flash-keys options doesn't work anymore
-
-
-KNOWN ISSUES:
-
-- no support for video input
-- no support for mutable SIM Card emulation yet
-- no support for bluetooth
-- no support for WiFi
-
-- on some Linux machines, the emulator might get stuck at startup. this
- seems to be related to audio input support. try starting with
- '-audio-in none' or even '-noaudio' to disable sound, or choose a different
- audio backend by defining QEMU_AUDIO_DRV to an appropriate value
- (read below).
-
- you can also select different audio backends for both output and input
- by defining QEMU_AUDIO_OUT_DRV and QEMU_AUDIO_IN_DRV independently.
-
-- on Windows, the emulator takes about 10-15% of the CPU even when the
- emulated system is idle. this is a known issue related to QEMU's internal
- event loop and Winsock. this should be fixed in a future emulator release.
-
-OTHER:
-
-- you can now use -debug-<component> and/or -debug-no-<component> to
- enable or disable the debug messages of a given emulator component. this
- can be very useful for troubleshooting. for all details, use -help-debug
- and -help-debug-tags
-
-- you can also use '-debug <tags>' where <tags> is a comma-separated list
- of component names, optionally prefixed by a single '-'. see -help-debug
- and -help-debug-tags for all details
-
-- you can now define the ANDROID_VERBOSE environment variable as a list
- of "debug" items (each <item> corresponds to a -debug-<item> option).
- for example, defining:
-
- ANDROID_VERBOSE=socket,keys
-
- is equivalent to using "-debug socket,keys" when invoking the emulator
-
-- as a special case, -debug-slirp enables logging of the router/firewall
- operations to a temporary file (e.g. /tmp/android/slirp.log). you can
- also specify a logging bitmask with the ANDROID_SLIRP_LOGMASK environment
- variable (the default is a mask of 7).
-
-- removed many obsolete / unused source files from the repository. also
- performed a rather heavy cleanup of the sources to make them somewhat
- more manageable.
-
-- integrate dynticks support from upstream QEMU depot. this only allows one
- to provide more precise timing accuracy in the guest under Linux.
- (NOTE: disabled in the source code, since it seems that it freezes
- the emulator sometimes)
-
-- audio input is now working on OS X, Windows and Linux. on Linux, there
- are four different backends supported: EsounD, ALSA, OSS and SDL. they
- are accessed through dlopen/dlsym, which means that the emulator binary
- will run on any system.
-
- you can specify a given backend by defining the QEMU_AUDIO_DRV environment
- variable to one of these values:
-
- alsa
- esd
- sdl
- oss
- none
-
- note that the "sdl" audio backend is the most compatible, but doesn't
- support audio input at all !!
-
-- a new option '-cpu-delay <delay>' can be used to slow down the CPU
- emulation. the <delay> is an integer between 0 and 1000. note that it
- doesn't necessarily scale linearly with effective performance.
-
- the delay process is not exactly deterministic. this is just a hack that
- may disappear or be completely re-implemented in the future
-
-- some new "gsm" and "sms" subcommands were added to the control console.
- they are used internally by the voice/sms auto-forwarder and are probably
- not very useful to typical developers
-
-- some code has been added to support save/restore of the AVD state to/from
- a file. however this is not properly tested yet, and requires that you
- use exactly the same options and disk images when reloading the AVD state.
-
-- added a new -cache <file> option to specify the cache partition image
- file. the default is to use a temporary file instead
-
-- added a new -report-console <socket> option to be able to report the
- automatically assigned console port to a remote third-party (e.g. a
- script) before starting the emulation. see the output of -help for all
- the details
-
-- (only useful to Android engineers)
- the audio sub-system is now compiled in its own static library (called
- libqemu-audio.a), which gets copied to the Android "prebuilt/Linux/qemu"
- directory. this is done to avoid forcing all developers to install various
- development packages on Linux, as well as all build servers. there is also
- now a script named "distrib/update-audio.sh" which will update the depot
- file automatically for you: call it whenever you change the audio sources.
diff --git a/COPYING b/COPYING
deleted file mode 100644
index e77696a..0000000
--- a/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/COPYING.LIB b/COPYING.LIB
deleted file mode 100644
index 223ede7..0000000
--- a/COPYING.LIB
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/Changelog b/Changelog
deleted file mode 100644
index 58f3e5e..0000000
--- a/Changelog
+++ /dev/null
@@ -1,395 +0,0 @@
-version 0.8.2:
-
- - ACPI support
- - PC VGA BIOS fixes
- - switch to OpenBios for SPARC targets (Blue Swirl)
- - VNC server fixes
- - MIPS FPU support (Marius Groeger)
- - Solaris/SPARC host support (Ben Taylor)
- - PPC breakpoints and single stepping (Jason Wessel)
- - USB updates (Paul Brook)
- - UDP/TCP/telnet character devices (Jason Wessel)
- - Windows sparse file support (Frediano Ziglio)
- - RTL8139 NIC TCP segmentation offloading (Igor Kovalenko)
- - PCNET NIC support (Antony T Curtis)
- - Support for variable frequency host CPUs
- - Workaround for win32 SMP hosts
- - Support for AMD Flash memories (Jocelyn Mayer)
- - Audio capture to WAV files support (malc)
-
-version 0.8.1:
-
- - USB tablet support (Brad Campbell, Anthony Liguori)
- - win32 host serial support (Kazu)
- - PC speaker support (Joachim Henke)
- - IDE LBA48 support (Jens Axboe)
- - SSE3 support
- - Solaris port (Ben Taylor)
- - Preliminary SH4 target (Samuel Tardieu)
- - VNC server (Anthony Liguori)
- - slirp fixes (Ed Swierk et al.)
- - USB fixes
- - ARM Versatile Platform Baseboard emulation (Paul Brook)
-
-version 0.8.0:
-
- - ARM system emulation: Arm Integrator/CP board with an arm1026ej-s
- cpu (Paul Brook)
- - SMP support
- - Mac OS X cocoa improvements (Mike Kronenberg)
- - Mac OS X CoreAudio driver (Mike Kronenberg)
- - DirectSound driver (malc)
- - ALSA audio driver (malc)
- - new audio options: '-soundhw' and '-audio-help' (malc)
- - ES1370 PCI audio device (malc)
- - Initial USB support
- - Linux host serial port access
- - Linux host low level parallel port access
- - New network emulation code supporting VLANs.
- - MIPS and MIPSel User Linux emulation
- - MIPS fixes to boot Linux (Daniel Jacobowitz)
- - NX bit support
- - Initial SPARC SMP support (Blue Swirl)
- - Major overhaul of the virtual FAT driver for read/write support
- (Johannes Schindelin)
-
-version 0.7.2:
-
- - x86_64 fixes (Win2000 and Linux 2.6 boot in 32 bit)
- - merge self modifying code handling in dirty ram page mecanism.
- - MIPS fixes (Ralf Baechle)
- - better user net performances
-
-version 0.7.1:
-
- - read-only Virtual FAT support (Johannes Schindelin)
- - Windows 2000 install disk full hack (original idea from Vladimir
- N. Oleynik)
- - VMDK disk image creation (Filip Navara)
- - SPARC64 progress (Blue Swirl)
- - initial MIPS support (Jocelyn mayer)
- - MIPS improvements (Ralf Baechle)
- - 64 bit fixes in user networking (initial patch by Gwenole Beauchesne)
- - IOAPIC support (Filip Navara)
-
-version 0.7.0:
-
- - better BIOS translation and HDD geometry auto-detection
- - user mode networking bug fix
- - undocumented FPU ops support
- - Cirrus VGA: support for 1280x1024x[8,15,16] modes
- - 'pidfile' option
- - .dmg disk image format support (Johannes Schindelin)
- - keymaps support (initial patch by Johannes Schindelin)
- - big endian ARM support (Lennert Buytenhek)
- - added generic 64 bit target support
- - x86_64 target support
- - initial APIC support
- - MMX/SSE/SSE2/PNI support
- - PC parallel port support (Mark Jonckheere)
- - initial SPARC64 support (Blue Swirl)
- - SPARC target boots Linux (Blue Swirl)
- - armv5te user mode support (Paul Brook)
- - ARM VFP support (Paul Brook)
- - ARM "Angel" semihosting syscalls (Paul Brook)
- - user mode gdb stub support (Paul Brook)
- - Samba 3 support
- - initial Cocoa support (Pierre d'Herbemont)
- - generic FPU emulation code
- - Virtual PC read-only disk image support (Alex Beregszaszi)
-
-version 0.6.1:
-
- - Mac OS X port (Pierre d'Herbemont)
- - Virtual console support
- - Better monitor line edition
- - New block device layer
- - New 'qcow' growable disk image support with AES encryption and
- transparent decompression
- - VMware 3 and 4 read-only disk image support (untested)
- - Support for up to 4 serial ports
- - TFTP server support (Magnus Damm)
- - Port redirection support in user mode networking
- - Support for not executable data sections
- - Compressed loop disk image support (Johannes Schindelin)
- - Level triggered IRQ fix (aka NE2000 PCI performance fix) (Steve
- Wormley)
- - Fixed Fedora Core 2 problems (now you can run qemu without any
- LD_ASSUME_KERNEL tricks on FC2)
- - DHCP fix for Windows (accept DHCPREQUEST alone)
- - SPARC system emulation (Blue Swirl)
- - Automatic Samba configuration for host file access from Windows.
- - '-loadvm' and '-full-screen' options
- - ne2000 savevm support (Johannes Schindelin)
- - Ctrl-Alt is now the default grab key. Ctrl-Alt-[0-9] switches to
- the virtual consoles.
- - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
- - Floppy fixes for NT4 and NT5 (Mike Nordell)
- - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
- - SDL Audio support and SB16 fixes (malc)
- - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
- - VGA font change fix
- - VGA read-only CRTC register fix
-
-version 0.6.0:
-
- - minimalist FPU exception support (NetBSD FPU probe fix)
- - cr0.ET fix (Win95 boot)
- - *BSD port (Markus Niemisto)
- - I/O access fix (signaled by Mark Jonckheere)
- - IDE drives serial number fix (Mike Nordell)
- - int13 CDROM BIOS fix (aka Solaris x86 install CD fix)
- - int15, ah=86 BIOS fix (aka Solaris x86 hardware probe hang up fix)
- - BSR/BSF "undefined behaviour" fix
- - vmdk2raw: convert VMware disk images to raw images
- - PCI support
- - NE2K PCI support
- - dummy VGA PCI support
- - VGA font selection fix (Daniel Serpell)
- - PIC reset fix (Hidemi KAWAI)
- - PIC spurious irq support (aka Solaris install bug)
- - added '-localtime' option
- - Cirrus CL-GD54xx VGA support (initial patch by Makoto Suzuki (suzu))
- - APM and system shutdown support
- - Fixed system reset
- - Support for other PC BIOSes
- - Initial PowerMac hardware emulation
- - PowerMac/PREP OpenFirmware compatible BIOS (Jocelyn Mayer)
- - initial IDE BMDMA support (needed for Darwin x86)
- - Set the default memory size for PC emulation to 128 MB
-
-version 0.5.5:
-
- - SDL full screen support (initial patch by malc)
- - VGA support on PowerPC PREP
- - VBE fixes (Matthew Mastracci)
- - PIT fixes (aka Win98 hardware probe and "VGA slowness" bug)
- - IDE master only fixes (aka Win98 CD-ROM probe bug)
- - ARM load/store half word fix (Ulrich Hecht)
- - FDC fixes for Win98
-
-version 0.5.4:
-
- - qemu-fast fixes
- - BIOS area protection fix (aka EMM386.EXE fix) (Mike Nordell)
- - keyboard/mouse fix (Mike Nordell)
- - IDE fixes (Linux did not recognized slave drivers)
- - VM86 EIP masking fix (aka NT5 install fix) (Mike Nordell)
- - QEMU can now boot a PowerPC Linux kernel (Jocelyn Mayer)
- - User mode network stack
- - imul imm8 fix + 0x82 opcode support (Hidemi KAWAI)
- - precise self modifying code (aka BeOS install bug)
-
-version 0.5.3:
-
- - added Bochs VESA VBE support
- - VGA memory map mode 3 access fix (OS/2 install fix)
- - IDE fixes (Jens Axboe)
- - CPU interrupt fixes
- - fixed various TLB invalidation cases (NT install)
- - fixed cr0.WP semantics (XP install)
- - direct chaining support for SPARC and PowerPC (faster)
- - ARM NWFPE support (initial patch by Ulrich Hecht)
- - added specific x86 to x86 translator (close to native performance
- in qemu-i386 and qemu-fast)
- - shm syscalls support (Paul McKerras)
- - added accurate CR0.MP/ME/TS emulation
- - fixed DMA memory write access (Win95 boot floppy fix)
- - graphical x86 linux loader
- - command line monitor
- - generic removable device support
- - support of CD-ROM change
- - multiple network interface support
- - initial x86-64 host support (Gwenole Beauchesne)
- - lret to outer priviledge fix (OS/2 install fix)
- - task switch fixes (SkyOS boot)
- - VM save/restore commands
- - new timer API
- - more precise RTC emulation (periodic timers + time updates)
- - Win32 port (initial patch by Kazu)
-
-version 0.5.2:
-
- - improved soft MMU speed (assembly functions and specializing)
- - improved multitasking speed by avoiding flushing TBs when
- switching tasks
- - improved qemu-fast speed
- - improved self modifying code handling (big performance gain in
- softmmu mode).
- - fixed IO checking
- - fixed CD-ROM detection (win98 install CD)
- - fixed addseg real mode bug (GRUB boot fix)
- - added ROM memory support (win98 boot)
- - fixed 'call Ev' in case of paging exception
- - updated the script 'qemu-binfmt-conf.sh' to use QEMU automagically
- when launching executables for the supported target CPUs.
- - PowerPC system emulation update (Jocelyn Mayer)
- - PC floppy emulation and DMA fixes (Jocelyn Mayer)
- - polled mode for PIC (Jocelyn Mayer)
- - fixed PTE dirty bit handling
- - fixed xadd same reg bug
- - fixed cmpxchg exception safeness
- - access to virtual memory in gdb stub
- - task gate and NT flag fixes
- - eflags optimisation fix for string operations
-
-version 0.5.1:
-
- - float access fixes when using soft mmu
- - PC emulation support on PowerPC
- - A20 support
- - IDE CD-ROM emulation
- - ARM fixes (Ulrich Hecht)
- - SB16 emulation (malc)
- - IRET and INT fixes in VM86 mode with IOPL=3
- - Port I/Os use TSS io map
- - Full task switching/task gate support
- - added verr, verw, arpl, fcmovxx
- - PowerPC target support (Jocelyn Mayer)
- - Major SPARC target fixes (dynamically linked programs begin to work)
-
-version 0.5.0:
-
- - full hardware level VGA emulation
- - graphical display with SDL
- - added PS/2 mouse and keyboard emulation
- - popw (%esp) fix
- - mov to/from segment data width fix
- - added real mode support
- - added Bochs BIOS and LGPL'ed VGA BIOS loader in qemu
- - m68k host port (Richard Zidlicky)
- - partial soft MMU support for memory mapped I/Os
- - multi-target build
- - fixed: no error code in hardware interrupts
- - fixed: pop ss, mov ss, x and sti disable hardware irqs for the next insn
- - correct single stepping thru string operations
- - preliminary SPARC target support (Thomas M. Ogrisegg)
- - tun-fd option (Rusty Russell)
- - automatic IDE geometry detection
- - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}.
- - added man page
- - added full soft mmu mode to launch unpatched OSes.
-
-version 0.4.3:
-
- - x86 exception fix in case of nop instruction.
- - gcc 3.2.2 bug workaround (RedHat 9 fix)
- - sparc and Alpha host fixes
- - many ARM target fixes: 'ls' and 'bash' can be launched.
-
-version 0.4.2:
-
- - many exception handling fixes (can compile a Linux kernel inside vl)
- - IDE emulation support
- - initial GDB stub support
- - deferred update support for disk images (Rusty Russell)
- - accept User Mode Linux Copy On Write disk images
- - SMP kernels can at least be booted
-
-version 0.4.1:
-
- - more accurate timer support in vl.
- - more reliable NE2000 probe in vl.
- - added 2.5.66 kernel in vl-test.
- - added VLTMPDIR environment variable in vl.
-
-version 0.4:
-
- - initial support for ring 0 x86 processor emulation
- - fixed signal handling for correct dosemu DPMI emulation
- - fast x86 MMU emulation with mmap()
- - fixed popl (%esp) case
- - Linux kernel can be executed by QEMU with the 'vl' command.
-
-version 0.3:
-
- - initial support for ARM emulation
- - added fnsave, frstor, fnstenv, fldenv FPU instructions
- - added FPU register save in signal emulation
- - initial ARM port
- - Sparc and Alpha ports work on the regression test
- - generic ioctl number conversion
- - fixed ioctl type conversion
-
-version 0.2:
-
- - PowerPC disassembly and ELF symbols output (Rusty Russell)
- - flock support (Rusty Russell)
- - ugetrlimit support (Rusty Russell)
- - fstat64 fix (Rusty Russell)
- - initial Alpha port (Falk Hueffner)
- - initial IA64 port (Matt Wilson)
- - initial Sparc and Sparc64 port (David S. Miller)
- - added HLT instruction
- - LRET instruction fix.
- - added GPF generation for I/Os.
- - added INT3 and TF flag support.
- - SHL instruction C flag fix.
- - mmap emulation for host page size > 4KB
- - self-modifying code support
- - better VM86 support (dosemu works on non trivial programs)
- - precise exception support (EIP is computed correctly in most cases)
- - more precise LDT/GDT/IDT emulation
- - faster segment load in vm86 mode
- - direct chaining of basic blocks (faster emulation)
-
-version 0.1.6:
-
- - automatic library search system. QEMU can now work with unpatched
- ELF dynamic loader and libc (Rusty Russell).
- - ISO C warning fixes (Alistair Strachan)
- - first self-virtualizable version (works only as long as the
- translation cache is not flushed)
- - RH9 fixes
-
-version 0.1.5:
-
- - ppc64 support + personality() patch (Rusty Russell)
- - first Alpha CPU patches (Falk Hueffner)
- - removed bfd.h dependancy
- - fixed shrd, shld, idivl and divl on PowerPC.
- - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
-
-version 0.1.4:
-
- - more accurate VM86 emulation (can launch small DOS 16 bit
- executables in wine).
- - fixed push/pop fs/gs
- - added iret instruction.
- - added times() syscall and SIOCATMARK ioctl.
-
-version 0.1.3:
-
- - S390 support (Ulrich Weigand)
- - glibc 2.3.x compile fix (Ulrich Weigand)
- - socketcall endian fix (Ulrich Weigand)
- - struct sockaddr endian fix (Ulrich Weigand)
- - sendmsg/recvmsg endian fix (Ulrich Weigand)
- - execve endian fix (Ulrich Weigand)
- - fdset endian fix (Ulrich Weigand)
- - partial setsockopt syscall support (Ulrich Weigand)
- - more accurate pushf/popf emulation
- - first partial vm86() syscall support (can be used with runcom example).
- - added bound, cmpxchg8b, cpuid instructions
- - added 16 bit addressing support/override for string operations
- - poll() fix
-
-version 0.1.2:
-
- - compile fixes
- - xlat instruction
- - xchg instruction memory lock
- - added simple vm86 example (not working with QEMU yet). The 54 byte
- DOS executable 'pi_10.com' program was released by Bertram
- Felgenhauer (more information at http://www.boo.net/~jasonp/pipage.html).
-
-version 0.1.1:
-
- - glibc 2.2 compilation fixes
- - added -s and -L options
- - binary distribution of x86 glibc and wine
- - big endian fixes in ELF loader and getdents.
-
-version 0.1:
-
- - initial public release.
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 95b64e1..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,119 +0,0 @@
-This package contains the sources to the Android emulator program.
-
-Supported Development Platforms:
---------------------------------
-
-The Android emulator can be built on the following platforms:
-
- - Linux 32-bits
- - Linux 64-bits (*only* generates 32-bit emulator binary)
- - Darwin x86
- - Darwin ppc (experimental only)
- - Windows x86 (through Cygwin only)
-
-Note that development on 64-bit versions of Darwin and Windows is
-not supported. The 32-bit emulator binary should run normally on
-these platforms though.
-
-The Windows emulator binary is built using the -no-cygwin option
-and thus doesn't depend on CYGWIN.DLL being installed on your system.
-
-It is possible to hack the android-configure.sh script to build
-a 64-bit emulator binary on Linux. Unfortunately the resulting
-program will crash pretty soon during emulation. This problem is
-due to the way the emulator works and cannot be easily fixed at
-the moment.
-
-Supported Compilers:
---------------------
-
-The Android emulator is a heavy fork of QEMU 0.8.2, and as such,
-can only be built properly with a small number of compilers. Moreover,
-which compiler can be used depends on your platform.
-
-The following table sums up the compilers that are *known* to produce
-correct output:
-
- Linux x86: gcc-3.4.6
- Linux x86 and x86_64: gcc-4.2.3
- Darwin x86: gcc-4.0.1 (build 5341)
- Darwin ppc: gcc-3.3 (build 1819)
-
-Use any other compiler at your own risks ! A 'bad binary' usually
-results in the VM crashing either immediately or after a few seconds.
-
-Note that on Darwin, the *build* number of your compiler *is* important.
-Some builds of gcc-4.0.1 are known to generate bad binaries on Darwin x86,
-so your own fails to build an executable that works correctly.
-You can find the sources to the required gcc here:
-
-
-We distribute a file named distrib/build_gcc_qemu_darwin.sh which can be
-used as a replacement for the Apple-provided build_gcc.sh that comes with
-their gcc distribution.
-
-
-Building the emulator with the Android build system:
-----------------------------------------------------
-
-Ensure that you have properly configured your build by running the
-envsetup.sh script and using the appropriate 'lunch' command.
-
-Then type:
-
- m emulator
-
-This will rebuild the emulator and place it in an adequate location.
-Simply type 'emulator' to start it with the currently built system
-image.
-
-
-Building the emulator without the Android build system:
--------------------------------------------------------
-
-You can also build the emulator as a stand-alone program, by following
-these simple steps:
-
- 1/ First, build Android's patched libSDL as a static library,
- this can be done as:
-
- cd $TOP/extlibs/libsdl-1.2.12
- ./android-configure --prefix=<PATH>
- make
- make install
-
- Where $TOP is the path of your open-source Android source tree, and
- where <PATH> is any path of your chosing where the library will
- be copied to by the 'make install' command. For example, you
- can use $HOME/android-sdl
-
- 2/ Configure the emulator with android-configure.sh, as in:
-
- cd $TOP/tools/qemu
- ./android-configure.sh --sdl-config=<PATH>
- make
-
- Where <PATH> is the same path you used with the --prefix option
- when building the SDL library
-
-The emulator binary is located into objs/emulator, you can strip it and
-copy it to any location of your choosing.
-
-
-Creating an emulator source distribution package:
--------------------------------------------------
-
-We provide a script to build a tar.gz package file that contains all the
-sources required to rebuild the emulator (i.e. it includes the patched SDL
-sources as well) plus a handy script to automate the rebuild.
-
-Simply invoke:
-
- cd $TOP/tools/qemu
- distrib/make-distrib.sh
-
-This script will create a tar.gz file under /tmp/android-package and will
-print its location when it completes.
-
-To rebuild the corresponding emulator, un-tar-gz the package, and run
-the 'rebuild.sh' script.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index bfc9a1f..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,12 +0,0 @@
-The following points clarify the QEMU licenses:
-
-1) The QEMU virtual CPU core library (libqemu.a) and the QEMU PC
- system emulator are released under the GNU Lesser General Public
- License.
-
-2) The Linux user mode QEMU emulator is released under the GNU General
- Public License.
-
-3) QEMU is a trademark of Fabrice Bellard.
-
-Fabrice Bellard. \ No newline at end of file
diff --git a/MODULE_LICENSE_GPL b/MODULE_LICENSE_GPL
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_GPL
+++ /dev/null
diff --git a/Makefile b/Makefile
deleted file mode 100644
index f39a14c..0000000
--- a/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# this is a set of definitions that allow the usage of Makefile.android
-# even if we're not using the Android build system.
-#
-
-BUILD_SYSTEM := android/build
-OBJS_DIR := objs
-CONFIG_MAKE := $(OBJS_DIR)/config.make
-CONFIG_H := $(OBJS_DIR)/config-host.h
-
-ifeq ($(wildcard $(CONFIG_MAKE)),)
- $(error "The configuration file '$(CONFIG_MAKE)' doesnt' exist, please run the "rebuilt.sh" script)
-endif
-
-include $(CONFIG_MAKE)
-include $(BUILD_SYSTEM)/definitions.make
-
-VPATH := $(OBJS_DIR)
-VPATH += :$(SRC_PATH)/android/config
-VPATH += :$(SRC_PATH):$(SRC_PATH)/target-$(TARGET_ARCH)
-
-.PHONY: all libraries executables clean clean-config clean-objs-dir \
- clean-executables clean-libraries
-
-CLEAR_VARS := $(BUILD_SYSTEM)/clear_vars.make
-BUILD_HOST_EXECUTABLE := $(BUILD_SYSTEM)/host_executable.make
-BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/host_static_library.make
-
-DEPENDENCY_DIRS :=
-
-all: libraries executables
-EXECUTABLES :=
-LIBRARIES :=
-
-SDL_CONFIG ?= $(PREBUILT)/sdl/bin/sdl-config
-SDL_LIBS := $(filter %.a,$(shell $(SDL_CONFIG) --static-libs))
-$(foreach lib,$(SDL_LIBS), \
- $(eval $(call copy-prebuilt-lib,$(lib))) \
-)
-
-clean: clean-intermediates
-
-distclean: clean clean-config
-
-# let's roll
-include Makefile.android
-
-libraries: $(LIBRARIES)
-executables: $(EXECUTABLES)
-
-clean-intermediates:
- rm -rf $(OBJS_DIR)/intermediates $(EXECUTABLES) $(LIBRARIES)
-
-clean-config:
- rm -f $(CONFIG_MAKE) $(CONFIG_H)
-
-# include dependency information
-DEPENDENCY_DIRS := $(sort $(DEPENDENCY_DIRS))
--include $(wildcard $(DEPENDENCY_DIRS:%=%/*.d)) \ No newline at end of file
diff --git a/Makefile.android b/Makefile.android
deleted file mode 100644
index fe89e4a..0000000
--- a/Makefile.android
+++ /dev/null
@@ -1,537 +0,0 @@
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_PATH:= $(call my-dir)
-
-# determine the location of platform-specific directories
-#
-CONFIG_DIRS := \
- $(LOCAL_PATH)/android/config \
- $(LOCAL_PATH)/android/config/$(HOST_PREBUILT_TAG)
-
-CONFIG_INCLUDES := $(CONFIG_DIRS:%=-I%)
-
-MY_CFLAGS := $(CONFIG_INCLUDES) -O2 -g \
- -fno-PIC \
- -falign-functions=0 \
- -fomit-frame-pointer \
-
-MY_LDFLAGS :=
-
-# this is needed to build the emulator on 64-bit Linux systems
-ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
- MY_CFLAGS += -Wa,--32
-endif
-
-ifeq ($(HOST_OS),freebsd)
- MY_CFLAGS += -Wa,--32 -I /usr/local/include
-endif
-
-ifeq ($(HOST_OS),windows)
- MY_CFLAGS += -D_WIN32 -mno-cygwin
- # we need Win32 features that are available since Windows 2000 Professional/Server (NT 5.0)
- MY_CFLAGS += -DWINVER=0x501
-endif
-
-ifeq ($(HOST_ARCH),ppc)
- MY_CFLAGS += -D__powerpc__
-endif
-
-ifeq ($(HOST_OS),darwin)
- MY_CFLAGS += -mdynamic-no-pic
-endif
-MY_CC := $(HOST_CC)
-
-# BUILD_STANDALONE_EMULATOR is only defined when building with
-# the android-rebuild.sh script. The script will also provide
-# adequate values for HOST_CC
-#
-ifneq ($(BUILD_STANDALONE_EMULATOR),true)
-
- ifneq ($(USE_CCACHE),)
- MY_CC := prebuilt/$(HOST_PREBUILT_TAG)/ccache/ccache $(MY_CC)
- endif
-endif
-
-
-ifneq ($(combo_target)$(TARGET_SIMULATOR),HOST_true)
- ifneq ($(HOST_ARCH),x86_64)
- MY_CFLAGS += -m32
- MY_LDFLAGS += -m32
- endif
-endif
-
-include $(CLEAR_VARS)
-
-###########################################################
-# Zlib configuration
-#
-ZLIB_DIR := distrib/zlib-1.2.3
-include $(LOCAL_PATH)/$(ZLIB_DIR)/sources.make
-
-###########################################################
-# Libpng configuration
-#
-LIBPNG_DIR := distrib/libpng-1.2.19
-include $(LOCAL_PATH)/$(LIBPNG_DIR)/sources.make
-
-###############################################################################
-# build the TCG code generator
-#
-include $(CLEAR_VARS)
-
-LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
-LOCAL_CC := $(MY_CC)
-LOCAL_CFLAGS := $(MY_CFLAGS) $(LOCAL_CFLAGS)
-LOCAL_LDFLAGS := $(MY_LDFLAGS)
-LOCAL_MODULE := emulator-tcg
-
-TCG_TARGET := $(HOST_ARCH)
-ifeq ($(TCG_TARGET),x86)
- TCG_TARGET := i386
-endif
-
-TCG_CFLAGS := -I$(LOCAL_PATH)/tcg -I$(LOCAL_PATH)/tcg/$(TCG_TARGET)
-
-LOCAL_CFLAGS += $(TCG_CFLAGS) \
- -I$(LOCAL_PATH)/target-arm \
- -I$(LOCAL_PATH)/fpu \
-
-LOCAL_SRC_FILES := \
- tcg/tcg.c \
- tcg/tcg-dyngen.c \
- tcg/tcg-runtime.c \
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-##############################################################################
-# build the HW emulation support
-#
-include $(CLEAR_VARS)
-
-LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
-LOCAL_CC := $(MY_CC)
-LOCAL_MODULE := emulator-hw
-
-HW_CFLAGS := -I$(LOCAL_PATH)/hw
-
-LOCAL_CFLAGS := $(MY_CFLAGS) $(LOCAL_CFLAGS)
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/target-arm -I$(LOCAL_PATH)/fpu $(HW_CFLAGS)
-LOCAL_CFLAGS += $(ZLIB_CFLAGS) -I$(LOCAL_PATH)/$(ZLIB_DIR)
-
-HW_SOURCES := \
- android_arm.c \
- arm_pic.c \
- cdrom.c \
- dma.c \
- irq.c \
- goldfish_audio.c \
- goldfish_battery.c \
- goldfish_device.c \
- goldfish_events_device.c \
- goldfish_fb.c \
- goldfish_interrupt.c \
- goldfish_memlog.c \
- goldfish_mmc.c \
- goldfish_nand.c \
- goldfish_switch.c \
- goldfish_timer.c \
- goldfish_trace.c \
- goldfish_tty.c \
- pci.c \
- scsi-disk.c \
- smc91c111.c \
- usb-hid.c \
- usb-hub.c \
- usb-msd.c \
- usb-ohci.c \
- usb.c \
-
-LOCAL_SRC_FILES += $(HW_SOURCES:%=hw/%)
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-##############################################################################
-# build the ARM-specific emulation engine sources
-#
-include $(CLEAR_VARS)
-
-LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
-LOCAL_CC := $(MY_CC)
-LOCAL_MODULE := emulator-arm
-LOCAL_LDFLAGS := $(MY_LDFLAGS)
-LOCAL_CFLAGS := $(MY_CFLAGS) $(LOCAL_CFLAGS)
-LOCAL_STATIC_LIBRARIES := emulator-hw
-
-LOCAL_CFLAGS := -fno-PIC -fomit-frame-pointer -Wno-sign-compare
-LOCAL_CFLAGS := $(MY_CFLAGS) $(LOCAL_CFLAGS)
-
-LOCAL_CFLAGS += -I$(LOCAL_PATH) \
- -I$(LOCAL_PATH)/target-arm \
- -I$(LOCAL_PATH)/fpu \
- $(TCG_CFLAGS) \
- $(HW_CFLAGS) \
-
-ifeq ($(HOST_ARCH),ppc)
- LOCAL_CFLAGS += -D__powerpc__
-endif
-
-LOCAL_SRC_FILES += exec.c cpu-exec.c \
- target-arm/op_helper.c \
- target-arm/iwmmxt_helper.c \
- target-arm/neon_helper.c \
- target-arm/helper.c \
- target-arm/translate.c \
- target-arm/machine.c \
- translate-all.c \
- hw/armv7m.c \
- hw/armv7m_nvic.c \
- arm-semi.c \
- trace.c \
- varint.c \
- dcache.c \
-
-LOCAL_SRC_FILES += fpu/softfloat.c
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-##############################################################################
-# SDL-related definitions
-#
-
-SDL_CONFIG ?= prebuilt/$(HOST_PREBUILT_TAG)/sdl/bin/sdl-config
-SDL_CFLAGS := $(shell $(SDL_CONFIG) --cflags)
-
-# We need to filter out the _GNU_SOURCE variable because it breaks recent
-# releases of Cygwin when using the -mno-cygwin option. Moreover, we don't
-# need this macro at all to build the Android emulator.
-SDL_CFLAGS := $(filter-out -D_GNU_SOURCE=1,$(SDL_CFLAGS))
-SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(SDL_CONFIG) --static-libs))
-
-
-##############################################################################
-# determine audio sources, build the prebuilt audio-library if needed
-#
-
-# determine AUDIO sources based on current configuration
-#
-AUDIO_SOURCES := audio.c noaudio.c wavaudio.c sdlaudio.c wavcapture.c mixeng.c
-AUDIO_CFLAGS := -I$(LOCAL_PATH)/audio -DHAS_AUDIO
-AUDIO_LDLIBS :=
-
-ifeq ($(HOST_OS),darwin)
- CONFIG_COREAUDIO ?= yes
-endif
-
-ifeq ($(HOST_OS),windows)
- CONFIG_WINAUDIO ?= yes
-endif
-
-ifeq ($(HOST_OS),linux)
- CONFIG_OSS ?= yes
- CONFIG_ALSA ?= yes
- CONFIG_ESD ?= yes
-endif
-
-ifeq ($(HOST_OS),freebsd)
- CONFIG_OSS ?= yes
-endif
-
-ifeq ($(CONFIG_COREAUDIO),yes)
- AUDIO_SOURCES += coreaudio.c
- AUDIO_CFLAGS += -DCONFIG_COREAUDIO
- AUDIO_LDLIBS += -Wl,-framework,CoreAudio
-endif
-
-ifeq ($(CONFIG_WINAUDIO),yes)
- AUDIO_SOURCES += winaudio.c
- AUDIO_CFLAGS += -DCONFIG_WINAUDIO
-endif
-
-ifeq ($(CONFIG_ALSA),yes)
- AUDIO_SOURCES += alsaaudio.c audio_pt_int.c
- AUDIO_CFLAGS += -DCONFIG_ALSA
-endif
-
-ifeq ($(CONFIG_ESD),yes)
- AUDIO_SOURCES += esdaudio.c
- AUDIO_CFLAGS += -DCONFIG_ESD
-endif
-
-ifeq ($(CONFIG_OSS),yes)
- AUDIO_SOURCES += ossaudio.c
- AUDIO_CFLAGS += -DCONFIG_OSS
-endif
-
-AUDIO_SOURCES := $(AUDIO_SOURCES:%=audio/%)
-
-# determine whether we're going to use the prebuilt
-# audio library (this is useful on Linux to avoid requiring
-# all sound-related development packages to be installed on
-# the build and developer machines).
-#
-# note that you can define BUILD_QEMU_AUDIO_LIB to true
-# in your environment to force recompilation.
-#
-QEMU_AUDIO_LIB :=
-
-ifneq ($(BUILD_STANDALONE_EMULATOR),true)
- QEMU_AUDIO_LIB := $(wildcard \
- prebuilt/$(HOST_PREBUILT_TAG)/emulator/libqemu-audio.a)
-endif
-
-ifeq ($(BUILD_QEMU_AUDIO_LIB),true)
- include $(CLEAR_VARS)
- LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
- LOCAL_CC := $(MY_CC)
- LOCAL_MODULE := libqemu-audio
- LOCAL_LDFLAGS := $(MY_LDFLAGS)
-
- LOCAL_CFLAGS := -Wno-sign-compare \
- -fno-strict-aliasing -W -Wall -Wno-unused-parameter \
- -I$(LOCAL_PATH) \
- -I$(LOCAL_PATH)/target-arm \
- -I$(LOCAL_PATH)/fpu \
-
- LOCAL_CFLAGS := $(MY_CFLAGS) $(LOCAL_CFLAGS) $(AUDIO_CFLAGS)
-
- LOCAL_CFLAGS += $(SDL_CFLAGS)
-
- LOCAL_SRC_FILES += $(AUDIO_SOURCES)
-
- include $(BUILD_HOST_STATIC_LIBRARY)
- QEMU_AUDIO_LIB := $(LOCAL_BUILT_MODULE)
-
-endif # !QEMU_AUDIO_LIB
-
-##############################################################################
-# now build the emulator itself
-#
-include $(CLEAR_VARS)
-
-LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
-LOCAL_CC := $(MY_CC)
-LOCAL_MODULE := emulator
-LOCAL_STATIC_LIBRARIES := emulator-hw emulator-arm emulator-tcg
-LOCAL_LDFLAGS := $(MY_LDFLAGS)
-
-# don't remove the -fno-strict-aliasing, or you'll break things
-# (e.g. slirp2/network support)
-#
-LOCAL_CFLAGS := -fno-PIC -fomit-frame-pointer -Wno-sign-compare \
- -fno-strict-aliasing -g -W -Wall -Wno-unused-parameter
-
-LOCAL_CFLAGS := $(MY_CFLAGS) $(LOCAL_CFLAGS)
-
-# add the build ID to the default macro definitions
-LOCAL_CFLAGS += -DANDROID_BUILD_ID="$(strip $(BUILD_ID))-$(strip $(BUILD_NUMBER))"
-
-# include the Zlib sources
-#
-LOCAL_SRC_FILES += $(ZLIB_SOURCES)
-LOCAL_CFLAGS += $(ZLIB_CFLAGS) -I$(LOCAL_PATH)/$(ZLIB_DIR)
-
-# include the Libpng sources
-#
-LOCAL_SRC_FILES += $(LIBPNG_SOURCES)
-LOCAL_CFLAGS += $(LIBPNG_CFLAGS) -I$(LOCAL_PATH)/$(LIBPNG_DIR)
-
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/ \
- -I$(LOCAL_PATH)/target-arm \
- -I$(LOCAL_PATH)/fpu \
- $(TCG_CFLAGS) \
- $(HW_CFLAGS) \
-
-# include telephony stuff
-#
-TELEPHONY_SOURCES := android_modem.c modem_driver.c gsm.c sim_card.c sysdeps_qemu.c sms.c remote_call.c
-LOCAL_SRC_FILES += $(TELEPHONY_SOURCES:%=telephony/%)
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/telephony
-
-# include sound support source files. we first try to see if we have a prebuilt audio
-# library. if not, we build things the "hard" way.
-#
-# note that to generate the prebuilt audio library, you should do the following:
-#
-# cd tools/qemu
-# ./android-rebuild.sh
-# distrib/update-audio.sh
-#
-ifeq ($(QEMU_AUDIO_LIB),)
- LOCAL_SRC_FILES += $(AUDIO_SOURCES)
-endif # !QEMU_AUDIO_LIB
-
-LOCAL_CFLAGS += $(AUDIO_CFLAGS)
-LOCAL_LDLIBS += $(AUDIO_LDLIBS)
-
-# include slirp2 code, i.e. the user-level networking stuff
-#
-SLIRP_SOURCES := bootp.c cksum.c debug.c if.c ip_icmp.c ip_input.c ip_output.c \
- mbuf.c misc.c sbuf.c slirp.c socket.c tcp_input.c tcp_output.c \
- tcp_subr.c tcp_timer.c tftp.c udp.c
-
-LOCAL_SRC_FILES += $(SLIRP_SOURCES:%=slirp2/%)
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/slirp2
-
-# socket proxy support
-#
-PROXY_SOURCES := \
- proxy_common.c \
- proxy_http.c \
- proxy_http_connector.c \
- proxy_http_rewriter.c \
-
-LOCAL_SRC_FILES += $(PROXY_SOURCES:%=proxy/%)
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/proxy
-
-# the linux-user sources, I doubt we really need these
-#
-#LINUX_SOURCES := main.c elfload.c mmap.c signal.c path.c syscall.c
-#LOCAL_SRC_FILES += $(LINUX_SOURCES:%=linux-user/%)
-
-# the skin support sources
-#
-SKIN_SOURCES := rect.c \
- region.c \
- image.c \
- trackball.c \
- keyboard.c \
- keyset.c \
- file.c \
- window.c \
- scaler.c \
- composer.c \
- surface.c \
-
-LOCAL_SRC_FILES += $(SKIN_SOURCES:%=android/skin/%)
-#LOCAL_CFLAGS += -I$(LOCAL_PATH)/skin
-
-ifeq ($(HOST_ARCH),x86)
-# enable MMX code for our skin scaler
-LOCAL_CFLAGS += -DUSE_MMX=1 -mmmx
-endif
-
-# include other sources
-#
-VL_SOURCES := vl.c osdep.c cutils.c \
- block.c readline.c monitor.c console.c loader.c sockets.c \
- block-qcow.c aes.c d3des.c block-cloop.c block-dmg.c block-vvfat.c \
- block-qcow2.c block-cow.c \
- cbuffer.c \
- gdbstub.c usb-linux.c \
- vnc.c disas.c arm-dis.c \
- shaper.c charpipe.c loadpng.c \
- framebuffer.c \
- tcpdump.c \
- android/charmap.c \
- android/cmdline-option.c \
- android/config.c \
- android/console.c \
- android/gps.c \
- android/help.c \
- android/hw-control.c \
- android/hw-events.c \
- android/hw-kmsg.c \
- android/main.c \
- android/qemud.c \
- android/resource.c \
- android/utils/bufprint.c \
- android/utils/debug.c \
- android/utils/dirscanner.c \
- android/utils/display.c \
- android/utils/ini.c \
- android/utils/filelock.c \
- android/utils/misc.c \
- android/utils/path.c \
- android/utils/reflist.c \
- android/utils/stralloc.c \
- android/utils/system.c \
- android/utils/tempfile.c \
- android/utils/timezone.c \
- android/avd/hw-config.c \
- android/avd/info.c \
-
-# we need to add a Quartz-specific file
-ifeq ($(HOST_OS),darwin)
- # Alas, the Android build system doesn't know how to deal
- # with Objective C sources yet.
- ifeq ($(BUILD_STANDALONE_EMULATOR),true)
- VL_SOURCES += android/utils/display-quartz.m
- else
- LOCAL_CFLAGS += -DCONFIG_NO_COCOA
- endif
-endif
-
-VL_SOURCES += hw/arm_boot.c \
- hw/android_arm.c \
-
-ifeq ($(HOST_OS),windows)
- VL_SOURCES += block-raw-win32.c
-else
- VL_SOURCES += block-raw-posix.c
-endif
-
-ifeq ($(HOST_OS),linux)
- LOCAL_LDLIBS += -lX11
-endif
-
-ifeq ($(HOST_ARCH),x86)
- VL_SOURCES += i386-dis.c
-endif
-ifeq ($(HOST_ARCH),x86_64)
- VL_SOURCES += i386-dis.c
-endif
-ifeq ($(HOST_ARCH),ppc)
- VL_SOURCES += ppc-dis.c
-endif
-
-ifeq ($(HOST_OS),windows)
- #VL_SOURCES += tap-win32.c
- LOCAL_LDLIBS += -mno-cygwin -mwindows -mconsole
-endif
-
-LOCAL_SRC_FILES += $(VL_SOURCES)
-
-ifeq ($(HOST_OS),linux)
- LOCAL_LDLIBS += -lutil -lrt
-endif
-
-# add SDL-specific flags
-#
-LOCAL_CFLAGS += $(SDL_CFLAGS)
-LOCAL_LDLIBS += $(SDL_LDLIBS)
-LOCAL_STATIC_LIBRARIES += libSDL libSDLmain
-LOCAL_STATIC_LIBRARIES += libSDL libSDLmain
-
-# on Windows, link the icon file as well into the executable
-# unfortunately, our build system doesn't help us much, so we need
-# to use some weird pathnames to make this work...
-#
-ifeq ($(HOST_OS),windows)
-INTERMEDIATE := $(call intermediates-dir-for,EXECUTABLES,$(LOCAL_MODULE),true)
-ANDROID_ICON_OBJ := android_icon.o
-ANDROID_ICON_PATH := $(LOCAL_PATH)/images
-$(ANDROID_ICON_PATH)/$(ANDROID_ICON_OBJ): $(ANDROID_ICON_PATH)/android_icon.rc
- windres $< -I $(ANDROID_ICON_PATH) -o $@
-
-# seems to be the only way to add an object file that was not generated from
-# a C/C++/Java source file to our build system. and very unfortunately,
-# $(TOPDIR)/$(LOCALPATH) will always be prepended to this value, which forces
-# us to put the object file in the source directory...
-#
-LOCAL_PREBUILT_OBJ_FILES += images/$(ANDROID_ICON_OBJ)
-endif
-
-# other flags
-LOCAL_CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LOCAL_LDLIBS += -lm -lpthread
-
-ifeq ($(HOST_OS),windows)
- LOCAL_LDLIBS += -lwinmm -lws2_32 -liphlpapi
-endif
-
-LOCAL_LDLIBS += $(QEMU_AUDIO_LIB)
-
-LOCAL_MODULE := emulator
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # TARGET_ARCH == arm
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index e77696a..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/README b/README
deleted file mode 100644
index 44ddc25..0000000
--- a/README
+++ /dev/null
@@ -1,23 +0,0 @@
-This package contains the sources to the Android emulator program.
-
-This program emulates a virtual ARM board that can be used to run Android
-system images on a typical developer machine. To do so, you'll need additionnal
-files provided with the public Android Software Development Kit (SDK).
-
-To download them, go to http://code.google.com/android/
-
-Emulator-specific documentation is available at the following page:
-
- http://code.google.com/android/reference/emulator.html
-
-Please read the INSTALL file to see how you can rebuild the emulator, or
-build a source distribution package tarball.
-
-Read the CHANGES.TXT file to see what important changes were added since
-the last release.
-
-Note: This program is distributed under the terms of the GNU General Public
- License, which exact licensing conditions are available in the COPYING
- file found within this package.
-
-- Android Emulator Team
diff --git a/a.out.h b/a.out.h
deleted file mode 100644
index 2d35ebf..0000000
--- a/a.out.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/* a.out.h
-
- Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#ifndef _A_OUT_H_
-#define _A_OUT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#define COFF_IMAGE_WITH_PE
-#define COFF_LONG_SECTION_NAMES
-
-/*** coff information for Intel 386/486. */
-
-
-/********************** FILE HEADER **********************/
-
-struct external_filehdr {
- short f_magic; /* magic number */
- short f_nscns; /* number of sections */
- host_ulong f_timdat; /* time & date stamp */
- host_ulong f_symptr; /* file pointer to symtab */
- host_ulong f_nsyms; /* number of symtab entries */
- short f_opthdr; /* sizeof(optional hdr) */
- short f_flags; /* flags */
-};
-
-/* Bits for f_flags:
- * F_RELFLG relocation info stripped from file
- * F_EXEC file is executable (no unresolved external references)
- * F_LNNO line numbers stripped from file
- * F_LSYMS local symbols stripped from file
- * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
- */
-
-#define F_RELFLG (0x0001)
-#define F_EXEC (0x0002)
-#define F_LNNO (0x0004)
-#define F_LSYMS (0x0008)
-
-
-
-#define I386MAGIC 0x14c
-#define I386PTXMAGIC 0x154
-#define I386AIXMAGIC 0x175
-
-/* This is Lynx's all-platform magic number for executables. */
-
-#define LYNXCOFFMAGIC 0415
-
-#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
- && (x).f_magic != I386AIXMAGIC \
- && (x).f_magic != I386PTXMAGIC \
- && (x).f_magic != LYNXCOFFMAGIC)
-
-#define FILHDR struct external_filehdr
-#define FILHSZ 20
-
-
-/********************** AOUT "OPTIONAL HEADER"=
- **********************/
-
-
-typedef struct
-{
- unsigned short magic; /* type of file */
- unsigned short vstamp; /* version stamp */
- host_ulong tsize; /* text size in bytes, padded to FW bdry*/
- host_ulong dsize; /* initialized data " " */
- host_ulong bsize; /* uninitialized data " " */
- host_ulong entry; /* entry pt. */
- host_ulong text_start; /* base of text used for this file */
- host_ulong data_start; /* base of data used for this file=
- */
-}
-AOUTHDR;
-
-#define AOUTSZ 28
-#define AOUTHDRSZ 28
-
-#define OMAGIC 0404 /* object files, eg as output */
-#define ZMAGIC 0413 /* demand load format, eg normal ld output */
-#define STMAGIC 0401 /* target shlib */
-#define SHMAGIC 0443 /* host shlib */
-
-
-/* define some NT default values */
-/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
-#define NT_SECTION_ALIGNMENT 0x1000
-#define NT_FILE_ALIGNMENT 0x200
-#define NT_DEF_RESERVE 0x100000
-#define NT_DEF_COMMIT 0x1000
-
-/********************** SECTION HEADER **********************/
-
-
-struct external_scnhdr {
- char s_name[8]; /* section name */
- host_ulong s_paddr; /* physical address, offset
- of last addr in scn */
- host_ulong s_vaddr; /* virtual address */
- host_ulong s_size; /* section size */
- host_ulong s_scnptr; /* file ptr to raw data for section */
- host_ulong s_relptr; /* file ptr to relocation */
- host_ulong s_lnnoptr; /* file ptr to line numbers */
- unsigned short s_nreloc; /* number of relocation entries */
- unsigned short s_nlnno; /* number of line number entries*/
- host_ulong s_flags; /* flags */
-};
-
-#define SCNHDR struct external_scnhdr
-#define SCNHSZ 40
-
-/*
- * names of "special" sections
- */
-#define _TEXT ".text"
-#define _DATA ".data"
-#define _BSS ".bss"
-#define _COMMENT ".comment"
-#define _LIB ".lib"
-
-/********************** LINE NUMBERS **********************/
-
-/* 1 line number entry for every "breakpointable" source line in a section.
- * Line numbers are grouped on a per function basis; first entry in a function
- * grouping will have l_lnno = 0 and in place of physical address will be the
- * symbol table index of the function name.
- */
-struct external_lineno {
- union {
- host_ulong l_symndx; /* function name symbol index, iff l_lnno 0 */
- host_ulong l_paddr; /* (physical) address of line number */
- } l_addr;
- unsigned short l_lnno; /* line number */
-};
-
-#define LINENO struct external_lineno
-#define LINESZ 6
-
-/********************** SYMBOLS **********************/
-
-#define E_SYMNMLEN 8 /* # characters in a symbol name */
-#define E_FILNMLEN 14 /* # characters in a file name */
-#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
-
-struct __attribute__((packed)) external_syment
-{
- union {
- char e_name[E_SYMNMLEN];
- struct {
- host_ulong e_zeroes;
- host_ulong e_offset;
- } e;
- } e;
- host_ulong e_value;
- unsigned short e_scnum;
- unsigned short e_type;
- char e_sclass[1];
- char e_numaux[1];
-};
-
-#define N_BTMASK (0xf)
-#define N_TMASK (0x30)
-#define N_BTSHFT (4)
-#define N_TSHIFT (2)
-
-union external_auxent {
- struct {
- host_ulong x_tagndx; /* str, un, or enum tag indx */
- union {
- struct {
- unsigned short x_lnno; /* declaration line number */
- unsigned short x_size; /* str/union/array size */
- } x_lnsz;
- host_ulong x_fsize; /* size of function */
- } x_misc;
- union {
- struct { /* if ISFCN, tag, or .bb */
- host_ulong x_lnnoptr;/* ptr to fcn line # */
- host_ulong x_endndx; /* entry ndx past block end */
- } x_fcn;
- struct { /* if ISARY, up to 4 dimen. */
- char x_dimen[E_DIMNUM][2];
- } x_ary;
- } x_fcnary;
- unsigned short x_tvndx; /* tv index */
- } x_sym;
-
- union {
- char x_fname[E_FILNMLEN];
- struct {
- host_ulong x_zeroes;
- host_ulong x_offset;
- } x_n;
- } x_file;
-
- struct {
- host_ulong x_scnlen; /* section length */
- unsigned short x_nreloc; /* # relocation entries */
- unsigned short x_nlinno; /* # line numbers */
- host_ulong x_checksum; /* section COMDAT checksum */
- unsigned short x_associated;/* COMDAT associated section index */
- char x_comdat[1]; /* COMDAT selection number */
- } x_scn;
-
- struct {
- host_ulong x_tvfill; /* tv fill value */
- unsigned short x_tvlen; /* length of .tv */
- char x_tvran[2][2]; /* tv range */
- } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
-
-};
-
-#define SYMENT struct external_syment
-#define SYMESZ 18
-#define AUXENT union external_auxent
-#define AUXESZ 18
-
-#define _ETEXT "etext"
-
-/********************** RELOCATION DIRECTIVES **********************/
-
-struct external_reloc {
- char r_vaddr[4];
- char r_symndx[4];
- char r_type[2];
-};
-
-#define RELOC struct external_reloc
-#define RELSZ 10
-
-/* end of coff/i386.h */
-
-/* PE COFF header information */
-
-#ifndef _PE_H
-#define _PE_H
-
-/* NT specific file attributes */
-#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
-#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
-#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
-#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
-#define IMAGE_FILE_32BIT_MACHINE 0x0100
-#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
-#define IMAGE_FILE_SYSTEM 0x1000
-#define IMAGE_FILE_DLL 0x2000
-#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
-
-/* additional flags to be set for section headers to allow the NT loader to
- read and write to the section data (to replace the addresses of data in
- dlls for one thing); also to execute the section in .text's case=
- */
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
-#define IMAGE_SCN_MEM_EXECUTE 0x20000000
-#define IMAGE_SCN_MEM_READ 0x40000000
-#define IMAGE_SCN_MEM_WRITE 0x80000000
-
-/*
- * Section characteristics added for ppc-nt
- */
-
-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
-
-#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
-
-#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
-#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
-#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
-#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
-
-#define IMAGE_SCN_MEM_FARDATA 0x00008000
-
-#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
-#define IMAGE_SCN_MEM_16BIT 0x00020000
-#define IMAGE_SCN_MEM_LOCKED 0x00040000
-#define IMAGE_SCN_MEM_PRELOAD 0x00080000
-
-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
-
-
-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
-#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
-
-/* COMDAT selection codes. */
-
-#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
-#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
-#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
-#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
-#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
-
-/* Magic values that are true for all dos/nt implementations */
-#define DOSMAGIC 0x5a4d
-#define NT_SIGNATURE 0x00004550
-
-/* NT allows long filenames, we want to accommodate this. This may break
- some of the bfd functions */
-#undef FILNMLEN
-#define FILNMLEN 18 /* # characters in a file name */
-
-
-#ifdef COFF_IMAGE_WITH_PE
-/* The filehdr is only weired in images */
-
-#undef FILHDR
-struct external_PE_filehdr
-{
- /* DOS header fields */
- unsigned short e_magic; /* Magic number, 0x5a4d */
- unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
- unsigned short e_cp; /* Pages in file, 0x3 */
- unsigned short e_crlc; /* Relocations, 0x0 */
- unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
- unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
- unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
- unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
- unsigned short e_sp; /* Initial SP value, 0xb8 */
- unsigned short e_csum; /* Checksum, 0x0 */
- unsigned short e_ip; /* Initial IP value, 0x0 */
- unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
- unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
- unsigned short e_ovno; /* Overlay number, 0x0 */
- char e_res[4][2]; /* Reserved words, all 0x0 */
- unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
- unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
- char e_res2[10][2]; /* Reserved words, all 0x0 */
- host_ulong e_lfanew; /* File address of new exe header, 0x80 */
- char dos_message[16][4]; /* other stuff, always follow DOS header */
- unsigned int nt_signature; /* required NT signature, 0x4550 */
-
- /* From standard header */
-
- unsigned short f_magic; /* magic number */
- unsigned short f_nscns; /* number of sections */
- host_ulong f_timdat; /* time & date stamp */
- host_ulong f_symptr; /* file pointer to symtab */
- host_ulong f_nsyms; /* number of symtab entries */
- unsigned short f_opthdr; /* sizeof(optional hdr) */
- unsigned short f_flags; /* flags */
-};
-
-
-#define FILHDR struct external_PE_filehdr
-#undef FILHSZ
-#define FILHSZ 152
-
-#endif
-
-typedef struct
-{
- unsigned short magic; /* type of file */
- unsigned short vstamp; /* version stamp */
- host_ulong tsize; /* text size in bytes, padded to FW bdry*/
- host_ulong dsize; /* initialized data " " */
- host_ulong bsize; /* uninitialized data " " */
- host_ulong entry; /* entry pt. */
- host_ulong text_start; /* base of text used for this file */
- host_ulong data_start; /* base of all data used for this file */
-
- /* NT extra fields; see internal.h for descriptions */
- host_ulong ImageBase;
- host_ulong SectionAlignment;
- host_ulong FileAlignment;
- unsigned short MajorOperatingSystemVersion;
- unsigned short MinorOperatingSystemVersion;
- unsigned short MajorImageVersion;
- unsigned short MinorImageVersion;
- unsigned short MajorSubsystemVersion;
- unsigned short MinorSubsystemVersion;
- char Reserved1[4];
- host_ulong SizeOfImage;
- host_ulong SizeOfHeaders;
- host_ulong CheckSum;
- unsigned short Subsystem;
- unsigned short DllCharacteristics;
- host_ulong SizeOfStackReserve;
- host_ulong SizeOfStackCommit;
- host_ulong SizeOfHeapReserve;
- host_ulong SizeOfHeapCommit;
- host_ulong LoaderFlags;
- host_ulong NumberOfRvaAndSizes;
- /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
- char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
-
-} PEAOUTHDR;
-
-
-#undef AOUTSZ
-#define AOUTSZ (AOUTHDRSZ + 196)
-
-#undef E_FILNMLEN
-#define E_FILNMLEN 18 /* # characters in a file name */
-#endif
-
-/* end of coff/pe.h */
-
-#define DT_NON (0) /* no derived type */
-#define DT_PTR (1) /* pointer */
-#define DT_FCN (2) /* function */
-#define DT_ARY (3) /* array */
-
-#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
-#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
-#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _A_OUT_H_ */
-
diff --git a/aes.c b/aes.c
deleted file mode 100644
index 3700894..0000000
--- a/aes.c
+++ /dev/null
@@ -1,1320 +0,0 @@
-/**
- *
- * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project.
- */
-/*
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "qemu-common.h"
-#include "aes.h"
-
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-
-#include <assert.h>
-
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
-
-#define MAXKC (256/32)
-#define MAXKB (256/8)
-#define MAXNR 14
-
-/* This controls loop-unrolling in aes_core.c */
-#undef FULL_UNROLL
-# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-static const u32 Te0[256] = {
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-static const u32 Te1[256] = {
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-static const u32 Te2[256] = {
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-static const u32 Te3[256] = {
-
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-static const u32 Te4[256] = {
- 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
- 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
- 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
- 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
- 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
- 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
- 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
- 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
- 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
- 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
- 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
- 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
- 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
- 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
- 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
- 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
- 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
- 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
- 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
- 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
- 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
- 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
- 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
- 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
- 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
- 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
- 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
- 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
- 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
- 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
- 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
- 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
- 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
- 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
- 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
- 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
- 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
- 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
- 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
- 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
- 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
- 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
- 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
- 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
- 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
- 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
- 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
- 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
- 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
- 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
- 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
- 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
- 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
- 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
- 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
- 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
- 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
- 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
- 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
- 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
- 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
- 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
- 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-static const u32 Td0[256] = {
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-static const u32 Td1[256] = {
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-static const u32 Td2[256] = {
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-static const u32 Td3[256] = {
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-static const u32 Td4[256] = {
- 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
- 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
- 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
- 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
- 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
- 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
- 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
- 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
- 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
- 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
- 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
- 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
- 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
- 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
- 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
- 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
- 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
- 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
- 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
- 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
- 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
- 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
- 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
- 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
- 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
- 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
- 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
- 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
- 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
- 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
- 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
- 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
- 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
- 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
- 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
- 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
- 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
- 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
- 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
- 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
- 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
- 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
- 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
- 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
- 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
- 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
- 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
- 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
- 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
- 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
- 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
- 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
- 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
- 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
- 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
- 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
- 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
- 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
- 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
- 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
- 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
- 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
- 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-static const u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-/**
- * Expand the cipher key into the encryption key schedule.
- */
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i = 0;
- u32 temp;
-
- if (!userKey || !key)
- return -1;
- if (bits != 128 && bits != 192 && bits != 256)
- return -2;
-
- rk = key->rd_key;
-
- if (bits==128)
- key->rounds = 10;
- else if (bits==192)
- key->rounds = 12;
- else
- key->rounds = 14;
-
- rk[0] = GETU32(userKey );
- rk[1] = GETU32(userKey + 4);
- rk[2] = GETU32(userKey + 8);
- rk[3] = GETU32(userKey + 12);
- if (bits == 128) {
- while (1) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 0;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(userKey + 16);
- rk[5] = GETU32(userKey + 20);
- if (bits == 192) {
- while (1) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 0;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(userKey + 24);
- rk[7] = GETU32(userKey + 28);
- if (bits == 256) {
- while (1) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 0;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (Te4[(temp >> 24) ] & 0xff000000) ^
- (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(temp ) & 0xff] & 0x000000ff);
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
-
- rk += 8;
- }
- }
- return 0;
-}
-
-/**
- * Expand the cipher key into the decryption key schedule.
- */
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i, j, status;
- u32 temp;
-
- /* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
- if (status < 0)
- return status;
-
- rk = key->rd_key;
-
- /* invert the order of the round keys: */
- for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */
- for (i = 1; i < (key->rounds); i++) {
- rk += 4;
- rk[0] =
- Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[0] ) & 0xff] & 0xff];
- rk[1] =
- Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[1] ) & 0xff] & 0xff];
- rk[2] =
- Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[2] ) & 0xff] & 0xff];
- rk[3] =
- Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[3] ) & 0xff] & 0xff];
- }
- return 0;
-}
-
-#ifndef AES_ASM
-/*
- * Encrypt a single block
- * in and out can overlap
- */
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[4];
- t1 =
- Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[5];
- t2 =
- Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[6];
- t3 =
- Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Te0[(t0 >> 24) ] ^
- Te1[(t1 >> 16) & 0xff] ^
- Te2[(t2 >> 8) & 0xff] ^
- Te3[(t3 ) & 0xff] ^
- rk[0];
- s1 =
- Te0[(t1 >> 24) ] ^
- Te1[(t2 >> 16) & 0xff] ^
- Te2[(t3 >> 8) & 0xff] ^
- Te3[(t0 ) & 0xff] ^
- rk[1];
- s2 =
- Te0[(t2 >> 24) ] ^
- Te1[(t3 >> 16) & 0xff] ^
- Te2[(t0 >> 8) & 0xff] ^
- Te3[(t1 ) & 0xff] ^
- rk[2];
- s3 =
- Te0[(t3 >> 24) ] ^
- Te1[(t0 >> 16) & 0xff] ^
- Te2[(t1 >> 8) & 0xff] ^
- Te3[(t2 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Te4[(t0 >> 24) ] & 0xff000000) ^
- (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (Te4[(t1 >> 24) ] & 0xff000000) ^
- (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (Te4[(t2 >> 24) ] & 0xff000000) ^
- (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (Te4[(t3 >> 24) ] & 0xff000000) ^
- (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-/*
- * Decrypt a single block
- * in and out can overlap
- */
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[4];
- t1 =
- Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[5];
- t2 =
- Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[6];
- t3 =
- Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Td0[(t0 >> 24) ] ^
- Td1[(t3 >> 16) & 0xff] ^
- Td2[(t2 >> 8) & 0xff] ^
- Td3[(t1 ) & 0xff] ^
- rk[0];
- s1 =
- Td0[(t1 >> 24) ] ^
- Td1[(t0 >> 16) & 0xff] ^
- Td2[(t3 >> 8) & 0xff] ^
- Td3[(t2 ) & 0xff] ^
- rk[1];
- s2 =
- Td0[(t2 >> 24) ] ^
- Td1[(t1 >> 16) & 0xff] ^
- Td2[(t0 >> 8) & 0xff] ^
- Td3[(t3 ) & 0xff] ^
- rk[2];
- s3 =
- Td0[(t3 >> 24) ] ^
- Td1[(t2 >> 16) & 0xff] ^
- Td2[(t1 >> 8) & 0xff] ^
- Td3[(t0 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Td4[(t0 >> 24) ] & 0xff000000) ^
- (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (Td4[(t1 >> 24) ] & 0xff000000) ^
- (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (Td4[(t2 >> 24) ] & 0xff000000) ^
- (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (Td4[(t3 >> 24) ] & 0xff000000) ^
- (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-#endif /* AES_ASM */
-
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
-{
-
- unsigned long n;
- unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
-
- assert(in && out && key && ivec);
-
- if (enc) {
- while (len >= AES_BLOCK_SIZE) {
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = in[n] ^ ivec[n];
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- for(n=0; n < len; ++n)
- tmp[n] = in[n] ^ ivec[n];
- for(n=len; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = ivec[n];
- AES_encrypt(tmp, tmp, key);
- memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- } else {
- while (len >= AES_BLOCK_SIZE) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(in, out, key);
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- out[n] ^= ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(tmp, tmp, key);
- for(n=0; n < len; ++n)
- out[n] = tmp[n] ^ ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- }
-}
diff --git a/aes.h b/aes.h
deleted file mode 100644
index a0167eb..0000000
--- a/aes.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef QEMU_AES_H
-#define QEMU_AES_H
-
-#define AES_MAXNR 14
-#define AES_BLOCK_SIZE 16
-
-struct aes_key_st {
- uint32_t rd_key[4 *(AES_MAXNR + 1)];
- int rounds;
-};
-typedef struct aes_key_st AES_KEY;
-
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc);
-
-#endif
diff --git a/alpha.ld b/alpha.ld
deleted file mode 100644
index 0975443..0000000
--- a/alpha.ld
+++ /dev/null
@@ -1,128 +0,0 @@
-OUTPUT_FORMAT("elf64-alpha", "elf64-alpha",
- "elf64-alpha")
-OUTPUT_ARCH(alpha)
-ENTRY(__start)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
diff --git a/android-configure.sh b/android-configure.sh
deleted file mode 100755
index c5e60ef..0000000
--- a/android-configure.sh
+++ /dev/null
@@ -1,646 +0,0 @@
-#!/bin/bash
-#
-# this script is used to rebuild the Android emulator from sources
-# in the current directory. It also contains logic to speed up the
-# rebuild if it detects that you're using the Android build system
-#
-# in this case, it will use prebuilt binaries for the compiler,
-# the audio library and the SDL library. You can disable this
-# by using the --no-prebuilt-libs and --cc=<compiler> options
-#
-#
-# here's the list of environment variables you can define before
-# calling this script to control it (besides options):
-#
-#
-
-# first, let's see which system we're running this on
-cd `dirname $0`
-PROGNAME=`basename $0`
-
-# this function will be used to execute commands and eventually
-# dump them if VERBOSE is 'yes'
-VERBOSE=yes
-VERBOSE2=no
-
-function log()
-{
- if [ "$VERBOSE" = "yes" ] ; then
- echo "$1"
- fi
-}
-
-function log2()
-{
- if [ "$VERBOSE2" = "yes" ] ; then
- echo "$1"
- fi
-}
-
-function execute()
-{
- log2 "Running: $*"
- $*
-}
-
-function compile()
-{
- log2 "Object : $CC -o $TMPO -c $CFLAGS $TMPC"
- $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL
-}
-
-function link()
-{
- log2 "Link : $LD $LDFLAGS -o $TMPE $TMPO"
- $LD $LDFLAGS -o $TMPE $TMPO 2> $TMPL
-}
-
-function compile-exec-run()
-{
- log2 "RunExec : $CC -o $TMPE $CFLAGS $TMPC"
- compile
- if [ $? != 0 ] ; then
- echo "Failure to compile test program"
- cat $TMPL
- exit 1
- fi
- link
- if [ $? != 0 ] ; then
- echo "Failure to link test program"
- cat $TMPL
- exit 1
- fi
- $TMPE
-}
-
-OS=`uname -s`
-CPU=`uname -m`
-EXE=""
-case "$CPU" in
- i?86) CPU=x86
- ;;
-esac
-
-case "$OS" in
- Darwin)
- OS=darwin-$CPU
- ;;
- Linux)
- # note that building on x86_64 is handled later
- OS=linux-$CPU
- ;;
- *_NT-*)
- OS=windows
- EXE=.exe
- ;;
-esac
-
-# Are we running in the Android build system ?
-unset TOP
-if [ -n "$ANDROID_PRODUCT_OUT" ] ; then
- TOP=`cd $ANDROID_PRODUCT_OUT/../../../.. && pwd`
- log "TOP found at $TOP"
- # $TOP/config/envsetup.make is for the old tree layout
- # $TOP/build/envsetup.sh is for the new one
- ANDROID_CONFIG_MK=$TOP/config/envsetup.make
- if [ ! -f $ANDROID_CONFIG_MK ] ; then
- ANDROID_CONFIG_MK=$TOP/build/core/config.mk
- fi
- if [ ! -f $ANDROID_CONFIG_MK ] ; then
- echo "Cannot find build system root (TOP)"
- echo "defaulting to non-Android build"
- unset TOP
- fi
-fi
-
-# normalize the TOP variable, we don't want any trailing /
-IN_ANDROID_BUILD=no
-if [ -n "$TOP" ] ; then
- TOPDIR=`dirname $TOP`
- if [ "$TOPDIR" != "." ] ; then
- TOP=$TOPDIR/`basename $TOP`
- fi
- IN_ANDROID_BUILD=yes
- log "In Android Build"
-fi
-
-# Parse options
-OPTION_TARGETS=""
-OPTION_DEBUG=no
-OPTION_IGNORE_AUDIO=no
-OPTION_NO_PREBUILTS=no
-OPTION_TRY_64=no
-OPTION_HELP=no
-
-if [ -z "$CC" ] ; then
- CC=gcc
-fi
-
-for opt do
- optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
- case "$opt" in
- --help|-h|-\?) OPTION_HELP=yes
- ;;
- --verbose)
- if [ "$VERBOSE" = "yes" ] ; then
- VERBOSE2=yes
- else
- VERBOSE=yes
- fi
- ;;
- --install=*) OPTION_TARGETS="$TARGETS $optarg";
- ;;
- --sdl-config=*) SDL_CONFIG=$optarg
- ;;
- --cc=*) CC="$optarg" ; HOSTCC=$CC
- ;;
- --no-strip) OPTION_NO_STRIP=yes
- ;;
- --debug) OPTION_DEBUG=yes
- ;;
- --ignore-audio) OPTION_IGNORE_AUDIO=yes
- ;;
- --no-prebuilts) OPTION_NO_PREBUILTS=yes
- ;;
- --try-64) OPTION_TRY_64=yes
- ;;
- *)
- echo "unknown option '$opt', use --help"
- exit 1
- esac
-done
-
-# Print the help message
-#
-if [ "$OPTION_HELP" = "yes" ] ; then
- cat << EOF
-
-Usage: rebuild.sh [options]
-Options: [defaults in brackets after descriptions]
-EOF
- echo "Standard options:"
- echo " --help print this message"
- echo " --install=FILEPATH copy emulator executable to FILEPATH [$TARGETS]"
- echo " --cc=PATH specify C compiler [$CC]"
- echo " --sdl-config=FILE use specific sdl-config script [$SDL_CONFIG]"
- echo " --no-strip do not strip emulator executable"
- echo " --debug enable debug (-O0 -g) build"
- echo " --ignore-audio ignore audio messages (may build sound-less emulator)"
- echo " --no-prebuilts do not use prebuilt libraries and compiler"
- echo " --try-64 try to build a 64-bit executable (may crash)"
- echo " --verbose verbose configuration"
- echo ""
- exit 1
-fi
-
-# Various probes are going to need to run a small C program
-TMPC=/tmp/android-qemu-$$.c
-TMPO=/tmp/android-qemu-$$.o
-TMPE=/tmp/android-qemu-$$$EXE
-TMPL=/tmp/android-qemu-$$.log
-
-function clean-exit ()
-{
- rm -f $TMPC $TMPO $TMPL $TMPE
- exit 1
-}
-
-# Adjust a few things when we're building within the Android build
-# system:
-# - locate prebuilt directory
-# - locate and use prebuilt libraries
-# - copy the new binary to the correct location
-#
-if [ "$OPTION_NO_PREBUILTS" = "yes" ] ; then
- IN_ANDROID_BUILD=no
-fi
-
-if [ "$IN_ANDROID_BUILD" = "yes" ] ; then
-
- # Get the value of a build variable as an absolute path.
- function get_abs_build_var()
- {
- (cd $TOP && CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f $ANDROID_CONFIG_MK dumpvar-abs-$1)
- }
-
- # locate prebuilt directory
- PREBUILT_HOST_TAG=$OS
- case $OS in
- linux-*)
- # Linux is a special case because in the old tree layout
- # we simply used 'Linux' as the prebuilt host tag, but
- # are now using "linux-x86" in the new layout
- # check which one should be used
- #
- if [ -d $TOP/prebuilt/Linux ] ; then
- PREBUILT_HOST_TAG=Linux
- fi
- ;;
- esac
- PREBUILT=$TOP/prebuilt/$PREBUILT_HOST_TAG
- if [ ! -d $PREBUILT ] ; then
- # this can happen when building on x86_64
- case $OS in
- linux-x86_64)
- PREBUILT_HOST_TAG=linux-x86
- PREBUILT=$TOP/prebuilt/$PREBUILT_HOST_TAG
- log "Forcing usage of 32-bit prebuilts"
- ;;
- *)
- esac
- if [ ! -d $PREBUILT ] ; then
- echo "Can't find the prebuilt directory $PREBUILT in Android build"
- exit 1
- fi
- fi
- log "Prebuilt : PREBUILT=$PREBUILT"
-
- # use ccache if USE_CCACHE is defined and the corresponding
- # binary is available.
- #
- # note: located in PREBUILT/ccache/ccache in the new tree layout
- # located in PREBUILT/ccache in the old one
- #
- if [ -n "$USE_CCACHE" ] ; then
- CCACHE="$PREBUILT/ccache/ccache$EXE"
- if [ ! -f $CCACHE ] ; then
- CCACHE="$PREBUILT/ccache$EXE"
- fi
- if [ -f $CCACHE ] ; then
- CC="$CCACHE $CC"
- fi
- log "Prebuilt : CCACHE=$CCACHE"
- fi
-
- # if the user didn't specify a sdl-config script, get the prebuilt one
- if [ -z "$SDL_CONFIG" -a "$OPTION_NO_PREBUILTS" = "no" ] ; then
- # always use our own static libSDL by default
- SDL_CONFIG=$PREBUILT/sdl/bin/sdl-config
- log "Prebuilt : SDL_CONFIG=$SDL_CONFIG"
- fi
-
- # finally ensure that our new binary is copied to the 'out'
- # subdirectory as 'emulator'
- HOST_BIN=$(get_abs_build_var HOST_OUT_EXECUTABLES)
- if [ -n "$HOST_BIN" ] ; then
- TARGETS="$TARGETS $HOST_BIN/emulator$EXE"
- log "Targets : TARGETS=$TARGETS"
- fi
-fi # IN_ANDROID_BUILD = no
-
-
-####
-#### Compiler checks
-####
-####
-if [ -z "$CC" ] ; then
- CC=gcc
- if [ $CPU = "powerpc" ] ; then
- CC=gcc-3.3
- fi
-fi
-
-cat > $TMPC <<EOF
-int main(void) {}
-EOF
-
-if [ -z "$LD" ] ; then
- LD=$CC
-fi
-
-# we only support generating 32-bit binaris on 64-bit systems.
-# And we may need to add a -Wa,--32 to CFLAGS to let the assembler
-# generate 32-bit binaries on Linux x86_64.
-#
-if [ "$OPTION_TRY_64" != "yes" ] ; then
- if [ "$CPU" = "x86_64" -o "$CPU" = "amd64" ] ; then
- log "Check32Bits: Forcing generation of 32-bit binaries (--try-64 to disable)"
- CPU="i386"
- case $OS in
- linux-*)
- OS=linux-x86
- ;;
- darwin-*)
- OS=darwin-x86
- ;;
- esac
- CFLAGS="$CFLAGS -m32"
- LDFLAGS="$LDFLAGS -m32"
- compile
- if [ $? != 0 ] ; then
- CFLAGS="$CFLAGS -Wa,--32"
- fi
- # check that the compiler can link 32-bit executables
- # if not, try the host linker
- link
- if [ $? != 0 ] ; then
- OLD_LD=$LD
- LD=gcc
- compile
- link
- if [ $? != 0 ] ; then
- log "not using gcc for LD"
- LD=$OLD_LD
- fi
- fi
- fi
-fi
-
-compile
-if [ $? != 0 ] ; then
- echo "C compiler doesn't seem to work:"
- cat $TMPL
- clean-exit
-fi
-log "CC : compiler check ok ($CC)"
-
-# on 64-bit systems, some of our prebuilt compilers are not
-# capable of linking 32-bit executables properly
-#
-link
-if [ $? != 0 ] ; then
- echo "Linker doesn't seem to work:"
- cat $TMPL
- clean-exit
-fi
-log "LD : linker check ok ($LD)"
-
-###
-### SDL Probe
-###
-
-# For now, we require an external libSDL library, if SDL_CONFIG is not
-# defined, try to grab it from the environment
-#
-if [ -z "$SDL_CONFIG" ] ; then
- SDL_CONFIG=`which sdl-config`
- if [ $? != 0 ] ; then
- echo "Please ensure that you have the emulator's patched libSDL"
- echo "built somewhere and point to its sdl-config script either"
- echo "with the SDL_CONFIG env. variable, or the --sdl-config=<script>"
- echo "option."
- clean-exit
- fi
-fi
-
-# check that we can link statically with the library.
-#
-SDL_CFLAGS=`$SDL_CONFIG --cflags`
-SDL_LIBS=`$SDL_CONFIG --static-libs`
-
-# quick hack, remove the -D_GNU_SOURCE=1 of some SDL Cflags
-# since they break recent Mingw releases
-SDL_CFLAGS=`echo $SDL_CFLAGS | sed -e s/-D_GNU_SOURCE=1//g`
-
-log "SDL-probe : SDL_CFLAGS = $SDL_CFLAGS"
-log "SDL-probe : SDL_LIBS = $SDL_LIBS"
-
-OLD_CFLAGS=$CFLAGS
-OLD_LDFLAGS=$LDFLAGS
-
-CFLAGS="$CFLAGS $SDL_CFLAGS"
-LDFLAGS="$LDFLAGS $SDL_LIBS"
-
-cat > $TMPC << EOF
-#include <SDL.h>
-#undef main
-int main( void ) {
- return SDL_Init (SDL_INIT_VIDEO);
-}
-EOF
-compile
-if [ $? != 0 ] ; then
- echo "You provided an explicit sdl-config script, but the corresponding library"
- echo "cannot be statically linked with the Android emulator directly."
- echo "Error message:"
- cat $TMPL
- clean-exit
-fi
-log "SDL-probe : static linking ok"
-
-# now, let's check that the SDL library has the special functions
-# we added to our own sources
-#
-cat > $TMPC << EOF
-#include <SDL.h>
-#undef main
-int main( void ) {
- int x, y;
- SDL_WM_GetPos(&x, &y);
- SDL_WM_SetPos(x, y);
- return SDL_Init (SDL_INIT_VIDEO);
-}
-EOF
-compile
-if [ $? != 0 ] ; then
- echo "You provided an explicit sdl-config script in SDL_CONFIG, but the"
- echo "corresponding library doesn't have the patches required to link"
- echo "with the Android emulator. Unsetting SDL_CONFIG will use the"
- echo "sources bundled with the emulator instead"
- echo "Error:"
- cat $TMPL
- clean-exit
-fi
-
-log "SDL-probe : extra features ok"
-rm -f $TMPL $TMPC $TMPE
-
-CFLAGS=$OLD_CFLAGS
-LDFLAGS=$OLD_LDFLAGS
-
-
-###
-### Audio subsystems probes
-###
-PROBE_COREAUDIO=no
-PROBE_ALSA=no
-PROBE_OSS=no
-PROBE_ESD=no
-PROBE_WINAUDIO=no
-
-case "$OS" in
- darwin*) PROBE_COREAUDIO=yes;
- ;;
- linux-*) PROBE_ALSA=yes; PROBE_OSS=yes; PROBE_ESD=yes;
- ;;
- windows) PROBE_WINAUDIO=yes
- ;;
-esac
-
-ORG_CFLAGS=$CFLAGS
-ORG_LDFLAGS=$LDFLAGS
-
-if [ "$PROBE_ESD" = yes ] ; then
- CFLAGS="$ORG_CFLAGS"
- LDFLAGS="$ORG_LDFLAGS -ldl"
- cp -f android/config/check-esd.c $TMPC
- compile && link && $TMPE
- if [ $? = 0 ] ; then
- log "AudioProbe : ESD seems to be usable on this system"
- else
- if [ "$OPTION_IGNORE_AUDIO" = no ] ; then
- echo "the EsounD development files do not seem to be installed on this system"
- echo "Are you missing the libesd-dev package ?"
- echo "Correct the errors below and try again:"
- cat $TMPL
- clean-exit
- fi
- PROBE_ESD=no
- log "AudioProbe : ESD seems to be UNUSABLE on this system !!"
- fi
-fi
-
-if [ "$PROBE_ALSA" = yes ] ; then
- CFLAGS="$ORG_CFLAGS"
- LDFLAGS="$ORG_CFLAGS -ldl"
- cp -f android/config/check-alsa.c $TMPC
- compile && link && $TMPE
- if [ $? = 0 ] ; then
- log "AudioProbe : ALSA seems to be usable on this system"
- else
- if [ "$OPTION_IGNORE_AUDIO" = no ] ; then
- echo "the ALSA development files do not seem to be installed on this system"
- echo "Are you missing the libasound-dev package ?"
- echo "Correct the erros below and try again"
- cat $TMPL
- clean-exit
- fi
- PROBE_ALSA=no
- log "AudioProbe : ALSA seems to be UNUSABLE on this system !!"
- fi
-fi
-
-CFLAGS=$ORG_CFLAGS
-LDFLAGS=$ORG_LDFLAGS
-
-# create the objs directory that is going to contain all generated files
-# including the configuration ones
-#
-mkdir -p objs
-
-###
-### Compiler probe
-###
-
-####
-#### Host system probe
-####
-
-# because the previous version could be read-only
-rm -f $TMPC
-
-# check host endianess
-#
-HOST_BIGENDIAN=no
-cat > $TMPC << EOF
-#include <inttypes.h>
-int main(int argc, char ** argv){
- volatile uint32_t i=0x01234567;
- return (*((uint8_t*)(&i))) == 0x67;
-}
-EOF
-compile-exec-run && HOST_BIGENDIAN=yes
-log "Host : HOST_BIGENDIAN=$HOST_BIGENDIAN"
-
-# check size of host long bits
-HOST_LONGBITS=32
-cat > $TMPC << EOF
-int main(void) {
- return sizeof(void*)*8;
-}
-EOF
-compile-exec-run
-HOST_LONGBITS=$?
-log "Host : HOST_LONGBITS=$HOST_LONGBITS"
-
-# check whether we have <byteswap.h>
-#
-HAVE_BYTESWAP_H=yes
-cat > $TMPC << EOF
-#include <byteswap.h>
-EOF
-compile
-if [ $? != 0 ] ; then
- HAVE_BYTESWAP_H=no
-fi
-log "Host : HAVE_BYTESWAP_H=$HAVE_BYTESWAP_H"
-
-# Build the config.make file
-#
-rm -rf objs
-mkdir -p objs
-config_mk=objs/config.make
-echo "# This file was autogenerated by $PROGNAME" > $config_mk
-echo "TARGET_ARCH := arm" >> $config_mk
-case $OS in
- linux-*) HOST_OS=linux
- ;;
- darwin-*) HOST_OS=darwin
- ;;
- *) HOST_OS=$OS
-esac
-echo "OS := $OS" >> $config_mk
-echo "HOST_OS := $HOST_OS" >> $config_mk
-case $CPU in
- i?86) HOST_ARCH=x86
- ;;
- amd64) HOST_ARCH=x86_64
- ;;
- powerpc) HOST_ARCH=ppc
- ;;
- *) HOST_ARCH=$CPU
-esac
-echo "HOST_ARCH := $HOST_ARCH" >> $config_mk
-PWD=`pwd`
-echo "SRC_PATH := $PWD" >> $config_mk
-echo "CC := $CC" >> $config_mk
-echo "HOST_CC := $CC" >> $config_mk
-echo "LD := $LD" >> $config_mk
-echo "NO_PREBUILT := $OPTION_NO_PREBUILTS" >> $config_mk
-echo "HOST_PREBUILT_TAG := $PREBUILT_HOST_TAG" >> $config_mk
-echo "PREBUILT := $PREBUILT" >> $config_mk
-echo "CFLAGS := $CFLAGS" >> $config_mk
-echo "LDFLAGS := $LDFLAGS" >> $config_mk
-echo "SDL_CONFIG := $SDL_CONFIG" >> $config_mk
-echo "CONFIG_COREAUDIO := $PROBE_COREAUDIO" >> $config_mk
-echo "CONFIG_WINAUDIO := $PROBE_WINAUDIO" >> $config_mk
-echo "CONFIG_ESD := $PROBE_ESD" >> $config_mk
-echo "CONFIG_ALSA := $PROBE_ALSA" >> $config_mk
-echo "CONFIG_OSS := $PROBE_OSS" >> $config_mk
-echo "" >> $config_mk
-echo "BUILD_STANDALONE_EMULATOR := true" >> $config_mk
-echo "HOST_PREBUILT_TAG := $PREBUILT_HOST_TAG" >> $config_mk
-
-log "Generate : $config_mk"
-
-# Build the config-host.h file
-#
-config_h=objs/config-host.h
-echo "/* This file was autogenerated by '$PROGNAME' */" > $config_h
-echo "#define CONFIG_QEMU_SHAREDIR \"/usr/local/share/qemu\"" >> $config_h
-echo "#define HOST_LONG_BITS $HOST_LONGBITS" >> $config_h
-if [ "$HAVE_BYTESWAP_H" = "yes" ] ; then
- echo "#define HAVE_BYTESWAP_H 1" >> $config_h
-fi
-echo "#define CONFIG_GDBSTUB 1" >> $config_h
-echo "#define CONFIG_SLIRP 1" >> $config_h
-echo "#define CONFIG_SKINS 1" >> $config_h
-# the -nand-limits options can only work on non-windows systems
-if [ "$OS" != "windows" ] ; then
- echo "#define CONFIG_NAND_LIMITS 1" >> $config_h
-fi
-echo "#define QEMU_VERSION \"0.8.2\"" >> $config_h
-case "$CPU" in
- i386) HOST_CPU=I386
- ;;
- powerpc) HOST_CPU=PPC
- ;;
- x86_64|amd64) HOST_CPU=X86_64
- ;;
- *) HOST_CPU=$CPU
- ;;
-esac
-echo "#define HOST_$HOST_CPU 1" >> $config_h
-log "Generate : $config_h"
-
-echo "Ready to go. Type 'make' to build emulator"
diff --git a/android-rebuild.sh b/android-rebuild.sh
deleted file mode 100755
index d488f69..0000000
--- a/android-rebuild.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#
-# this script is used to rebuild all QEMU binaries for the host
-# platforms.
-#
-# assume that the device tree is in TOP
-#
-
-cd `dirname $0`
-./android-configure.sh $* && \
-make -j4 && \
-echo "Done. !!"
diff --git a/android/android.h b/android/android.h
deleted file mode 100644
index 71a20f6..0000000
--- a/android/android.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (C) 2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _qemu_android_h
-#define _qemu_android_h
-
-#define ANDROID_VERSION_MAJOR 1
-#define ANDROID_VERSION_MINOR 9
-
-#define CONFIG_SHAPER 1
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-/** in vl.c */
-
-/* emulated network up/down speeds, expressed in bits/seconds */
-extern double qemu_net_upload_speed;
-extern double qemu_net_download_speed;
-
-/* emulated network min-max latency, expressed in ms */
-extern int qemu_net_min_latency;
-extern int qemu_net_max_latency;
-
-/* global flag, when true, network is disabled */
-extern int qemu_net_disable;
-
-/* list of supported network speed names and values in bits/seconds */
-typedef struct {
- const char* name;
- const char* display;
- int upload;
- int download;
-} NetworkSpeed;
-
-extern const NetworkSpeed android_netspeeds[];
-
-/* list of supported network latency names and min-max values in ms */
-typedef struct {
- const char* name;
- const char* display;
- int min_ms;
- int max_ms;
-} NetworkLatency;
-
-extern const NetworkLatency android_netdelays[];
-
-/* enable/disable interrupt polling mode. the emulator will always use 100%
- * of host CPU time, but will get high-quality time measurments. this is
- * required for the tracing mode unless you can bear 10ms granularities
- */
-extern void qemu_polling_enable(void);
-extern void qemu_polling_disable(void);
-
-/**in hw/goldfish_fb.c */
-
-/* framebuffer dimensions in pixels, note these can change dynamically */
-extern int android_framebuffer_w;
-extern int android_framebuffer_h;
-/* framebuffer dimensions in mm */
-extern int android_framebuffer_phys_w;
-extern int android_framebuffer_phys_h;
-
-/* framebuffer rotation, relative to device */
-typedef enum {
- ANDROID_ROTATION_0 = 0,
- ANDROID_ROTATION_90,
- ANDROID_ROTATION_180,
- ANDROID_ROTATION_270
-} AndroidRotation;
-
-extern AndroidRotation android_framebuffer_rotation;
-
-/** in android_main.c */
-
-/* this is the port used for the control console in this emulator instance.
- * starts at 5554, with increments of 2 */
-extern int android_base_port;
-
-/* parses a network speed parameter and sets qemu_net_upload_speed and
- * qemu_net_download_speed accordingly. returns -1 on failure, 0 on success */
-extern int android_parse_network_speed(const char* speed);
-
-/* parse a network delay parameter and sets qemu_net_min/max_latency
- * accordingly. returns -1 on error, 0 on success */
-extern int android_parse_network_latency(const char* delay);
-
-extern void android_emulation_setup( void );
-extern void android_emulation_teardown( void );
-
-#endif /* _qemu_android_h */
diff --git a/android/avd/hardware-properties.ini b/android/avd/hardware-properties.ini
deleted file mode 100644
index f2293d1..0000000
--- a/android/avd/hardware-properties.ini
+++ /dev/null
@@ -1,158 +0,0 @@
-# This file describes the properties of a given virtual device configuration file.
-#
-# Note: Most top-level properties are boolean that control whether a feature is
-# present or not. Sub-features that depend on it are ignored if their
-# parent is set to 'false' or 'no'
-#
-# This file is parsed by 'android/tools/gen-hw-config.py' to generate
-# 'android/avd/hw-config-defs.h'. The latter is a special header containing
-# macro statements that is used several times:
-#
-# - once to define the fields of the AndroidHwConfig structure
-# (see android/avd/hw-config.h)
-#
-# - once to implement the hardware configuration loader
-# (see android/avd/hw-config.h)
-#
-# Hopefully, this file should also be read by a virtual device creation
-# tool/wizard to provide a nice user interface (hence the presence of
-# the 'abstract' and 'description' keys which are not currently used)
-#
-#
-# NOTE: if you remove items from this file, be sure that you do not break
-# the emulator build.
-#
-
-# Ram size
-name = hw.ramSize
-type = integer
-default = 96
-abstract = Device ram size
-description = The amount of physical RAM on the device, in megabytes.
-
-# Touch screen support
-name = hw.touchScreen
-type = boolean
-default = yes
-abstract = Touch-screen support
-description = Whether there is a touch screen or not on the device.
-
-# Trackball support
-name = hw.trackBall
-type = boolean
-default = yes
-abstract = Track-ball support
-description = Whether there is a trackball on the device.
-
-# Keyboard support (qwerty/azerty)
-name = hw.keyboard
-type = boolean
-default = yes
-abstract = Keyboard support
-description = Whether the device has a QWERTY keyboard.
-
-# DPad keys
-name = hw.dPad
-type = boolean
-default = yes
-abstract = DPad support
-description = Whether the device has DPad keys
-
-# GSM Modem support
-name = hw.gsmModem
-type = boolean
-default = yes
-abstract = GSM modem support
-description = Whether there is a GSM modem in the device.
-
-# Wifi support
-name = hw.wifi
-type = boolean
-default = no
-abstract = Wifi support
-description = Whether the device has a Wifi chipset.
-
-# Bluetooth support
-name = hw.bluetooth
-type = boolean
-default = no
-abstract = Bluetooth support
-description = Whether the device has a Bluetooth chipset.
-
-# Camera support
-name = hw.camera
-type = boolean
-default = no
-abstract = Camera support
-description = Whether the device has a camera.
-
-name = hw.camera.maxHorizontalPixels
-type = integer
-default = 640
-abstract = Maximum horizontal camera pixels
-
-name = hw.camera.maxVerticalPixels
-type = integer
-default = 480
-abstract = Maximum vertical camera pixels
-
-# GPS support
-name = hw.gps
-type = boolean
-default = no
-abstract = GPS support
-description = Whether there is a GPS in the device.
-
-# Accelerometer
-name = hw.accelerometer
-type = boolean
-default = no
-abstract = Accelerometer support
-description = Whether there is an accelerometer in the device.
-
-# Battery
-name = hw.battery
-type = boolean
-default = yes
-abstract = Battery support
-description = Whether the device can run on a battery.
-
-# Audio input
-name = hw.audioInput
-type = boolean
-default = yes
-abstract = Audio recording support
-description = Whether the device can record audio
-
-# Audio output
-name = hw.audioOutput
-type = boolean
-default = yes
-abstract = Audio playback support
-description = Whether the device can play audio
-
-# Compass
-name = hw.compass
-type = boolean
-default = no
-abstract = Compass support
-description = Whether there is a compass in the device.
-
-# SDCard support
-name = hw.sdCard
-type = boolean
-default = yes
-abstract = SD Card support
-description = Whether the device supports insertion/removal of virtual SD Cards.
-
-# Cache partition
-name = disk.cachePartition
-type = boolean
-default = yes
-abstract = Cache partition support
-description = Whether we use a /cache partition on the device.
-
-name = disk.cachePartition.size
-type = diskSize
-abstract = Cache partition size
-default = 66MB
diff --git a/android/avd/hw-config-defs.h b/android/avd/hw-config-defs.h
deleted file mode 100644
index 5c3b9ab..0000000
--- a/android/avd/hw-config-defs.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* this file is automatically generated from 'hardware-properties.ini'
- * DO NOT EDIT IT. To re-generate it, use android/tools/gen-hw-config.py'
- */
-#ifndef HWCFG_INT
-#error HWCFG_INT not defined
-#endif
-#ifndef HWCFG_BOOL
-#error HWCFG_BOOL not defined
-#endif
-#ifndef HWCFG_DISKSIZE
-#error HWCFG_DISKSIZE not defined
-#endif
-#ifndef HWCFG_STRING
-#error HWCFG_STRING not defined
-#endif
-#ifndef HWCFG_DOUBLE
-#error HWCFG_DOUBLE not defined
-#endif
-
-HWCFG_INT(
- hw_ramSize,
- "hw.ramSize",
- 96,
- "Device ram size",
- "The amount of physical RAM on the device, in megabytes.")
-
-HWCFG_BOOL(
- hw_touchScreen,
- "hw.touchScreen",
- "yes",
- "Touch-screen support",
- "Whether there is a touch screen or not on the device.")
-
-HWCFG_BOOL(
- hw_trackBall,
- "hw.trackBall",
- "yes",
- "Track-ball support",
- "Whether there is a trackball on the device.")
-
-HWCFG_BOOL(
- hw_keyboard,
- "hw.keyboard",
- "yes",
- "Keyboard support",
- "Whether the device has a QWERTY keyboard.")
-
-HWCFG_BOOL(
- hw_dPad,
- "hw.dPad",
- "yes",
- "DPad support",
- "Whether the device has DPad keys")
-
-HWCFG_BOOL(
- hw_gsmModem,
- "hw.gsmModem",
- "yes",
- "GSM modem support",
- "Whether there is a GSM modem in the device.")
-
-HWCFG_BOOL(
- hw_wifi,
- "hw.wifi",
- "no",
- "Wifi support",
- "Whether the device has a Wifi chipset.")
-
-HWCFG_BOOL(
- hw_bluetooth,
- "hw.bluetooth",
- "no",
- "Bluetooth support",
- "Whether the device has a Bluetooth chipset.")
-
-HWCFG_BOOL(
- hw_camera,
- "hw.camera",
- "no",
- "Camera support",
- "Whether the device has a camera.")
-
-HWCFG_INT(
- hw_camera_maxHorizontalPixels,
- "hw.camera.maxHorizontalPixels",
- 640,
- "Maximum horizontal camera pixels",
- "")
-
-HWCFG_INT(
- hw_camera_maxVerticalPixels,
- "hw.camera.maxVerticalPixels",
- 480,
- "Maximum vertical camera pixels",
- "")
-
-HWCFG_BOOL(
- hw_gps,
- "hw.gps",
- "no",
- "GPS support",
- "Whether there is a GPS in the device.")
-
-HWCFG_BOOL(
- hw_accelerometer,
- "hw.accelerometer",
- "no",
- "Accelerometer support",
- "Whether there is an accelerometer in the device.")
-
-HWCFG_BOOL(
- hw_battery,
- "hw.battery",
- "yes",
- "Battery support",
- "Whether the device can run on a battery.")
-
-HWCFG_BOOL(
- hw_audioInput,
- "hw.audioInput",
- "yes",
- "Audio recording support",
- "Whether the device can record audio")
-
-HWCFG_BOOL(
- hw_audioOutput,
- "hw.audioOutput",
- "yes",
- "Audio playback support",
- "Whether the device can play audio")
-
-HWCFG_BOOL(
- hw_compass,
- "hw.compass",
- "no",
- "Compass support",
- "Whether there is a compass in the device.")
-
-HWCFG_BOOL(
- hw_sdCard,
- "hw.sdCard",
- "yes",
- "SD Card support",
- "Whether the device supports insertion/removal of virtual SD Cards.")
-
-HWCFG_BOOL(
- disk_cachePartition,
- "disk.cachePartition",
- "yes",
- "Cache partition support",
- "Whether we use a /cache partition on the device.")
-
-HWCFG_DISKSIZE(
- disk_cachePartition_size,
- "disk.cachePartition.size",
- "66MB",
- "Cache partition size",
- "")
-
-#undef HWCFG_INT
-#undef HWCFG_BOOL
-#undef HWCFG_DISKSIZE
-#undef HWCFG_STRING
-#undef HWCFG_DOUBLE
-/* end of auto-generated file */
diff --git a/android/avd/hw-config.c b/android/avd/hw-config.c
deleted file mode 100644
index 2362b59..0000000
--- a/android/avd/hw-config.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/avd/hw-config.h"
-#include "android/utils/ini.h"
-#include <string.h>
-#include <stdlib.h>
-
-
-/* the global variable containing the hardware config for this device */
-AndroidHwConfig android_hw[1];
-
-int
-androidHwConfig_read( AndroidHwConfig* config,
- IniFile* ini )
-{
- if (ini == NULL)
- return -1;
-
- /* use the magic of macros to implement the hardware configuration loaded */
-
-#define HWCFG_BOOL(n,s,d,a,t) config->n = iniFile_getBoolean(ini, s, d);
-#define HWCFG_INT(n,s,d,a,t) config->n = iniFile_getInteger(ini, s, d);
-#define HWCFG_STRING(n,s,d,a,t) config->n = iniFile_getString(ini, s, d);
-#define HWCFG_DOUBLE(n,s,d,a,t) config->n = iniFile_getDouble(ini, s, d);
-#define HWCFG_DISKSIZE(n,s,d,a,t) config->n = iniFile_getDiskSize(ini, s, d);
-
-#include "android/avd/hw-config-defs.h"
-
- return 0;
-}
diff --git a/android/avd/hw-config.h b/android/avd/hw-config.h
deleted file mode 100644
index 05eb828..0000000
--- a/android/avd/hw-config.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_AVD_HW_CONFIG_H
-#define _ANDROID_AVD_HW_CONFIG_H
-
-#include <stdint.h>
-#include "android/utils/ini.h"
-
-typedef char hw_bool_t;
-typedef int hw_int_t;
-typedef int64_t hw_disksize_t;
-typedef char* hw_string_t;
-typedef double hw_double_t;
-
-/* these macros are used to define the fields of AndroidHwConfig
- * declared below
- */
-#define HWCFG_BOOL(n,s,d,a,t) hw_bool_t n;
-#define HWCFG_INT(n,s,d,a,t) hw_int_t n;
-#define HWCFG_STRING(n,s,d,a,t) hw_string_t n;
-#define HWCFG_DOUBLE(n,s,d,a,t) hw_double_t n;
-#define HWCFG_DISKSIZE(n,s,d,a,t) hw_disksize_t n;
-
-typedef struct {
-#include "android/avd/hw-config-defs.h"
-} AndroidHwConfig;
-
-/* reads a hardware configuration file from disk.
- * returns -1 if the file could not be read, or 0 in case of success.
- *
- * note that default values are written to hwConfig if the configuration
- * file doesn't have the corresponding hardware properties.
- */
-int androidHwConfig_read( AndroidHwConfig* hwConfig,
- IniFile* configFile );
-
-#endif /* _ANDROID_AVD_HW_CONFIG_H */
diff --git a/android/avd/info.c b/android/avd/info.c
deleted file mode 100644
index 432e279..0000000
--- a/android/avd/info.c
+++ /dev/null
@@ -1,1585 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/avd/info.h"
-#include "android/utils/path.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/filelock.h"
-#include "android/utils/tempfile.h"
-#include "android/utils/debug.h"
-#include "android/utils/dirscanner.h"
-#include "qemu-common.h"
-#include <stddef.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* global variables - see android/globals.h */
-AvdInfoParams android_avdParams[1];
-AvdInfo* android_avdInfo;
-
-/* for debugging */
-#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
-#define DD(...) VERBOSE_PRINT(avd_config,__VA_ARGS__)
-
-/* technical note on how all of this is supposed to work:
- *
- * we assume the following SDK layout:
- *
- * SDK/
- * tools/
- * emulator[.exe]
- * libs/
- * hardware-properties.ini
- * ...
- *
- * platforms/
- * <platform1>/
- * build.prop
- * images/
- * <default kernel/disk images>
- * skins/
- * default/ --> default skin
- * layout
- * <skin bitmaps>
- * <skin2>/ --> another skin
- * layout
- * <skin bitmaps>
- * <skin3>/ --> skin alias to <skin2>
- * alias-<skin2>
- *
- * <platform2>/
- * build.prop
- * images/
- * <other default kernel/disk images>
- *
- * add-ons/
- * <partner1>/
- * manifest.ini
- * images/
- * <replacement disk images>
- *
- * <partner2>/
- * manifest.ini
- * <replacement disk images>
- * hardware.ini
- * skins/
- * default/
- * layout
- * <skin bitmaps>
- * <skin2>/
- * layout
- * <skin bitmaps>
- *
- *
- * we define a 'platform' as a directory that provides a complete
- * set of disk/kernel images, some skins, as well as a build.prop
- * file.
- *
- * we define an 'addon' as a directory that provides additionnal
- * or replacement files related to a given existing platform.
- * each add-on provides at the minimum a 'manifest.ini' file
- * that describes it (see below).
- *
- * important notes:
- *
- * - the build.prop file of a given platform directory contains
- * a line that reads 'ro.build.version.sdk=<version>' where
- * <version> is an integer corresponding to the corresponding
- * official API version number as defined by Android.
- *
- * each platform provided with the SDK must have a unique
- * version number.
- *
- * - the manifest.ini of a given addon must contain lines
- * that include:
- *
- * name=<addOnName>
- * vendor=<vendorName>
- * api=<version>
- *
- * where <version> is used to identify the platform the add-on
- * refers to. Note that the platform's directory name is
- * irrelevant to the matching algorithm.
- *
- * each addon available must have a unique
- * <vendor>:<name>:<sdk> triplet
- *
- * - an add-on can provide a hardware.ini file. If present, this
- * is used to force the hardware setting of any virtual device
- * built from the add-on.
- *
- * - the file in SDK/tools/lib/hardware-properties.ini declares which
- * hardware properties are supported by the emulator binary.
- * these can appear in the config.ini file of a given virtual
- * device, or the hardware.ini of a given add-on.
- *
- * normally, a virtual device corresponds to:
- *
- * - a root configuration file, placed in ~/.android/avd/<foo>.ini
- * where <foo> is the name of the virtual device.
- *
- * - a "content" directory, which contains disk images for the
- * virtual device (e.g. at a minimum, the userdata.img file)
- * plus some configuration information.
- *
- * - the root config file must have at least two lines like:
- *
- * path=<pathToContentDirectory>
- * target=<targetAddonOrPlatform>
- *
- * the 'path' value must point to the location of
- * the virtual device's content directory. By default, this
- * should be ~/.android/avd/<foo>/, though the user should be
- * able to choose an alternative path at creation time.
- *
- * the 'target' value can be one of:
- *
- * android-<version>
- * <vendor>:<name>:<version>
- *
- * the first form is used to refer to a given platform.
- * the second form is used to refer to a unique add-on.
- * in both forms, <version> must be an integer that
- * matches one of the available platforms.
- *
- * <vendor>:<name>:<version> must match the triplet of one
- * of the available add-ons
- *
- * if the target value is incorrect, or if the content path
- * is invalid, the emulator will abort with an error.
- *
- * - the content directory shall contain a 'config.ini' that
- * contains hardware properties for the virtual device
- * (as defined by SDK/tools/lib/hardware-properties.ini), as
- * well as additional lines like:
- *
- * sdcard=<pathToDefaultSDCard>
- * skin=<defaultSkinName>
- * options=<additionalEmulatorStartupOptions>
- *
- *
- * Finally, to find the skin to be used with a given virtual
- * device, the following logic is used:
- *
- * - if no skin name has been manually specified on
- * the command line, or in the config.ini file,
- * look in $CONTENT/skin/layout and use it if available.
- *
- * - otherwise, set SKINNAME to 'default' if not manually
- * specified, and look for $ADDON/skins/$SKINNAME/layout
- * and use it if available
- *
- * - otherwise, look for $PLATFORM/skins/$SKINNAME/layout
- * and use it if available.
- *
- * - otherwise, look for $PLATFORM/skins/$SKINNAME/alias-<other>.
- * if a file exist by that name, look at $PLATFORM/skins/<other>/layout
- * and use it if available. Aliases are not recursives :-)
- */
-
-/* now, things get a little bit more complicated when working
- * within the Android build system. In this mode, which can be
- * detected by looking at the definition of the ANDROID_PRODUCT_OUT
- * environment variable, we're going to simply pick the image files
- * from the out directory, or from $BUILDROOT/prebuilt
- */
-
-/* the name of the $SDKROOT subdirectory that contains all platforms */
-#define PLATFORMS_SUBDIR "platforms"
-
-/* the name of the $SDKROOT subdirectory that contains add-ons */
-#define ADDONS_SUBDIR "add-ons"
-
-/* this is the subdirectory of $HOME/.android where all
- * root configuration files (and default content directories)
- * are located.
- */
-#define ANDROID_AVD_DIR "avd"
-
-/* certain disk image files are mounted read/write by the emulator
- * to ensure that several emulators referencing the same files
- * do not corrupt these files, we need to lock them and respond
- * to collision depending on the image type.
- *
- * the enumeration below is used to record information about
- * each image file path.
- *
- * READONLY means that the file will be mounted read-only
- * and this doesn't need to be locked. must be first in list
- *
- * MUSTLOCK means that the file should be locked before
- * being mounted by the emulator
- *
- * TEMPORARY means that the file has been copied to a
- * temporary image, which can be mounted read/write
- * but doesn't require locking.
- */
-typedef enum {
- IMAGE_STATE_READONLY, /* unlocked */
- IMAGE_STATE_MUSTLOCK, /* must be locked */
- IMAGE_STATE_LOCKED, /* locked */
- IMAGE_STATE_LOCKED_EMPTY, /* locked and empty */
- IMAGE_STATE_TEMPORARY, /* copied to temp file (no lock needed) */
-} AvdImageState;
-
-struct AvdInfo {
- /* for the Android build system case */
- char inAndroidBuild;
- char* androidOut;
- char* androidBuildRoot;
-
- /* for the normal virtual device case */
- char* deviceName;
- char* sdkRootPath;
- int platformVersion;
- char* platformPath;
- char* addonTarget;
- char* addonPath;
- char* contentPath;
- IniFile* rootIni; /* root <foo>.ini file */
- IniFile* configIni; /* virtual device's config.ini */
-
- /* for both */
- char* skinName; /* skin name */
- char* skinDirPath; /* skin directory */
-
- /* image files */
- char* imagePath [ AVD_IMAGE_MAX ];
- char imageState[ AVD_IMAGE_MAX ];
-};
-
-
-void
-avdInfo_free( AvdInfo* i )
-{
- if (i) {
- int nn;
-
- for (nn = 0; nn < AVD_IMAGE_MAX; nn++)
- qemu_free(i->imagePath[nn]);
-
- qemu_free(i->skinName);
- qemu_free(i->skinDirPath);
-
- if (i->configIni) {
- iniFile_free(i->configIni);
- i->configIni = NULL;
- }
-
- if (i->rootIni) {
- iniFile_free(i->rootIni);
- i->rootIni = NULL;
- }
-
- qemu_free(i->contentPath);
- qemu_free(i->sdkRootPath);
-
- if (i->inAndroidBuild) {
- qemu_free(i->androidOut);
- qemu_free(i->androidBuildRoot);
- } else {
- qemu_free(i->platformPath);
- qemu_free(i->addonTarget);
- qemu_free(i->addonPath);
- }
-
- qemu_free(i->deviceName);
- qemu_free(i);
- }
-}
-
-/* list of default file names for each supported image file type */
-static const char* const _imageFileNames[ AVD_IMAGE_MAX ] = {
-#define _AVD_IMG(x,y,z) y,
- AVD_IMAGE_LIST
-#undef _AVD_IMG
-};
-
-/* list of short text description for each supported image file type */
-static const char* const _imageFileText[ AVD_IMAGE_MAX ] = {
-#define _AVD_IMG(x,y,z) z,
- AVD_IMAGE_LIST
-#undef _AVD_IMG
-};
-
-/***************************************************************
- ***************************************************************
- *****
- ***** NORMAL VIRTUAL DEVICE SUPPORT
- *****
- *****/
-
-/* compute path to the root SDK directory
- * assume we are in $SDKROOT/tools/emulator[.exe]
- */
-static int
-_getSdkRoot( AvdInfo* i )
-{
- const char* env;
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
-
-#define SDK_ROOT_ENV "ANDROID_SDK_ROOT"
-
- env = getenv(SDK_ROOT_ENV);
- if (env != NULL && env[0] != 0) {
- if (path_exists(env)) {
- D("found " SDK_ROOT_ENV ": %s", env);
- i->sdkRootPath = qemu_strdup(env);
- return 0;
- }
- D(SDK_ROOT_ENV " points to unknown directory: %s", env);
- }
-
- (void) bufprint_app_dir(temp, end);
-
- i->sdkRootPath = path_parent(temp, 1);
- if (i->sdkRootPath == NULL) {
- derror("can't find root of SDK directory");
- return -1;
- }
- D("found SDK root at %s", i->sdkRootPath);
- return 0;
-}
-
-/* returns the full path of the platform subdirectory
- * corresponding to a given API version
- */
-static char*
-_findPlatformByVersion( const char* sdkRoot, int version )
-{
- char temp[PATH_MAX], *p=temp, *end=p+sizeof temp;
- char* subdir = NULL;
- DirScanner* scanner;
-
- DD("> %s(%s,%d)", __FUNCTION__, sdkRoot, version);
- p = bufprint(temp, end, "%s/%s", sdkRoot, PLATFORMS_SUBDIR);
- if (p >= end) {
- DD("! path too long");
- return NULL;
- }
-
- scanner = dirScanner_new(temp);
- if (scanner == NULL) {
- DD("! cannot scan path %s: %s", temp, strerror(errno));
- return NULL;
- }
-
- for (;;) {
- IniFile* ini;
- int apiVersion;
-
- subdir = (char*) dirScanner_nextFull(scanner);
- if (subdir == NULL)
- break;
-
- /* look for a file named "build.prop */
- p = bufprint(temp, end, "%s/build.prop", subdir);
- if (p >= end)
- continue;
-
- if (!path_exists(temp)) {
- DD("! no file at %s", temp);
- continue;
- }
-
- ini = iniFile_newFromFile(temp);
- if (ini == NULL)
- continue;
-
- apiVersion = iniFile_getInteger(ini, "ro.build.version.sdk", -1);
- iniFile_free(ini);
-
- DD("! found %s (version %d)", temp, apiVersion);
-
- if (apiVersion == version) {
- /* Bingo */
- subdir = qemu_strdup(subdir);
- break;
- }
- }
-
- if (!subdir) {
- DD("< didn't found anything");
- }
-
- dirScanner_free(scanner);
- return subdir;
-}
-
-/* returns the full path of the addon corresponding to a given target,
- * or NULL if not found. on success, *pversion will contain the SDK
- * version number
- */
-static char*
-_findAddonByTarget( const char* sdkRoot, const char* target, int *pversion )
-{
- char* targetCopy = qemu_strdup(target);
- char* targetVendor = NULL;
- char* targetName = NULL;
- int targetVersion = -1;
-
- char temp[PATH_MAX];
- char* p;
- char* end;
- DirScanner* scanner;
- char* subdir;
-
- DD("> %s(%s,%s)", __FUNCTION__, sdkRoot, target);
-
- /* extract triplet from target string */
- targetVendor = targetCopy;
-
- p = strchr(targetVendor, ':');
- if (p == NULL) {
- DD("< missing first column separator");
- goto FAIL;
- }
- *p = 0;
- targetName = p + 1;
- p = strchr(targetName, ':');
- if (p == NULL) {
- DD("< missing second column separator");
- goto FAIL;
- }
- *p++ = 0;
-
- targetVersion = atoi(p);
-
- if (targetVersion == 0) {
- DD("< invalid version number");
- goto FAIL;
- }
- /* now scan addons directory */
- p = temp;
- end = p + sizeof temp;
-
- p = bufprint(p, end, "%s/%s", sdkRoot, ADDONS_SUBDIR);
- if (p >= end) {
- DD("< add-on path too long");
- goto FAIL;
- }
- scanner = dirScanner_new(temp);
- if (scanner == NULL) {
- DD("< cannot scan add-on path %s: %s", temp, strerror(errno));
- goto FAIL;
- }
- for (;;) {
- IniFile* ini;
- const char* vendor;
- const char* name;
- int version;
- int matches;
-
- subdir = (char*) dirScanner_nextFull(scanner);
- if (subdir == NULL)
- break;
-
- /* try to open the manifest.ini file */
- p = bufprint(temp, end, "%s/manifest.ini", subdir);
- if (p >= end)
- continue;
-
- ini = iniFile_newFromFile(temp);
- if (ini == NULL)
- continue;
-
- DD("! scanning manifest.ini in %s", temp);
-
- /* find the vendor, name and version */
- vendor = iniFile_getValue(ini, "vendor");
- name = iniFile_getValue(ini, "name");
- version = iniFile_getInteger(ini, "api", -1);
-
- matches = 0;
-
- matches += (version == targetVersion);
- matches += (vendor && !strcmp(vendor, targetVendor));
- matches += (name && !strcmp(name, targetName));
-
- DD("! matches=%d vendor=[%s] name=[%s] version=%d",
- matches,
- vendor ? vendor : "<NULL>",
- name ? name : "<NULL>",
- version);
-
- iniFile_free(ini);
-
- if (matches == 3) {
- /* bingo */
- *pversion = version;
- subdir = qemu_strdup(subdir);
- break;
- }
- }
-
- dirScanner_free(scanner);
-
- DD("< returning %s", subdir ? subdir : "<NULL>");
- return subdir;
-
-FAIL:
- qemu_free(targetCopy);
- return NULL;
-}
-
-static int
-_checkAvdName( const char* name )
-{
- int len = strlen(name);
- int len2 = strspn(name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789_.-");
- return (len == len2);
-}
-
-/* parse the root config .ini file. it is located in
- * ~/.android/avd/<name>.ini or Windows equivalent
- */
-static int
-_getRootIni( AvdInfo* i )
-{
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
-
- p = bufprint_config_path(temp, end);
- p = bufprint(p, end, "/" ANDROID_AVD_DIR "/%s.ini", i->deviceName);
- if (p >= end) {
- derror("device name too long");
- return -1;
- }
-
- i->rootIni = iniFile_newFromFile(temp);
- if (i->rootIni == NULL) {
- derror("unknown virtual device name: '%s'", i->deviceName);
- return -1;
- }
- D("root virtual device file at %s", temp);
- return 0;
-}
-
-/* the .ini variable name that points to the content directory
- * in a root AVD ini file. This is required */
-# define ROOT_PATH_KEY "path"
-# define ROOT_TARGET_KEY "target"
-
-/* retrieve the content path and target from the root .ini file */
-static int
-_getTarget( AvdInfo* i )
-{
- i->contentPath = iniFile_getString(i->rootIni, ROOT_PATH_KEY);
- i->addonTarget = iniFile_getString(i->rootIni, ROOT_TARGET_KEY);
-
- iniFile_free(i->rootIni);
- i->rootIni = NULL;
-
- if (i->contentPath == NULL) {
- derror("bad config: %s",
- "virtual device file lacks a "ROOT_PATH_KEY" entry");
- return -1;
- }
-
- if (i->addonTarget == NULL) {
- derror("bad config: %s",
- "virtual device file lacks a "ROOT_TARGET_KEY" entry");
- return -1;
- }
-
- D("virtual device content at %s", i->contentPath);
- D("virtual device target is %s", i->addonTarget);
-
- if (!strncmp(i->addonTarget, "android-", 8)) { /* target is platform */
- char* end;
- const char* versionString = i->addonTarget+8;
- int version = (int) strtol(versionString, &end, 10);
- if (*end != 0 || version <= 0) {
- derror("bad config: invalid platform version: '%s'", versionString);
- return -1;
- }
- i->platformVersion = version;
- i->platformPath = _findPlatformByVersion(i->sdkRootPath,
- version);
- if (i->platformPath == NULL) {
- derror("bad config: unknown platform version: '%d'", version);
- return -1;
- }
- }
- else /* target is add-on */
- {
- i->addonPath = _findAddonByTarget(i->sdkRootPath, i->addonTarget,
- &i->platformVersion);
- if (i->addonPath == NULL) {
- derror("bad config: %s",
- "unknown add-on target: '%s'", i->addonTarget);
- return -1;
- }
-
- i->platformPath = _findPlatformByVersion(i->sdkRootPath,
- i->platformVersion);
- if (i->platformPath == NULL) {
- derror("bad config: %s",
- "unknown add-on platform version: '%d'", i->platformVersion);
- return -1;
- }
- D("virtual device add-on path: %s", i->addonPath);
- }
- D("virtual device platform path: %s", i->platformPath);
- D("virtual device platform version %d", i->platformVersion);
- return 0;
-}
-
-
-/* find and parse the config.ini file from the content directory */
-static int
-_getConfigIni(AvdInfo* i)
-{
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
-
- p = bufprint(p, end, "%s/config.ini", i->contentPath);
- if (p >= end) {
- derror("can't access virtual device content directory");
- return -1;
- }
-
-#if 1 /* XXX: TODO: remove this in the future */
- /* for now, allow a non-existing config.ini */
- if (!path_exists(temp)) {
- D("virtual device has no config file - no problem");
- return 0;
- }
-#endif
-
- i->configIni = iniFile_newFromFile(temp);
- if (i->configIni == NULL) {
- derror("bad config: %s",
- "virtual device directory lacks config.ini");
- return -1;
- }
- D("virtual device config file: %s", temp);
- return 0;
-}
-
-/***************************************************************
- ***************************************************************
- *****
- ***** KERNEL/DISK IMAGE LOADER
- *****
- *****/
-
-/* a structure used to handle the loading of
- * kernel/disk images.
- */
-typedef struct {
- AvdInfo* info;
- AvdInfoParams* params;
- AvdImageType id;
- const char* imageFile;
- const char* imageText;
- char** pPath;
- char* pState;
- char temp[PATH_MAX];
-} ImageLoader;
-
-static void
-imageLoader_init( ImageLoader* l, AvdInfo* info, AvdInfoParams* params )
-{
- memset(l, 0, sizeof(*l));
- l->info = info;
- l->params = params;
-}
-
-/* set the type of the image to load */
-static void
-imageLoader_set( ImageLoader* l, AvdImageType id )
-{
- l->id = id;
- l->imageFile = _imageFileNames[id];
- l->imageText = _imageFileText[id];
- l->pPath = &l->info->imagePath[id];
- l->pState = &l->info->imageState[id];
-
- l->pState[0] = IMAGE_STATE_READONLY;
-}
-
-/* change the image path */
-static char*
-imageLoader_setPath( ImageLoader* l, const char* path )
-{
- path = path ? qemu_strdup(path) : NULL;
-
- qemu_free(l->pPath[0]);
- l->pPath[0] = (char*) path;
-
- return (char*) path;
-}
-
-static char*
-imageLoader_extractPath( ImageLoader* l )
-{
- char* result = l->pPath[0];
- l->pPath[0] = NULL;
- return result;
-}
-
-/* flags used when loading images */
-enum {
- IMAGE_REQUIRED = (1<<0), /* image is required */
- IMAGE_SEARCH_SDK = (1<<1), /* search image in SDK */
- IMAGE_EMPTY_IF_MISSING = (1<<2), /* create empty file if missing */
- IMAGE_DONT_LOCK = (1<<4), /* don't try to lock image */
- IMAGE_IGNORE_IF_LOCKED = (1<<5), /* ignore file if it's locked */
-};
-
-#define IMAGE_OPTIONAL 0
-
-/* find an image from the SDK add-on and/or platform
- * directories. returns the full path or NULL if
- * the file could not be found.
- *
- * note: this stores the result in the image's path as well
- */
-static char*
-imageLoader_lookupSdk( ImageLoader* l )
-{
- AvdInfo* i = l->info;
- char* temp = l->temp, *p = temp, *end = p + sizeof(l->temp);
-
- do {
- /* try the add-on directory, if any */
- if (i->addonPath != NULL) {
- DD("searching %s in add-on directory: %s",
- l->imageFile, i->addonPath);
-
- p = bufprint(temp, end, "%s/images/%s",
- i->addonPath, l->imageFile);
-
- if (p < end && path_exists(temp))
- break;
- }
-
- /* or try the platform directory */
- DD("searching %s in platform directory: %s",
- l->imageFile, i->platformPath);
-
- p = bufprint(temp, end, "%s/images/%s",
- i->platformPath, l->imageFile);
- if (p < end && path_exists(temp))
- break;
-
- DD("could not find %s in SDK", l->imageFile);
- return NULL;
-
- } while (0);
-
- l->pState[0] = IMAGE_STATE_READONLY;
-
- return imageLoader_setPath(l, temp);
-}
-
-/* search for a file in the content directory.
- * returns NULL if the file cannot be found.
- *
- * note that this formats l->temp with the file's path
- * allowing you to retrieve it if the function returns NULL
- */
-static char*
-imageLoader_lookupContent( ImageLoader* l )
-{
- AvdInfo* i = l->info;
- char* temp = l->temp, *p = temp, *end = p + sizeof(l->temp);
-
- DD("searching %s in content directory", l->imageFile);
- p = bufprint(temp, end, "%s/%s", i->contentPath, l->imageFile);
- if (p >= end) {
- derror("content directory path too long");
- exit(2);
- }
- if (!path_exists(temp)) {
- DD("not found %s in content directory", l->imageFile);
- return NULL;
- }
-
- /* assume content image files must be locked */
- l->pState[0] = IMAGE_STATE_MUSTLOCK;
-
- return imageLoader_setPath(l, temp);
-}
-
-/* lock a file image depending on its state and user flags
- * note that this clears l->pPath[0] if the lock could not
- * be acquired and that IMAGE_IGNORE_IF_LOCKED is used.
- */
-static void
-imageLoader_lock( ImageLoader* l, unsigned flags )
-{
- const char* path = l->pPath[0];
-
- if (flags & IMAGE_DONT_LOCK)
- return;
-
- if (l->pState[0] != IMAGE_STATE_MUSTLOCK)
- return;
-
- D("locking %s image at %s", l->imageText, path);
-
- if (filelock_create(path) != NULL) {
- /* succesful lock */
- l->pState[0] = IMAGE_STATE_LOCKED;
- return;
- }
-
- if (flags & IMAGE_IGNORE_IF_LOCKED) {
- dwarning("ignoring locked %s image at %s", l->imageText, path);
- imageLoader_setPath(l, NULL);
- return;
- }
-
- derror("the %s image is used by another emulator. aborting",
- l->imageText);
- exit(2);
-}
-
-/* make a file image empty, this may require locking */
-static void
-imageLoader_empty( ImageLoader* l, unsigned flags )
-{
- const char* path;
-
- imageLoader_lock(l, flags);
-
- path = l->pPath[0];
- if (path == NULL) /* failed to lock, caller will handle it */
- return;
-
- if (path_empty_file(path) < 0) {
- derror("could not create %s image at %s: %s",
- l->imageText, path, strerror(errno));
- exit(2);
- }
- l->pState[0] = IMAGE_STATE_LOCKED_EMPTY;
-}
-
-
-/* copy image file from a given source
- * assumes locking is needed.
- */
-static void
-imageLoader_copyFrom( ImageLoader* l, const char* srcPath )
-{
- const char* dstPath = NULL;
-
- /* find destination file */
- if (l->params) {
- dstPath = l->params->forcePaths[l->id];
- }
- if (!dstPath) {
- imageLoader_lookupContent(l);
- dstPath = l->temp;
- }
-
- /* lock destination */
- imageLoader_setPath(l, dstPath);
- l->pState[0] = IMAGE_STATE_MUSTLOCK;
- imageLoader_lock(l, 0);
-
- /* make the copy */
- if (path_copy_file(dstPath, srcPath) < 0) {
- derror("can't initialize %s image from SDK: %s: %s",
- l->imageText, dstPath, strerror(errno));
- exit(2);
- }
-}
-
-/* this will load and eventually lock and image file, depending
- * on the flags being used. on exit, this function udpates
- * l->pState[0] and l->pPath[0]
- *
- * returns the path to the file. Note that it returns NULL
- * only if the file was optional and could not be found.
- *
- * if the file is required and missing, the function aborts
- * the program.
- */
-static char*
-imageLoader_load( ImageLoader* l,
- unsigned flags )
-{
- const char* path = NULL;
-
- DD("looking for %s image (%s)", l->imageText, l->imageFile);
-
- /* first, check user-provided path */
- path = l->params->forcePaths[l->id];
- if (path != NULL) {
- imageLoader_setPath(l, path);
- if (path_exists(path))
- goto EXIT;
-
- D("user-provided %s image does not exist: %s",
- l->imageText, path);
-
- /* if the file is required, abort */
- if (flags & IMAGE_REQUIRED) {
- derror("user-provided %s image at %s doesn't exist",
- l->imageText, path);
- exit(2);
- }
- }
- else {
- const char* contentFile;
-
- /* second, look in the content directory */
- path = imageLoader_lookupContent(l);
- if (path) goto EXIT;
-
- contentFile = qemu_strdup(l->temp);
-
- /* it's not there */
- if (flags & IMAGE_SEARCH_SDK) {
- /* third, look in the SDK directory */
- path = imageLoader_lookupSdk(l);
- if (path) {
- qemu_free((char*)contentFile);
- goto EXIT;
- }
- }
- DD("found no %s image (%s)", l->imageText, l->imageFile);
-
- /* if the file is required, abort */
- if (flags & IMAGE_REQUIRED) {
- derror("could not find required %s image (%s)",
- l->imageText, l->imageFile);
- exit(2);
- }
-
- path = imageLoader_setPath(l, contentFile);
- qemu_free((char*)contentFile);
- }
-
- /* otherwise, do we need to create it ? */
- if (flags & IMAGE_EMPTY_IF_MISSING) {
- imageLoader_empty(l, flags);
- return l->pPath[0];
- }
- return NULL;
-
-EXIT:
- imageLoader_lock(l, flags);
- return l->pPath[0];
-}
-
-
-
-/* find the correct path of all image files we're going to need
- * and lock the files that need it.
- */
-static int
-_getImagePaths(AvdInfo* i, AvdInfoParams* params )
-{
- int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0;
- int wipeCache = (params->flags & AVDINFO_WIPE_CACHE) != 0;
- int noCache = (params->flags & AVDINFO_NO_CACHE) != 0;
- int noSdCard = (params->flags & AVDINFO_NO_SDCARD) != 0;
-
- ImageLoader l[1];
-
- imageLoader_init(l, i, params);
-
- /* pick up the kernel and ramdisk image files - these don't
- * need a specific handling.
- */
- imageLoader_set ( l, AVD_IMAGE_KERNEL );
- imageLoader_load( l, IMAGE_REQUIRED | IMAGE_SEARCH_SDK | IMAGE_DONT_LOCK );
-
- imageLoader_set ( l, AVD_IMAGE_RAMDISK );
- imageLoader_load( l, IMAGE_REQUIRED | IMAGE_SEARCH_SDK | IMAGE_DONT_LOCK );
-
- /* the system image
- *
- * if there is one in the content directory just lock
- * and use it.
- */
- imageLoader_set ( l, AVD_IMAGE_SYSTEM );
- imageLoader_load( l, IMAGE_REQUIRED | IMAGE_SEARCH_SDK );
-
- /* the data partition - this one is special because if it
- * is missing, we need to copy the initial image file into it.
- *
- * first, try to see if it is in the content directory
- * (or the user-provided path)
- */
- imageLoader_set( l, AVD_IMAGE_USERDATA );
- if ( !imageLoader_load( l, IMAGE_OPTIONAL |
- IMAGE_EMPTY_IF_MISSING |
- IMAGE_DONT_LOCK ) )
- {
- /* it's not, we're going to initialize it. simply
- * forcing a data wipe should be enough */
- D("initializing new data partition image: %s", l->pPath[0]);
- wipeData = 1;
- }
-
- if (wipeData) {
- /* find SDK source file */
- const char* srcPath;
-
- if (imageLoader_lookupSdk(l)) {
- derror("can't locate initial %s image in SDK",
- l->imageText);
- exit(2);
- }
- srcPath = imageLoader_extractPath(l);
-
- imageLoader_copyFrom( l, srcPath );
- qemu_free((char*) srcPath);
- }
- else
- {
- /* lock the data partition image */
- l->pState[0] = IMAGE_STATE_MUSTLOCK;
- imageLoader_lock( l, 0 );
- }
-
- /* the cache partition: unless the user doesn't want one,
- * we're going to create it in the content directory
- */
- if (!noCache) {
- imageLoader_set (l, AVD_IMAGE_CACHE);
- imageLoader_load(l, IMAGE_OPTIONAL |
- IMAGE_EMPTY_IF_MISSING );
-
- if (wipeCache) {
- if (path_empty_file(l->pPath[0]) < 0) {
- derror("cannot wipe %s image at %s: %s",
- l->imageText, l->pPath[0],
- strerror(errno));
- exit(2);
- }
- }
- }
-
- /* the SD Card image. unless the user doesn't want to, we're
- * going to mount it if available. Note that if the image is
- * already used, we must ignore it.
- */
- if (!noSdCard) {
- imageLoader_set (l, AVD_IMAGE_SDCARD);
- imageLoader_load(l, IMAGE_OPTIONAL |
- IMAGE_IGNORE_IF_LOCKED);
-
- /* if the file was not found, ignore it */
- if (l->pPath[0] && !path_exists(l->pPath[0]))
- {
- D("ignoring non-existing %s at %s: %s",
- l->imageText, l->pPath[0], strerror(errno));
-
- /* if the user provided the SD Card path by hand,
- * warn him. */
- if (params->forcePaths[AVD_IMAGE_SDCARD] != NULL)
- dwarning("ignoring non-existing SD Card image");
-
- imageLoader_setPath(l, NULL);
- }
- }
-
- return 0;
-}
-
-/* check that there is a skin named 'skinName' listed from 'skinDirRoot'
- * this returns 1 on success, 0 on failure
- * on success, the 'temp' buffer will get the path containing the real
- * skin directory (after alias expansion), including the skin name.
- */
-static int
-_checkSkinDir( char* temp, char* end, const char* skinDirRoot, const char* skinName )
-{
- DirScanner* scanner;
- char *p, *q;
- int result;
-
- p = bufprint(temp, end, "%s/skins/%s",
- skinDirRoot, skinName);
-
- DD("probing skin content in %s", temp);
-
- if (p >= end || !path_exists(temp)) {
- return 0;
- }
-
- /* first, is this a normal skin directory ? */
- q = bufprint(p, end, "/layout");
- if (q < end && path_exists(temp)) {
- /* yes */
- *p = 0;
- return 1;
- }
-
- /* second, is it an alias to another skin ? */
- *p = 0;
- result = 0;
- scanner = dirScanner_new(temp);
- if (scanner != NULL) {
- for (;;) {
- const char* file = dirScanner_next(scanner);
-
- if (file == NULL)
- break;
-
- if (strncmp(file, "alias-", 6) || file[6] == 0)
- continue;
-
- p = bufprint(temp, end, "%s/skins/%s",
- skinDirRoot, file+6);
-
- q = bufprint(p, end, "/layout");
- if (q < end && path_exists(temp)) {
- /* yes, it's an alias */
- *p = 0;
- result = 1;
- break;
- }
- }
- dirScanner_free(scanner);
- }
- return result;
-}
-
-static int
-_getSkin( AvdInfo* i, AvdInfoParams* params )
-{
- char* skinName;
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
- char explicitSkin = 1;
-
- /* determine the skin name, the default is "HVGA"
- * unless specified by the caller or in config.ini
- */
- if (params->skinName) {
- skinName = qemu_strdup(params->skinName);
- } else {
- skinName = iniFile_getString( i->configIni, "skin" );
- if (skinName == NULL) {
- skinName = qemu_strdup("HVGA");
- explicitSkin = 0;
- }
- }
-
- i->skinName = skinName;
-
- /* if the skin name has the format 'NNNNxNNN' where
- * NNN is a decimal value, then this is a 'magic' skin
- * name that doesn't require a skin directory
- */
- if (isdigit(skinName[0])) {
- int width, height;
- if (sscanf(skinName, "%dx%d", &width, &height) == 2) {
- D("'magic' skin format detected: %s", skinName);
- i->skinDirPath = NULL;
- return 0;
- }
- }
-
- /* now try to find the skin directory for that name -
- * first try the content directory */
- do {
- /* if there is a single 'skin' directory in
- * the content directory, assume that's what the
- * user wants, unless an explicit name was given
- */
- if (!explicitSkin) {
- char* q;
-
- p = bufprint(temp, end, "%s/skin", i->contentPath);
- q = bufprint(p, end, "/layout");
- if (q < end && path_exists(temp)) {
- /* use this one - cheat a little */
- *p = 0;
- D("using skin content from %s", temp);
- qemu_free(i->skinName);
- i->skinName = qemu_strdup("skin");
- i->skinDirPath = qemu_strdup(i->contentPath);
- return 0;
- }
- }
-
- /* look in content directory */
- if (_checkSkinDir(temp, end, i->contentPath, skinName))
- break;
-
- /* look in the add-on directory, if any */
- if (i->addonPath &&
- _checkSkinDir(temp, end, i->addonPath, skinName))
- break;
-
- /* look in the platforms directory */
- if (_checkSkinDir(temp, end, i->platformPath, skinName))
- break;
-
- /* didn't find it */
- if (explicitSkin)
- dwarning("could not find directory for skin '%s'", skinName);
-
- return -1;
-
- } while (0);
-
- /* separate skin name from parent directory. the skin name
- * returned in 'temp' might be different from the original
- * one due to alias expansion so strip it.
- */
- p = strrchr(temp, '/');
- if (p == NULL) {
- /* should not happen */
- DD("weird skin path: %s", temp);
- return -1;
- }
-
- *p = 0;
- DD("found skin content in %s", temp);
- i->skinDirPath = qemu_strdup(temp);
- return 0;
-}
-
-
-AvdInfo*
-avdInfo_new( const char* name, AvdInfoParams* params )
-{
- AvdInfo* i;
-
- if (name == NULL)
- return NULL;
-
- if (!_checkAvdName(name)) {
- derror("virtual device name contains invalid characters");
- exit(1);
- }
-
- i = qemu_mallocz(sizeof *i);
- i->deviceName = qemu_strdup(name);
-
- if ( _getSdkRoot(i) < 0 ||
- _getRootIni(i) < 0 ||
- _getTarget(i) < 0 ||
- _getConfigIni(i) < 0 )
- goto FAIL;
-
- if ( _getImagePaths(i, params) < 0 ||
- _getSkin (i, params) < 0 )
- goto FAIL;
-
- return i;
-
-FAIL:
- avdInfo_free(i);
- return NULL;
-}
-
-/***************************************************************
- ***************************************************************
- *****
- ***** ANDROID BUILD SUPPORT
- *****
- ***** The code below corresponds to the case where we're
- ***** starting the emulator inside the Android build
- ***** system. The main differences are that:
- *****
- ***** - the $ANDROID_PRODUCT_OUT directory is used as the
- ***** content file.
- *****
- ***** - built images must not be modified by the emulator,
- ***** so system.img must be copied to a temporary file
- ***** and userdata.img must be copied to userdata-qemu.img
- ***** if the latter doesn't exist.
- *****
- ***** - the kernel and default skin directory are taken from
- ***** prebuilt
- *****
- ***** - there is no root .ini file, or any config.ini in
- ***** the content directory, no SDK platform version
- ***** and no add-on to consider.
- *****/
-
-/* used to fake a config.ini located in the content directory */
-static int
-_getBuildConfigIni( AvdInfo* i )
-{
- /* a blank file is ok at the moment */
- i->configIni = iniFile_newFromMemory( "", 0 );
- return 0;
-}
-
-static int
-_getBuildImagePaths( AvdInfo* i, AvdInfoParams* params )
-{
- int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0;
- int noCache = (params->flags & AVDINFO_NO_CACHE) != 0;
- int noSdCard = (params->flags & AVDINFO_NO_SDCARD) != 0;
-
- char temp[PATH_MAX], *p=temp, *end=p+sizeof temp;
- char* srcData;
- ImageLoader l[1];
-
- imageLoader_init(l, i, params);
-
- /** load the kernel image
- **/
-
- /* if it is not in the out directory, get it from prebuilt
- */
- imageLoader_set ( l, AVD_IMAGE_KERNEL );
-
- if ( !imageLoader_load( l, IMAGE_OPTIONAL |
- IMAGE_DONT_LOCK ) )
- {
-#define PREBUILT_KERNEL_PATH "prebuilt/android-arm/kernel/kernel-qemu"
- p = bufprint(temp, end, "%s/%s", i->androidBuildRoot,
- PREBUILT_KERNEL_PATH);
- if (p >= end || !path_exists(temp)) {
- derror("bad workspace: cannot find prebuilt kernel in: %s", temp);
- exit(1);
- }
- imageLoader_setPath(l, temp);
- }
-
- /** load the data partition. note that we use userdata-qemu.img
- ** since we don't want to modify userdata.img at all
- **/
- imageLoader_set ( l, AVD_IMAGE_USERDATA );
- imageLoader_load( l, IMAGE_OPTIONAL | IMAGE_DONT_LOCK );
-
- /* get the path of the source file, and check that it actually exists
- * if the user didn't provide an explicit data file
- */
- srcData = imageLoader_extractPath(l);
- if (srcData == NULL && params->forcePaths[AVD_IMAGE_USERDATA] == NULL) {
- derror("There is no %s image in your build directory. Please make a full build",
- l->imageText, l->imageFile);
- exit(2);
- }
-
- /* get the path of the target file */
- l->imageFile = "userdata-qemu.img";
- imageLoader_load( l, IMAGE_OPTIONAL |
- IMAGE_EMPTY_IF_MISSING |
- IMAGE_IGNORE_IF_LOCKED );
-
- /* force a data wipe if we just created the image */
- if (l->pState[0] == IMAGE_STATE_LOCKED_EMPTY)
- wipeData = 1;
-
- /* if the image was already locked, create a temp file
- * then force a data wipe.
- */
- if (l->pPath[0] == NULL) {
- TempFile* temp = tempfile_create();
- imageLoader_setPath(l, tempfile_path(temp));
- dwarning( "Another emulator is running. user data changes will *NOT* be saved");
- wipeData = 1;
- }
-
- /* in the case of a data wipe, copy userdata.img into
- * the destination */
- if (wipeData) {
- if (srcData == NULL || !path_exists(srcData)) {
- derror("There is no %s image in your build directory. Please make a full build",
- l->imageText, _imageFileNames[l->id]);
- exit(2);
- }
- if (path_copy_file( l->pPath[0], srcData ) < 0) {
- derror("could not initialize %s image from %s: %s",
- l->imageText, temp, strerror(errno));
- exit(2);
- }
- }
-
- qemu_free(srcData);
-
- /** load the ramdisk image
- **/
- imageLoader_set ( l, AVD_IMAGE_RAMDISK );
- imageLoader_load( l, IMAGE_REQUIRED |
- IMAGE_DONT_LOCK );
-
- /** load the system image. read-only. the caller must
- ** take care of checking the state
- **/
- imageLoader_set ( l, AVD_IMAGE_SYSTEM );
- imageLoader_load( l, IMAGE_REQUIRED | IMAGE_DONT_LOCK );
-
- /* force the system image to read-only status */
- l->pState[0] = IMAGE_STATE_READONLY;
-
- /** cache partition handling
- **/
- if (!noCache) {
- imageLoader_set (l, AVD_IMAGE_CACHE);
-
- /* if the user provided one cache image, lock & use it */
- if ( params->forcePaths[l->id] != NULL ) {
- imageLoader_load(l, IMAGE_REQUIRED |
- IMAGE_IGNORE_IF_LOCKED);
- }
- }
-
- /** SD Card image
- **/
- if (!noSdCard) {
- imageLoader_set (l, AVD_IMAGE_SDCARD);
- imageLoader_load(l, IMAGE_OPTIONAL | IMAGE_IGNORE_IF_LOCKED);
- }
-
- return 0;
-}
-
-static int
-_getBuildSkin( AvdInfo* i, AvdInfoParams* params )
-{
- /* the (current) default skin name for our build system */
- const char* skinName = params->skinName;
- const char* skinDir = params->skinRootPath;
- char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
- char* q;
-
- if (!skinName) {
- /* the (current) default skin name for the build system */
- skinName = "HVGA";
- DD("selecting default skin name '%s'", skinName);
- }
-
- i->skinName = qemu_strdup(skinName);
-
- if (!skinDir) {
-
-#define PREBUILT_SKINS_DIR "development/emulator/skins"
-
- /* the (current) default skin directory */
- p = bufprint( temp, end, "%s/%s",
- i->androidBuildRoot, PREBUILT_SKINS_DIR );
- } else {
- p = bufprint( temp, end, "%s", skinDir );
- }
-
- q = bufprint(p, end, "/%s/layout", skinName);
- if (q >= end || !path_exists(temp)) {
- DD("skin content directory does not exist: %s", temp);
- if (skinDir)
- dwarning("could not find valid skin '%s' in %s:\n",
- skinName, temp);
- return -1;
- }
- *p = 0;
- DD("found skin path: %s", temp);
- i->skinDirPath = qemu_strdup(temp);
-
- return 0;
-}
-
-AvdInfo*
-avdInfo_newForAndroidBuild( const char* androidBuildRoot,
- const char* androidOut,
- AvdInfoParams* params )
-{
- AvdInfo* i;
-
- i = qemu_mallocz(sizeof *i);
-
- i->inAndroidBuild = 1;
- i->androidBuildRoot = qemu_strdup(androidBuildRoot);
- i->androidOut = qemu_strdup(androidOut);
- i->contentPath = qemu_strdup(androidOut);
-
- /* TODO: find a way to provide better information from the build files */
- i->deviceName = qemu_strdup("<build>");
-
- if (_getBuildConfigIni(i) < 0 ||
- _getBuildImagePaths(i, params) < 0 )
- goto FAIL;
-
- /* we don't need to fail if there is no valid skin */
- _getBuildSkin(i, params);
-
- return i;
-
-FAIL:
- avdInfo_free(i);
- return NULL;
-}
-
-const char*
-avdInfo_getName( AvdInfo* i )
-{
- return i ? i->deviceName : NULL;
-}
-
-const char*
-avdInfo_getImageFile( AvdInfo* i, AvdImageType imageType )
-{
- if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX)
- return NULL;
-
- return i->imagePath[imageType];
-}
-
-int
-avdInfo_isImageReadOnly( AvdInfo* i, AvdImageType imageType )
-{
- if (i == NULL || (unsigned)imageType >= AVD_IMAGE_MAX)
- return 1;
-
- return (i->imageState[imageType] == IMAGE_STATE_READONLY);
-}
-
-const char*
-avdInfo_getSkinName( AvdInfo* i )
-{
- return i->skinName;
-}
-
-const char*
-avdInfo_getSkinDir ( AvdInfo* i )
-{
- return i->skinDirPath;
-}
-
-int
-avdInfo_getHwConfig( AvdInfo* i, AndroidHwConfig* hw )
-{
- IniFile* ini = i->configIni;
- int ret;
-
- if (ini == NULL)
- ini = iniFile_newFromMemory("", 0);
-
- ret = androidHwConfig_read(hw, ini);
-
- if (ini != i->configIni)
- iniFile_free(ini);
-
- return ret;
-}
-
-
-char*
-avdInfo_getTracePath( AvdInfo* i, const char* traceName )
-{
- char tmp[MAX_PATH], *p=tmp, *end=p + sizeof(tmp);
-
- if (i == NULL || traceName == NULL || traceName[0] == 0)
- return NULL;
-
- if (i->inAndroidBuild) {
- p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s",
- i->androidOut, traceName );
- } else {
- p = bufprint( p, end, "%s" PATH_SEP "traces" PATH_SEP "%s",
- i->contentPath, traceName );
- }
- return qemu_strdup(tmp);
-}
diff --git a/android/avd/info.h b/android/avd/info.h
deleted file mode 100644
index ad8a138..0000000
--- a/android/avd/info.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef ANDROID_AVD_INFO_H
-#define ANDROID_AVD_INFO_H
-
-#include "android/utils/ini.h"
-#include "android/avd/hw-config.h"
-
-/* An Android Virtual Device (AVD for short) corresponds to a
- * directory containing all kernel/disk images for a given virtual
- * device, as well as information about its hardware capabilities,
- * SDK version number, skin, etc...
- *
- * Each AVD has a human-readable name and is backed by a root
- * configuration file and a content directory. For example, an
- * AVD named 'foo' will correspond to the following:
- *
- * - a root configuration file named ~/.android/avd/foo.ini
- * describing where the AVD's content can be found
- *
- * - a content directory like ~/.android/avd/foo/ containing all
- * disk image and configuration files for the virtual device.
- *
- * the 'foo.ini' file should contain at least one line of the form:
- *
- * rootPath=<content-path>
- *
- * it may also contain other lines that cache stuff found in the
- * content directory, like hardware properties or SDK version number.
- *
- * it is possible to move the content directory by updating the foo.ini
- * file to point to the new location. This can be interesting when your
- * $HOME directory is located on a network share or in a roaming profile
- * (Windows), given that the content directory of a single virtual device
- * can easily use more than 100MB of data.
- *
- */
-
-/* a macro used to define the list of disk images managed by the
- * implementation. This macro will be expanded several times with
- * varying definitions of _AVD_IMG
- */
-#define AVD_IMAGE_LIST \
- _AVD_IMG(KERNEL,"kernel-qemu","kernel") \
- _AVD_IMG(RAMDISK,"ramdisk.img","ramdisk") \
- _AVD_IMG(SYSTEM,"system.img","system") \
- _AVD_IMG(USERDATA,"userdata.img","user data") \
- _AVD_IMG(CACHE,"cache.img","cache") \
- _AVD_IMG(SDCARD,"sdcard.img","SD Card") \
-
-/* define the enumared values corresponding to each AVD image type
- * examples are: AVD_IMAGE_KERNEL, AVD_IMAGE_SYSTEM, etc..
- */
-#define _AVD_IMG(x,y,z) AVD_IMAGE_##x ,
-typedef enum {
- AVD_IMAGE_LIST
- AVD_IMAGE_MAX /* do not remove */
-} AvdImageType;
-#undef _AVD_IMG
-
-/* AvdInfo is an opaque structure used to model the information
- * corresponding to a given AVD instance
- */
-typedef struct AvdInfo AvdInfo;
-
-/* various flags used when creating an AvdInfo object */
-typedef enum {
- /* use to force a data wipe */
- AVDINFO_WIPE_DATA = (1 << 0),
- /* use to ignore the cache partition */
- AVDINFO_NO_CACHE = (1 << 1),
- /* use to wipe cache partition, ignored if NO_CACHE is set */
- AVDINFO_WIPE_CACHE = (1 << 2),
- /* use to ignore ignore SDCard image (default or provided) */
- AVDINFO_NO_SDCARD = (1 << 3),
-} AvdFlags;
-
-typedef struct {
- unsigned flags;
- const char* skinName;
- const char* skinRootPath;
- const char* forcePaths[AVD_IMAGE_MAX];
-} AvdInfoParams;
-
-/* Creates a new AvdInfo object from a name. Returns NULL if name is NULL
- * or contains characters that are not part of the following list:
- * letters, digits, underscores, dashes and periods
- */
-AvdInfo* avdInfo_new( const char* name, AvdInfoParams* params );
-
-/* A special function used to setup an AvdInfo for use when starting
- * the emulator from the Android build system. In this specific instance
- * we're going to create temporary files to hold all writable image
- * files, and activate all hardware features by default
- *
- * 'androidBuildRoot' must be the absolute path to the root of the
- * Android build system (i.e. the 'android' directory)
- *
- * 'androidOut' must be the target-specific out directory where
- * disk images will be looked for.
- */
-AvdInfo* avdInfo_newForAndroidBuild( const char* androidBuildRoot,
- const char* androidOut,
- AvdInfoParams* params );
-
-/* Frees an AvdInfo object and the corresponding strings that may be
- * returned by its getXXX() methods
- */
-void avdInfo_free( AvdInfo* i );
-
-/* Return the name of the Android Virtual Device
- */
-const char* avdInfo_getName( AvdInfo* i );
-
-/* Try to find the path of a given image file, returns NULL
- * if the corresponding file could not be found. the string
- * belongs to the AvdInfo object.
- */
-const char* avdInfo_getImageFile( AvdInfo* i, AvdImageType imageType );
-
-/* Returns 1 if the corresponding image file is read-only
- */
-int avdInfo_isImageReadOnly( AvdInfo* i, AvdImageType imageType );
-
-/* lock an image file if it is writable. returns 0 on success, or -1
- * otherwise. note that if the file is read-only, it doesn't need to
- * be locked and the function will return success.
- */
-int avdInfo_lockImageFile( AvdInfo* i, AvdImageType imageType, int abortOnError);
-
-/* Manually set the path of a given image file. */
-void avdInfo_setImageFile( AvdInfo* i, AvdImageType imageType, const char* imagePath );
-
-/* Returns the path of the skin directory */
-/* the string belongs to the AvdInfo object */
-const char* avdInfo_getSkinPath( AvdInfo* i );
-
-/* Returns the name of the virtual device's skin */
-const char* avdInfo_getSkinName( AvdInfo* i );
-
-/* Returns the root skin directory for this device */
-const char* avdInfo_getSkinDir ( AvdInfo* i );
-
-/* Reads the AVD's hardware configuration into 'hw'. returns -1 on error, 0 otherwise */
-int avdInfo_getHwConfig( AvdInfo* i, AndroidHwConfig* hw );
-
-/* Returns a *copy* of the path used to store trace 'foo'. result must be freed by caller */
-char* avdInfo_getTracePath( AvdInfo* i, const char* traceName );
-
-/* */
-
-#endif /* ANDROID_AVD_INFO_H */
diff --git a/android/build/binary.make b/android/build/binary.make
deleted file mode 100644
index 1c75d52..0000000
--- a/android/build/binary.make
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# definitions shared by host_executable.make and host_static_library.make
-#
-
-# the directory where we're going to place our object files
-LOCAL_OBJS_DIR := $(call intermediates-dir-for,EXECUTABLES,$(LOCAL_MODULE))
-LOCAL_OBJECTS :=
-LOCAL_CC ?= $(CC)
-LOCAL_C_SOURCES := $(filter %.c,$(LOCAL_SRC_FILES))
-LOCAL_OBJC_SOURCES := $(filter %.m,$(LOCAL_SRC_FILES))
-
-$(foreach src,$(LOCAL_C_SOURCES), \
- $(eval $(call compile-c-source,$(src))) \
-)
-
-$(foreach src,$(LOCAL_OBJC_SOURCES), \
- $(eval $(call compile-objc-source,$(src))) \
-)
-
-CLEAN_OBJS_DIRS += $(LOCAL_OBJS_DIR)
diff --git a/android/build/clear_vars.make b/android/build/clear_vars.make
deleted file mode 100644
index a9289b0..0000000
--- a/android/build/clear_vars.make
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# called multiple times to clear variables used to define a given 'module'
-#
-LOCAL_NO_DEFAULT_COMPILER_FLAGS:=
-LOCAL_CC :=
-LOCAL_CXX :=
-LOCAL_CFLAGS :=
-LOCAL_LDFLAGS :=
-LOCAL_LDLIBS :=
-LOCAL_SRC_FILES :=
-LOCAL_MODULE :=
-LOCAL_MODULE_PATH:=
-LOCAL_STATIC_LIBRARIES :=
-LOCAL_BUILT_MODULE :=
-LOCAL_PREBUILT_OBJ_FILES :=
-
diff --git a/android/build/definitions.make b/android/build/definitions.make
deleted file mode 100644
index cd03f89..0000000
--- a/android/build/definitions.make
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# shared definitions
-ifeq ($(strip $(SHOW)),)
-define pretty
-@echo $1
-endef
-hide := @
-else
-define pretty
-endef
-hide :=
-endif
-
-define my-dir
-.
-endef
-
-# return the directory containing the intermediate files for a given
-# kind of executable
-# $1 = type (EXECUTABLES or STATIC_LIBRARIES)
-# $2 = module name
-# $3 = ignored
-#
-define intermediates-dir-for
-$(OBJS_DIR)/intermediates/$(2)
-endef
-
-# Generate the full path of a given static library
-define library-path
-$(OBJS_DIR)/$(1).a
-endef
-
-define executable-path
-$(OBJS_DIR)/$(1)$(EXE)
-endef
-
-# Compile a C source file
-#
-define compile-c-source
-SRC:=$(1)
-OBJ:=$$(LOCAL_OBJS_DIR)/$$(SRC:%.c=%.o)
-LOCAL_OBJECTS += $$(OBJ)
-DEPENDENCY_DIRS += $$(dir $$(OBJ))
-$$(OBJ): PRIVATE_CFLAGS := $$(CFLAGS) $$(LOCAL_CFLAGS) -I$$(LOCAL_PATH) -I$$(OBJS_DIR)
-$$(OBJ): PRIVATE_CC := $$(LOCAL_CC)
-$$(OBJ): PRIVATE_OBJ := $$(OBJ)
-$$(OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE)
-$$(OBJ): PRIVATE_SRC := $$(SRC_PATH)/$$(SRC)
-$$(OBJ): PRIVATE_SRC0 := $$(SRC)
-$$(OBJ): $$(SRC_PATH)/$$(SRC)
- @mkdir -p $$(dir $$(PRIVATE_OBJ))
- @echo "Compile: $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC0)"
- $(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c -o $$(PRIVATE_OBJ) -MMD -MP -MF $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_SRC)
- $(hide) $$(SRC_PATH)/android/build/mkdeps.sh $$(PRIVATE_OBJ) $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_OBJ).d
-endef
-
-# Compile an Objective-C source file
-#
-define compile-objc-source
-SRC:=$(1)
-OBJ:=$$(LOCAL_OBJS_DIR)/$$(SRC:%.m=%.o)
-LOCAL_OBJECTS += $$(OBJ)
-DEPENDENCY_DIRS += $$(dir $$(OBJ))
-$$(OBJ): PRIVATE_CFLAGS := $$(CFLAGS) $$(LOCAL_CFLAGS) -I$$(LOCAL_PATH) -I$$(OBJS_DIR)
-$$(OBJ): PRIVATE_CC := $$(LOCAL_CC)
-$$(OBJ): PRIVATE_OBJ := $$(OBJ)
-$$(OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE)
-$$(OBJ): PRIVATE_SRC := $$(SRC_PATH)/$$(SRC)
-$$(OBJ): PRIVATE_SRC0 := $$(SRC)
-$$(OBJ): $$(SRC_PATH)/$$(SRC)
- @mkdir -p $$(dir $$(PRIVATE_OBJ))
- @echo "Compile: $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC0)"
- $(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c -o $$(PRIVATE_OBJ) -MMD -MP -MF $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_SRC)
- $(hide) $$(SRC_PATH)/android/build/mkdeps.sh $$(PRIVATE_OBJ) $$(PRIVATE_OBJ).d.tmp $$(PRIVATE_OBJ).d
-endef
-
-# for now, we only use prebuilt SDL libraries, so copy them
-define copy-prebuilt-lib
-_SRC := $(1)
-_SRC1 := $$(notdir $$(_SRC))
-_DST := $$(OBJS_DIR)/$$(_SRC1)
-LIBRARIES += $$(_DST)
-$$(_DST): PRIVATE_DST := $$(_DST)
-$$(_DST): PRIVATE_SRC := $$(_SRC)
-$$(_DST): $$(_SRC)
- @mkdir -p $$(dir $$(PRIVATE_DST))
- @echo "Prebuilt: $$(PRIVATE_DST)"
- $(hide) cp -f $$(PRIVATE_SRC) $$(PRIVATE_DST)
-endef
-
-define create-dir
-$(1):
- mkdir -p $(1)
-endef
-
diff --git a/android/build/getdir.make b/android/build/getdir.make
deleted file mode 100644
index a4dadd3..0000000
--- a/android/build/getdir.make
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# used to return in 'dir' the name of the current operating system
-# we really get the value from the configuration script
-#
-dir := $(HOST_OS)
diff --git a/android/build/host_executable.make b/android/build/host_executable.make
deleted file mode 100644
index 62f4762..0000000
--- a/android/build/host_executable.make
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# first, call a library containing all object files
-LOCAL_BUILT_MODULE := $(call executable-path,$(LOCAL_MODULE))
-LOCAL_CC ?= $(CC)
-include $(BUILD_SYSTEM)/binary.make
-
-LOCAL_LDLIBS := $(foreach lib,$(LOCAL_STATIC_LIBRARIES),$(call library-path,$(lib))) $(LOCAL_LDLIBS)
-
-$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(LDFLAGS) $(LOCAL_LDFLAGS)
-$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS := $(LOCAL_LDLIBS)
-$(LOCAL_BUILT_MODULE): PRIVATE_OBJS := $(LOCAL_OBJECTS)
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
- @ mkdir -p $(dir $@)
- @ echo "Executable: $@"
- $(hide) $(LD) $(PRIVATE_LDFLAGS) -o $@ $(PRIVATE_LIBRARY) $(PRIVATE_OBJS) $(PRIVATE_LDLIBS)
-
-EXECUTABLES += $(LOCAL_BUILT_MODULE)
-$(LOCAL_BUILT_MODULE): $(foreach lib,$(LOCAL_STATIC_LIBRARIES),$(call library-path,$(lib)))
-
diff --git a/android/build/host_static_library.make b/android/build/host_static_library.make
deleted file mode 100644
index 3de5a99..0000000
--- a/android/build/host_static_library.make
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# build a host executable, the name of the final executable should be
-# put in LOCAL_BUILT_MODULE for use by the caller
-#
-
-#$(info STATIC_LIBRARY SRCS=$(LOCAL_SRC_FILES))
-LOCAL_BUILT_MODULE := $(call library-path,$(LOCAL_MODULE))
-LOCAL_CC ?= $(CC)
-include $(BUILD_SYSTEM)/binary.make
-
-LOCAL_AR ?= $(AR)
-ARFLAGS := crs
-
-$(LOCAL_BUILT_MODULE): PRIVATE_AR := $(LOCAL_AR)
-$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS := $(LOCAL_OBJECTS)
-$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
- @mkdir -p $(dir $@)
- @echo "Library: $@"
- $(hide) $(PRIVATE_AR) $(ARFLAGS) $@ $(PRIVATE_OBJECTS)
-
-LIBRARIES += $(LOCAL_BUILT_MODULE)
diff --git a/android/build/mkdeps.sh b/android/build/mkdeps.sh
deleted file mode 100755
index abecec7..0000000
--- a/android/build/mkdeps.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This script is used to transform the dependency files generated by GCC
-# For example, a typical .d file will have a line like:
-#
-# source.o: /full/path/to/source.c other.h headers.h
-# ...
-#
-# the script is used to replace 'source.o' to a full path, as in
-#
-# objs/intermediates/emulator/source.o: /full/path/to/source.c other.h headers.h
-#
-# parameters
-#
-# $1: object file (full path)
-# $2: source dependency file to modify (erased on success)
-# $3: target source dependency file
-#
-
-# quote the object path. we change a single '.' into
-# a '\.' since this will be parsed by sed.
-#
-OBJECT=`echo $1 | sed -e s/\\\\./\\\\\\\\./g`
-#echo OBJECT=$OBJECT
-
-OBJ_NAME=`basename $OBJECT`
-#echo OBJ_NAME=$OBJ_NAME
-
-# we replace $OBJ_NAME with $OBJECT only if $OBJ_NAME starts the line
-# that's because some versions of GCC (e.g. 4.2.3) already produce
-# a correct dependency line with the full path to the object file.
-# In this case, we don't want to touch anything
-#
-cat $2 | sed -e s%^$OBJ_NAME%$OBJECT%g > $3 && rm -f $2
-
-
-
diff --git a/android/charmap.c b/android/charmap.c
deleted file mode 100644
index c8ed2d6..0000000
--- a/android/charmap.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/charmap.h"
-
-/* the following is automatically generated by the 'gen-charmap.py' script
- * do not touch. the generation command was:
- * gen-charmap.py qwerty.kcm qwerty2.kcm
- */
-
-static const AKeyEntry _qwerty_keys[] =
-{
- /* keycode base caps fn caps+fn number */
-
- { kKeyCodeA , 'a', 'A', '#', 0x00, '#' },
- { kKeyCodeB , 'b', 'B', '<', 0x00, '<' },
- { kKeyCodeC , 'c', 'C', '9', 0x00E7, '9' },
- { kKeyCodeD , 'd', 'D', '5', 0x00, '5' },
- { kKeyCodeE , 'e', 'E', '2', 0x0301, '2' },
- { kKeyCodeF , 'f', 'F', '6', 0x00A5, '6' },
- { kKeyCodeG , 'g', 'G', '-', '_', '-' },
- { kKeyCodeH , 'h', 'H', '[', '{', '[' },
- { kKeyCodeI , 'i', 'I', '$', 0x0302, '$' },
- { kKeyCodeJ , 'j', 'J', ']', '}', ']' },
- { kKeyCodeK , 'k', 'K', '"', '~', '"' },
- { kKeyCodeL , 'l', 'L', '\'', '`', '\'' },
- { kKeyCodeM , 'm', 'M', '!', 0x00, '!' },
- { kKeyCodeN , 'n', 'N', '>', 0x0303, '>' },
- { kKeyCodeO , 'o', 'O', '(', 0x00, '(' },
- { kKeyCodeP , 'p', 'P', ')', 0x00, ')' },
- { kKeyCodeQ , 'q', 'Q', '*', 0x0300, '*' },
- { kKeyCodeR , 'r', 'R', '3', 0x20AC, '3' },
- { kKeyCodeS , 's', 'S', '4', 0x00DF, '4' },
- { kKeyCodeT , 't', 'T', '+', 0x00A3, '+' },
- { kKeyCodeU , 'u', 'U', '&', 0x0308, '&' },
- { kKeyCodeV , 'v', 'V', '=', '^', '=' },
- { kKeyCodeW , 'w', 'W', '1', 0x00, '1' },
- { kKeyCodeX , 'x', 'X', '8', 0x00, '8' },
- { kKeyCodeY , 'y', 'Y', '%', 0x00A1, '%' },
- { kKeyCodeZ , 'z', 'Z', '7', 0x00, '7' },
- { kKeyCodeComma , ',', ';', ';', '|', ',' },
- { kKeyCodePeriod , '.', ':', ':', 0x2026, '.' },
- { kKeyCodeAt , '@', '0', '0', 0x2022, '0' },
- { kKeyCodeSlash , '/', '?', '?', '\\', '/' },
- { kKeyCodeSpace , 0x20, 0x20, 0x9, 0x9, 0x20 },
- { kKeyCodeNewline , 0xa, 0xa, 0xa, 0xa, 0xa },
- { kKeyCodeTab , 0x9, 0x9, 0x9, 0x9, 0x9 },
- { kKeyCode0 , '0', ')', '0', ')', '0' },
- { kKeyCode1 , '1', '!', '1', '!', '1' },
- { kKeyCode2 , '2', '@', '2', '@', '2' },
- { kKeyCode3 , '3', '#', '3', '#', '3' },
- { kKeyCode4 , '4', '$', '4', '$', '4' },
- { kKeyCode5 , '5', '%', '5', '%', '5' },
- { kKeyCode6 , '6', '^', '6', '^', '6' },
- { kKeyCode7 , '7', '&', '7', '&', '7' },
- { kKeyCode8 , '8', '*', '8', '*', '8' },
- { kKeyCode9 , '9', '(', '9', '(', '9' },
- { kKeyCodeGrave , '`', '~', '`', '~', '`' },
- { kKeyCodeMinus , '-', '_', '-', '_', '-' },
- { kKeyCodeEquals , '=', '+', '=', '+', '=' },
- { kKeyCodeLeftBracket , '[', '{', '[', '{', '[' },
- { kKeyCodeRightBracket , ']', '}', ']', '}', ']' },
- { kKeyCodeBackslash , '\\', '|', '\\', '|', '\\' },
- { kKeyCodeSemicolon , ';', ':', ';', ':', ';' },
- { kKeyCodeApostrophe , '\'', '"', '\'', '"', '\'' },
-};
-
-static const AKeyCharmap _qwerty_charmap =
-{
- _qwerty_keys,
- 51,
- "qwerty"
-};
-
-static const AKeyEntry _qwerty2_keys[] =
-{
- /* keycode base caps fn caps+fn number */
-
- { kKeyCodeA , 'a', 'A', 'a', 'A', 'a' },
- { kKeyCodeB , 'b', 'B', 'b', 'B', 'b' },
- { kKeyCodeC , 'c', 'C', 0x00e7, 0x00E7, 'c' },
- { kKeyCodeD , 'd', 'D', '\'', '\'', '\'' },
- { kKeyCodeE , 'e', 'E', '"', 0x0301, '"' },
- { kKeyCodeF , 'f', 'F', '[', '[', '[' },
- { kKeyCodeG , 'g', 'G', ']', ']', ']' },
- { kKeyCodeH , 'h', 'H', '<', '<', '<' },
- { kKeyCodeI , 'i', 'I', '-', 0x0302, '-' },
- { kKeyCodeJ , 'j', 'J', '>', '>', '>' },
- { kKeyCodeK , 'k', 'K', ';', '~', ';' },
- { kKeyCodeL , 'l', 'L', ':', '`', ':' },
- { kKeyCodeM , 'm', 'M', '%', 0x00, '%' },
- { kKeyCodeN , 'n', 'N', 0x00, 0x0303, 'n' },
- { kKeyCodeO , 'o', 'O', '+', '+', '+' },
- { kKeyCodeP , 'p', 'P', '=', 0x00A5, '=' },
- { kKeyCodeQ , 'q', 'Q', '|', 0x0300, '|' },
- { kKeyCodeR , 'r', 'R', '`', 0x20AC, '`' },
- { kKeyCodeS , 's', 'S', '\\', 0x00DF, '\\' },
- { kKeyCodeT , 't', 'T', '{', 0x00A3, '}' },
- { kKeyCodeU , 'u', 'U', '_', 0x0308, '_' },
- { kKeyCodeV , 'v', 'V', 'v', 'V', 'v' },
- { kKeyCodeW , 'w', 'W', '~', '~', '~' },
- { kKeyCodeX , 'x', 'X', 'x', 'X', 'x' },
- { kKeyCodeY , 'y', 'Y', '}', 0x00A1, '}' },
- { kKeyCodeZ , 'z', 'Z', 'z', 'Z', 'z' },
- { kKeyCodeComma , ',', '<', ',', ',', ',' },
- { kKeyCodePeriod , '.', '>', '.', 0x2026, '.' },
- { kKeyCodeAt , '@', '@', '@', 0x2022, '@' },
- { kKeyCodeSlash , '/', '?', '?', '?', '/' },
- { kKeyCodeSpace , 0x20, 0x20, 0x9, 0x9, 0x20 },
- { kKeyCodeNewline , 0xa, 0xa, 0xa, 0xa, 0xa },
- { kKeyCode0 , '0', ')', ')', ')', '0' },
- { kKeyCode1 , '1', '!', '!', '!', '1' },
- { kKeyCode2 , '2', '@', '@', '@', '2' },
- { kKeyCode3 , '3', '#', '#', '#', '3' },
- { kKeyCode4 , '4', '$', '$', '$', '4' },
- { kKeyCode5 , '5', '%', '%', '%', '5' },
- { kKeyCode6 , '6', '^', '^', '^', '6' },
- { kKeyCode7 , '7', '&', '&', '&', '7' },
- { kKeyCode8 , '8', '*', '*', '*', '8' },
- { kKeyCode9 , '9', '(', '(', '(', '9' },
- { kKeyCodeTab , 0x9, 0x9, 0x9, 0x9, 0x9 },
- { kKeyCodeGrave , '`', '~', '`', '~', '`' },
- { kKeyCodeMinus , '-', '_', '-', '_', '-' },
- { kKeyCodeEquals , '=', '+', '=', '+', '=' },
- { kKeyCodeLeftBracket , '[', '{', '[', '{', '[' },
- { kKeyCodeRightBracket , ']', '}', ']', '}', ']' },
- { kKeyCodeBackslash , '\\', '|', '\\', '|', '\\' },
- { kKeyCodeSemicolon , ';', ':', ';', ':', ';' },
- { kKeyCodeApostrophe , '\'', '"', '\'', '"', '\'' },
-};
-
-static const AKeyCharmap _qwerty2_charmap =
-{
- _qwerty2_keys,
- 51,
- "qwerty2"
-};
-
-const AKeyCharmap* android_charmaps[2] = { &_qwerty_charmap , &_qwerty2_charmap };
-const int android_charmap_count = 2;
diff --git a/android/charmap.h b/android/charmap.h
deleted file mode 100644
index f300e68..0000000
--- a/android/charmap.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_charmap_h
-#define _android_charmap_h
-
-#include "linux_keycodes.h"
-
-/* Keep it consistent with linux/input.h */
-typedef enum {
- kKeyCodeSoftLeft = KEY_SOFT1,
- kKeyCodeSoftRight = KEY_SOFT2,
- kKeyCodeHome = KEY_HOME,
- kKeyCodeBack = KEY_BACK,
- kKeyCodeCall = KEY_SEND,
- kKeyCodeEndCall = KEY_END,
- kKeyCode0 = KEY_0,
- kKeyCode1 = KEY_1,
- kKeyCode2 = KEY_2,
- kKeyCode3 = KEY_3,
- kKeyCode4 = KEY_4,
- kKeyCode5 = KEY_5,
- kKeyCode6 = KEY_6,
- kKeyCode7 = KEY_7,
- kKeyCode8 = KEY_8,
- kKeyCode9 = KEY_9,
- kKeyCodeStar = KEY_STAR,
- kKeyCodePound = KEY_SHARP,
- kKeyCodeDpadUp = KEY_UP,
- kKeyCodeDpadDown = KEY_DOWN,
- kKeyCodeDpadLeft = KEY_LEFT,
- kKeyCodeDpadRight = KEY_RIGHT,
- kKeyCodeDpadCenter = KEY_CENTER,
- kKeyCodeVolumeUp = KEY_VOLUMEUP,
- kKeyCodeVolumeDown = KEY_VOLUMEDOWN,
- kKeyCodePower = KEY_POWER,
- kKeyCodeCamera = KEY_CAMERA,
- kKeyCodeClear = KEY_CLEAR,
- kKeyCodeA = KEY_A,
- kKeyCodeB = KEY_B,
- kKeyCodeC = KEY_C,
- kKeyCodeD = KEY_D,
- kKeyCodeE = KEY_E,
- kKeyCodeF = KEY_F,
- kKeyCodeG = KEY_G,
- kKeyCodeH = KEY_H,
- kKeyCodeI = KEY_I,
- kKeyCodeJ = KEY_J,
- kKeyCodeK = KEY_K,
- kKeyCodeL = KEY_L,
- kKeyCodeM = KEY_M,
- kKeyCodeN = KEY_N,
- kKeyCodeO = KEY_O,
- kKeyCodeP = KEY_P,
- kKeyCodeQ = KEY_Q,
- kKeyCodeR = KEY_R,
- kKeyCodeS = KEY_S,
- kKeyCodeT = KEY_T,
- kKeyCodeU = KEY_U,
- kKeyCodeV = KEY_V,
- kKeyCodeW = KEY_W,
- kKeyCodeX = KEY_X,
- kKeyCodeY = KEY_Y,
- kKeyCodeZ = KEY_Z,
-
- kKeyCodeComma = KEY_COMMA,
- kKeyCodePeriod = KEY_DOT,
- kKeyCodeAltLeft = KEY_LEFTALT,
- kKeyCodeAltRight = KEY_RIGHTALT,
- kKeyCodeCapLeft = KEY_LEFTSHIFT,
- kKeyCodeCapRight = KEY_RIGHTSHIFT,
- kKeyCodeTab = KEY_TAB,
- kKeyCodeSpace = KEY_SPACE,
- kKeyCodeSym = KEY_COMPOSE,
- kKeyCodeExplorer = KEY_WWW,
- kKeyCodeEnvelope = KEY_MAIL,
- kKeyCodeNewline = KEY_ENTER,
- kKeyCodeDel = KEY_BACKSPACE,
- kKeyCodeGrave = 399,
- kKeyCodeMinus = KEY_MINUS,
- kKeyCodeEquals = KEY_EQUAL,
- kKeyCodeLeftBracket = KEY_LEFTBRACE,
- kKeyCodeRightBracket = KEY_RIGHTBRACE,
- kKeyCodeBackslash = KEY_BACKSLASH,
- kKeyCodeSemicolon = KEY_SEMICOLON,
- kKeyCodeApostrophe = KEY_APOSTROPHE,
- kKeyCodeSlash = KEY_SLASH,
- kKeyCodeAt = KEY_EMAIL,
- kKeyCodeNum = KEY_NUM,
- kKeyCodeHeadsetHook = KEY_HEADSETHOOK,
- kKeyCodeFocus = KEY_FOCUS,
- kKeyCodePlus = KEY_PLUS,
- kKeyCodeMenu = KEY_MENU,
- kKeyCodeNotification = KEY_NOTIFICATION,
- kKeyCodeSearch = KEY_SEARCH,
-
- kKeyCodeBtnMouse = BTN_MOUSE,
-
- kKeyCodeOrientation0 = 77,
- kKeyCodeOrientation90 = 78,
- kKeyCodeOrientation180 = 79,
- kKeyCodeOrientation270 = 80
-} AndroidKeyCode;
-
-
-/* this defines a structure used to describe an Android keyboard charmap */
-typedef struct AKeyEntry {
- unsigned short code;
- unsigned short base;
- unsigned short caps;
- unsigned short fn;
- unsigned short caps_fn;
- unsigned short number;
-} AKeyEntry;
-
-typedef struct {
- const AKeyEntry* entries;
- int num_entries;
- char name[ 32 ];
-} AKeyCharmap;
-
-extern const int android_charmap_count;
-extern const AKeyCharmap* android_charmaps[];
-
-#endif /* _android_charmap_h */
diff --git a/android/cmdline-option.c b/android/cmdline-option.c
deleted file mode 100644
index b773d9d..0000000
--- a/android/cmdline-option.c
+++ /dev/null
@@ -1,255 +0,0 @@
-#include "android/cmdline-option.h"
-#include "android/utils/debug.h"
-#include "android/utils/misc.h"
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-
-#define _VERBOSE_TAG(x,y) { #x, VERBOSE_##x, y },
-static const struct { const char* name; int flag; const char* text; }
-debug_tags[] = {
- VERBOSE_TAG_LIST
- { 0, 0, 0 }
-};
-
-static void parse_debug_tags( const char* tags );
-void parse_env_debug_tags( void );
-
-
-typedef struct {
- const char* name;
- int var_offset;
- int var_is_param;
- int var_is_config;
-} OptionInfo;
-
-#define OPTION(_name,_type,_config) \
- { #_name, offsetof(AndroidOptions,_name), _type, _config },
-
-
-static const OptionInfo option_keys[] = {
-#define OPT_PARAM(_name,_template,_descr) OPTION(_name,1,0)
-#define OPT_FLAG(_name,_descr) OPTION(_name,0,0)
-#define CFG_PARAM(_name,_template,_descr) OPTION(_name,1,1)
-#define CFG_FLAG(_name,_descr) OPTION(_name,0,1)
-#include "android/cmdline-options.h"
- { NULL, 0, 0, 0 }
-};
-
-int
-android_parse_options( int *pargc, char** *pargv, AndroidOptions* opt )
-{
- int nargs = *pargc-1;
- char** aread = *pargv+1;
- char** awrite = aread;
-
- memset( opt, 0, sizeof *opt );
-
- while (nargs > 0) {
- char* arg;
- char arg2_tab[64], *arg2 = arg2_tab;
- int nn;
-
- /* process @<name> as a special exception meaning
- * '-avd <name>'
- */
- if (aread[0][0] == '@') {
- opt->avd = aread[0]+1;
- nargs--;
- aread++;
- continue;
- }
-
- /* anything that isn't an option past this points
- * exits the loop
- */
- if (aread[0][0] != '-') {
- break;
- }
-
- arg = aread[0]+1;
-
- /* an option cannot contain an underscore */
- if (strchr(arg, '_') != NULL) {
- break;
- }
-
- nargs--;
- aread++;
-
- /* for backwards compatibility with previous versions */
- if (!strcmp(arg, "verbose")) {
- arg = "debug-init";
- }
-
- /* special handing for -debug <tags> */
- if (!strcmp(arg, "debug")) {
- if (nargs == 0) {
- derror( "-debug must be followed by tags (see -help-verbose)\n");
- exit(1);
- }
- nargs--;
- parse_debug_tags(*aread++);
- continue;
- }
-
- /* NOTE: variable tables map option names to values
- * (e.g. field offsets into the AndroidOptions structure).
- *
- * however, the names stored in the table used underscores
- * instead of dashes. this means that the command-line option
- * '-foo-bar' will be associated to the name 'foo_bar' in
- * this table, and will point to the field 'foo_bar' or
- * AndroidOptions.
- *
- * as such, before comparing the current option to the
- * content of the table, we're going to translate dashes
- * into underscores.
- */
- arg2 = arg2_tab;
- buffer_translate_char( arg2_tab, sizeof(arg2_tab),
- arg, '-', '_');
-
- /* special handling for -debug-<tag> and -debug-no-<tag> */
- if (!memcmp(arg2, "debug_", 6)) {
- int remove = 0;
- unsigned long mask = 0;
- arg2 += 6;
- if (!memcmp(arg2, "no_", 3)) {
- arg2 += 3;
- remove = 1;
- }
- if (!strcmp(arg2, "all")) {
- mask = ~0;
- }
- for (nn = 0; debug_tags[nn].name; nn++) {
- if (!strcmp(arg2, debug_tags[nn].name)) {
- mask = (1UL << debug_tags[nn].flag);
- break;
- }
- }
- if (remove)
- android_verbose &= ~mask;
- else
- android_verbose |= mask;
- continue;
- }
-
- /* look into our table of options
- *
- */
- {
- const OptionInfo* oo = option_keys;
-
- for ( ; oo->name; oo++ ) {
- if ( !strcmp( oo->name, arg2 ) ) {
- void* field = (char*)opt + oo->var_offset;
-
- if (oo->var_is_param) {
- /* parameter option */
- if (nargs == 0) {
- derror( "-%s must be followed by parameter (see -help-%s)",
- arg, arg );
- exit(1);
- }
- nargs--;
- ((char**)field)[0] = *aread++;
- } else {
- /* flag option */
- ((int*)field)[0] = 1;
- }
- break;
- }
- }
-
- if (oo->name == NULL) { /* unknown option ? */
- nargs++;
- aread--;
- break;
- }
- }
- }
-
- /* copy remaining parameters, if any, to command line */
- *pargc = nargs + 1;
-
- while (nargs > 0) {
- awrite[0] = aread[0];
- awrite ++;
- aread ++;
- nargs --;
- }
-
- awrite[0] = NULL;
-
- return 0;
-}
-
-
-
-/* special handling of -debug option and tags */
-#define ENV_DEBUG "ANDROID_DEBUG"
-
-static void
-parse_debug_tags( const char* tags )
-{
- char* x;
- char* y;
- char* x0;
-
- if (tags == NULL)
- return;
-
- x = x0 = strdup(tags);
- while (*x) {
- y = strchr(x, ',');
- if (y == NULL)
- y = x + strlen(x);
- else
- *y++ = 0;
-
- if (y > x+1) {
- int nn, remove = 0;
- unsigned mask = 0;
-
- if (x[0] == '-') {
- remove = 1;
- x += 1;
- }
-
- if (!strcmp( "all", x ))
- mask = ~0;
- else {
- char temp[32];
- buffer_translate_char(temp, sizeof temp, x, '-', '_');
-
- for (nn = 0; debug_tags[nn].name != NULL; nn++) {
- if ( !strcmp( debug_tags[nn].name, temp ) ) {
- mask |= (1 << debug_tags[nn].flag);
- break;
- }
- }
- }
-
- if (mask == 0)
- dprint( "ignoring unknown " ENV_DEBUG " item '%s'", x );
- else {
- if (remove)
- android_verbose &= ~mask;
- else
- android_verbose |= mask;
- }
- }
- x = y;
- }
-
- free(x0);
-}
-
-void
-parse_env_debug_tags( void )
-{
- const char* env = getenv( ENV_DEBUG );
- parse_debug_tags( env );
-}
-
diff --git a/android/cmdline-option.h b/android/cmdline-option.h
deleted file mode 100644
index b87144d..0000000
--- a/android/cmdline-option.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_OPTION_H
-#define _ANDROID_OPTION_H
-
-/* define a structure that will hold all option variables
- */
-typedef struct {
-#define OPT_PARAM(n,t,d) char* n;
-#define OPT_FLAG(n,d) int n;
-#include "android/cmdline-options.h"
-} AndroidOptions;
-
-
-/* parse command-line arguments options and remove them from (argc,argv)
- * 'opt' will be set to the content of parsed options
- * returns 0 on success, -1 on error (unknown option)
- */
-extern int
-android_parse_options( int *pargc, char** *pargv, AndroidOptions* opt );
-
-/* name of default keyset file */
-#define KEYSET_FILE "default.keyset"
-
-/* the default device DPI if none is specified by the skin
- */
-#define DEFAULT_DEVICE_DPI 165
-
-/* default network settings for emulator */
-#define DEFAULT_NETSPEED "full"
-#define DEFAULT_NETDELAY "none"
-
-#endif /* _ANDROID_OPTION_H */
diff --git a/android/cmdline-options.h b/android/cmdline-options.h
deleted file mode 100644
index c0d121e..0000000
--- a/android/cmdline-options.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* this header file can be included several times by the same source code.
- * it contains the list of support command-line options for the Android
- * emulator program
- */
-#ifndef OPT_PARAM
-#error OPT_PARAM is not defined
-#endif
-#ifndef OPT_FLAG
-#error OPT_FLAG is not defined
-#endif
-#ifndef CFG_PARAM
-#define CFG_PARAM OPT_PARAM
-#endif
-#ifndef CFG_FLAG
-#define CFG_FLAG OPT_FLAG
-#endif
-
-/* required to ensure that the CONFIG_XXX macros are properly defined */
-//XXX#include "config.h"
-
-/* Some options acts like flags, while others must be followed by a parameter
- * string. Nothing really new here.
- *
- * Some options correspond to AVD (Android Virtual Device) configuration
- * and will be ignored if you start the emulator with the -avd <name> flag.
- *
- * However, if you use them with -avd-create <name>, these options will be
- * recorded into the new AVD directory. Once an AVD is created, there is no
- * way to change these options.
- *
- * Several macros are used to define options:
- *
- * OPT_FLAG( name, "description" )
- * used to define a non-config flag option.
- * * 'name' is the option suffix that must follow the dash (-)
- * as well as the name of an integer variable whose value will
- * be 1 if the flag is used, or 0 otherwise.
- * * "description" is a short description string that will be
- * displayed by 'emulator -help'.
- *
- * OPT_PARAM( name, "<param>", "description" )
- * used to define a non-config parameter option
- * * 'name' will point to a char* variable (NULL if option is unused)
- * * "<param>" is a template for the parameter displayed by the help
- * * 'varname' is the name of a char* variable that will point
- * to the parameter string, if any, or will be NULL otherwise.
- *
- * CFG_FLAG( name, "description" )
- * used to define a configuration-specific flag option.
- *
- * CFG_PARAM( name, "<param>", "description" )
- * used to define a configuration-specific parameter option.
- *
- * NOTE: Keep in mind that optio names are converted by translating
- * dashes into underscore.
- *
- * This means that '-some-option' is equivalent to '-some_option'
- * and will be backed by a variable name 'some_option'
- *
- */
-
-CFG_PARAM( system, "<dir>", "read system image from <dir>" )
-CFG_PARAM( datadir, "<dir>", "write user data into <dir>" )
-CFG_PARAM( kernel, "<file>", "use specific emulated kernel" )
-CFG_PARAM( ramdisk, "<file>", "ramdisk image (default <system>/ramdisk.img" )
-CFG_PARAM( image, "<file>", "system image (default <system>/system.img" )
-CFG_PARAM( initdata, "<file>", "initial data image (default <system>/userdata.img" )
-CFG_PARAM( data, "<file>", "data image (default <datadir>/userdata-qemu.img" )
-CFG_PARAM( cache, "<file>", "cache partition image (default is temporary file)" )
-CFG_FLAG ( nocache, "disable the cache partition" )
-OPT_PARAM( sdcard, "<file>", "SD card image (default <system>/sdcard.img")
-OPT_FLAG ( wipe_data, "reset the use data image (copy it from initdata)" )
-CFG_PARAM( avd, "<name>", "use a specific android virtual device" )
-CFG_PARAM( skindir, "<dir>", "search skins in <dir> (default <system>/skins)" )
-CFG_PARAM( skin, "<file>", "select a given skin" )
-CFG_FLAG ( noskin, "don't use any emulator skin" )
-CFG_PARAM( memory, "<size>", "physical RAM size in MBs" )
-
-OPT_PARAM( netspeed, "<speed>", "maximum network download/upload speeds" )
-OPT_PARAM( netdelay, "<delay>", "network latency emulation" )
-OPT_FLAG ( netfast, "disable network shaping" )
-
-OPT_PARAM( trace, "<name>", "enable code profiling (F9 to start)" )
-OPT_FLAG ( show_kernel, "display kernel messages" )
-OPT_FLAG ( shell, "enable root shell on current terminal" )
-OPT_FLAG ( nojni, "disable JNI checks in the Dalvik runtime" )
-OPT_PARAM( logcat, "<tags>", "enable logcat output with given tags" )
-
-OPT_FLAG ( noaudio, "disable audio support" )
-OPT_PARAM( audio, "<backend>", "use specific audio backend" )
-OPT_PARAM( audio_in, "<backend>", "use specific audio input backend" )
-OPT_PARAM( audio_out,"<backend>", "use specific audio output backend" )
-
-OPT_FLAG ( raw_keys, "disable Unicode keyboard reverse-mapping" )
-OPT_PARAM( radio, "<device>", "redirect radio modem interface to character device" )
-OPT_PARAM( port, "<port>", "TCP port that will be used for the console" )
-OPT_PARAM( ports, "<consoleport>,<adbport>", "TCP ports used for the console and adb bridge" )
-OPT_PARAM( onion, "<image>", "use overlay PNG image over screen" )
-OPT_PARAM( onion_alpha, "<%age>", "specify onion-skin translucency" )
-OPT_PARAM( onion_rotation, "0|1|2|3", "specify onion-skin rotation" )
-
-OPT_PARAM( scale, "<scale>", "scale emulator window" )
-OPT_PARAM( dpi_device, "<dpi>", "specify device's resolution in dpi (default "
- STRINGIFY(DEFAULT_DEVICE_DPI) ")" )
-
-OPT_PARAM( http_proxy, "<proxy>", "make TCP connections through a HTTP/HTTPS proxy" )
-OPT_PARAM( timezone, "<timezone>", "use this timezone instead of the host's default" )
-OPT_PARAM( dns_server, "<servers>", "use this DNS server(s) in the emulated system" )
-OPT_PARAM( cpu_delay, "<cpudelay>", "throttle CPU emulation" )
-OPT_FLAG ( no_boot_anim, "disable animation for faster boot" )
-
-OPT_FLAG( no_window, "disable graphical window display" )
-OPT_FLAG( version, "display emulator version number" )
-
-OPT_PARAM( report_console, "<socket>", "report console port to remote socket" )
-OPT_PARAM( gps, "<device>", "redirect NMEA GPS to character device" )
-OPT_PARAM( keyset, "<name>", "specify keyset file name" )
-OPT_PARAM( shell_serial, "<device>", "specific character device for root shell" )
-OPT_FLAG ( old_system, "support old (pre 1.4) system images" )
-OPT_PARAM( tcpdump, "<file>", "capture network packets to file" )
-
-#ifdef CONFIG_NAND_LIMITS
-OPT_PARAM( nand_limits, "<nlimits>", "enforce NAND/Flash read/write thresholds" )
-#endif
-
-OPT_PARAM( bootchart, "<timeout>", "enable bootcharting")
-
-#undef CFG_FLAG
-#undef CFG_PARAM
-#undef OPT_FLAG
-#undef OPT_PARAM
diff --git a/android/config.c b/android/config.c
deleted file mode 100644
index 36fab11..0000000
--- a/android/config.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "android/config.h"
-#include "android/utils/path.h"
-
-AConfig*
-aconfig_node(const char *name, const char *value)
-{
- AConfig *n;
-
- n = (AConfig*) calloc(sizeof(AConfig), 1);
- n->name = name ? name : "";
- n->value = value ? value : "";
-
- return n;
-}
-
-static AConfig*
-_aconfig_find(AConfig *root, const char *name, int create)
-{
- AConfig *node;
-
- for(node = root->first_child; node; node = node->next) {
- if(!strcmp(node->name, name)) return node;
- }
-
- if(create) {
- node = (AConfig*) calloc(sizeof(AConfig), 1);
- node->name = name;
- node->value = "";
-
- if(root->last_child) {
- root->last_child->next = node;
- } else {
- root->first_child = node;
- }
- root->last_child = node;
- }
-
- return node;
-}
-
-AConfig*
-aconfig_find(AConfig *root, const char *name)
-{
- return _aconfig_find(root, name, 0);
-}
-
-int
-aconfig_bool(AConfig *root, const char *name, int _default)
-{
- AConfig *n = _aconfig_find(root, name, 0);
- if(n == 0) {
- return _default;
- } else {
- switch(n->value[0]){
- case 'y':
- case 'Y':
- case '1':
- return 1;
- default:
- return 0;
- }
- }
-}
-
-unsigned
-aconfig_unsigned(AConfig *root, const char *name, unsigned _default)
-{
- AConfig *n = _aconfig_find(root, name, 0);
- if(n == 0) {
- return _default;
- } else {
- return strtoul(n->value, 0, 0);
- }
-}
-
-int
-aconfig_int(AConfig *root, const char *name, int _default)
-{
- AConfig *n = _aconfig_find(root, name, 0);
- if(n == 0) {
- return _default;
- } else {
- return strtol(n->value, 0, 0);
- }
-}
-
-
-const char*
-aconfig_str(AConfig *root, const char *name, const char *_default)
-{
- AConfig *n = _aconfig_find(root, name, 0);
- if(n == 0) {
- return _default;
- } else {
- return n->value;
- }
-}
-
-void
-aconfig_set(AConfig *root, const char *name, const char *value)
-{
- AConfig *node = _aconfig_find(root, name, 1);
- node->value = value;
-}
-
-#define T_EOF 0
-#define T_TEXT 1
-#define T_DOT 2
-#define T_OBRACE 3
-#define T_CBRACE 4
-
-typedef struct
-{
- char *data;
- char *text;
- int len;
- char next;
-} cstate;
-
-
-static int _lex(cstate *cs, int value)
-{
- char c;
- char *s;
- char *data;
-
- data = cs->data;
-
- if(cs->next != 0) {
- c = cs->next;
- cs->next = 0;
- goto got_c;
- }
-
-restart:
- for(;;) {
- c = *data++;
- got_c:
- if(isspace(c)) continue;
-
- switch(c) {
- case 0:
- return T_EOF;
-
- /* a sharp sign (#) starts a line comment and everything
- * behind that is ignored until the end of line
- */
- case '#':
- for(;;) {
- switch(*data) {
- case 0:
- cs->data = data;
- return T_EOF;
- case '\n':
- cs->data = data + 1;
- goto restart;
- default:
- data++;
- }
- }
- break;
-
- case '.':
- cs->data = data;
- return T_DOT;
-
- case '{':
- cs->data = data;
- return T_OBRACE;
-
- case '}':
- cs->data = data;
- return T_CBRACE;
-
- default:
- s = data - 1;
-
- if(value) {
- /* if we're looking for a value, then take anything
- * until the end of line. note that sharp signs do
- * not start comments then. the result will be stripped
- * from trailing whitespace.
- */
- for(;;) {
- if(*data == 0) {
- cs->data = data;
- break;
- }
- if(*data == '\n') {
- cs->data = data + 1;
- *data-- = 0;
- break;
- }
- data++;
- }
-
- /* strip trailing whitespace */
- while(data > s){
- if(!isspace(*data)) break;
- *data-- = 0;
- }
-
- goto got_text;
- } else {
- /* looking for a key name. we stop at whitspace,
- * EOF, of T_DOT/T_OBRACE/T_CBRACE characters.
- * note that the name can include sharp signs
- */
- for(;;) {
- if(isspace(*data)) {
- *data = 0;
- cs->data = data + 1;
- goto got_text;
- }
- switch(*data) {
- case 0:
- cs->data = data;
- goto got_text;
- case '.':
- case '{':
- case '}':
- cs->next = *data;
- *data = 0;
- cs->data = data + 1;
- goto got_text;
- default:
- data++;
- }
- }
- }
- }
- }
-
-got_text:
- cs->text = s;
- return T_TEXT;
-}
-
-#if 0
-char *TOKENNAMES[] = { "EOF", "TEXT", "DOT", "OBRACE", "CBRACE" };
-
-static int lex(cstate *cs, int value)
-{
- int tok = _lex(cs, value);
- printf("TOKEN(%d) %s %s\n", value, TOKENNAMES[tok],
- tok == T_TEXT ? cs->text : "");
- return tok;
-}
-#else
-#define lex(cs,v) _lex(cs,v)
-#endif
-
-static int parse_expr(cstate *cs, AConfig *node);
-
-static int
-parse_block(cstate *cs, AConfig *node)
-{
- for(;;){
- switch(lex(cs, 0)){
- case T_TEXT:
- if(parse_expr(cs, node)) return -1;
- continue;
-
- case T_CBRACE:
- return 0;
-
- default:
- return -1;
- }
- }
-}
-
-static int
-parse_expr(cstate *cs, AConfig *node)
-{
- /* last token was T_TEXT */
- node = _aconfig_find(node, cs->text, 1);
-
- for(;;) {
- switch(lex(cs, 1)) {
- case T_DOT:
- if(lex(cs, 0) != T_TEXT) return -1;
- node = _aconfig_find(node, cs->text, 1);
- continue;
-
- case T_TEXT:
- node->value = cs->text;
- return 0;
-
- case T_OBRACE:
- return parse_block(cs, node);
-
- default:
- return -1;
- }
- }
-}
-
-void
-aconfig_load(AConfig *root, char *data)
-{
- if(data != 0) {
- cstate cs;
- cs.data = data;
- cs.next = 0;
-
- for(;;) {
- switch(lex(&cs, 0)){
- case T_TEXT:
- if(parse_expr(&cs, root)) return;
- break;
- default:
- return;
- }
- }
- }
-}
-
-int
-aconfig_load_file(AConfig *root, const char *fn)
-{
- char *data;
- data = path_load_file(fn, NULL);
- if (data == NULL)
- return -1;
-
- aconfig_load(root, data);
- return 0;
-}
-
-
-typedef struct
-{
- char buff[1024];
- char* p;
- char* end;
- int fd;
-} Writer;
-
-static int
-writer_init( Writer* w, const char* fn )
-{
- w->p = w->buff;
- w->end = w->buff + sizeof(w->buff);
-
- w->fd = creat( fn, 0755 );
- if (w->fd < 0)
- return -1;
-
-#ifdef _WIN32
- _setmode( w->fd, _O_BINARY );
-#endif
- return 0;
-}
-
-static void
-writer_write( Writer* w, const char* src, int len )
-{
- while (len > 0) {
- int avail = w->end - w->p;
-
- if (avail > len)
- avail = len;
-
- memcpy( w->p, src, avail );
- src += avail;
- len -= avail;
-
- w->p += avail;
- if (w->p == w->end) {
- write( w->fd, w->buff, w->p - w->buff );
- w->p = w->buff;
- }
- }
-}
-
-static void
-writer_done( Writer* w )
-{
- if (w->p > w->buff)
- write( w->fd, w->buff, w->p - w->buff );
- close( w->fd );
-}
-
-static void
-writer_margin( Writer* w, int margin)
-{
- static const char spaces[10] = " ";
- while (margin >= 10) {
- writer_write(w,spaces,10);
- margin -= 10;
- }
- if (margin > 0)
- writer_write(w,spaces,margin);
-}
-
-static void
-writer_c(Writer* w, char c)
-{
- writer_write(w, &c, 1);
-}
-
-static void
-writer_str(Writer* w, const char* str)
-{
- writer_write(w, str, strlen(str));
-}
-
-static void
-writer_node(Writer* w, AConfig* node, int margin)
-{
- writer_margin(w,margin);
- writer_str(w, node->name);
- writer_c(w,' ');
-
- if (node->value[0]) {
- writer_str(w, node->value);
- writer_c(w,'\n');
- }
- else
- {
- AConfig* child;
-
- writer_c(w, '{');
- writer_c(w, '\n');
-
- for (child = node->first_child; child; child = child->next)
- writer_node(w,child,margin+4);
-
- writer_margin(w,margin);
- writer_c(w,'}');
- writer_c(w,'\n');
- }
-}
-
-int
-aconfig_save_file(AConfig *root, const char *fn)
-{
- AConfig* child;
- Writer w[1];
-
- if (writer_init(w,fn) < 0)
- return -1;
-
- for (child = root->first_child; child; child = child->next)
- writer_node(w,child,0);
-
- writer_done(w);
- return 0;
-}
diff --git a/android/config.h b/android/config.h
deleted file mode 100644
index 5e8b048..0000000
--- a/android/config.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef ANDROID_CONFIG_H
-#define ANDROID_CONFIG_H
-
-/** ANDROID CONFIGURATION FILE SUPPORT
- **
- ** A configuration file is loaded as a simplre tree of (key,value)
- ** pairs. keys and values are simple strings
- **/
-typedef struct AConfig AConfig;
-
-struct AConfig
-{
- AConfig* next;
- AConfig* first_child;
- AConfig* last_child;
- const char* name;
- const char* value;
-};
-
-/* parse a text string into a config node tree */
-extern void aconfig_load(AConfig* root, char* data);
-
-/* parse a file into a config node tree, return 0 in case of success, -1 otherwise */
-extern int aconfig_load_file(AConfig* root, const char* path);
-
-/* save a config node tree into a file, return 0 in case of success, -1 otherwise */
-extern int aconfig_save_file(AConfig* root, const char* path);
-
-/* create a single config node */
-extern AConfig* aconfig_node(const char *name, const char *value);
-
-/* locate a named child of a config node */
-extern AConfig* aconfig_find(AConfig *root, const char *name);
-
-/* add a named child to a config node (or modify it if it already exists) */
-extern void aconfig_set(AConfig *root, const char *name, const char *value);
-
-
-/* look up a child by name and return its value, eventually converted
- * into a boolean or integer */
-extern int aconfig_bool (AConfig *root, const char *name, int _default);
-extern unsigned aconfig_unsigned(AConfig *root, const char *name, unsigned _default);
-extern int aconfig_int (AConfig *root, const char *name, int _default);
-extern const char* aconfig_str (AConfig *root, const char *name, const char *_default);
-
-#endif /* ANDROID_CONFIG_H */
diff --git a/android/config/Linux/config-host.h b/android/config/Linux/config-host.h
deleted file mode 100644
index 90defbd..0000000
--- a/android/config/Linux/config-host.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Automatically generated by configure - do not modify */
-#define CONFIG_QEMU_SHAREDIR "/usr/local/share/qemu"
-#define HOST_I386 1
-#define HOST_LONG_BITS 32
-#define HAVE_BYTESWAP_H 1
-#define CONFIG_GDBSTUB 1
-#define CONFIG_SLIRP 1
-#define QEMU_VERSION "0.8.2"
-#define CONFIG_SKINS 1
-#define CONFIG_UNAME_RELEASE ""
diff --git a/android/config/check-alsa.c b/android/config/check-alsa.c
deleted file mode 100644
index 4ab2945..0000000
--- a/android/config/check-alsa.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <dlfcn.h>
-#include <stdio.h>
-#include <alsa/asoundlib.h>
-
-#define D(...) fprintf(stderr,__VA_ARGS__)
-#define STRINGIFY(x) _STRINGIFY(x)
-#define _STRINGIFY(x) #x
-
-#define DYN_SYMBOLS \
- DYN_FUNCTION(size_t,snd_pcm_sw_params_sizeof,(void)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_current,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \
- DYN_FUNCTION(int,snd_pcm_sw_params_set_start_threshold,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)) \
- DYN_FUNCTION(int,snd_pcm_sw_params,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)) \
- DYN_FUNCTION(int,snd_pcm_sw_params_current,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)) \
- DYN_FUNCTION(size_t,snd_pcm_hw_params_sizeof,(void)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_any,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_access,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_format,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_rate_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_channels_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_buffer_time_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \
- DYN_FUNCTION(int,snd_pcm_hw_params,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_get_buffer_size,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \
- DYN_FUNCTION(int,snd_pcm_prepare,(snd_pcm_t *pcm)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_get_period_size,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_get_period_size_min,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_period_size,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_get_buffer_size_min,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_buffer_size,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)) \
- DYN_FUNCTION(int,snd_pcm_hw_params_set_period_time_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \
- DYN_FUNCTION(snd_pcm_sframes_t,snd_pcm_avail_update,(snd_pcm_t *pcm)) \
- DYN_FUNCTION(int,snd_pcm_drop,(snd_pcm_t *pcm)) \
- DYN_FUNCTION(snd_pcm_sframes_t,snd_pcm_writei,(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)) \
- DYN_FUNCTION(snd_pcm_sframes_t,snd_pcm_readi,(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)) \
- DYN_FUNCTION(snd_pcm_state_t,snd_pcm_state,(snd_pcm_t *pcm)) \
- DYN_FUNCTION(const char*,snd_strerror,(int errnum)) \
- DYN_FUNCTION(int,snd_pcm_open,(snd_pcm_t **pcm, const char *name,snd_pcm_stream_t stream, int mode)) \
- DYN_FUNCTION(int,snd_pcm_close,(snd_pcm_t *pcm)) \
-
-
-
-/* define pointers to library functions we're going to use */
-#define DYN_FUNCTION(ret,name,sig) \
- static ret (*func_ ## name)sig;
-
-DYN_SYMBOLS
-
-#undef DYN_FUNCTION
-
-#define func_snd_pcm_hw_params_alloca(ptr) \
- do { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(func_snd_pcm_hw_params_sizeof()); memset(*ptr, 0, func_snd_pcm_hw_params_sizeof()); } while (0)
-
-#define func_snd_pcm_sw_params_alloca(ptr) \
- do { assert(ptr); *ptr = (snd_pcm_sw_params_t *) alloca(func_snd_pcm_sw_params_sizeof()); memset(*ptr, 0, func_snd_pcm_sw_params_sizeof()); } while (0)
-
-static void* alsa_lib;
-
-int main(void)
-{
- int result = 1;
-
- alsa_lib = dlopen( "libasound.so", RTLD_NOW );
- if (alsa_lib == NULL)
- alsa_lib = dlopen( "libasound.so.2", RTLD_NOW );
-
- if (alsa_lib == NULL) {
- D("could not find libasound on this system\n");
- return 1;
- }
-
-#undef DYN_FUNCTION
-#define DYN_FUNCTION(ret,name,sig) \
- do { \
- (func_ ##name) = dlsym( alsa_lib, STRINGIFY(name) ); \
- if ((func_##name) == NULL) { \
- D("could not find %s in libasound\n", STRINGIFY(name)); \
- goto Fail; \
- } \
- } while (0);
-
- DYN_SYMBOLS
-
- result = 0;
- goto Exit;
-
-Fail:
- D("failed to open library\n");
-
-Exit:
- dlclose(alsa_lib);
- return result;
-}
diff --git a/android/config/check-esd.c b/android/config/check-esd.c
deleted file mode 100644
index a8eb11b..0000000
--- a/android/config/check-esd.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* this file is used to test that we can use libesd with lazy dynamic linking */
-
-#include <esd.h>
-#include <dlfcn.h>
-#include <stdio.h>
-
-#define D(...) fprintf(stderr,__VA_ARGS__)
-#define STRINGIFY(x) _STRINGIFY(x)
-#define _STRINGIFY(x) #x
-
-#define ESD_SYMBOLS \
- ESD_FUNCTION(int,esd_play_stream,(esd_format_t,int,const char*,const char*)) \
- ESD_FUNCTION(int,esd_record_stream,(esd_format_t,int,const char*,const char*)) \
- ESD_FUNCTION(int,esd_open_sound,( const char *host )) \
- ESD_FUNCTION(int,esd_close,(int)) \
-
-/* define pointers to library functions we're going to use */
-#define ESD_FUNCTION(ret,name,sig) \
- static ret (*func_ ## name)sig;
-
-ESD_SYMBOLS
-
-#undef ESD_FUNCTION
-static void* esd_lib;
-
-int main( void )
-{
- int fd;
-
- esd_lib = dlopen( "libesd.so", RTLD_NOW );
- if (esd_lib == NULL)
- esd_lib = dlopen( "libesd.so.0", RTLD_NOW );
-
- if (esd_lib == NULL) {
- D("could not find libesd on this system");
- return 1;
- }
-
-#undef ESD_FUNCTION
-#define ESD_FUNCTION(ret,name,sig) \
- do { \
- (func_ ##name) = dlsym( esd_lib, STRINGIFY(name) ); \
- if ((func_##name) == NULL) { \
- D("could not find %s in libesd\n", STRINGIFY(name)); \
- return 1; \
- } \
- } while (0);
-
- ESD_SYMBOLS
-
- return 0;
-}
diff --git a/android/config/config.h b/android/config/config.h
deleted file mode 100644
index be83607..0000000
--- a/android/config/config.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Automatically generated by configure - do not modify */
-#include "config-host.h"
-#define CONFIG_QEMU_PREFIX "/usr/gnemul/qemu-arm"
-#define TARGET_ARCH "arm"
-#define TARGET_ARM 1
-#define CONFIG_TRACE 1
-#define CONFIG_NAND 1
-#define CONFIG_SHAPER 1
-#define CONFIG_SOFTMMU 1
-#define CONFIG_SOFTFLOAT 1
-#define CONFIG_SDL 1
-#ifndef _WIN32
-#define CONFIG_NAND_LIMITS 1
-#endif
diff --git a/android/config/darwin-ppc/config-host.h b/android/config/darwin-ppc/config-host.h
deleted file mode 100644
index cbd43d1..0000000
--- a/android/config/darwin-ppc/config-host.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Automatically generated by configure - do not modify */
-#define CONFIG_QEMU_SHAREDIR "/usr/local/share/qemu"
-#define HOST_PPC 1
-#define HOST_LONG_BITS 32
-#define CONFIG_DARWIN 1
-#define CONFIG_GDBSTUB 1
-#define CONFIG_SLIRP 1
-#define QEMU_VERSION "0.8.2"
-#define O_LARGEFILE 0
-#define MAP_ANONYMOUS MAP_ANON
-#define _BSD 1
-#define CONFIG_SKINS 1
-#define CONFIG_UNAME_RELEASE ""
diff --git a/android/config/darwin-x86/config-host.h b/android/config/darwin-x86/config-host.h
deleted file mode 100644
index aaf0195..0000000
--- a/android/config/darwin-x86/config-host.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Automatically generated by configure - do not modify */
-#define CONFIG_QEMU_SHAREDIR "/usr/local/share/qemu"
-#define HOST_I386 1
-#define HOST_LONG_BITS 32
-#define CONFIG_DARWIN 1
-#define CONFIG_GDBSTUB 1
-#define CONFIG_SLIRP 1
-#define QEMU_VERSION "0.8.2"
-#define O_LARGEFILE 0
-#define MAP_ANONYMOUS MAP_ANON
-#define _BSD 1
-#define CONFIG_SKINS 1
-#define CONFIG_UNAME_RELEASE ""
diff --git a/android/config/linux-x86/config-host.h b/android/config/linux-x86/config-host.h
deleted file mode 100644
index 90defbd..0000000
--- a/android/config/linux-x86/config-host.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Automatically generated by configure - do not modify */
-#define CONFIG_QEMU_SHAREDIR "/usr/local/share/qemu"
-#define HOST_I386 1
-#define HOST_LONG_BITS 32
-#define HAVE_BYTESWAP_H 1
-#define CONFIG_GDBSTUB 1
-#define CONFIG_SLIRP 1
-#define QEMU_VERSION "0.8.2"
-#define CONFIG_SKINS 1
-#define CONFIG_UNAME_RELEASE ""
diff --git a/android/config/windows/config-host.h b/android/config/windows/config-host.h
deleted file mode 100644
index 8f9e0d9..0000000
--- a/android/config/windows/config-host.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Automatically generated by configure - do not modify */
-#define CONFIG_QEMU_SHAREDIR "/usr/local/share/qemu"
-#define HOST_I386 1
-#define HOST_LONG_BITS 32
-#define CONFIG_WIN32 1
-#define CONFIG_GDBSTUB 1
-#define CONFIG_SLIRP 1
-#define QEMU_VERSION "0.8.2"
-#define CONFIG_SKINS 1
-#define CONFIG_UNAME_RELEASE ""
diff --git a/android/console.c b/android/console.c
deleted file mode 100644
index 3a769c1..0000000
--- a/android/console.c
+++ /dev/null
@@ -1,2190 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/*
- * Android emulator control console
- *
- * this console is enabled automatically at emulator startup, on port 5554 by default,
- * unless some other emulator is already running. See (android_emulation_start in android_sdl.c
- * for details)
- *
- * you can telnet to the console, then use commands like 'help' or others to dynamically
- * change emulator settings.
- *
- */
-
-#include "sockets.h"
-#include "qemu-char.h"
-#include "sysemu.h"
-#include "android/android.h"
-#include "sockets.h"
-#include "cpu.h"
-#include "hw/goldfish_device.h"
-#include "hw/power_supply.h"
-#include "shaper.h"
-#include "modem_driver.h"
-#include "android/gps.h"
-#include "android/globals.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-#include "android/utils/stralloc.h"
-#include "tcpdump.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include "android/hw-events.h"
-#include "android/skin/keyboard.h"
-
-#if defined(CONFIG_SLIRP)
-#include "libslirp.h"
-#endif
-
-/* set to 1 to use the i/o and event functions
- * defined in "telephony/sysdeps.h"
- */
-#define USE_SYSDEPS 0
-
-#include "sysdeps.h"
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(console)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(x) do { if (D_ACTIVE) ( printf x , fflush(stdout) ); } while (0)
-#else
-# define D(x) do{}while(0)
-#endif
-
-extern int slirp_inited; /* in vl.c */
-
-typedef struct ControlGlobalRec_* ControlGlobal;
-
-typedef struct ControlClientRec_* ControlClient;
-
-typedef struct {
- int host_port;
- int host_udp;
- unsigned int guest_ip;
- int guest_port;
-} RedirRec, *Redir;
-
-
-#if USE_SYSDEPS
-typedef SysChannel Socket;
-#else /* !USE_SYSDEPS */
-typedef int Socket;
-#endif /* !USE_SYSDEPS */
-
-
-typedef struct ControlClientRec_
-{
- struct ControlClientRec_* next; /* next client in list */
- Socket sock; /* socket used for communication */
- ControlGlobal global;
- char finished;
- char buff[ 4096 ];
- int buff_len;
-
-} ControlClientRec;
-
-
-typedef struct ControlGlobalRec_
-{
- /* listening socket */
- Socket listen_fd;
-
- /* the list of current clients */
- ControlClient clients;
-
- /* the list of redirections currently active */
- Redir redirs;
- int num_redirs;
- int max_redirs;
-
-} ControlGlobalRec;
-
-
-static int
-control_global_add_redir( ControlGlobal global,
- int host_port,
- int host_udp,
- unsigned int guest_ip,
- int guest_port )
-{
- Redir redir;
-
- if (global->num_redirs >= global->max_redirs)
- {
- int old_max = global->max_redirs;
- int new_max = old_max + (old_max >> 1) + 4;
-
- Redir new_redirs = realloc( global->redirs, new_max*sizeof(global->redirs[0]) );
- if (new_redirs == NULL)
- return -1;
-
- global->redirs = new_redirs;
- global->max_redirs = new_max;
- }
-
- redir = &global->redirs[ global->num_redirs++ ];
-
- redir->host_port = host_port;
- redir->host_udp = host_udp;
- redir->guest_ip = guest_ip;
- redir->guest_port = guest_port;
-
- return 0;
-}
-
-static int
-control_global_del_redir( ControlGlobal global,
- int host_port,
- int host_udp )
-{
- int nn;
-
- for (nn = 0; nn < global->num_redirs; nn++)
- {
- Redir redir = &global->redirs[nn];
-
- if ( redir->host_port == host_port &&
- redir->host_udp == host_udp )
- {
- memmove( redir, redir + 1, ((global->num_redirs - nn)-1)*sizeof(*redir) );
- global->num_redirs -= 1;
- return 0;
- }
- }
- /* we didn't find it */
- return -1;
-}
-
-static void
-control_client_destroy( ControlClient client )
-{
- ControlGlobal global = client->global;
- ControlClient *pnode = &global->clients;
-
- D(( "destroying control client %p\n", client ));
-
-#if USE_SYSDEPS
- sys_channel_on( client->sock, 0, NULL, NULL );
-#else
- qemu_set_fd_handler( client->sock, NULL, NULL, NULL );
-#endif
-
- for ( ;; ) {
- ControlClient node = *pnode;
- if ( node == NULL )
- break;
- if ( node == client ) {
- *pnode = node->next;
- node->next = NULL;
- break;
- }
- pnode = &node->next;
- }
-
-#if USE_SYSDEPS
- sys_channel_close( client->sock );
- client->sock = NULL;
-#else
- socket_close( client->sock );
- client->sock = -1;
-#endif
-
- free( client );
-}
-
-static void control_client_read( void* _client ); /* forward */
-
-
-static void control_control_write( ControlClient client, const char* buff, int len )
-{
- int ret;
-
- if (len < 0)
- len = strlen(buff);
-
- while (len > 0) {
-#if USE_SYSDEPS
- ret = sys_channel_write( client->sock, buff, len );
-#else
- ret = socket_send( client->sock, buff, len);
-#endif
- if (ret < 0) {
- if (errno != EINTR && errno != EWOULDBLOCK)
- return;
- } else {
- buff += ret;
- len -= ret;
- }
- }
-}
-
-static void control_write( ControlClient client, const char* format, ... )
-{
- static char temp[1024];
- va_list args;
-
- va_start(args, format);
- vsnprintf( temp, sizeof(temp), format, args );
- va_end(args);
-
- temp[ sizeof(temp)-1 ] = 0;
-
- control_control_write( client, temp, -1 );
-}
-
-
-static ControlClient
-control_client_create( Socket socket,
- ControlGlobal global )
-{
- ControlClient client = calloc( sizeof(*client), 1 );
-
- if (client) {
-#if !USE_SYSDEPS
- socket_set_nodelay( socket );
- socket_set_nonblock( socket );
-#endif
- client->finished = 0;
- client->global = global;
- client->sock = socket;
- client->next = global->clients;
- global->clients = client;
-
-#if USE_SYSDEPS
- sys_channel_on( socket, SYS_EVENT_READ,
- (SysChannelCallback) control_client_read,
- client );
-#else
- qemu_set_fd_handler( socket, control_client_read, NULL, client );
-#endif
- }
- return client;
-}
-
-typedef const struct CommandDefRec_ *CommandDef;
-
-typedef struct CommandDefRec_ {
- const char* names;
- const char* abstract;
- const char* description;
- void (*descriptor)( ControlClient client );
- int (*handler)( ControlClient client, char* args );
- CommandDef subcommands; /* if handler is NULL */
-
-} CommandDefRec;
-
-static const CommandDefRec main_commands[]; /* forward */
-
-static CommandDef
-find_command( char* input, CommandDef commands, char* *pend, char* *pargs )
-{
- int nn;
- char* args = strchr(input, ' ');
-
- if (args != NULL) {
- while (*args == ' ')
- args++;
-
- if (args[0] == 0)
- args = NULL;
- }
-
- for (nn = 0; commands[nn].names != NULL; nn++)
- {
- const char* name = commands[nn].names;
- const char* sep;
-
- do {
- int len, c;
-
- sep = strchr( name, '|' );
- if (sep)
- len = sep - name;
- else
- len = strlen(name);
-
- c = input[len];
- if ( !memcmp( name, input, len ) && (c == ' ' || c == 0) ) {
- *pend = input + len;
- *pargs = args;
- return &commands[nn];
- }
-
- if (sep)
- name = sep + 1;
-
- } while (sep != NULL && *name);
- }
- /* NOTE: don't touch *pend and *pargs if no command is found */
- return NULL;
-}
-
-static void
-dump_help( ControlClient client,
- CommandDef cmd,
- const char* prefix )
-{
- if (cmd->description) {
- control_write( client, "%s", cmd->description );
- } else if (cmd->descriptor) {
- cmd->descriptor( client );
- } else
- control_write( client, "%s\r\n", cmd->abstract );
-
- if (cmd->subcommands) {
- cmd = cmd->subcommands;
- control_write( client, "\r\navailable sub-commands:\r\n" );
- for ( ; cmd->names != NULL; cmd++ ) {
- control_write( client, " %s %-15s %s\r\n", prefix, cmd->names, cmd->abstract );
- }
- control_write( client, "\r\n" );
- }
-}
-
-static void
-control_client_do_command( ControlClient client )
-{
- char* line = client->buff;
- char* args = NULL;
- CommandDef commands = main_commands;
- char* cmdend = client->buff;
- CommandDef cmd = find_command( line, commands, &cmdend, &args );
-
- if (cmd == NULL) {
- control_write( client, "KO: unknown command, try 'help'\r\n" );
- return;
- }
-
- for (;;) {
- CommandDef subcmd;
-
- if (cmd->handler) {
- if ( !cmd->handler( client, args ) )
- control_write( client, "OK\r\n" );
- break;
- }
-
- /* no handler means we should have sub-commands */
- if (cmd->subcommands == NULL) {
- control_write( client, "KO: internal error: buggy command table for '%.*s'\r\n",
- cmdend - client->buff, client->buff );
- break;
- }
-
- /* we need a sub-command here */
- if ( !args ) {
- dump_help( client, cmd, "" );
- control_write( client, "KO: missing sub-command\r\n" );
- break;
- }
-
- line = args;
- commands = cmd->subcommands;
- subcmd = find_command( line, commands, &cmdend, &args );
- if (subcmd == NULL) {
- dump_help( client, cmd, "" );
- control_write( client, "KO: bad sub-command\r\n" );
- break;
- }
- cmd = subcmd;
- }
-}
-
-/* implement the 'help' command */
-static int
-do_help( ControlClient client, char* args )
-{
- char* line;
- char* start = args;
- char* end = start;
- CommandDef cmd = main_commands;
-
- /* without arguments, simply dump all commands */
- if (args == NULL) {
- control_write( client, "Android console command help:\r\n\r\n" );
- for ( ; cmd->names != NULL; cmd++ ) {
- control_write( client, " %-15s %s\r\n", cmd->names, cmd->abstract );
- }
- control_write( client, "\r\ntry 'help <command>' for command-specific help\r\n" );
- return 0;
- }
-
- /* with an argument, find the corresponding command */
- for (;;) {
- CommandDef subcmd;
-
- line = args;
- subcmd = find_command( line, cmd, &end, &args );
- if (subcmd == NULL) {
- control_write( client, "try one of these instead:\r\n\r\n" );
- for ( ; cmd->names != NULL; cmd++ ) {
- control_write( client, " %.*s %s\r\n",
- end - start, start, cmd->names );
- }
- control_write( client, "\r\nKO: unknown command\r\n" );
- return -1;
- }
-
- if ( !args || !subcmd->subcommands ) {
- dump_help( client, subcmd, start );
- return 0;
- }
- cmd = subcmd->subcommands;
- }
-}
-
-
-static void
-control_client_read_byte( ControlClient client, unsigned char ch )
-{
- if (ch == '\r')
- {
- /* filter them out */
- }
- else if (ch == '\n')
- {
- client->buff[ client->buff_len ] = 0;
- control_client_do_command( client );
- if (client->finished)
- return;
-
- client->buff_len = 0;
- }
- else
- {
- if (client->buff_len >= sizeof(client->buff)-1)
- client->buff_len = 0;
-
- client->buff[ client->buff_len++ ] = ch;
- }
-}
-
-static void
-control_client_read( void* _client )
-{
- ControlClient client = _client;
- unsigned char buf[4096];
- int size;
-
- D(( "in control_client read: " ));
-#if USE_SYSDEPS
- size = sys_channel_read( client->sock, buf, sizeof(buf) );
-#else
- size = socket_recv( client->sock, buf, sizeof(buf) );
-#endif
- if (size < 0) {
- D(( "size < 0, exiting with %d: %s\n", errno, errno_str ));
- if (errno != EWOULDBLOCK && errno != EINTR)
- control_client_destroy( client );
- return;
- }
-
- if (size == 0) {
- /* end of connection */
- D(( "end of connection detected !!\n" ));
- control_client_destroy( client );
- }
- else {
- int nn;
-#ifdef _WIN32
-# if DEBUG
- char temp[16];
- int count = size > sizeof(temp)-1 ? sizeof(temp)-1 : size;
- for (nn = 0; nn < count; nn++) {
- int c = buf[nn];
- if (c == '\n')
- temp[nn] = '!';
- else if (c < 32)
- temp[nn] = '.';
- else
- temp[nn] = (char)c;
- }
- temp[nn] = 0;
- D(( "received %d bytes: %s\n", size, temp ));
-# endif
-#else
- D(( "received %.*s\n", size, buf ));
-#endif
- for (nn = 0; nn < size; nn++) {
- control_client_read_byte( client, buf[nn] );
- if (client->finished) {
- control_client_destroy(client);
- return;
- }
- }
- }
-}
-
-
-/* this function is called on each new client connection */
-static void
-control_global_accept( void* _global )
-{
- ControlGlobal global = _global;
- ControlClient client;
- Socket fd;
-
- D(( "control_global_accept: just in (fd=%p)\n", (void*)global->listen_fd ));
-
-#if USE_SYSDEPS
- fd = sys_channel_create_tcp_handler( global->listen_fd );
- if (fd == NULL) {
- perror("accept");
- return;
- }
-#else
- for(;;) {
- fd = socket_accept( global->listen_fd, NULL );
- if (fd < 0 && errno != EINTR) {
- D(( "problem in accept: %d: %s\n", errno, errno_str ));
- perror("accept");
- return;
- } else if (fd >= 0) {
- break;
- }
- D(( "relooping in accept()\n" ));
- }
-
- socket_set_xreuseaddr( fd );
-#endif
-
- D(( "control_global_accept: creating new client\n" ));
- client = control_client_create( fd, global );
- if (client) {
- D(( "control_global_accept: new client %p\n", client ));
- control_write( client, "Android Console: type 'help' for a list of commands\r\n" );
- control_write( client, "OK\r\n" );
- }
-}
-
-
-static int
-control_global_init( ControlGlobal global,
- int control_port )
-{
- Socket fd;
-#if !USE_SYSDEPS
- int ret;
- SockAddress sockaddr;
-#endif
-
- memset( global, 0, sizeof(*global) );
-
- sys_main_init();
-
-#if USE_SYSDEPS
- fd = sys_channel_create_tcp_server( control_port );
- if (fd == NULL) {
- return -1;
- }
-
- D(("global fd=%p\n", fd));
-
- global->listen_fd = fd;
- sys_channel_on( fd, SYS_EVENT_READ,
- (SysChannelCallback) control_global_accept,
- global );
-#else
- fd = socket_create_inet( SOCKET_STREAM );
- if (fd < 0) {
- perror("socket");
- return -1;
- }
-
- socket_set_xreuseaddr( fd );
-
- sock_address_init_inet( &sockaddr, SOCK_ADDRESS_INET_LOOPBACK, control_port );
-
- ret = socket_bind(fd, &sockaddr );
- if (ret < 0) {
- perror("bind");
- socket_close( fd );
- return -1;
- }
-
- ret = socket_listen(fd, 0);
- if (ret < 0) {
- perror("listen");
- socket_close( fd );
- return -1;
- }
-
- socket_set_nonblock(fd);
-
- global->listen_fd = fd;
-
- qemu_set_fd_handler( fd, control_global_accept, NULL, global );
-#endif
- return 0;
-}
-
-
-
-static int
-do_quit( ControlClient client, char* args )
-{
- client->finished = 1;
- return -1;
-}
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** N E T W O R K S E T T I N G S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static int
-do_network_status( ControlClient client, char* args )
-{
- control_write( client, "Current network status:\r\n" );
-
- control_write( client, " download speed: %8d bits/s (%.1f KB/s)\r\n",
- (long)qemu_net_download_speed, qemu_net_download_speed/8192. );
-
- control_write( client, " upload speed: %8d bits/s (%.1f KB/s)\r\n",
- (long)qemu_net_upload_speed, qemu_net_upload_speed/8192. );
-
- control_write( client, " minimum latency: %ld ms\r\n", qemu_net_min_latency );
- control_write( client, " maximum latency: %ld ms\r\n", qemu_net_max_latency );
- return 0;
-}
-
-static void
-dump_network_speeds( ControlClient client )
-{
- const NetworkSpeed* speed = android_netspeeds;
- const char* const format = " %-8s %s\r\n";
- for ( ; speed->name; speed++ ) {
- control_write( client, format, speed->name, speed->display );
- }
- control_write( client, format, "<num>", "selects both upload and download speed" );
- control_write( client, format, "<up>:<down>", "select individual upload/download speeds" );
-}
-
-
-static int
-do_network_speed( ControlClient client, char* args )
-{
- if ( !args ) {
- control_write( client, "KO: missing <speed> argument, see 'help network speed'\r\n" );
- return -1;
- }
- if ( android_parse_network_speed( args ) < 0 ) {
- control_write( client, "KO: invalid <speed> argument, see 'help network speed' for valid values\r\n" );
- return -1;
- }
-
- netshaper_set_rate( slirp_shaper_in, qemu_net_download_speed );
- netshaper_set_rate( slirp_shaper_out, qemu_net_upload_speed );
-
- if (android_modem) {
- amodem_set_data_network_type( android_modem,
- android_parse_network_type( args ) );
- }
- return 0;
-}
-
-static void
-describe_network_speed( ControlClient client )
-{
- control_write( client,
- "'network speed <speed>' allows you to dynamically change the speed of the emulated\r\n"
- "network on the device, where <speed> is one of the following:\r\n\r\n" );
- dump_network_speeds( client );
-}
-
-static int
-do_network_delay( ControlClient client, char* args )
-{
- if ( !args ) {
- control_write( client, "KO: missing <delay> argument, see 'help network delay'\r\n" );
- return -1;
- }
- if ( android_parse_network_latency( args ) < 0 ) {
- control_write( client, "KO: invalid <delay> argument, see 'help network delay' for valid values\r\n" );
- return -1;
- }
- netdelay_set_latency( slirp_delay_in, qemu_net_min_latency, qemu_net_max_latency );
- return 0;
-}
-
-static void
-describe_network_delay( ControlClient client )
-{
- control_write( client,
- "'network delay <latency>' allows you to dynamically change the latency of the emulated\r\n"
- "network on the device, where <latency> is one of the following:\r\n\r\n" );
- /* XXX: TODO */
-}
-
-static int
-do_network_capture_start( ControlClient client, char* args )
-{
- if ( !args ) {
- control_write( client, "KO: missing <file> argument, see 'help network capture start'\r\n" );
- return -1;
- }
- if ( qemu_tcpdump_start(args) < 0) {
- control_write( client, "KO: could not start capture: %s", strerror(errno) );
- return -1;
- }
- return 0;
-}
-
-static int
-do_network_capture_stop( ControlClient client, char* args )
-{
- /* no need to return an error here */
- qemu_tcpdump_stop();
- return 0;
-}
-
-static const CommandDefRec network_capture_commands[] =
-{
- { "start", "start network capture",
- "'network capture start <file>' starts a new capture of network packets\r\n"
- "into a specific <file>. This will stop any capture already in progress.\r\n"
- "the capture file can later be analyzed by tools like WireShark. It uses\r\n"
- "the libpcap file format.\r\n\r\n"
- "you can stop the capture anytime with 'network capture stop'\r\n", NULL,
- do_network_capture_start, NULL },
-
- { "stop", "stop network capture",
- "'network capture stop' stops a currently running packet capture, if any.\r\n"
- "you can start one with 'network capture start <file>'\r\n", NULL,
- do_network_capture_stop, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static const CommandDefRec network_commands[] =
-{
- { "status", "dump network status", NULL, NULL,
- do_network_status, NULL },
-
- { "speed", "change network speed", NULL, describe_network_speed,
- do_network_speed, NULL },
-
- { "delay", "change network latency", NULL, describe_network_delay,
- do_network_delay, NULL },
-
- { "capture", "dump network packets to file",
- "allows to start/stop capture of network packets to a file for later analysis\r\n", NULL,
- NULL, network_capture_commands },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** P O R T R E D I R E C T I O N S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static int
-do_redir_list( ControlClient client, char* args )
-{
- ControlGlobal global = client->global;
-
- if (global->num_redirs == 0)
- control_write( client, "no active redirections\r\n" );
- else {
- int nn;
- for (nn = 0; nn < global->num_redirs; nn++) {
- Redir redir = &global->redirs[nn];
- control_write( client, "%s:%-5d => %-5d\r\n",
- redir->host_udp ? "udp" : "tcp",
- redir->host_port,
- redir->guest_port );
- }
- }
- return 0;
-}
-
-/* parse a protocol:port specification */
-static int
-redir_parse_proto_port( char* args, int *pport, int *pproto )
-{
- int proto = -1;
- int len = 0;
- char* end;
-
- if ( !memcmp( args, "tcp:", 4 ) ) {
- proto = 0;
- len = 4;
- }
- else if ( !memcmp( args, "udp:", 4 ) ) {
- proto = 1;
- len = 4;
- }
- else
- return 0;
-
- args += len;
- *pproto = proto;
- *pport = strtol( args, &end, 10 );
- if (end == args)
- return 0;
-
- len += end - args;
- return len;
-}
-
-static int
-redir_parse_guest_port( char* arg, int *pport )
-{
- char* end;
-
- *pport = strtoul( arg, &end, 10 );
- if (end == arg)
- return 0;
-
- return end - arg;
-}
-
-static Redir
-redir_find( ControlGlobal global, int port, int isudp )
-{
- int nn;
-
- for (nn = 0; nn < global->num_redirs; nn++) {
- Redir redir = &global->redirs[nn];
-
- if (redir->host_port == port && redir->host_udp == isudp)
- return redir;
- }
- return NULL;
-}
-
-
-static int
-do_redir_add( ControlClient client, char* args )
-{
- int len, host_proto, host_port, guest_port;
- uint32_t guest_ip;
- Redir redir;
-
- if ( !args )
- goto BadFormat;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- len = redir_parse_proto_port( args, &host_port, &host_proto );
- if (len == 0 || args[len] != ':')
- goto BadFormat;
-
- args += len + 1;
- len = redir_parse_guest_port( args, &guest_port );
- if (len == 0 || args[len] != 0)
- goto BadFormat;
-
- redir = redir_find( client->global, host_port, host_proto );
- if ( redir != NULL ) {
- control_write( client, "KO: host port already active, use 'redir del' to remove first\r\n" );
- return -1;
- }
-
- if (!inet_strtoip("10.0.2.15", &guest_ip)) {
- control_write( client, "KO: unexpected internal failure when resolving 10.0.2.15\r\n" );
- return -1;
- }
-
- D(("pattern hport=%d gport=%d proto=%d\n", host_port, guest_port, host_proto ));
- if ( control_global_add_redir( client->global, host_port, host_proto,
- guest_ip, guest_port ) < 0 )
- {
- control_write( client, "KO: not enough memory to allocate redirection\r\n" );
- return -1;
- }
-
- if (slirp_redir(host_proto, host_port, guest_ip, guest_port) < 0) {
- control_write( client, "KO: can't setup redirection, port probably used by another program on host\r\n" );
- control_global_del_redir( client->global, host_port, host_proto );
- return -1;
- }
-
- return 0;
-
-BadFormat:
- control_write( client, "KO: bad redirection format, try (tcp|udp):hostport:guestport\r\n", -1 );
- return -1;
-}
-
-
-static int
-do_redir_del( ControlClient client, char* args )
-{
- int len, proto, port;
- Redir redir;
-
- if ( !args )
- goto BadFormat;
- len = redir_parse_proto_port( args, &port, &proto );
- if ( len == 0 || args[len] != 0 )
- goto BadFormat;
-
- redir = redir_find( client->global, port, proto );
- if (redir == NULL) {
- control_write( client, "KO: can't remove unknown redirection (%s:%d)\r\n",
- proto ? "udp" : "tcp", port );
- return -1;
- }
-
- slirp_unredir( redir->host_udp, redir->host_port );
- control_global_del_redir( client->global, port, proto );\
-
- return 0;
-
-BadFormat:
- control_write( client, "KO: bad redirection format, try (tcp|udp):hostport\r\n" );
- return -1;
-}
-
-static const CommandDefRec redir_commands[] =
-{
- { "list", "list current redirections",
- "list current port redirections. use 'redir add' and 'redir del' to add and remove them\r\n", NULL,
- do_redir_list, NULL },
-
- { "add", "add new redirection",
- "add a new port redirection, arguments must be:\r\n\r\n"
- " redir add <protocol>:<host-port>:<guest-port>\r\n\r\n"
- "where: <protocol> is either 'tcp' or 'udp'\r\n"
- " <host-port> a number indicating which port on the host to open\r\n"
- " <guest-port> a number indicating which port to route to on the device\r\n"
- "\r\nas an example, 'redir tcp:5000:6000' will allow any packets sent to\r\n"
- "the host's TCP port 5000 to be routed to TCP port 6000 of the emulated device\r\n", NULL,
- do_redir_add, NULL },
-
- { "del", "remove existing redirection",
- "remove a port redirecion that was created with 'redir add', arguments must be:\r\n\r\n"
- " redir del <protocol>:<host-port>\r\n\r\n"
- "see the 'help redir add' for the meaning of <protocol> and <host-port>\r\n", NULL,
- do_redir_del, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** G S M M O D E M ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static const struct {
- const char* name;
- const char* display;
- ARegistrationState state;
-} _gsm_states[] = {
- { "unregistered", "no network available", A_REGISTRATION_UNREGISTERED },
- { "home", "on local network, non-roaming", A_REGISTRATION_HOME },
- { "roaming", "on roaming network", A_REGISTRATION_ROAMING },
- { "searching", "searching networks", A_REGISTRATION_SEARCHING },
- { "denied", "emergency calls only", A_REGISTRATION_DENIED },
- { "off", "same as 'unregistered'", A_REGISTRATION_UNREGISTERED },
- { "on", "same as 'home'", A_REGISTRATION_HOME },
- { NULL, NULL, A_REGISTRATION_UNREGISTERED }
-};
-
-static const char*
-gsm_state_to_string( ARegistrationState state )
-{
- int nn;
- for (nn = 0; _gsm_states[nn].name != NULL; nn++) {
- if (state == _gsm_states[nn].state)
- return _gsm_states[nn].name;
- }
- return "<unknown>";
-}
-
-static int
-do_gsm_status( ControlClient client, char* args )
-{
- if (args) {
- control_write( client, "KO: no argument required\r\n" );
- return -1;
- }
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
- control_write( client, "gsm voice state: %s\r\n",
- gsm_state_to_string(
- amodem_get_voice_registration(android_modem) ) );
- control_write( client, "gsm data state: %s\r\n",
- gsm_state_to_string(
- amodem_get_data_registration(android_modem) ) );
- return 0;
-}
-
-
-static void
-help_gsm_data( ControlClient client )
-{
- int nn;
- control_write( client,
- "the 'gsm data <state>' allows you to change the state of your GPRS connection\r\n"
- "valid values for <state> are the following:\r\n\r\n" );
- for (nn = 0; ; nn++) {
- const char* name = _gsm_states[nn].name;
- const char* display = _gsm_states[nn].display;
-
- if (!name)
- break;
-
- control_write( client, " %-15s %s\r\n", name, display );
- }
- control_write( client, "\r\n" );
-}
-
-
-static int
-do_gsm_data( ControlClient client, char* args )
-{
- int nn;
-
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm data <state>'\r\n" );
- return -1;
- }
-
- for (nn = 0; ; nn++) {
- const char* name = _gsm_states[nn].name;
- ARegistrationState state = _gsm_states[nn].state;
-
- if (!name)
- break;
-
- if ( !strcmp( args, name ) ) {
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
- amodem_set_data_registration( android_modem, state );
- qemu_net_disable = (state != A_REGISTRATION_HOME &&
- state != A_REGISTRATION_ROAMING );
- return 0;
- }
- }
- control_write( client, "KO: bad GSM data state name, try 'help gsm data' for list of valid values\r\n" );
- return -1;
-}
-
-static void
-help_gsm_voice( ControlClient client )
-{
- int nn;
- control_write( client,
- "the 'gsm voice <state>' allows you to change the state of your GPRS connection\r\n"
- "valid values for <state> are the following:\r\n\r\n" );
- for (nn = 0; ; nn++) {
- const char* name = _gsm_states[nn].name;
- const char* display = _gsm_states[nn].display;
-
- if (!name)
- break;
-
- control_write( client, " %-15s %s\r\n", name, display );
- }
- control_write( client, "\r\n" );
-}
-
-
-static int
-do_gsm_voice( ControlClient client, char* args )
-{
- int nn;
-
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm voice <state>'\r\n" );
- return -1;
- }
-
- for (nn = 0; ; nn++) {
- const char* name = _gsm_states[nn].name;
- ARegistrationState state = _gsm_states[nn].state;
-
- if (!name)
- break;
-
- if ( !strcmp( args, name ) ) {
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
- amodem_set_voice_registration( android_modem, state );
- return 0;
- }
- }
- control_write( client, "KO: bad GSM data state name, try 'help gsm voice' for list of valid values\r\n" );
- return -1;
-}
-
-
-static int
-gsm_check_number( char* args )
-{
- int nn;
-
- for (nn = 0; args[nn] != 0; nn++) {
- int c = args[nn];
- if ( !isdigit(c) && c != '+' && c != '#' ) {
- return -1;
- }
- }
- if (nn == 0)
- return -1;
-
- return 0;
-}
-
-static int
-do_gsm_call( ControlClient client, char* args )
-{
- /* check that we have a phone number made of digits */
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm call <phonenumber>'\r\n" );
- return -1;
- }
-
- if (gsm_check_number(args)) {
- control_write( client, "KO: bad phone number format, use digits, # and + only\r\n" );
- return -1;
- }
-
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
- amodem_add_inbound_call( android_modem, args );
- return 0;
-}
-
-static int
-do_gsm_cancel( ControlClient client, char* args )
-{
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm call <phonenumber>'\r\n" );
- return -1;
- }
- if (gsm_check_number(args)) {
- control_write( client, "KO: bad phone number format, use digits, # and + only\r\n" );
- return -1;
- }
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
- if ( amodem_disconnect_call( android_modem, args ) < 0 ) {
- control_write( client, "KO: could not cancel this number\r\n" );
- return -1;
- }
- return 0;
-}
-
-
-static const char*
-call_state_to_string( ACallState state )
-{
- switch (state) {
- case A_CALL_ACTIVE: return "active";
- case A_CALL_HELD: return "held";
- case A_CALL_ALERTING: return "ringing";
- case A_CALL_WAITING: return "waiting";
- case A_CALL_INCOMING: return "incoming";
- default: return "unknown";
- }
-}
-
-static int
-do_gsm_list( ControlClient client, char* args )
-{
- /* check that we have a phone number made of digits */
- int count = amodem_get_call_count( android_modem );
- int nn;
- for (nn = 0; nn < count; nn++) {
- ACall call = amodem_get_call( android_modem, nn );
- const char* dir;
-
- if (call == NULL)
- continue;
-
- if (call->dir == A_CALL_OUTBOUND)
- dir = "outbound to ";
- else
- dir = "inbound from";
-
- control_write( client, "%s %-10s : %s\r\n", dir,
- call->number, call_state_to_string(call->state) );
- }
- return 0;
-}
-
-static int
-do_gsm_busy( ControlClient client, char* args )
-{
- ACall call;
-
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm busy <phonenumber>'\r\n" );
- return -1;
- }
- call = amodem_find_call_by_number( android_modem, args );
- if (call == NULL || call->dir != A_CALL_OUTBOUND) {
- control_write( client, "KO: no current outbound call to number '%s' (call %p)\r\n", args, call );
- return -1;
- }
- if ( amodem_disconnect_call( android_modem, args ) < 0 ) {
- control_write( client, "KO: could not cancel this number\r\n" );
- return -1;
- }
- return 0;
-}
-
-static int
-do_gsm_hold( ControlClient client, char* args )
-{
- ACall call;
-
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm out hold <phonenumber>'\r\n" );
- return -1;
- }
- call = amodem_find_call_by_number( android_modem, args );
- if (call == NULL) {
- control_write( client, "KO: no current call to/from number '%s'\r\n", args );
- return -1;
- }
- if ( amodem_update_call( android_modem, args, A_CALL_HELD ) < 0 ) {
- control_write( client, "KO: could put this call on hold\r\n" );
- return -1;
- }
- return 0;
-}
-
-
-static int
-do_gsm_accept( ControlClient client, char* args )
-{
- ACall call;
-
- if (!args) {
- control_write( client, "KO: missing argument, try 'gsm accept <phonenumber>'\r\n" );
- return -1;
- }
- call = amodem_find_call_by_number( android_modem, args );
- if (call == NULL) {
- control_write( client, "KO: no current call to/from number '%s'\r\n", args );
- return -1;
- }
- if ( amodem_update_call( android_modem, args, A_CALL_ACTIVE ) < 0 ) {
- control_write( client, "KO: could not activate this call\r\n" );
- return -1;
- }
- return 0;
-}
-
-
-#if 0
-static const CommandDefRec gsm_in_commands[] =
-{
- { "new", "create a new 'waiting' inbound call",
- "'gsm in create <phonenumber>' creates a new inbound phone call, placed in\r\n"
- "the 'waiting' state by default, until the system answers/holds/closes it\r\n", NULL
- do_gsm_in_create, NULL },
-
- { "hold", "change the state of an oubtound call to 'held'",
- "change the state of an outbound call to 'held'. this is only possible\r\n"
- "if the call in the 'waiting' or 'active' state\r\n", NULL,
- do_gsm_out_hold, NULL },
-
- { "accept", "change the state of an outbound call to 'active'",
- "change the state of an outbound call to 'active'. this is only possible\r\n"
- "if the call is in the 'waiting' or 'held' state\r\n", NULL,
- do_gsm_out_accept, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-#endif
-
-
-static const CommandDefRec gsm_commands[] =
-{
- { "list", "list current phone calls",
- "'gsm list' lists all inbound and outbound calls and their state\r\n", NULL,
- do_gsm_list, NULL },
-
- { "call", "create inbound phone call",
- "'gsm call <phonenumber>' allows you to simulate a new inbound call\r\n", NULL,
- do_gsm_call, NULL },
-
- { "busy", "close waiting outbound call as busy",
- "'gsm busy <remoteNumber>' closes an outbound call, reporting\r\n"
- "the remote phone as busy. only possible if the call is 'waiting'.\r\n", NULL,
- do_gsm_busy, NULL },
-
- { "hold", "change the state of an oubtound call to 'held'",
- "'gsm hold <remoteNumber>' change the state of a call to 'held'. this is only possible\r\n"
- "if the call in the 'waiting' or 'active' state\r\n", NULL,
- do_gsm_hold, NULL },
-
- { "accept", "change the state of an outbound call to 'active'",
- "'gsm accept <remoteNumber>' change the state of a call to 'active'. this is only possible\r\n"
- "if the call is in the 'waiting' or 'held' state\r\n", NULL,
- do_gsm_accept, NULL },
-
- { "cancel", "disconnect an inbound or outbound phone call",
- "'gsm cancel <phonenumber>' allows you to simulate the end of an inbound or outbound call\r\n", NULL,
- do_gsm_cancel, NULL },
-
- { "data", "modify data connection state", NULL, help_gsm_data,
- do_gsm_data, NULL },
-
- { "voice", "modify voice connection state", NULL, help_gsm_voice,
- do_gsm_voice, NULL },
-
- { "status", "display GSM status",
- "'gsm status' displays the current state of the GSM emulation\r\n", NULL,
- do_gsm_status, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** S M S C O M M A N D ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static int
-do_sms_send( ControlClient client, char* args )
-{
- char* p;
- int textlen;
- SmsAddressRec sender;
- SmsPDU* pdus;
- int nn;
-
- /* check that we have a phone number made of digits */
- if (!args) {
- MissingArgument:
- control_write( client, "KO: missing argument, try 'sms send <phonenumber> <text message>'\r\n" );
- return -1;
- }
- p = strchr( args, ' ' );
- if (!p) {
- goto MissingArgument;
- }
-
- if ( sms_address_from_str( &sender, args, p - args ) < 0 ) {
- control_write( client, "KO: bad phone number format, must be [+](0-9)*\r\n" );
- return -1;
- }
-
-
- /* un-secape message text into proper utf-8 (conversion happens in-site) */
- p += 1;
- textlen = strlen(p);
- textlen = sms_utf8_from_message_str( p, textlen, (unsigned char*)p, textlen );
- if (textlen < 0) {
- control_write( client, "message must be utf8 and can use the following escapes:\r\n"
- " \\n for a newline\r\n"
- " \\xNN where NN are two hexadecimal numbers\r\n"
- " \\uNNNN where NNNN are four hexadecimal numbers\r\n"
- " \\\\ to send a '\\' character\r\n\r\n"
- " anything else is an error\r\n"
- "KO: badly formatted text\r\n" );
- return -1;
- }
-
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
-
- /* create a list of SMS PDUs, then send them */
- pdus = smspdu_create_deliver_utf8( (cbytes_t)p, textlen, &sender, NULL );
- if (pdus == NULL) {
- control_write( client, "KO: internal error when creating SMS-DELIVER PDUs\n" );
- return -1;
- }
-
- for (nn = 0; pdus[nn] != NULL; nn++)
- amodem_receive_sms( android_modem, pdus[nn] );
-
- smspdu_free_list( pdus );
- return 0;
-}
-
-static int
-do_sms_sendpdu( ControlClient client, char* args )
-{
- SmsPDU pdu;
-
- /* check that we have a phone number made of digits */
- if (!args) {
- control_write( client, "KO: missing argument, try 'sms sendpdu <hexstring>'\r\n" );
- return -1;
- }
-
- if (!android_modem) {
- control_write( client, "KO: modem emulation not running\r\n" );
- return -1;
- }
-
- pdu = smspdu_create_from_hex( args, strlen(args) );
- if (pdu == NULL) {
- control_write( client, "KO: badly formatted <hexstring>\r\n" );
- return -1;
- }
-
- amodem_receive_sms( android_modem, pdu );
- smspdu_free( pdu );
- return 0;
-}
-
-static const CommandDefRec sms_commands[] =
-{
- { "send", "send inbound SMS text message",
- "'sms send <phonenumber> <message>' allows you to simulate a new inbound sms message\r\n", NULL,
- do_sms_send, NULL },
-
- { "pdu", "send inbound SMS PDU",
- "'sms pdu <hexstring>' allows you to simulate a new inbound sms PDU\r\n"
- "(used internally when one emulator sends SMS messages to another instance).\r\n"
- "you probably don't want to play with this at all\r\n", NULL,
- do_sms_sendpdu, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static void
-do_control_write(void* data, const char* string)
-{
- control_write((ControlClient)data, string);
-}
-
-static int
-do_power_display( ControlClient client, char* args )
-{
- goldfish_battery_display(do_control_write, client);
- return 0;
-}
-
-static int
-do_ac_state( ControlClient client, char* args )
-{
- if (args) {
- if (strcasecmp(args, "on") == 0) {
- goldfish_battery_set_prop(1, POWER_SUPPLY_PROP_ONLINE, 1);
- return 0;
- }
- if (strcasecmp(args, "off") == 0) {
- goldfish_battery_set_prop(1, POWER_SUPPLY_PROP_ONLINE, 0);
- return 0;
- }
- }
-
- control_write( client, "KO: Usage: \"ac on\" or \"ac off\"\n" );
- return -1;
-}
-
-static int
-do_battery_status( ControlClient client, char* args )
-{
- if (args) {
- if (strcasecmp(args, "unknown") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_UNKNOWN);
- return 0;
- }
- if (strcasecmp(args, "charging") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_CHARGING);
- return 0;
- }
- if (strcasecmp(args, "discharging") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_DISCHARGING);
- return 0;
- }
- if (strcasecmp(args, "not-charging") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_NOT_CHARGING);
- return 0;
- }
- if (strcasecmp(args, "full") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_STATUS_FULL);
- return 0;
- }
- }
-
- control_write( client, "KO: Usage: \"status unknown|charging|discharging|not-charging|full\"\n" );
- return -1;
-}
-
-static int
-do_battery_present( ControlClient client, char* args )
-{
- if (args) {
- if (strcasecmp(args, "true") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_PRESENT, 1);
- return 0;
- }
- if (strcasecmp(args, "false") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_PRESENT, 0);
- return 0;
- }
- }
-
- control_write( client, "KO: Usage: \"present true\" or \"present false\"\n" );
- return -1;
-}
-
-static int
-do_battery_health( ControlClient client, char* args )
-{
- if (args) {
- if (strcasecmp(args, "unknown") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_UNKNOWN);
- return 0;
- }
- if (strcasecmp(args, "good") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_GOOD);
- return 0;
- }
- if (strcasecmp(args, "overheat") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_OVERHEAT);
- return 0;
- }
- if (strcasecmp(args, "dead") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_DEAD);
- return 0;
- }
- if (strcasecmp(args, "overvoltage") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_OVERVOLTAGE);
- return 0;
- }
- if (strcasecmp(args, "failure") == 0) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_HEALTH_UNSPEC_FAILURE);
- return 0;
- }
- }
-
- control_write( client, "KO: Usage: \"health unknown|good|overheat|dead|overvoltage|failure\"\n" );
- return -1;
-}
-
-static int
-do_battery_capacity( ControlClient client, char* args )
-{
- if (args) {
- int capacity;
-
- if (sscanf(args, "%d", &capacity) == 1 && capacity >= 0 && capacity <= 100) {
- goldfish_battery_set_prop(0, POWER_SUPPLY_PROP_CAPACITY, capacity);
- return 0;
- }
- }
-
- control_write( client, "KO: Usage: \"capacity <percentage>\"\n" );
- return -1;
-}
-
-
-static const CommandDefRec power_commands[] =
-{
- { "display", "display battery and charger state",
- "display battery and charger state\r\n", NULL,
- do_power_display, NULL },
-
- { "ac", "set AC charging state",
- "'ac on|off' allows you to set the AC charging state to on or off\r\n", NULL,
- do_ac_state, NULL },
-
- { "status", "set battery status",
- "'status unknown|charging|discharging|not-charging|full' allows you to set battery status\r\n", NULL,
- do_battery_status, NULL },
-
- { "present", "set battery present state",
- "'present true|false' allows you to set battery present state to true or false\r\n", NULL,
- do_battery_present, NULL },
-
- { "health", "set battery health state",
- "'health unknown|good|overheat|dead|overvoltage|failure' allows you to set battery health state\r\n", NULL,
- do_battery_health, NULL },
-
- { "capacity", "set battery capacity state",
- "'capacity <percentage>' allows you to set battery capacity to a value 0 - 100\r\n", NULL,
- do_battery_capacity, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** E V E N T C O M M A N D S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-
-static int
-do_event_send( ControlClient client, char* args )
-{
- char* p;
-
- if (!args) {
- control_write( client, "KO: Usage: event send <type>:<code>:<value> ...\r\n" );
- return -1;
- }
-
- p = args;
- while (*p) {
- char* q;
- int type, code, value, ret;
-
- p += strspn( args, " \t" ); /* skip spaces */
- if (*p == 0)
- break;
-
- q = p + strcspn( p, " \t" );
-
- if (q == p)
- break;
-
- ret = android_event_from_str( p, &type, &code, &value );
- if (ret < 0) {
- if (ret == -1) {
- control_write( client,
- "KO: invalid event type in '%.*s', try 'event list types' for valid values\r\n",
- q-p, p );
- } else if (ret == -2) {
- control_write( client,
- "KO: invalid event code in '%.*s', try 'event list codes <type>' for valid values\r\n",
- q-p, p );
- } else {
- control_write( client,
- "KO: invalid event value in '%.*s', must be an integer\r\n",
- q-p, p);
- }
- return -1;
- }
-
- kbd_generic_event( type, code, value );
- p = q;
- }
- return 0;
-}
-
-static int
-do_event_types( ControlClient client, char* args )
-{
- int count = android_event_get_type_count();
- int nn;
-
- control_write( client, "event <type> can be an integer or one of the following aliases\r\n" );
- for (nn = 0; nn < count; nn++) {
- char tmp[16];
- char* p = tmp;
- char* end = p + sizeof(tmp);
- int count2 = android_event_get_code_count( nn );;
-
- p = android_event_bufprint_type_str( p, end, nn );
-
- control_write( client, " %-8s", tmp );
- if (count2 > 0)
- control_write( client, " (%d code aliases)", count2 );
-
- control_write( client, "\r\n" );
- }
- return 0;
-}
-
-static int
-do_event_codes( ControlClient client, char* args )
-{
- int count;
- int nn, type, dummy;
-
- if (!args) {
- control_write( client, "KO: argument missing, try 'event codes <type>'\r\n" );
- return -1;
- }
-
- if ( android_event_from_str( args, &type, &dummy, &dummy ) < 0 ) {
- control_write( client, "KO: bad argument, see 'event types' for valid values\r\n" );
- return -1;
- }
-
- count = android_event_get_code_count( type );
- if (count == 0) {
- control_write( client, "no code aliases defined for this type\r\n" );
- } else {
- control_write( client, "type '%s' accepts the following <code> aliases:\r\n",
- args );
- for (nn = 0; nn < count; nn++) {
- char temp[20], *p = temp, *end = p + sizeof(temp);
- android_event_bufprint_code_str( p, end, type, nn );
- control_write( client, " %-12s\r\n", temp );
- }
- }
-
- return 0;
-}
-
-static __inline__ int
-utf8_next( unsigned char* *pp, unsigned char* end )
-{
- unsigned char* p = *pp;
- int result = -1;
-
- if (p < end) {
- int c= *p++;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
-
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- }
- }
- result = c;
- *pp = p;
- }
- return result;
-}
-
-static int
-do_event_text( ControlClient client, char* args )
-{
- SkinKeyboard* keyboard;
- unsigned char* p = (unsigned char*) args;
- unsigned char* end = p + strlen(args);
- int textlen;
-
- if (!args) {
- control_write( client, "KO: argument missing, try 'event text <message>'\r\n" );
- return -1;
- }
- keyboard = android_emulator_get_keyboard();
- if (keyboard == NULL) {
- control_write( client, "KO: no keyboard active in current device layout/config\r\n" );
- return -1;
- }
-
- /* un-secape message text into proper utf-8 (conversion happens in-site) */
- textlen = strlen((char*)p);
- textlen = sms_utf8_from_message_str( args, textlen, (unsigned char*)p, textlen );
- if (textlen < 0) {
- control_write( client, "message must be utf8 and can use the following escapes:\r\n"
- " \\n for a newline\r\n"
- " \\xNN where NN are two hexadecimal numbers\r\n"
- " \\uNNNN where NNNN are four hexadecimal numbers\r\n"
- " \\\\ to send a '\\' character\r\n\r\n"
- " anything else is an error\r\n"
- "KO: badly formatted text\r\n" );
- return -1;
- }
-
- end = p + textlen;
- while (p < end) {
- int c = utf8_next( &p, end );
- if (c <= 0)
- break;
-
- skin_keyboard_process_unicode_event( keyboard, (unsigned)c, 1 );
- skin_keyboard_process_unicode_event( keyboard, (unsigned)c, 0 );
- skin_keyboard_flush( keyboard );
- }
-
- return 0;
-}
-
-static const CommandDefRec event_commands[] =
-{
- { "send", "send a series of events to the kernel",
- "'event send <type>:<code>:<value> ...' allows your to send one or more hardware events\r\n"
- "to the Android kernel. you can use text names or integers for <type> and <code>\r\n", NULL,
- do_event_send, NULL },
-
- { "types", "list all <type> aliases",
- "'event types' list all <type> string aliases supported by the 'event' subcommands\r\n",
- NULL, do_event_types, NULL },
-
- { "codes", "list all <code> aliases for a given <type>",
- "'event codes <type>' lists all <code> string aliases for a given event <type>\r\n",
- NULL, do_event_codes, NULL },
-
- { "text", "simulate keystrokes from a given text",
- "'event text <message>' allows you to simulate keypresses to generate a given text\r\n"
- "message. <message> must be an utf-8 string. Unicode points will be reverse-mapped\r\n"
- "according to the current device keyboard. unsupported characters will be discarded\r\n"
- "silently\r\n", NULL, do_event_text, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** V M C O M M A N D S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static int
-do_avd_stop( ControlClient client, char* args )
-{
- if (!vm_running) {
- control_write( client, "KO: virtual device already stopped\r\n" );
- return -1;
- }
- vm_stop(EXCP_INTERRUPT);
- return 0;
-}
-
-static int
-do_avd_start( ControlClient client, char* args )
-{
- if (vm_running) {
- control_write( client, "KO: virtual device already running\r\n" );
- return -1;
- }
- vm_start();
- return 0;
-}
-
-static int
-do_avd_status( ControlClient client, char* args )
-{
- control_write( client, "virtual device is %s\r\n", vm_running ? "running" : "stopped" );
- return 0;
-}
-
-static int
-do_avd_name( ControlClient client, char* args )
-{
- control_write( client, "%s\r\n", avdInfo_getName(android_avdInfo) );
- return 0;
-}
-
-static const CommandDefRec vm_commands[] =
-{
- { "stop", "stop the virtual device",
- "'avd stop' stops the virtual device immediately, use 'avd start' to continue execution\r\n",
- NULL, do_avd_stop, NULL },
-
- { "start", "start/restart the virtual device",
- "'avd start' will start or continue the virtual device, use 'avd stop' to stop it\r\n",
- NULL, do_avd_start, NULL },
-
- { "status", "query virtual device status",
- "'avd status' will indicate wether the virtual device is running or not\r\n",
- NULL, do_avd_status, NULL },
-
- { "name", "query virtual device name",
- "'avd name' will return the name of this virtual device\r\n",
- NULL, do_avd_name, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** G E O C O M M A N D S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static int
-do_geo_nmea( ControlClient client, char* args )
-{
- if (!args) {
- control_write( client, "KO: NMEA sentence missing, try 'help geo nmea'\r\n" );
- return -1;
- }
- if (!android_gps_cs) {
- control_write( client, "KO: no GPS emulation in this virtual device\r\n" );
- return -1;
- }
- android_gps_send_nmea( args );
- return 0;
-}
-
-static int
-do_geo_fix( ControlClient client, char* args )
-{
-#define MAX_GEO_PARAMS 3
- char* p = args;
- int n_params = 0;
- double params[ MAX_GEO_PARAMS ];
-
- static int last_time = 0;
- static double last_altitude = 0.;
-
- if (!p)
- p = "";
-
- /* tokenize */
- while (*p) {
- char* end;
- double val = strtod( p, &end );
-
- if (end == p) {
- control_write( client, "KO: argument '%s' is not a number\n", p );
- return -1;
- }
-
- params[n_params++] = val;
- if (n_params >= MAX_GEO_PARAMS)
- break;
-
- p = end;
- while (*p && (p[0] == ' ' || p[0] == '\t'))
- p += 1;
- }
-
- /* sanity check */
- if (n_params < 2) {
- control_write( client, "KO: not enough arguments: see 'help geo fix' for details\r\n" );
- return -1;
- }
-
- /* generate an NMEA sentence for this fix */
- {
- STRALLOC_DEFINE(s);
- double val;
- int deg, min;
- char hemi;
-
- /* first, the time */
- stralloc_add_format( s, "$GPGGA,%06d", last_time );
- last_time ++;
-
- /* then the latitude */
- hemi = 'N';
- val = params[1];
- if (val < 0) {
- hemi = 'S';
- val = -val;
- }
- deg = (int) val;
- min = 60*(val - deg);
- val = val - min/60.;
- stralloc_add_format( s, ",%02d%02d.%04d,%c", deg, min, (int)(val * 10000), hemi );
-
- /* the longitude */
- hemi = 'E';
- val = params[0];
- if (val < 0) {
- hemi = 'W';
- val = -val;
- }
- deg = (int) val;
- min = 60*(val - deg);
- val = val - min/60.;
- stralloc_add_format( s, ",%02d%02d.%04d,%c", deg, min, (int)(val * 10000), hemi );
-
- /* bogus fix quality, empty satellite count and dilutions */
- stralloc_add_str( s, ",1,,,," );
-
- /* optional altitude */
- if (n_params >= 3) {
- stralloc_add_format( s, "%.1g", params[2] );
- last_altitude = params[2];
- } else {
- stralloc_add_str( s, "," );
- }
- /* bogus rest and checksum */
- stralloc_add_str( s, ",,,*47" );
-
- /* send it, then free */
- android_gps_send_nmea( stralloc_cstr(s) );
- stralloc_reset( s );
- }
- return 0;
-}
-
-static const CommandDefRec geo_commands[] =
-{
- { "nmea", "send an GPS NMEA sentence",
- "'geo nema <sentence>' sends a NMEA 0183 sentence to the emulated device, as\r\n"
- "if it came from an emulated GPS modem. <sentence> must begin with '$GP'. only\r\n"
- "'$GPGGA' and '$GPRCM' sentences are supported at the moment.\r\n",
- NULL, do_geo_nmea, NULL },
-
- { "fix", "send a simple GPS fix",
- "'geo fix <longitude> <latitude> [<altitude>]' allows you to send a\r\n"
- "simple GPS fix to the emulated system. the parameters are:\r\n\r\n"
- " <longitude> longitude, in decimal degrees\r\n"
- " <latitude> latitude, in decimal degrees\r\n"
- " <altitude> optional altitude in meters\r\n"
- "\r\n",
- NULL, do_geo_fix, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** M A I N C O M M A N D S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-extern void android_emulator_set_window_scale( double, int );
-
-static int
-do_window_scale( ControlClient client, char* args )
-{
- double scale;
- int is_dpi = 0;
- char* end;
-
- if (!args) {
- control_write( client, "KO: argument missing, try 'window scale <scale>'\r\n" );
- return -1;
- }
-
- scale = strtol( args, &end, 10 );
- if (end > args && !memcmp( end, "dpi", 4 )) {
- is_dpi = 1;
- }
- else {
- scale = strtod( args, &end );
- if (end == args || end[0]) {
- control_write( client, "KO: argument <scale> must be a real number, or an integer followed by 'dpi'\r\n" );
- return -1;
- }
- }
-
- android_emulator_set_window_scale( scale, is_dpi );
- return 0;
-}
-
-static const CommandDefRec window_commands[] =
-{
- { "scale", "change the window scale",
- "'window scale <scale>' allows you to change the scale of the emulator window at runtime\r\n"
- "<scale> must be either a real number between 0.1 and 3.0, or an integer followed by\r\n"
- "the 'dpi' prefix (as in '120dpi')\r\n",
- NULL, do_window_scale, NULL },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-/********************************************************************************************/
-/********************************************************************************************/
-/***** ******/
-/***** M A I N C O M M A N D S ******/
-/***** ******/
-/********************************************************************************************/
-/********************************************************************************************/
-
-static int
-do_kill( ControlClient client, char* args )
-{
- control_write( client, "OK: killing emulator, bye bye\r\n" );
- exit(0);
-}
-
-static const CommandDefRec main_commands[] =
-{
- { "help|h|?", "print a list of commands", NULL, NULL, do_help, NULL },
-
- { "event", "simulate hardware events",
- "allows you to send fake hardware events to the kernel\r\n", NULL,
- NULL, event_commands },
-
- { "geo", "Geo-location commands",
- "allows you to change Geo-related settings, or to send GPS NMEA sentences\r\n", NULL,
- NULL, geo_commands },
-
- { "gsm", "GSM related commands",
- "allows you to change GSM-related settings, or to make a new inbound phone call\r\n", NULL,
- NULL, gsm_commands },
-
- { "kill", "kill the emulator instance", NULL, NULL,
- do_kill, NULL },
-
- { "network", "manage network settings",
- "allows you to manage the settings related to the network data connection of the\r\n"
- "emulated device.\r\n", NULL,
- NULL, network_commands },
-
- { "power", "power related commands",
- "allows to change battery and AC power status\r\n", NULL,
- NULL, power_commands },
-
- { "quit|exit", "quit control session", NULL, NULL,
- do_quit, NULL },
-
- { "redir", "manage port redirections",
- "allows you to add, list and remove UDP and/or PORT redirection from the host to the device\r\n"
- "as an example, 'redir tcp:5000:6000' will route any packet sent to the host's TCP port 5000\r\n"
- "to TCP port 6000 of the emulated device\r\n", NULL,
- NULL, redir_commands },
-
- { "sms", "SMS related commands",
- "allows you to simulate an inbound SMS\r\n", NULL,
- NULL, sms_commands },
-
- { "avd", "manager virtual device state",
- "allows to change (e.g. start/stop) the virtual device state\r\n", NULL,
- NULL, vm_commands },
-
- { "window", "manage emulator window",
- "allows you to modify the emulator window\r\n", NULL,
- NULL, window_commands },
-
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-static ControlGlobalRec _g_global;
-
-int
-control_console_start( int port )
-{
- return control_global_init( &_g_global, port );
-}
diff --git a/android/globals.h b/android/globals.h
deleted file mode 100644
index b26663d..0000000
--- a/android/globals.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_GLOBALS_H
-#define _ANDROID_GLOBALS_H
-
-#include "android/avd/info.h"
-#include "android/avd/hw-config.h"
-
-/* this structure is setup when loading the virtual device
- * after that, you can read the 'flags' field to determine
- * wether a data or cache wipe has been in effect.
- */
-extern AvdInfoParams android_avdParams[1];
-
-/* a pointer to the android virtual device information
- * object, which can be queried for the paths of various
- * image files or the skin
- */
-extern AvdInfo* android_avdInfo;
-
-/* the hardware configuration for this specific virtual device */
-extern AndroidHwConfig android_hw[1];
-
-#endif /* _ANDROID_GLOBALS_H */
diff --git a/android/gps.c b/android/gps.c
deleted file mode 100644
index be68cfc..0000000
--- a/android/gps.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/gps.h"
-#include "android/utils/debug.h"
-#include "qemu-char.h"
-
-CharDriverState* android_gps_cs;
-
-#define D(...) VERBOSE_PRINT(gps,__VA_ARGS__)
-
-void
-android_gps_send_nmea( const char* sentence )
-{
- if (sentence == NULL)
- return;
-
- D("sending '%s'", sentence);
-
- if (android_gps_cs == NULL) {
- D("missing GPS channel, ignored");
- return;
- }
-
- qemu_chr_write( android_gps_cs, (const void*)sentence, strlen(sentence) );
- qemu_chr_write( android_gps_cs, (const void*)"\n", 1 );
-}
-
-
diff --git a/android/gps.h b/android/gps.h
deleted file mode 100644
index 33ecece..0000000
--- a/android/gps.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_gps_h
-#define _android_gps_h
-
-#include "qemu-common.h"
-
-/* this is the internal character driver used to communicate with the
- * emulated GPS unit. see qemu_chr_open() in vl.c */
-extern CharDriverState* android_gps_cs;
-
-extern void android_gps_send_nmea( const char* sentence );
-
-#endif /* _android_gps_h */
diff --git a/android/help.c b/android/help.c
deleted file mode 100644
index cd1b827..0000000
--- a/android/help.c
+++ /dev/null
@@ -1,1432 +0,0 @@
-#include "android/help.h"
-#include "android/cmdline-option.h"
-#include "android/utils/path.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-#include "android/utils/misc.h"
-#include "android/skin/keyset.h"
-#include "android/android.h"
-#include <stdint.h>
-#include "audio/audio.h"
-#include <string.h>
-#include <stdlib.h>
-
-/* XXX: TODO: put most of the help stuff in auto-generated files */
-
-#define PRINTF(...) stralloc_add_format(out,__VA_ARGS__)
-
-static void
-help_virtual_device( stralloc_t* out )
-{
- PRINTF(
- " An Android Virtual Device (AVD) models a single virtual\n"
- " device running the Android platform that has, at least, its own\n"
- " kernel, system image and data partition.\n\n"
-
- " Only one emulator process can run a given AVD at a time, but\n"
- " you can create several AVDs and run them concurrently.\n\n"
-
- " You can invoke a given AVD at startup using either '-avd <name>'\n"
- " or '@<name>', both forms being equivalent. For example, to launch\n"
- " the AVD named 'foo', type:\n\n"
-
- " emulator @foo\n\n"
-
- " The 'android' helper tool can be used to manage virtual devices.\n"
- " For example:\n\n"
-
- " android avd -- creates a new virtual device.\n"
- " android list -- list all virtual devices available.\n\n"
-
- " Each AVD really corresponds to a content directory which stores\n"
- " persistent and writable disk images as well as configuration files.\n"
-
- " Each AVD must be created against an existing SDK platform or add-on.\n"
- " For more information on this topic, see -help-sdk-images.\n\n"
-
- " SPECIAL NOTE: in the case where you are *not* using the emulator\n"
- " with the Android SDK, but with the Android build system, you will\n"
- " need to define the ANDROID_PRODUCT_OUT variable in your environment.\n"
- " See -help-build-images for the details.\n"
- );
-}
-
-
-static void
-help_sdk_images( stralloc_t* out )
-{
- PRINTF(
- " The Android SDK now supports multiple versions of the Android platform.\n"
- " Each SDK 'platform' corresponds to:\n\n"
-
- " - a given version of the Android API.\n"
- " - a set of corresponding system image files.\n"
- " - build and configuration properties.\n"
- " - an android.jar file used when building your application.\n"
- " - skins.\n\n"
-
- " The Android SDK also supports the concept of 'add-ons'. Each add-on is\n"
- " based on an existing platform, and provides replacement or additional\n"
- " image files, android.jar, hardware configuration options and/or skins.\n\n"
-
- " The purpose of add-ons is to allow vendors to provide their own customized\n"
- " system images and APIs without needing to package a complete SDK.\n\n"
-
- " Before using the SDK, you need to create an Android Virtual Device (AVD)\n"
- " (see -help-virtual-device for details). Each AVD is created in reference\n"
- " to a given SDK platform *or* add-on, and will search the corresponding\n"
- " directories for system image files, in the following order:\n\n"
-
- " - in the AVD's content directory.\n"
- " - in the AVD's SDK add-on directory, if any.\n"
- " - in the AVD's SDK platform directory, if any.\n\n"
-
- " The image files are documented in -help-disk-images. By default, an AVD\n"
- " content directory will contain the following persistent image files:\n\n"
-
- " userdata-qemu.img - the /data partition image file\n"
- " cache.img - the /cache partition image file\n\n"
-
- " You can use -wipe-data to re-initialize the /data partition to its factory\n"
- " defaults. This will erase all user settings for the virtual device.\n\n"
- );
-}
-
-static void
-help_build_images( stralloc_t* out )
-{
- PRINTF(
- " The emulator detects that you are working from the Android build system\n"
- " by looking at the ANDROID_PRODUCT_OUT variable in your environment.\n\n"
-
- " If it is defined, it should point to the product-specific directory that\n"
- " contains the generated system images.\n"
-
- " In this case, the emulator will look by default for the following image\n"
- " files there:\n\n"
-
- " - system.img : the *initial* system image.\n"
- " - ramdisk.img : the ramdisk image used to boot the system.\n"
- " - userdata.img : the *initial* user data image (see below).\n"
- " - kernel-qemu : the emulator-specific Linux kernel image.\n\n"
-
- " If the kernel image is not found in the out directory, then it is searched\n"
- " in <build-root>/prebuilt/android-arm/kernel/.\n\n"
-
- " Skins will be looked in <build-root>/development/emulator/skins/\n\n"
-
- " You can use the -system, -image, -kernel, -ramdisk, -datadir, -data options\n"
- " to specify different search directories or specific image files. You can\n"
- " also use the -cache and -sdcard options to indicate specific cache partition\n"
- " and SD Card image files.\n\n"
-
- " For more details, see the corresponding -help-<option> section.\n\n"
-
- " Note that the following behaviour is specific to 'build mode':\n\n"
-
- " - the *initial* system image is copied to a temporary file which is\n"
- " automatically removed when the emulator exits. There is thus no way to\n"
- " make persistent changes to this image through the emulator, even if\n"
- " you use the '-image <file>' option.\n\n"
-
- " - unless you use the '-cache <file>' option, the cache partition image\n"
- " is backed by a temporary file that is initially empty and destroyed on\n"
- " program exit.\n\n"
-
- " SPECIAL NOTE: If you are using the emulator with the Android SDK, the\n"
- " information above doesn't apply. See -help-sdk-images for more details.\n"
- );
-}
-
-static void
-help_disk_images( stralloc_t* out )
-{
- char datadir[256];
-
- bufprint_config_path( datadir, datadir + sizeof(datadir) );
-
- PRINTF(
- " The emulator needs several key image files to run appropriately.\n"
- " Their exact location depends on whether you're using the emulator\n"
- " from the Android SDK, or not (more details below).\n\n"
-
- " The minimal required image files are the following:\n\n"
-
- " kernel-qemu the emulator-specific Linux kernel image\n"
- " ramdisk.img the ramdisk image used to boot the system\n"
- " system.img the *initial* system image\n"
- " userdata.img the *initial* data partition image\n\n"
-
- " It will also use the following writable image files:\n\n"
-
- " userdata-qemu.img the persistent data partition image\n"
- " cache.img an *optional* cache partition image\n"
- " sdcard.img an *optional* SD Card partition image\n\n"
-
- " If you use a virtual device, its content directory should store\n"
- " all writable images, and read-only ones will be found from the\n"
- " corresponding platform/add-on directories. See -help-sdk-images\n"
- " for more details.\n\n"
-
- " If you are building from the Android build system, you should\n"
- " have ANDROID_PRODUCT_OUT defined in your environment, and the\n"
- " emulator shall be able to pick-up the right image files automatically.\n"
- " See -help-build-images for more details.\n\n"
-
- " If you're neither using the SDK or the Android build system, you\n"
- " can still run the emulator by explicitely providing the paths to\n"
- " *all* required disk images through a combination of the following\n"
- " options: -system, -kernel, -ramdisk, -image, -datadir, -data, -cache\n"
- " and -sdcard\n\n"
-
- " The actual logic being that the emulator should be able to find all\n"
- " images from the options you give it.\n\n"
-
- " For more detail, see the corresponding -help-<option> entry.\n\n"
-
- " Other related options are:\n\n"
-
- " -initdata Specify an alernative *initial* user data image\n\n"
-
- " -wipe-data Copy the content of the *initial* user data image\n"
- " (userdata.img) into the writable one (userdata-qemu.img)\n\n"
-
- " -nocache do not use a cache partition, even if one is\n"
- " available.\n\n"
- ,
- datadir );
-}
-
-static void
-help_keys(stralloc_t* out)
-{
- int pass, maxw = 0;
-
- stralloc_add_str( out, " When running the emulator, use the following keypresses:\n\n");
-
- if (!android_keyset)
- android_keyset = skin_keyset_new_from_text( skin_keyset_get_default() );
-
- for (pass = 0; pass < 2; pass++) {
- SkinKeyCommand cmd;
-
- for (cmd = SKIN_KEY_COMMAND_NONE+1; cmd < SKIN_KEY_COMMAND_MAX; cmd++)
- {
- SkinKeyBinding bindings[ SKIN_KEY_COMMAND_MAX_BINDINGS ];
- int n, count, len;
- char temp[32], *p = temp, *end = p + sizeof(temp);
-
- count = skin_keyset_get_bindings( android_keyset, cmd, bindings );
- if (count <= 0)
- continue;
-
- for (n = 0; n < count; n++) {
- p = bufprint(p, end, "%s%s", (n == 0) ? "" : ", ",
- skin_key_symmod_to_str( bindings[n].sym, bindings[n].mod ) );
- }
-
- if (pass == 0) {
- len = strlen(temp);
- if (len > maxw)
- maxw = len;
- } else {
- PRINTF( " %-*s %s\n", maxw, temp, skin_key_command_description(cmd) );
- }
- }
- }
- PRINTF( "\n" );
- PRINTF( " note that NumLock must be deactivated for keypad keys to work\n\n" );
-}
-
-
-static void
-help_environment(stralloc_t* out)
-{
- PRINTF(
- " The Android emulator looks at various environment variables when it starts:\n\n"
-
- " If ANDROID_LOG_TAGS is defined, it will be used as in '-logcat <tags>'.\n\n"
-
- " If 'http_proxy' is defined, it will be used as in '-http-proxy <proxy>'.\n\n"
-
- " If ANDROID_VERBOSE is defined, it can contain a comma-separated list of\n"
- " verbose items. for example:\n\n"
-
- " ANDROID_VERBOSE=socket,radio\n\n"
-
- " is equivalent to using the '-verbose -verbose-socket -verbose-radio'\n"
- " options together. unsupported items will be ignored.\n\n"
-
- " If ANDROID_LOG_TAGS is defined, it will be used as in '-logcat <tags>'.\n\n"
-
- " If ANDROID_SDK_HOME is defined, it indicates the path of the '.android'\n"
- " directory which contains the SDK user data (Android Virtual Devices,\n"
- " DDMS preferences, key stores, etc.).\n\n"
-
- " If ANDROID_SDK_ROOT is defined, it indicates the path of the SDK\n"
- " installation directory.\n\n"
-
- );
-}
-
-
-static void
-help_keyset_file(stralloc_t* out)
-{
- int n, count;
- const char** strings;
- char temp[MAX_PATH];
-
- PRINTF(
- " on startup, the emulator looks for 'keyset' file that contains the\n"
- " configuration of key-bindings to use. the default location on this\n"
- " system is:\n\n"
- );
-
- bufprint_config_file( temp, temp+sizeof(temp), KEYSET_FILE );
- PRINTF( " %s\n\n", temp );
-
- PRINTF(
- " if the file doesn't exist, the emulator writes one containing factory\n"
- " defaults. you are then free to modify it to suit specific needs.\n\n"
- " this file shall contain a list of text lines in the following format:\n\n"
-
- " <command> [<modifiers>]<key>\n\n"
-
- " where <command> is an emulator-specific command name, i.e. one of:\n\n"
- );
-
- count = SKIN_KEY_COMMAND_MAX-1;
- strings = calloc( count, sizeof(char*) );
- for (n = 0; n < count; n++)
- strings[n] = skin_key_command_to_str(n+1);
-
- stralloc_tabular( out, strings, count, " ", 80-8 );
- free(strings);
-
- PRINTF(
- "\n"
- " <modifers> is an optional list of <modifier> elements (without separators)\n"
- " which can be one of:\n\n"
-
- " Ctrl- Left Control Key\n"
- " Shift- Left Shift Key\n"
- " Alt- Left Alt key\n"
- " RCtrl- Right Control Key\n"
- " RShift- Right Shift Key\n"
- " RAlt- Right Alt key (a.k.a AltGr)\n"
- "\n"
- " finally <key> is a QWERTY-specific keyboard symbol which can be one of:\n\n"
- );
- count = skin_keysym_str_count();
- strings = calloc( count, sizeof(char*) );
- for (n = 0; n < count; n++)
- strings[n] = skin_keysym_str(n);
-
- stralloc_tabular( out, strings, count, " ", 80-8 );
- free(strings);
-
- PRINTF(
- "\n"
- " case is not significant, and a single command can be associated to up\n"
- " to %d different keys. to bind a command to multiple keys, use commas to\n"
- " separate them. here are some examples:\n\n",
- SKIN_KEY_COMMAND_MAX_BINDINGS );
-
- PRINTF(
- " TOGGLE_NETWORK F8 # toggle the network on/off\n"
- " CHANGE_LAYOUT_PREV Keypad_7,Ctrl-J # switch to a previous skin layout\n"
- "\n"
- );
-}
-
-
-static void
-help_debug_tags(stralloc_t* out)
-{
- int n;
-
-#define _VERBOSE_TAG(x,y) { #x, VERBOSE_##x, y },
- static const struct { const char* name; int flag; const char* text; }
- verbose_options[] = {
- VERBOSE_TAG_LIST
- { 0, 0, 0 }
- };
-#undef _VERBOSE_TAG
-
- PRINTF(
- " the '-debug <tags>' option can be used to enable or disable debug\n"
- " messages from specific parts of the emulator. <tags> must be a list\n"
- " (separated by space/comma/column) of <component> names, which can be one of:\n\n"
- );
-
- for (n = 0; n < VERBOSE_MAX; n++)
- PRINTF( " %-12s %s\n", verbose_options[n].name, verbose_options[n].text );
- PRINTF( " %-12s %s\n", "all", "all components together\n" );
-
- PRINTF(
- "\n"
- " each <component> can be prefixed with a single '-' to indicate the disabling\n"
- " of its debug messages. for example:\n\n"
-
- " -debug all,-socket,-keys\n\n"
-
- " enables all debug messages, except the ones related to network sockets\n"
- " and key bindings/presses\n\n"
- );
-}
-
-static void
-help_char_devices(stralloc_t* out)
-{
- PRINTF(
- " various emulation options take a <device> specification that can be used to\n"
- " specify something to hook to an emulated device or communication channel.\n"
- " here is the list of supported <device> specifications:\n\n"
-
- " stdio\n"
- " standard input/output. this may be subject to character\n"
- " translation (e.g. LN <=> CR/LF)\n\n"
-
- " COM<n> [Windows only]\n"
- " where <n> is a digit. host serial communication port.\n\n"
-
- " pipe:<filename>\n"
- " named pipe <filename>\n\n"
-
- " file:<filename>\n"
- " write output to <filename>, no input can be read\n\n"
-
- " pty [Linux only]\n"
- " pseudo TTY (a new PTY is automatically allocated)\n\n"
-
- " /dev/<file> [Unix only]\n"
- " host char device file, e.g. /dev/ttyS0. may require root access\n\n"
-
- " /dev/parport<N> [Linux only]\n"
- " use host parallel port. may require root access\n\n"
-
- " unix:<path>[,server][,nowait]] [Unix only]\n"
- " use a Unix domain socket. if you use the 'server' option, then\n"
- " the emulator will create the socket and wait for a client to\n"
- " connect before continuing, unless you also use 'nowait'\n\n"
-
- " tcp:[<host>]:<port>[,server][,nowait][,nodelay]\n"
- " use a TCP socket. 'host' is set to localhost by default. if you\n"
- " use the 'server' option will bind the port and wait for a client\n"
- " to connect before continuing, unless you also use 'nowait'. the\n"
- " 'nodelay' option disables the TCP Nagle algorithm\n\n"
-
- " telnet:[<host>]:<port>[,server][,nowait][,nodelay]\n"
- " similar to 'tcp:' but uses the telnet protocol instead of raw TCP\n\n"
-
- " udp:[<remote_host>]:<remote_port>[@[<src_ip>]:<src_port>]\n"
- " send output to a remote UDP server. if 'remote_host' is no\n"
- " specified it will default to '0.0.0.0'. you can also receive input\n"
- " through UDP by specifying a source address after the optional '@'.\n\n"
-
- " fdpair:<fd1>,<fd2> [Unix only]\n"
- " redirection input and output to a pair of pre-opened file\n"
- " descriptors. this is mostly useful for scripts and other\n"
- " programmatic launches of the emulator.\n\n"
-
- " none\n"
- " no device connected\n\n"
-
- " null\n"
- " the null device (a.k.a /dev/null on Unix, or NUL on Win32)\n\n"
-
- " NOTE: these correspond to the <device> parameter of the QEMU -serial option\n"
- " as described on http://bellard.org/qemu/qemu-doc.html#SEC10\n\n"
- );
-}
-
-static void
-help_avd(stralloc_t* out)
-{
- PRINTF(
- " use '-avd <name>' to start the emulator program with a given avd,\n"
- " where <name> must correspond to the name of one of the\n"
- " Android Virtual Devices available on your host.\n\n"
-
- " As a special convenience, using '@<name>' is equivalent to using\n"
- " '-avd <name>'.\n\n"
-
- " For more information about virtual devices, see -help-virtual-device.\n"
- );
-}
-
-static void
-help_system(stralloc_t* out)
-{
- char systemdir[MAX_PATH];
- char *p = systemdir, *end = p + sizeof(systemdir);
-
- p = bufprint_app_dir( p, end );
- p = bufprint( p, end, PATH_SEP "lib" PATH_SEP "images" );
-
- PRINTF(
- " use '-system <dir>' to specify a directory where system read-only\n"
- " image files will be searched. on this system, the default directory is:\n\n"
- " %s\n\n", systemdir );
-
- PRINTF(
- " see '-help-disk-images' for more information about disk image files\n\n" );
-}
-
-static void
-help_datadir(stralloc_t* out)
-{
- char datadir[MAX_PATH];
-
- bufprint_config_path(datadir, datadir + sizeof(datadir));
-
- PRINTF(
- " use '-datadir <dir>' to specify a directory where writable image files\n"
- " will be searched. on this system, the default directory is:\n\n"
- " %s\n\n", datadir );
-
- PRINTF(
- " see '-help-disk-images' for more information about disk image files\n\n" );
-}
-
-static void
-help_kernel(stralloc_t* out)
-{
- PRINTF(
- " use '-kernel <file>' to specify a Linux kernel image to be run.\n"
- " the default image is 'kernel-qemu' from the system directory.\n\n"
-
- " you can use '-debug-kernel' to see debug messages from the kernel\n"
- " to the terminal\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_ramdisk(stralloc_t* out)
-{
- PRINTF(
- " use '-ramdisk <file>' to specify a Linux ramdisk boot image to be run in\n"
- " the emulator. the default image is 'ramdisk.img' from the system directory.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_image(stralloc_t* out)
-{
- PRINTF(
- " use '-image <file>' to specify the intial system image that will be loaded.\n"
- " the default image is 'system.img' from the system directory.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_initdata(stralloc_t* out)
-{
- PRINTF(
- " use '-initdata <file>' to specify an *init* /data partition file.\n"
- " it is only used when creating a new writable /data image file, or\n"
- " when you use '-wipe-data' to reset it. the default is 'userdata.img'\n"
- " from the system directory.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_data(stralloc_t* out)
-{
- PRINTF(
- " use '-data <file>' to specify a different /data partition image file.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_wipe_data(stralloc_t* out)
-{
- PRINTF(
- " use '-wipe-data' to reset your /data partition image to its factory\n"
- " defaults. this removes all installed applications and settings.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_cache(stralloc_t* out)
-{
- PRINTF(
- " use '-cache <file>' to specify a /cache partition image. if <file> does\n"
- " not exist, it will be created empty. by default, the cache partition is\n"
- " backed by a temporary file that is deleted when the emulator exits.\n"
- " using the -cache option allows it to be persistent.\n\n"
-
- " the '-nocache' option can be used to disable the cache partition.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_nocache(stralloc_t* out)
-{
- PRINTF(
- " use '-nocache' to disable the cache partition in the emulated system.\n"
- " the cache partition is optional, but when available, is used by the browser\n"
- " to cache web pages and images\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_sdcard(stralloc_t* out)
-{
- PRINTF(
- " use '-sdcard <file>' to specify a SD Card image file that will be attached\n"
- " to the emulator. By default, the 'sdcard.img' file is searched in the data\n"
- " directory.\n\n"
-
- " if the file does not exist, the emulator will still start, but without an\n"
- " attached SD Card.\n\n"
-
- " see '-help-disk-images' for more information about disk image files\n\n"
- );
-}
-
-static void
-help_skindir(stralloc_t* out)
-{
- PRINTF(
- " use '-skindir <dir>' to specify a directory that will be used to search\n"
- " for emulator skins. each skin must be a subdirectory of <dir>. by default\n"
- " the emulator will look in the 'skins' sub-directory of the system directory\n\n"
-
- " the '-skin <name>' option is required when -skindir is used.\n"
- );
-}
-
-static void
-help_skin(stralloc_t* out)
-{
- PRINTF(
- " use '-skin <skin>' to specify an emulator skin, each skin corresponds to\n"
- " the visual appearance of a given device, including buttons and keyboards,\n"
- " and is stored as subdirectory <skin> of the skin root directory\n"
- " (see '-help-skindir')\n\n" );
-
- PRINTF(
- " note that <skin> can also be '<width>x<height>' (e.g. '320x480') to\n"
- " specify an exact framebuffer size, without any visual ornaments.\n\n" );
-}
-
-/* default network settings for emulator */
-#define DEFAULT_NETSPEED "full"
-#define DEFAULT_NETDELAY "none"
-
-static void
-help_shaper(stralloc_t* out)
-{
- int n;
-
- PRINTF(
- " the Android emulator supports network throttling, i.e. slower network\n"
- " bandwidth as well as higher connection latencies. this is done either through\n"
- " skin configuration, or with '-netspeed <speed>' and '-netdelay <delay>'.\n\n"
-
- " the format of -netspeed is one of the following (numbers are kbits/s):\n\n" );
-
- for (n = 0; android_netspeeds[n].name != NULL; n++) {
- PRINTF( " -netspeed %-12s %-15s (up: %.1f, down: %.1f)\n",
- android_netspeeds[n].name,
- android_netspeeds[n].display,
- android_netspeeds[n].upload/1000.,
- android_netspeeds[n].download/1000. );
- }
- PRINTF( "\n" );
- PRINTF( " -netspeed %-12s %s", "<num>", "select both upload and download speed\n");
- PRINTF( " -netspeed %-12s %s", "<up>:<down>", "select individual up and down speed\n");
-
- PRINTF( "\n The format of -netdelay is one of the following (numbers are msec):\n\n" );
- for (n = 0; android_netdelays[n].name != NULL; n++) {
- PRINTF( " -netdelay %-10s %-15s (min %d, max %d)\n",
- android_netdelays[n].name, android_netdelays[n].display,
- android_netdelays[n].min_ms, android_netdelays[n].max_ms );
- }
- PRINTF( " -netdelay %-10s %s", "<num>", "select exact latency\n");
- PRINTF( " -netdelay %-10s %s", "<min>:<max>", "select min and max latencies\n\n");
-
- PRINTF( " the emulator uses the following defaults:\n\n" );
- PRINTF( " Default network speed is '%s'\n", DEFAULT_NETSPEED);
- PRINTF( " Default network latency is '%s'\n\n", DEFAULT_NETDELAY);
-}
-
-static void
-help_http_proxy(stralloc_t* out)
-{
- PRINTF(
- " the Android emulator allows you to redirect all TCP connections through\n"
- " a HTTP/HTTPS proxy. this can be enabled by using the '-http-proxy <proxy>'\n"
- " option, or by defining the 'http_proxy' environment variable.\n\n"
-
- " <proxy> can be one of the following:\n\n"
- " http://<server>:<port>\n"
- " http://<username>:<password>@<server>:<port>\n\n"
-
- " the 'http://' prefix can be omitted. If '-http-proxy <proxy>' is not used,\n"
- " the 'http_proxy' environment variable is looked up and any value matching\n"
- " the <proxy> format will be used automatically\n\n" );
-}
-
-static void
-help_report_console(stralloc_t* out)
-{
- PRINTF(
- " the '-report-console <socket>' option can be used to report the\n"
- " automatically-assigned console port number to a remote third-party\n"
- " before starting the emulation. <socket> must be in one of these\n"
- " formats:\n\n"
-
- " tcp:<port>[,server][,max=<seconds>]\n"
- " unix:<path>[,server][,max=<seconds>]\n"
- "\n"
- " if the 'server' option is used, the emulator opens a server socket\n"
- " and waits for an incoming connection to it. by default, it will instead\n"
- " try to make a normal client connection to the socket, and, in case of\n"
- " failure, will repeat this operation every second for 10 seconds.\n"
- " the 'max=<seconds>' option can be used to modify the timeout\n\n"
-
- " when the connection is established, the emulator sends its console port\n"
- " number as text to the remote third-party, then closes the connection and\n"
- " starts the emulation as usual. *any* failure in the process described here\n"
- " will result in the emulator aborting immediately\n\n"
-
- " as an example, here's a small Unix shell script that starts the emulator in\n"
- " the background and waits for its port number with the help of the 'netcat'\n"
- " utility:\n\n"
-
- " MYPORT=5000\n"
- " emulator -no-window -report-console tcp:$MYPORT &\n"
- " CONSOLEPORT=`nc -l localhost $MYPORT`\n"
- "\n"
- );
-}
-
-static void
-help_dpi_device(stralloc_t* out)
-{
- PRINTF(
- " use '-dpi-device <dpi>' to specify the screen resolution of the emulated\n"
- " device. <dpi> must be an integer between 72 and 1000. the default is taken\n"
- " from the skin, if available, or uses the contant value %d (an average of\n"
- " several prototypes used during Android development).\n\n", DEFAULT_DEVICE_DPI );
-
- PRINTF(
- " the device resolution can also used to rescale the emulator window with\n"
- " the '-scale' option (see -help-scale)\n\n"
- );
-}
-
-static void
-help_audio(stralloc_t* out)
-{
- PRINTF(
- " the '-audio <backend>' option allows you to select a specific backend\n"
- " to be used to both play and record audio in the Android emulator.\n\n"
-
- " this is equivalent to calling both '-audio-in <backend>' and\n"
- " '-audio-out <backend>' at the same time.\n\n"
-
- " use '-help-audio-out' to see a list of valid output <backend> values.\n"
- " use '-help-audio-in' to see a list of valid input <backend> values.\n"
- " use '-audio none' to disable audio completely.\n\n"
- );
-}
-
-static void
-help_audio_out(stralloc_t* out)
-{
- int nn;
-
- PRINTF(
- " the '-audio-out <backend>' option allows you to select a specific\n"
- " backend to play audio in the Android emulator. this is mostly useful\n"
- " on Linux\n\n"
-
- " on this system, output <backend> can be one of the following:\n\n"
- );
- for ( nn = 0; ; nn++ ) {
- const char* descr;
- const char* name = audio_get_backend_name( 0, nn, &descr );
- if (name == NULL)
- break;
- PRINTF( " %-10s %s\n", name, descr );
- }
- PRINTF( "\n" );
-}
-
-static void
-help_audio_in(stralloc_t* out)
-{
- int nn;
-
- PRINTF(
- " the '-audio-in <backend>' option allows you to select a specific\n"
- " backend to play audio in the Android emulator. this is mostly useful\n"
- " on Linux\n\n"
-
- " IMPORTANT NOTE:\n"
- " on some Linux systems, broken Esd/ALSA/driver implementations will\n"
- " make your emulator freeze and become totally unresponsive when\n"
- " using audio recording. the only way to avoid this is to use\n"
- " '-audio-in none' to disable it\n\n"
-
- " on this system, input <backend> can be one of:\n\n"
- );
- for ( nn = 0; ; nn++ ) {
- const char* descr;
- const char* name = audio_get_backend_name( 1, nn, &descr );
- if (name == NULL)
- break;
- PRINTF( " %-10s %s\n", name, descr );
- }
- PRINTF( "\n" );
-}
-
-
-static void
-help_scale(stralloc_t* out)
-{
- PRINTF(
- " the '-scale <scale>' option is used to scale the emulator window to\n"
- " something that better fits the physical dimensions of a real device. this\n"
- " can be *very* useful to check that your UI isn't too small to be usable\n"
- " on a real device.\n\n"
-
- " there are three supported formats for <scale>:\n\n"
-
- " * if <scale> is a real number (between 0.1 and 3.0) it is used as a\n"
- " scaling factor for the emulator's window.\n\n"
-
- " * if <scale> is an integer followed by the suffix 'dpi' (e.g. '110dpi'),\n"
- " then it is interpreted as the resolution of your monitor screen. this\n"
- " will be divided by the emulated device's resolution to get an absolute\n"
- " scale. (see -help-dpi-device for details).\n\n"
-
- " * finally, if <scale> is the keyword 'auto', the emulator tries to guess\n"
- " your monitor's resolution and automatically adjusts its window\n"
- " accordingly\n\n"
-
- " NOTE: this process is *very* unreliable, depending on your OS, video\n"
- " driver issues and other random system parameters\n\n"
-
- " the emulator's scale can be changed anytime at runtime through the control\n"
- " console. see the help for the 'window scale' command for details\n\n" );
-}
-
-static void
-help_trace(stralloc_t* out)
-{
- PRINTF(
- " use '-trace <name>' to start the emulator with runtime code profiling support\n"
- " profiling itself will not be enabled unless you press F9 to activate it, or\n"
- " the executed code turns it on programmatically.\n\n"
-
- " trace information is stored in directory <name>, several files are created\n"
- " there, that can later be used with the 'traceview' program that comes with\n"
- " the Android SDK for analysis.\n\n"
-
- " note that execution will be slightly slower when enabling code profiling,\n"
- " this is a necessary requirement of the operations being performed to record\n"
- " the execution trace. this slowdown should not affect your system until you\n"
- " enable the profiling though...\n\n"
- );
-}
-
-static void
-help_show_kernel(stralloc_t* out)
-{
- PRINTF(
- " use '-show-kernel' to redirect debug messages from the kernel to the current\n"
- " terminal. this is useful to check that the boot process works correctly.\n\n"
- );
-}
-
-static void
-help_shell(stralloc_t* out)
-{
- PRINTF(
- " use '-shell' to create a root shell console on the current terminal.\n"
- " this is unlike the 'adb shell' command for the following reasons:\n\n"
-
- " * this is a *root* shell that allows you to modify many parts of the system\n"
- " * this works even if the ADB daemon in the emulated system is broken\n"
- " * pressing Ctrl-C will stop the emulator, instead of the shell.\n\n"
- " See also '-shell-serial'.\n\n" );
-}
-
-static void
-help_shell_serial(stralloc_t* out)
-{
- PRINTF(
- " use '-shell-serial <device>' instead of '-shell' to open a root shell\n"
- " to the emulated system, while specifying an external communication\n"
- " channel / host device.\n\n"
-
- " '-shell-serial stdio' is identical to '-shell', while you can use\n"
- " '-shell-serial tcp::4444,server,nowait' to talk to the shell over local\n"
- " TCP port 4444. '-shell-serial fdpair:3:6' would let a parent process\n"
- " talk to the shell using fds 3 and 6.\n\n"
-
- " see -help-char-devices for a list of available <device> specifications.\n\n"
- " NOTE: you can have only one shell per emulator instance at the moment\n\n"
- );
-}
-
-static void
-help_logcat(stralloc_t* out)
-{
- PRINTF(
- " use '-logcat <tags>' to redirect log messages from the emulated system to\n"
- " the current terminal. <tags> is a list of space/comma-separated log filters\n"
- " where each filter has the following format:\n\n"
-
- " <componentName>:<logLevel>\n\n"
-
- " where <componentName> is either '*' or the name of a given component,\n"
- " and <logLevel> is one of the following letters:\n\n"
-
- " v verbose level\n"
- " d debug level\n"
- " i informative log level\n"
- " w warning log level\n"
- " e error log level\n"
- " s silent log level\n\n"
-
- " for example, the following only displays messages from the 'GSM' component\n"
- " that are at least at the informative level:\n\n"
-
- " -logcat '*:s GSM:i'\n\n"
-
- " if '-logcat <tags>' is not used, the emulator looks for ANDROID_LOG_TAGS\n"
- " in the environment. if it is defined, its value must match the <tags>\n"
- " format and will be used to redirect log messages to the terminal.\n\n"
-
- " note that this doesn't prevent you from redirecting the same, or other,\n"
- " log messages through the ADB or DDMS tools too.\n\n");
-}
-
-static void
-help_noaudio(stralloc_t* out)
-{
- PRINTF(
- " use '-noaudio' to disable all audio support in the emulator. this may be\n"
- " unfortunately be necessary in some cases:\n\n"
-
- " * at least two users have reported that their Windows machine rebooted\n"
- " instantly unless they used this option when starting the emulator.\n"
- " it is very likely that the problem comes from buggy audio drivers.\n\n"
-
- " * on some Linux machines, the emulator might get stuck at startup with\n"
- " audio support enabled. this problem is hard to reproduce, but seems to\n"
- " be related too to flaky ALSA / audio driver support.\n\n"
-
- " on Linux, another option is to try to change the default audio backend\n"
- " used by the emulator. you can do that by setting the QEMU_AUDIO_DRV\n"
- " environment variables to one of the following values:\n\n"
-
- " alsa (use the ALSA backend)\n"
- " esd (use the EsounD backend)\n"
- " sdl (use the SDL audio backend, no audio input supported)\n"
- " oss (use the OSS backend)\n"
- " none (do not support audio)\n"
- "\n"
- " the very brave can also try to use distinct backends for audio input\n"
- " and audio outputs, this is possible by selecting one of the above values\n"
- " into the QEMU_AUDIO_OUT_DRV and QEMU_AUDIO_IN_DRV environment variables.\n\n"
- );
-}
-
-static void
-help_raw_keys(stralloc_t* out)
-{
- PRINTF(
- " this option is deprecated because one can do the same using Ctrl-K\n"
- " at runtime (this keypress toggles between unicode/raw keyboard modes)\n\n"
-
- " by default, the emulator tries to reverse-map the characters you type on\n"
- " your keyboard to device-specific key presses whenever possible. this is\n"
- " done to make the emulator usable with a non-QWERTY keyboard.\n\n"
-
- " however, this also means that single keypresses like Shift or Alt are not\n"
- " passed to the emulated device. the '-raw-keys' option disables the reverse\n"
- " mapping. it should only be used when using a QWERTY keyboard on your machine\n"
-
- " (should only be useful to Android system hackers, e.g. when implementing a\n"
- " new input method).\n\n"
- );
-}
-
-static void
-help_radio(stralloc_t* out)
-{
- PRINTF(
- " use '-radio <device>' to redirect the GSM modem emulation to an external\n"
- " character device or program. this bypasses the emulator's internal modem\n"
- " and should only be used for testing.\n\n"
-
- " see '-help-char-devices' for the format of <device>\n\n"
-
- " the data exchanged with the external device/program are GSM AT commands\n\n"
-
- " note that, when running in the emulator, the Android GSM stack only supports\n"
- " a *very* basic subset of the GSM protocol. trying to link the emulator to\n"
- " a real GSM modem is very likely to not work properly.\n\n"
- );
-}
-
-
-static void
-help_port(stralloc_t* out)
-{
- PRINTF(
- " at startup, the emulator tries to bind its control console at a free port\n"
- " starting from 5554, in increments of two (i.e. 5554, then 5556, 5558, etc..)\n"
- " this allows several emulator instances to run concurrently on the same\n"
- " machine, each one using a different console port number.\n\n"
-
- " use '-port <port>' to force an emulator instance to use a given console port\n\n"
-
- " note that <port> must be an *even* integer between 5554 and 5584 included.\n"
- " <port>+1 must also be free and will be reserved for ADB. if any of these\n"
- " ports is already used, the emulator will fail to start.\n\n" );
-}
-
-static void
-help_ports(stralloc_t* out)
-{
- PRINTF(
- " the '-ports <consoleport>,<adbport>' option allows you to explicitely set\n"
- " the TCP ports used by the emulator to implement its control console and\n"
- " communicate with the ADB tool.\n\n"
-
- " This is a very special option that should probably *not* be used by typical\n"
- " developers using the Android SDK (use '-port <port>' instead), because the\n"
- " corresponding instance is probably not going to be seen from adb/DDMS. Its\n"
- " purpose is to use the emulator in very specific network configurations.\n\n"
-
- " <consoleport> is the TCP port used to bind the control console\n"
- " <adbport> is the TCP port used to bind the ADB local transport/tunnel.\n\n"
-
- " If both ports aren't available on startup, the emulator will exit.\n\n");
-}
-
-
-static void
-help_onion(stralloc_t* out)
-{
- PRINTF(
- " use '-onion <file>' to specify a PNG image file that will be displayed on\n"
- " top of the emulated framebuffer with translucency. this can be useful to\n"
- " check that UI elements are correctly positioned with regards to a reference\n"
- " graphics specification.\n\n"
-
- " the default translucency is 50%%, but you can use '-onion-alpha <%%age>' to\n"
- " select a different one, or even use keypresses at runtime to alter it\n"
- " (see -help-keys for details)\n\n"
-
- " finally, the onion image can be rotated (see -help-onion-rotate)\n\n"
- );
-}
-
-static void
-help_onion_alpha(stralloc_t* out)
-{
- PRINTF(
- " use '-onion-alpha <percent>' to change the translucency level of the onion\n"
- " image that is going to be displayed on top of the framebuffer (see also\n"
- " -help-onion). the default is 50%%.\n\n"
-
- " <percent> must be an integer between 0 and 100.\n\n"
-
- " you can also change the translucency dynamically (see -help-keys)\n\n"
- );
-}
-
-static void
-help_onion_rotation(stralloc_t* out)
-{
- PRINTF(
- " use '-onion-rotation <rotation>' to change the rotation of the onion\n"
- " image loaded through '-onion <file>'. valid values for <rotation> are:\n\n"
-
- " 0 no rotation\n"
- " 1 90 degrees clockwise\n"
- " 2 180 degrees\n"
- " 3 270 degrees clockwise\n\n"
- );
-}
-
-
-static void
-help_timezone(stralloc_t* out)
-{
- PRINTF(
- " by default, the emulator tries to detect your current timezone to report\n"
- " it to the emulated system. use the '-timezone <timezone>' option to choose\n"
- " a different timezone, or if the automatic detection doesn't work correctly.\n\n"
-
- " VERY IMPORTANT NOTE:\n\n"
- " the <timezone> value must be in zoneinfo format, i.e. it should look like\n"
- " Area/Location or even Area/SubArea/Location. valid examples are:\n\n"
-
- " America/Los_Angeles\n"
- " Europe/Paris\n\n"
-
- " using a human-friendly abbreviation like 'PST' or 'CET' will not work, as\n"
- " well as using values that are not defined by the zoneinfo database.\n\n"
-
- " NOTE: unfortunately, this will not work on M5 and older SDK releases\n\n"
- );
-}
-
-
-static void
-help_dns_server(stralloc_t* out)
-{
- PRINTF(
- " by default, the emulator tries to detect the DNS servers you're using and\n"
- " will setup special aliases in the emulated firewall network to allow the\n"
- " Android system to connect directly to them. use '-dns-server <servers>' to\n"
- " select a different list of DNS servers to be used.\n\n"
-
- " <servers> must be a comma-separated list of up to 4 DNS server names or\n"
- " IP addresses.\n\n"
-
- " NOTE: on M5 and older SDK releases, only the first server in the list will\n"
- " be used.\n\n"
- );
-}
-
-
-static void
-help_cpu_delay(stralloc_t* out)
-{
- PRINTF(
- " this option is purely experimental, probably doesn't work as you would\n"
- " expect, and may even disappear in a later emulator release.\n\n"
-
- " use '-cpu-delay <delay>' to throttle CPU emulation. this may be useful\n"
- " to detect weird race conditions that only happen on 'lower' CPUs. note\n"
- " that <delay> is a unit-less integer that doesn't even scale linearly\n"
- " to observable slowdowns. use trial and error to find something that\n"
- " suits you, the 'correct' machine is very probably dependent on your\n"
- " host CPU and memory anyway...\n\n"
- );
-}
-
-
-static void
-help_no_boot_anim(stralloc_t* out)
-{
- PRINTF(
- " use '-no-boot-anim' to disable the boot animation (red bouncing ball) when\n"
- " starting the emulator. on slow machines, this can surprisingly speed up the\n"
- " boot sequence in tremendous ways.\n\n"
-
- " NOTE: unfortunately, this will not work on M5 and older SDK releases\n\n"
- );
-}
-
-
-static void
-help_gps(stralloc_t* out)
-{
- PRINTF(
- " use '-gps <device>' to emulate an NMEA-compatible GPS unit connected to\n"
- " an external character device or socket. the format of <device> is the same\n"
- " than the one used for '-radio <device>' (see -help-char-devices for details)\n\n"
- );
-}
-
-
-static void
-help_keyset(stralloc_t* out)
-{
- char temp[256];
-
- PRINTF(
- " use '-keyset <name>' to specify a different keyset file name to use when\n"
- " starting the emulator. a keyset file contains a list of key bindings used\n"
- " to control the emulator with the host keyboard.\n\n"
-
- " by default, the emulator looks for the following file:\n\n"
- );
-
- bufprint_config_file(temp, temp+sizeof(temp), KEYSET_FILE);
- PRINTF(
- " %s\n\n", temp );
-
- bufprint_config_path(temp, temp+sizeof(temp));
- PRINTF(
- " however, if -keyset is used, then the emulator does the following:\n\n"
-
- " - first, if <name> doesn't have an extension, then the '.keyset' suffix\n"
- " is appended to it (e.g. \"foo\" => \"foo.keyset\"),\n\n"
-
- " - then, the emulator searches for a file named <name> in the following\n"
- " directories:\n\n"
-
- " * the emulator configuration directory: %s\n"
- " * the 'keysets' subdirectory of <systemdir>, if any\n"
- " * the 'keysets' subdirectory of the program location, if any\n\n",
- temp );
-
- PRINTF(
- " if no corresponding file is found, a default set of key bindings is used.\n\n"
- " use '-help-keys' to list the default key bindings.\n"
- " use '-help-keyset-file' to learn more about the format of keyset files.\n"
- "\n"
- );
-}
-
-static void
-help_old_system(stralloc_t* out)
-{
- PRINTF(
- " use '-old-system' if you want to use a recent emulator binary to run\n"
- " an old version of the Android SDK system images. Here, 'old' means anything\n"
- " older than version 1.4 of the emulator.\n\n"
-
- " NOTE: using '-old-system' with recent system images is likely to not work\n"
- " properly, though you may not notice it immediately (e.g. failure to\n"
- " start the emulated GPS hardware)\n\n"
- );
-}
-
-#ifdef CONFIG_NAND_LIMITS
-static void
-help_nand_limits(stralloc_t* out)
-{
- PRINTF(
- " use '-nand-limits <limits>' to enable a debugging feature that sends a\n"
- " signal to an external process once a read and/or write limit is achieved\n"
- " in the emulated system. the format of <limits> is the following:\n\n"
-
- " pid=<number>,signal=<number>,[reads=<threshold>][,writes=<threshold>]\n\n"
-
- " where 'pid' is the target process identifier, 'signal' the number of the\n"
- " target signal. the read and/or write threshold'reads' are a number optionally\n"
- " followed by a K, M or G suffix, corresponding to the number of bytes to be\n"
- " read or written before the signal is sent.\n\n"
- );
-}
-#endif /* CONFIG_NAND_LIMITS */
-
-static void
-help_bootchart(stralloc_t *out)
-{
- PRINTF(
- " some Android system images have a modified 'init' system that integrates\n"
- " a bootcharting facility (see http://www.bootchart.org/). You can pass a\n"
- " bootcharting period to the system with the following:\n\n"
-
- " -bootchart <timeout>\n\n"
-
- " where 'timeout' is a period expressed in seconds. Note that this won't do\n"
- " anything if your init doesn't have bootcharting activated.\n\n"
- );
-}
-
-static void
-help_tcpdump(stralloc_t *out)
-{
- PRINTF(
- " use the -tcpdump <file> option to start capturing all network packets\n"
- " that are sent through the emulator's virtual Ethernet LAN. You can later\n"
- " use tools like WireShark to analyze the traffic and understand what\n"
- " really happens.\n\n"
-
- " note that this captures all Ethernet packets, and is not limited to TCP\n"
- " connections.\n\n"
-
- " you can also start/stop the packet capture dynamically through the console;\n"
- " see the 'network capture start' and 'network capture stop' commands for\n"
- " details.\n\n"
- );
-}
-
-#define help_noskin NULL
-#define help_netspeed help_shaper
-#define help_netdelay help_shaper
-#define help_netfast help_shaper
-
-#define help_nojni NULL
-#define help_no_window NULL
-#define help_version NULL
-#define help_memory NULL
-
-typedef struct {
- const char* name;
- const char* template;
- const char* descr;
- void (*func)(stralloc_t*);
-} OptionHelp;
-
-static const OptionHelp option_help[] = {
-#define OPT_FLAG(_name,_descr) { STRINGIFY(_name), NULL, _descr, help_##_name },
-#define OPT_PARAM(_name,_template,_descr) { STRINGIFY(_name), _template, _descr, help_##_name },
-#include "android/cmdline-options.h"
- { NULL, NULL, NULL, NULL }
-};
-
-typedef struct {
- const char* name;
- const char* desc;
- void (*func)(stralloc_t*);
-} TopicHelp;
-
-
-static const TopicHelp topic_help[] = {
- { "disk-images", "about disk images", help_disk_images },
- { "keys", "supported key bindings", help_keys },
- { "debug-tags", "debug tags for -debug <tags>", help_debug_tags },
- { "char-devices", "character <device> specification", help_char_devices },
- { "environment", "environment variables", help_environment },
- { "keyset-file", "key bindings configuration file", help_keyset_file },
- { "virtual-device", "virtual device management", help_virtual_device },
- { "sdk-images", "about disk images when using the SDK", help_sdk_images },
- { "build-images", "about disk images when building Android", help_build_images },
- { NULL, NULL, NULL }
-};
-
-int
-android_help_for_option( const char* option, stralloc_t* out )
-{
- OptionHelp const* oo;
- char temp[32];
-
- /* the names in the option_help table use underscore instead
- * of dashes, so create a tranlated copy of the option name
- * before scanning the table for matches
- */
- buffer_translate_char( temp, sizeof temp, option, '-', '_' );
-
- for ( oo = option_help; oo->name != NULL; oo++ ) {
- if ( !strcmp(oo->name, temp) ) {
- if (oo->func)
- oo->func(out);
- else
- stralloc_add_str(out, oo->descr);
- return 0;
- }
- }
- return -1;
-}
-
-
-int
-android_help_for_topic( const char* topic, stralloc_t* out )
-{
- const TopicHelp* tt;
-
- for ( tt = topic_help; tt->name != NULL; tt++ ) {
- if ( !strcmp(tt->name, topic) ) {
- tt->func(out);
- return 0;
- }
- }
- return -1;
-}
-
-
-extern void
-android_help_list_options( stralloc_t* out )
-{
- const OptionHelp* oo;
- const TopicHelp* tt;
- int maxwidth = 0;
-
- for ( oo = option_help; oo->name != NULL; oo++ ) {
- int width = strlen(oo->name);
- if (oo->template != NULL)
- width += strlen(oo->template);
- if (width > maxwidth)
- maxwidth = width;
- }
-
- for (oo = option_help; oo->name != NULL; oo++) {
- char temp[32];
- /* the names in the option_help table use underscores instead
- * of dashes, so create a translated copy of the option's name
- */
- buffer_translate_char(temp, sizeof temp, oo->name, '_', '-');
-
- stralloc_add_format( out, " -%s %-*s %s\n",
- temp,
- (int)(maxwidth - strlen(oo->name)),
- oo->template ? oo->template : "",
- oo->descr );
- }
-
- PRINTF( "\n" );
- PRINTF( " %-*s %s\n", maxwidth, "-qemu args...", "pass arguments to qemu");
- PRINTF( " %-*s %s\n", maxwidth, "-qemu -h", "display qemu help");
- PRINTF( "\n" );
- PRINTF( " %-*s %s\n", maxwidth, "-verbose", "same as '-debug-init'");
- PRINTF( " %-*s %s\n", maxwidth, "-debug <tags>", "enable/disable debug messages");
- PRINTF( " %-*s %s\n", maxwidth, "-debug-<tag>", "enable specific debug messages");
- PRINTF( " %-*s %s\n", maxwidth, "-debug-no-<tag>","disable specific debug messages");
- PRINTF( "\n" );
- PRINTF( " %-*s %s\n", maxwidth, "-help", "print this help");
- PRINTF( " %-*s %s\n", maxwidth, "-help-<option>", "print option-specific help");
- PRINTF( "\n" );
-
- for (tt = topic_help; tt->name != NULL; tt += 1) {
- char help[32];
- snprintf(help, sizeof(help), "-help-%s", tt->name);
- PRINTF( " %-*s %s\n", maxwidth, help, tt->desc );
- }
- PRINTF( " %-*s %s\n", maxwidth, "-help-all", "prints all help content");
- PRINTF( "\n");
-}
-
-
-void
-android_help_main( stralloc_t* out )
-{
- stralloc_add_str(out, "Android Emulator usage: emulator [options] [-qemu args]\n");
- stralloc_add_str(out, " options:\n" );
-
- android_help_list_options(out);
-
- /*printf( "%.*s", out->n, out->s );*/
-}
-
-
-void
-android_help_all( stralloc_t* out )
-{
- const OptionHelp* oo;
- const TopicHelp* tt;
-
- for (oo = option_help; oo->name != NULL; oo++) {
- PRINTF( "========= help for option -%s:\n\n", oo->name );
- android_help_for_option( oo->name, out );
- }
-
- for (tt = topic_help; tt->name != NULL; tt++) {
- PRINTF( "========= help for -help-%s\n\n", tt->name );
- android_help_for_topic( tt->name, out );
- }
- PRINTF( "========= top-level help\n\n" );
- android_help_main(out);
-}
diff --git a/android/help.h b/android/help.h
deleted file mode 100644
index 94feca1..0000000
--- a/android/help.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_HELP_H
-#define _ANDROID_HELP_H
-
-#include "android/utils/stralloc.h"
-
-/* appends the list of options with a small description to a dynamic string */
-extern void android_help_list_options( stralloc_t* out );
-
-/* output main help screen into a single dynamic string */
-extern void android_help_main( stralloc_t* out );
-
-/* output all help into a single dynamic string */
-extern void android_help_all( stralloc_t* out );
-
-/* appends the help for a given command-line option into a dynamic string
- * returns 0 on success, or -1 on error (i.e. unknown option)
- */
-extern int android_help_for_option( const char* option, stralloc_t* out );
-
-/* appends the help for a given help topic into a dynamic string
- * returns 0 on success, or -1 on error (i.e. unknown topic)
- */
-extern int android_help_for_topic( const char* topic, stralloc_t* out );
-
-#endif /* _ANDROID_HELP_H */
diff --git a/android/hw-control.c b/android/hw-control.c
deleted file mode 100644
index 681e85b..0000000
--- a/android/hw-control.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-/* this file implements the support of the new 'hardware control'
- * qemud communication channel, which is used by libs/hardware on
- * the system image to communicate with the emulator program for
- * emulating the following:
- *
- * - power management
- * - led(s) brightness
- * - vibrator
- * - flashlight
- */
-#include "android/hw-control.h"
-#include "cbuffer.h"
-#include "android/qemud.h"
-#include "android/utils/misc.h"
-#include "android/utils/debug.h"
-#include "qemu-char.h"
-#include <stdio.h>
-#include <string.h>
-
-#define D(...) VERBOSE_PRINT(hw_control,__VA_ARGS__)
-
-/* define T_ACTIVE to 1 to debug transport communications */
-#define T_ACTIVE 0
-
-#if T_ACTIVE
-#define T(...) VERBOSE_PRINT(hw_control,__VA_ARGS__)
-#else
-#define T(...) ((void)0)
-#endif
-
-static void* hw_control_client;
-static AndroidHwControlFuncs hw_control_funcs;
-
-#define BUFFER_SIZE 512
-
-typedef struct {
- CharDriverState* cs;
- int overflow;
- int wanted;
- CBuffer input[1];
- char input_0[ BUFFER_SIZE ];
- /* note: 1 more byte to zero-terminate the query */
- char query[ BUFFER_SIZE+1 ];
-} HwControl;
-
-/* forward */
-static void hw_control_do_query( HwControl* h,
- uint8_t* query,
- int querylen );
-
-static void
-hw_control_init( HwControl* h, CharDriverState* cs )
-{
- h->cs = cs;
- h->overflow = 0;
- h->wanted = 0;
- cbuffer_reset( h->input, h->input_0, sizeof h->input_0 );
-}
-
-static int
-hw_control_can_read( void* _hw )
-{
- HwControl* h = _hw;
- return cbuffer_write_avail( h->input );
-}
-
-static void
-hw_control_read( void* _hw, const uint8_t* data, int len )
-{
- HwControl* h = _hw;
- CBuffer* input = h->input;
-
- T("%s: %4d '%.*s'", __FUNCTION__, len, len, data);
-
- cbuffer_write( input, data, len );
-
- while ( input->count > 0 )
- {
- /* skip over unwanted data, if any */
- while (h->overflow > 0) {
- uint8_t* dummy;
- int avail = cbuffer_read_peek( input, &dummy );
-
- if (avail == 0)
- return;
-
- if (avail > h->overflow)
- avail = h->overflow;
-
- cbuffer_read_step( input, avail );
- h->overflow -= avail;
- }
-
- /* all incoming messages are made of a 4-byte hexchar sequence giving */
- /* the length of the following payload */
- if (h->wanted == 0)
- {
- char header[4];
- int len;
-
- if (input->count < 4)
- return;
-
- cbuffer_read( input, header, 4 );
- len = hex2int( (uint8_t*)header, 4 );
- if (len >= 0) {
- /* if the message is too long, skip it */
- if (len > input->size) {
- T("%s: skipping oversized message (%d > %d)",
- __FUNCTION__, len, input->size);
- h->overflow = len;
- } else {
- T("%s: waiting for %d bytes", __FUNCTION__, len);
- h->wanted = len;
- }
- }
- }
- else
- {
- if (input->count < h->wanted)
- break;
-
- cbuffer_read( input, h->query, h->wanted );
- h->query[h->wanted] = 0;
- hw_control_do_query( h, (uint8_t*)h->query, h->wanted );
- h->wanted = 0;
- }
- }
-}
-
-
-static uint8_t*
-if_starts_with( uint8_t* buf, int buflen, const char* prefix )
-{
- int prefixlen = strlen(prefix);
-
- if (buflen < prefixlen || memcmp(buf, prefix, prefixlen))
- return NULL;
-
- return (uint8_t*)buf + prefixlen;
-}
-
-
-static void
-hw_control_do_query( HwControl* h,
- uint8_t* query,
- int querylen )
-{
- uint8_t* q;
-
- D("%s: query %4d '%.*s'", __FUNCTION__, querylen, querylen, query );
-
- q = if_starts_with( query, querylen, "power:light:brightness:" );
- if (q != NULL) {
- if (hw_control_funcs.light_brightness) {
- char* qq = strchr((const char*)q, ':');
- int value;
- if (qq == NULL) {
- D("%s: badly formatted", __FUNCTION__ );
- return;
- }
- *qq++ = 0;
- value = atoi(qq);
- hw_control_funcs.light_brightness( hw_control_client, (char*)q, value );
- }
- return;
- }
-}
-
-
-void
-android_hw_control_init( void* opaque, const AndroidHwControlFuncs* funcs )
-{
- static CharDriverState* hw_control_cs;
- static HwControl hwstate[1];
-
- if (hw_control_cs == NULL) {
- CharDriverState* cs;
- if ( android_qemud_get_channel( ANDROID_QEMUD_CONTROL, &cs ) < 0 ) {
- derror( "could not create hardware control charpipe" );
- exit(1);
- }
-
- hw_control_cs = cs;
- hw_control_init( hwstate, cs );
- qemu_chr_add_handlers( cs, hw_control_can_read, hw_control_read, NULL, hwstate );
-
- D("%s: hw-control char pipe initialized", __FUNCTION__);
- }
- hw_control_client = opaque;
- hw_control_funcs = funcs[0];
-}
diff --git a/android/hw-control.h b/android/hw-control.h
deleted file mode 100644
index 6e9874e..0000000
--- a/android/hw-control.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_hw_control_h
-#define _android_hw_control_h
-
-#include "qemu-common.h"
-
-/* a callback function called when the system wants to change the brightness
- * of a given light. 'light' is a string which can be one of:
- * 'lcd_backlight', 'button_backlight' or 'Keyboard_backlight'
- *
- * brightness is an integer (acceptable range are 0..255), however the
- * default is around 105, and we probably don't want to dim the emulator's
- * output at that level.
- */
-typedef void (*AndroidHwLightBrightnessFunc)( void* opaque,
- const char* light,
- int brightness );
-
-/* used to record a hw control 'client' */
-typedef struct {
- AndroidHwLightBrightnessFunc light_brightness;
-} AndroidHwControlFuncs;
-
-/* used to initialize the hardware control support */
-extern void android_hw_control_init( void* opaque,
- const AndroidHwControlFuncs* funcs );
-
-#endif /* _android_hw_control_h */
diff --git a/android/hw-events.c b/android/hw-events.c
deleted file mode 100644
index e72440c..0000000
--- a/android/hw-events.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/hw-events.h"
-#include "android/utils/bufprint.h"
-#include <stdlib.h>
-#include <string.h>
-
-typedef struct {
- const char* name;
- int value;
-} PairRec;
-
-#define EV_TYPE(n,v) { STRINGIFY(n), (v) },
-#define BTN_CODE(n,v) { STRINGIFY(n), (v) },
-#define REL_CODE(n,v) { STRINGIFY(n), (v) },
-#define ABS_CODE(n,v) { STRINGIFY(n), (v) },
-
-static const PairRec _ev_types_tab[] =
-{
- EVENT_TYPE_LIST
- { NULL, 0 }
-};
-
-static const PairRec _btn_codes_list[] =
-{
- EVENT_BTN_LIST
- { NULL, 0 }
-};
-
-static const PairRec _rel_codes_list[] =
-{
- EVENT_REL_LIST
- { NULL, 0 }
-};
-
-static const PairRec _abs_codes_list[] =
-{
- EVENT_ABS_LIST
- { NULL, 0 }
-};
-
-#undef EV_TYPE
-#undef BTN_CODE
-#undef REL_CODE
-#undef ABS_CODE
-
-static int
-count_list( const PairRec* list )
-{
- int nn = 0;
- while (list[nn].name != NULL)
- nn += 1;
-
- return nn;
-}
-
-static int
-scan_list( const PairRec* list,
- const char* prefix,
- const char* name,
- int namelen )
-{
- int len;
-
- if (namelen <= 0)
- return -1;
-
- len = strlen(prefix);
- if (namelen <= len)
- return -1;
- if ( memcmp( name, prefix, len ) != 0 )
- return -1;
-
- name += len;
- namelen -= len;
-
- for ( ; list->name != NULL; list += 1 )
- {
- if ( memcmp( list->name, name, namelen ) == 0 && list->name[namelen] == 0 )
- return list->value;
- }
- return -1;
-}
-
-
-typedef struct {
- int type;
- const char* prefix;
- const PairRec* pairs;
-} TypeListRec;
-
-typedef const TypeListRec* TypeList;
-
-static const TypeListRec _types_list[] =
-{
- { EV_KEY, "BTN_", _btn_codes_list },
- { EV_REL, "REL_", _rel_codes_list },
- { EV_ABS, "ABS_", _abs_codes_list },
- { -1, NULL, NULL }
-};
-
-
-static TypeList
-find_type_list( int type )
-{
- TypeList list = _types_list;
-
- for ( ; list->type >= 0; list += 1 )
- if (list->type == type)
- return list;
-
- return NULL;
-}
-
-
-int
-android_event_from_str( const char* name,
- int *ptype,
- int *pcode,
- int *pvalue )
-{
- const char* p;
- const char* pend;
- const char* q;
- TypeList list;
- char* end;
-
- *ptype = 0;
- *pcode = 0;
- *pvalue = 0;
-
- p = name;
- pend = p + strcspn(p, " \t");
- q = strchr(p, ':');
- if (q == NULL || q > pend)
- q = pend;
-
- *ptype = scan_list( _ev_types_tab, "EV_", p, q-p );
- if (*ptype < 0) {
- *ptype = (int) strtol( p, &end, 0 );
- if (end != q)
- return -1;
- }
-
- if (*q != ':')
- return 0;
-
- p = q + 1;
- q = strchr(p, ':');
- if (q == NULL || q > pend)
- q = pend;
-
- list = find_type_list( *ptype );
-
- *pcode = -1;
- if (list != NULL) {
- *pcode = scan_list( list->pairs, list->prefix, p, q-p );
- }
- if (*pcode < 0) {
- *pcode = (int) strtol( p, &end, 0 );
- if (end != q)
- return -2;
- }
-
- if (*q != ':')
- return 0;
-
- p = q + 1;
- q = strchr(p, ':');
- if (q == NULL || q > pend)
- q = pend;
-
- *pvalue = (int)strtol( p, &end, 0 );
- if (end != q)
- return -3;
-
- return 0;
-}
-
-int
-android_event_get_type_count( void )
-{
- return count_list( _ev_types_tab );
-}
-
-char*
-android_event_bufprint_type_str( char* buff, char* end, int type_index )
-{
- return bufprint( buff, end, "EV_%s", _ev_types_tab[type_index].name );
-}
-
-/* returns the list of valid event code string aliases for a given event type */
-int
-android_event_get_code_count( int type )
-{
- TypeList list = find_type_list(type);
-
- if (list == NULL)
- return 0;
-
- return count_list( list->pairs );
-}
-
-char*
-android_event_bufprint_code_str( char* buff, char* end, int type, int code_index )
-{
- TypeList list = find_type_list(type);
-
- if (list == NULL)
- return buff;
-
- return bufprint( buff, end, "%s%s", list->prefix, list->pairs[code_index].name );
-}
-
diff --git a/android/hw-events.h b/android/hw-events.h
deleted file mode 100644
index 74100b8..0000000
--- a/android/hw-events.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_HW_EVENTS_H
-#define _ANDROID_HW_EVENTS_H
-
-#include "android/utils/system.h"
-
-/* from the Linux kernel */
-
-#define EVENT_TYPE_LIST \
- EV_TYPE(SYN,0x00) \
- EV_TYPE(KEY,0x01) \
- EV_TYPE(REL,0x02) \
- EV_TYPE(ABS,0x03) \
- EV_TYPE(MSC,0x04) \
- EV_TYPE(SW, 0x05) \
- EV_TYPE(LED,0x11) \
- EV_TYPE(SND,0x12) \
- EV_TYPE(REP,0x14) \
- EV_TYPE(FF, 0x15) \
- EV_TYPE(PWR,0x16) \
- EV_TYPE(FF_STATUS,0x17) \
- EV_TYPE(MAX,0x1f)
-
-#undef EV_TYPE
-#define EV_TYPE(n,v) GLUE(EV_,n) = v,
-typedef enum {
- EVENT_TYPE_LIST
-} EventType;
-#undef EV_TYPE
-
-#define EVENT_BTN_LIST \
- BTN_CODE(MISC,0x100) \
- BTN_CODE(0,0x100) \
- BTN_CODE(1,0x101) \
- BTN_CODE(2,0x102) \
- BTN_CODE(3,0x103) \
- BTN_CODE(4,0x104) \
- BTN_CODE(5,0x105) \
- BTN_CODE(6,0x106) \
- BTN_CODE(7,0x107) \
- BTN_CODE(8,0x108) \
- BTN_CODE(9,0x109) \
- \
- BTN_CODE(MOUSE, 0x110) \
- BTN_CODE(LEFT, 0x110) \
- BTN_CODE(RIGHT, 0x111) \
- BTN_CODE(MIDDLE, 0x112) \
- BTN_CODE(SIDE, 0x113) \
- BTN_CODE(EXTRA, 0x114) \
- BTN_CODE(FORWARD,0x115) \
- BTN_CODE(BACK, 0x116) \
- BTN_CODE(TASK, 0x117) \
- \
- BTN_CODE(JOYSTICK,0x120) \
- BTN_CODE(TRIGGER, 0x120) \
- BTN_CODE(THUMB, 0x121) \
- BTN_CODE(THUMB2, 0x122) \
- BTN_CODE(TOP, 0x123) \
- BTN_CODE(TOP2, 0x124) \
- BTN_CODE(PINKIE, 0x125) \
- BTN_CODE(BASE, 0x126) \
- BTN_CODE(BASE2, 0x127) \
- BTN_CODE(BASE3, 0x128) \
- BTN_CODE(BASE4, 0x129) \
- BTN_CODE(BASE5, 0x12a) \
- BTN_CODE(BASE6, 0x12b) \
- BTN_CODE(DEAD, 0x12f) \
- \
- BTN_CODE(GAMEPAD, 0x130) \
- BTN_CODE(A, 0x130) \
- BTN_CODE(B, 0x131) \
- BTN_CODE(C, 0x132) \
- BTN_CODE(X, 0x133) \
- BTN_CODE(Y, 0x134) \
- BTN_CODE(Z, 0x135) \
- BTN_CODE(TL, 0x136) \
- BTN_CODE(TR, 0x137) \
- BTN_CODE(TL2, 0x138) \
- BTN_CODE(TR2, 0x139) \
- BTN_CODE(SELECT, 0x13a) \
- BTN_CODE(START, 0x13b) \
- BTN_CODE(MODE, 0x13c) \
- BTN_CODE(THUMBL, 0x13d) \
- BTN_CODE(THUMBR, 0x13e) \
- \
- BTN_CODE(DIGI, 0x140) \
- BTN_CODE(TOOL_PEN, 0x140) \
- BTN_CODE(TOOL_RUBBER, 0x141) \
- BTN_CODE(TOOL_BRUSH, 0x142) \
- BTN_CODE(TOOL_PENCIL, 0x143) \
- BTN_CODE(TOOL_AIRBRUSH, 0x144) \
- BTN_CODE(TOOL_FINGER, 0x145) \
- BTN_CODE(TOOL_MOUSE, 0x146) \
- BTN_CODE(TOOL_LENS, 0x147) \
- BTN_CODE(TOUCH, 0x14a) \
- BTN_CODE(STYLUS, 0x14b) \
- BTN_CODE(STYLUS2, 0x14c) \
- BTN_CODE(TOOL_DOUBLETAP, 0x14d) \
- BTN_CODE(TOOL_TRIPLETAP, 0x14e) \
- \
- BTN_CODE(WHEEL, 0x150) \
- BTN_CODE(GEAR_DOWN, 0x150) \
- BTN_CODE(GEAR_UP, 0x150)
-
-#undef BTN_CODE
-#define BTN_CODE(n,v) GLUE(BTN_,n) = v,
-typedef enum {
- EVENT_BTN_LIST
-} EventBtnCode;
-#undef BTN_CODE
-
-#define EVENT_REL_LIST \
- REL_CODE(X, 0x00) \
- REL_CODE(Y, 0x01)
-
-#define REL_CODE(n,v) GLUE(REL_,n) = v,
-typedef enum {
- EVENT_REL_LIST
-} EventRelCode;
-#undef REL_CODE
-
-#define EVENT_ABS_LIST \
- ABS_CODE(X, 0x00) \
- ABS_CODE(Y, 0x01) \
- ABS_CODE(Z, 0x02) \
- ABS_CODE(RX, 0x03) \
- ABS_CODE(RY, 0x04) \
- ABS_CODE(RZ, 0x05) \
- ABS_CODE(THROTTLE, 0x06) \
- ABS_CODE(RUDDER, 0x07) \
- ABS_CODE(WHEEL, 0x08) \
- ABS_CODE(GAS, 0x09) \
- ABS_CODE(BRAKE, 0x0a) \
- ABS_CODE(HAT0X, 0x10) \
- ABS_CODE(HAT0Y, 0x11) \
- ABS_CODE(HAT1X, 0x12) \
- ABS_CODE(HAT1Y, 0x13) \
- ABS_CODE(HAT2X, 0x14) \
- ABS_CODE(HAT2Y, 0x15) \
- ABS_CODE(HAT3X, 0x16) \
- ABS_CODE(HAT3Y, 0x17) \
- ABS_CODE(PRESSURE, 0x18) \
- ABS_CODE(DISTANCE, 0x19) \
- ABS_CODE(TILT_X, 0x1a) \
- ABS_CODE(TILT_Y, 0x1b) \
- ABS_CODE(TOOL_WIDTH, 0x1c) \
- ABS_CODE(VOLUME, 0x20) \
- ABS_CODE(MISC, 0x28) \
- ABS_CODE(MAX, 0x3f)
-
-#define ABS_CODE(n,v) GLUE(ABS_,n) = v,
-
-typedef enum {
- EVENT_ABS_LIST
-} EventAbsCode;
-#undef ABS_CODE
-
-/* convert an event string specification like <type>:<code>:<value>
- * into three integers. returns 0 on success, or -1 in case of error
- */
-extern int android_event_from_str( const char* name,
- int *ptype,
- int *pcode,
- int *pvalue );
-
-/* returns the list of valid event type string aliases */
-extern int android_event_get_type_count( void );
-extern char* android_event_bufprint_type_str( char* buff, char* end, int type_index );
-
-/* returns the list of valid event code string aliases for a given event type */
-extern int android_event_get_code_count( int type );
-extern char* android_event_bufprint_code_str( char* buff, char* end, int type, int code_index );
-
-#endif /* _ANDROID_HW_EVENTS_H */
diff --git a/android/hw-kmsg.c b/android/hw-kmsg.c
deleted file mode 100644
index 987943b..0000000
--- a/android/hw-kmsg.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/hw-kmsg.h"
-#include "qemu-char.h"
-#include "charpipe.h"
-#include "android/utils/debug.h"
-
-static CharDriverState* android_kmsg_cs;
-
-typedef struct {
- CharDriverState* cs;
- AndroidKmsgFlags flags;
-} KernelLog;
-
-static int
-kernel_log_can_read( void* opaque )
-{
- return 1024;
-}
-
-static void
-kernel_log_read( void* opaque, const uint8_t* from, int len )
-{
- KernelLog* k = opaque;
-
- if (k->flags & ANDROID_KMSG_PRINT_MESSAGES)
- printf( "%.*s", len, (const char*)from );
-
- /* XXXX: TODO: save messages into in-memory buffer for later retrieval */
-}
-
-static void
-kernel_log_init( KernelLog* k, AndroidKmsgFlags flags )
-{
- if ( qemu_chr_open_charpipe( &k->cs, &android_kmsg_cs ) < 0 ) {
- derror( "could not create kernel log charpipe" );
- exit(1);
- }
-
- qemu_chr_add_handlers( k->cs, kernel_log_can_read, kernel_log_read, NULL, k );
-
- k->flags = flags;
-}
-
-static KernelLog _kernel_log[1];
-
-void
-android_kmsg_init( AndroidKmsgFlags flags )
-{
- if (_kernel_log->cs == NULL)
- kernel_log_init( _kernel_log, flags );
-}
-
-
-CharDriverState* android_kmsg_get_cs( void )
-{
- if (android_kmsg_cs == NULL) {
- android_kmsg_init(0);
- }
- return android_kmsg_cs;
-}
diff --git a/android/hw-kmsg.h b/android/hw-kmsg.h
deleted file mode 100644
index 51d6731..0000000
--- a/android/hw-kmsg.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_kmsg_h
-#define _android_kmsg_h
-
-#include "qemu-common.h"
-
-/* this chardriver is used to read the kernel messages coming
- * from the first serial port (i.e. /dev/ttyS0) and store them
- * in memory for later...
- */
-
-typedef enum {
- ANDROID_KMSG_SAVE_MESSAGES = (1 << 0),
- ANDROID_KMSG_PRINT_MESSAGES = (1 << 1),
-} AndroidKmsgFlags;
-
-extern void android_kmsg_init( AndroidKmsgFlags flags );
-
-extern CharDriverState* android_kmsg_get_cs( void );
-
-#endif /* _android_kmsg_h */
diff --git a/android/icons.h b/android/icons.h
deleted file mode 100644
index e4ec861..0000000
--- a/android/icons.h
+++ /dev/null
@@ -1,984 +0,0 @@
-/* Copyright (C) 2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-/* automatically generated, do not touch */
-
-static const unsigned char _data_android_icon_16_png[460] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 16, 0, 0, 0, 16, 8, 6, 0, 0, 0, 31,243,255,
- 97, 0, 0, 1,147, 73, 68, 65, 84, 56,141,173, 82, 77, 75, 66,
- 65, 20, 61, 79,173,199,148,125, 64,209, 35,112, 97,145, 84,219,
- 30,210, 7,173,162, 64,168, 77,235, 8,132, 86,110,251, 39,109,
- 94,109, 10,177, 40,104, 47, 73, 59,169, 80,136, 90, 68,144,182,
- 8, 18,162, 44, 42,165,184,111, 20,229,182,200, 39,126,188,146,
- 160, 3, 3,119,152,115,207, 61, 51,115,192,204,104, 92, 68, 82,
- 39,146, 61, 53,123, 65, 36,167,237,184,182,205,145,228, 12,231,
- 62, 94,152, 72,222, 17,201,251,143,207, 28, 71,146, 51,108, 39,
- 226, 66, 51, 2,139,227,135, 56, 78,175, 65,150,222,134,152,203,
- 80, 93,189, 8,140, 70, 0, 32, 0, 32, 81,199,110,152, 62,250,
- 244,126,203,225,196, 36, 19, 73, 54,226, 94, 54,226, 94, 38,146,
- 188,115, 54,193, 15,175, 87, 77, 46, 28,150,144,105, 22,102, 1,
- 132, 82,217, 61, 80, 49,139,240,249, 88,117, 72,248,124, 12,178,
- 244,134,235,199,109, 0, 8,153,102, 97,193, 58, 83,152, 25,166,
- 89,152,205,126, 94,156,104,110,221,230, 70, 63, 98, 73, 8, 53,
- 106,189, 65, 40,253,124,128,163,155, 21, 4,253,169,186,233,181,
- 8,250, 83,216,191,244, 99,160, 75,199,188,111, 43, 4, 32,234,
- 176,101,254, 1,255, 38, 80, 86,224,132,162, 56, 91, 54, 40,138,
- 3,202,119, 91, 25, 64, 53, 7,155,186,103,125,117,164,127,185,
- 165,192,156,207, 64,103,155, 6, 0,155, 85, 7, 66,168,137,142,
- 118,205, 51,216, 61,181,209, 74, 64,115,235,187,110,213, 51, 44,
- 132, 26, 3,208, 28, 36, 34,105,228,205, 12, 27,113, 47,231,205,
- 12,215,214, 68, 50,242, 99,144, 42, 78,210, 0,162,191, 24,136,
- 9,161,214, 69,217,238, 23, 46, 74, 69, 7,134,251,150, 80,144,
- 69, 0,168,173, 19,141,100,133,153,155, 20,172, 88,163,242, 80,
- 86, 45,132,122,218,200,253, 2, 34,145, 32,131,249,218,106,138,
- 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-#ifdef CONFIG_DARWIN
-static const unsigned char _data_android_icon_256_png[13369] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 1, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0, 92,114,168,
- 102, 0, 0, 32, 0, 73, 68, 65, 84,120,156,237,157,119,124, 84,
- 85,222,255, 63, 51,119,122, 50,105, 36,164,144, 10, 36, 4,144,
- 162, 16, 69, 17, 68, 4, 17, 69,220, 93, 5,101,125,118,117,197,
- 125, 22,244,121, 30, 93, 86,244,167,235,174,143,186,174,171,176,
- 214, 69,121,118,215,222,176, 23,176, 32,138, 65,164, 8, 2, 73,
- 32, 16,106,122, 47,147, 73,153,126,231,254,254,184,153,100,106,
- 114,238,100,250, 61,239,215,107, 94, 19,134,115,238, 57,183,124,
- 63,247,123,234, 87,194,113, 28, 40, 20,138, 56,145,134,187, 2,
- 20, 10, 37,124, 80, 1,160, 80, 68,140, 44,208, 7, 52, 26,205,
- 129, 62,100,196,163,209,168, 36,129, 56,142,193, 96, 18, 85,123,
- 140, 94, 55,255, 81,171,149, 1, 57,142, 36,208,125, 0, 98, 18,
- 128, 97, 30, 96, 41,120,113,101, 6,190, 37, 0,216,129,143, 13,
- 128, 29, 0, 55,240,241, 74,172, 62,212,195, 92, 51, 9,134,174,
- 23, 51,240,225,192, 95, 47,199,181,115, 92, 55,175,196,234, 53,
- 243, 70,160, 4,128, 54, 1,252, 64,163, 81, 73,188, 60,200, 12,
- 0, 21,128,132, 39,159,220, 48,169,186,186,230,209,174, 46,221,
- 238,254,126, 67,131,193, 96,234,236,233,233, 61,209,210,210,250,
- 246,161, 67,135, 86, 1, 72, 4,160, 1, 32, 7,127, 15, 36, 3,
- 31,151, 50, 66,112, 42, 33,197,203, 57, 73,193, 95, 3, 13,128,
- 196, 67,135, 14,173,106,105,105,125,187,167,167,247,132,193, 96,
- 234,236,239, 55, 52,116,117,233,118, 87, 87,215, 60,250,228,147,
- 27,138, 0, 36, 0, 80,131,191,214, 94,175, 89, 44, 94,183, 96,
- 66, 61, 0,129,120,121,192, 36,224,223, 90,154,150,150,214,151,
- 180,218,132,107, 36, 18,201, 72,242,204,153,205,166,170,147, 39,
- 79, 62, 60,103,206, 69,219, 0, 88,192,191,225, 6,255,223,241,
- 71,172,188,213,220,174,155, 4,188,241, 43,203,202,202, 87,228,
- 231, 23, 60,160, 80, 40, 38,194,205,160,221,225, 56,206,220,219,
- 219,243,121, 70, 70,250,237, 0, 12,224,189, 3,199,245,113,185,
- 78,177,114,221,124, 65,155, 0, 97,192,199, 27, 76,249,209, 71,
- 31, 95,176,120,241,226, 15, 25, 70, 54, 86,232, 49,219,219,219,
- 62,202,203,203, 93, 13,192, 8, 31, 15,116,180, 63,204, 94,140,
- 159, 1,160,105,110,110,125, 45, 49, 49,241, 58,161,199,179, 90,
- 45,237, 95,127,189,253,250, 21, 43, 86, 28, 6, 96,198, 80,115,
- 74, 52, 34, 64, 5, 32, 12,184, 61,200, 82, 0,170,250,250,134,
- 39,198,140, 73, 93,139, 81, 52,167,140, 70, 99,237,152, 49,201,
- 179, 0,244,129, 23, 1,192,237,129,142,214,135,217,139,241,203,
- 0,196,245,244,244,150,203,100,242, 28,255,143,204,217, 91, 90,
- 90,254, 57,126,124,193,122, 0, 38,120, 17,129,104,189,102, 36,
- 208, 62,128, 16,227,229, 65,150,151,151, 87,220, 54,102, 76,234,
- 157, 24,229,117, 84,171,213,121,157,157, 93, 21, 0,226,192,191,
- 29, 29,101, 12,150, 25,141,109, 91, 31,111,126,245,232,141, 31,
- 0, 36,210,140,140,204, 53,223,125, 87,122, 39, 0, 5,134,174,
- 87, 84, 95,179, 80, 67, 5, 64, 56,142,246,107,220,196,137,133,
- 79, 4,234,160,106,181, 38,235,228,201, 83,239, 98,168,147,203,
- 81, 86, 44, 60,196,131,109,254,166,166,230,215, 71,111,252, 67,
- 204,158, 61,251, 97, 0,169,112,125,150, 99,225,154,133, 4, 42,
- 0,194,145, 0, 80,233,116,221,223, 75, 36, 18,117, 32, 15,156,
- 147,147,187,232,163,143, 62, 94, 13,222, 77,246,120,160,163,233,
- 141,230, 84, 87,199, 55,115,224,192,193, 27,147,146,146,151, 7,
- 178, 28,134,145, 41,155,155, 91,118,130, 31,129,113,140,168, 80,
- 8,161, 2, 32, 28,201,182,109,159,207, 82, 42, 85, 83,130,113,
- 240,203, 47,191,252,127,193,191,209,124, 14,117, 5,163,220, 64,
- 226, 99,136, 52,110,242,228, 41, 27,131, 81, 94, 98, 98,210,132,
- 135, 31,126,100, 41,232,243, 44,152,128,207, 4, 20,202,171, 7,
- 139,195, 93, 5, 33, 72, 0,200,166, 79,159,113,115,176, 10, 80,
- 42, 85,218,234,234,154,207, 10, 10,242, 47, 7, 63,212,229, 49,
- 60, 24, 69,215,204,225,250,171,218,219, 59,183, 49, 12,147, 20,
- 172,130, 22, 45, 90,180,234,161,135,254,188, 29,124, 71,170, 3,
- 46,210,175,213,173, 37, 85, 97, 45,159, 42,166,112,100, 90,109,
- 252,165,193, 44, 32, 61, 61, 99,198, 7, 31,124,176, 22, 67,179,
- 8, 93, 58,184,238,184,172, 38, 98,189, 0,167,186, 57,234, 43,
- 59,120,240,167,155,227,226,226, 46, 14,102,185,121,121,249, 51,
- 192, 79,176,138,216,107, 19,137, 80, 1, 16,142, 76,161, 80, 20,
- 144, 36,236,232,175,192, 87, 85,191,194, 7, 21,139,112,164,241,
- 121, 65,133, 44, 92,184,232,255,129,111, 10, 56, 68,192,133, 72,
- 20, 1, 47,117,146, 2,136, 47, 46, 46,126, 92,200,113, 14, 53,
- 60,133, 15, 42, 22,225,171,170, 95,161,163,191,130, 40, 79, 66,
- 66, 66, 38,128,160,121, 24,177, 74,216,155, 0,209,128,243, 91,
- 237, 79,127,250, 83,186, 68, 34, 85,141,148,135,181,155,240,205,
- 169, 53, 48,217,186, 0, 0,229, 77,155, 96,231,172,152,149,189,
- 142,168, 76,149, 74,165,173,174,174,249,180, 96,168, 41,224, 60,
- 166,205, 57,234,245,194,174,252,193,223, 67, 45, 10,195,148,237,
- 236,250,127,198, 48, 50, 98,195, 60,212,240, 20,142, 54,255, 19,
- 0,208,103,110,192, 55,167,214, 96,197,140,157, 96, 70,184,228,
- 50,153, 76,185, 96,193,130,156,210,210,210, 42, 56,205, 7,112,
- 191, 70, 20, 87,168, 0, 8, 67,114,227,141, 55, 93, 78,146, 80,
- 111,170, 30, 52,126, 7,199, 90, 94, 66,110,210, 66,164,197,207,
- 36, 42,204,209, 20,184,225,134, 27,158, 3,255, 64,219,157,254,
- 123,240, 1,119,175,163,151,127, 15,247,113, 28,203,125, 34,141,
- 163, 60, 95,198,195,249, 16, 28,191, 93,255,246,190, 50, 28,107,
- 121,201,229, 55,147,173, 11,122, 83, 53, 82, 52,147, 71,204,127,
- 235,173,183, 94, 90, 90, 90,186, 19,174,253, 38,148, 97,160, 2,
- 32, 12,238,221,119,183,124,119,255,253,127, 28, 49, 97,162,170,
- 0, 10, 70, 11, 11,219, 59,148,153, 99,241, 67,245,253,184,238,
- 188,207, 32,149,200,137, 10, 28,104, 10,188, 13,160, 13, 67, 43,
- 9, 1,222,200, 56,167,191, 25,240,111, 93, 41,134, 86,211, 73,
- 211,210,210,228,159,127,254,197, 34,133, 66,145,234, 56,102,124,
- 124,124,102, 92, 92,156, 75,239, 88,127,127,127, 85, 95, 95, 95,
- 179,227,223, 70,163,177, 99,249,242,107,191,109,111,111,183, 12,
- 148,105,135,235,170, 60,111, 43, 26, 7,135,252, 0,104, 39, 77,
- 34,119,253,237,156, 21, 63, 84,223, 15,142,115,181, 93, 5,163,
- 69,162,138,168,197,133,205,155,255,239, 16, 0, 37,248,181, 21,
- 20, 2,168, 0, 8,131,123,244,209, 71,219,238,187,239,126,147,
- 84, 58,188, 79,202, 72, 85,152,157,179, 30,123,107,254,236,242,
- 187,222, 84,141,195, 13,207, 96,118,206,122,162, 2, 85, 42,149,
- 246,220,185,234, 79,198,143, 47,184, 2,124, 83, 96,176, 8,167,
- 143,124,223,190,125, 87,101,103,231, 92,166, 80, 40,115,149, 74,
- 197, 68,153, 76,150, 42,145, 72, 53, 18,137,132,232, 30, 39, 38,
- 38,121,204,201,175,173,173, 7,199,113, 54,187,221,110, 96, 89,
- 91,135,201,100, 58,107, 54,155,235,154,154, 26, 75, 47,190,248,
- 226,237, 0,172,224, 69,201,177,100, 23,224, 69, 64,221,214,214,
- 254,153, 76, 70,238,250, 31,110,120, 6,122, 83,181,199,239,179,
- 115,214,143,232,254, 3,128,213,106,181,236,223,191, 79, 7,126,
- 77, 5,133, 16, 42, 0,194,177, 89,173,150,106,165, 82, 53,162,
- 79, 90,148,182, 18, 53, 93, 95,161,169,103,175,203,239,149,173,
- 175, 34, 47,121, 49,113, 83, 32, 35, 35,115,198,150, 45,239,174,
- 189,233,166, 27,255, 9, 0,119,223,253,251,180,223,253,238,119,
- 191, 76, 77, 77, 93,160, 84,170,138,101, 50, 89, 50,130,212,251,
- 45,145, 72,100, 12,195, 36, 48, 12,147,160, 80, 40,199, 3, 64,
- 90,218,216,213, 6,131,137,179,217,108, 58,179,217, 84,213,209,
- 209, 81,250,210, 75,255,126,107,227,198,141,109, 0,240,195, 15,
- 123,110,140,143,215,206, 33, 45,163,189,175, 12,149,173,175,122,
- 252,158,149,112, 9,138,210, 86, 18, 29, 67,175,215, 55,129, 31,
- 2,180,143,148,150, 50, 68,216, 23, 3, 69,250, 56, 45,224, 49,
- 180,165,172,169,169,125,110,236,216,244,219, 73,242,246, 91,154,
- 241,201,209,107, 96,181, 27, 92,126, 79, 84, 21, 8,106, 10, 24,
- 141,134, 62,171,213,218, 28, 23, 23,159,195, 48,204,200,175,196,
- 48,192,178,172,201,100, 50,214,202,229,138, 12,133, 66,145, 72,
- 146,199,206, 89,241,233,177,229, 30,111,127,185, 84,131,159, 77,
- 251, 28,113,138, 76,162,178, 15, 30, 60,240,217,101,151,205,255,
- 127, 0,206,194,181,137,130, 72,238, 4,244,119, 30, 0, 93, 12,
- 20, 62,216,159,126, 58,248, 14,105,226, 56, 69, 38, 46,204,125,
- 192,227,119, 71, 83,128, 20,181, 90, 19,159,144,144, 88, 24,169,
- 198, 15, 0, 12,195,168,226,226,226, 39,145, 26, 63,224,219,245,
- 191, 48,247, 1, 98,227, 7,128, 45, 91,222,249, 26, 64, 15,113,
- 6, 10, 0, 42, 0, 68,184,189, 65,236, 55,220,112,195, 97,163,
- 209,120,134, 52,127, 97,218, 13,200, 74,184,196,227,247,202,214,
- 87,209,222, 87, 22,136, 42, 70, 37, 29,253, 21, 62, 93,255,194,
- 180, 27,136,143,211,213,213, 89,255,226,139, 47, 86, 1,112,244,
- 184, 14,222,175, 72,126,251, 71, 2, 84, 0,132,195, 1, 48,109,
- 216,240,228,207,237,118, 59,241,112,211,220,130,199,160, 96,180,
- 174, 7, 26, 24, 21,176,115,214, 64,215, 49,226,177,115, 86,236,
- 62,119,159,215, 94,255,185, 5,143, 17, 31,135,101, 89,118,197,
- 138, 27,238, 7,208, 2,190,247,159, 26,188, 0,168, 0,248, 7,
- 251,183,191, 61, 94,215,209,209,254, 17,105,134, 56, 69, 38, 74,
- 114,238,243,248, 93,104, 83, 32, 86,240,229,250,151,228,220, 39,
- 200,245, 63,118,236,104,233,190,125,251,106, 1,212,130, 26,191,
- 96,168, 0, 8,195,121,178,140, 37, 63, 63,239,206,254,254,190,
- 58,210,204,180, 41,192, 19, 40,215,191,179,179,179,249,226,139,
- 231,252, 29, 64, 3,248, 97, 72,111, 19,154, 40,195, 64, 5,192,
- 63, 56,240, 15,156, 97,221,186,223, 47,181,219,237,182,145, 50,
- 56,184,180,224,113, 81, 55, 5, 2,229,250,219,108, 54,246,170,
- 171,174,188, 7, 64, 35,128,118, 80,195,247, 11, 58, 15, 96,116,
- 216,222,120,227,141,166,135, 31,126,228,227,140,140,204, 21, 36,
- 25, 52,138,116,148,228,220,135, 61, 53, 15,186,252, 46,116,130,
- 144, 16,244,166,106,216,216,161, 97, 72, 51,171, 71,159,185,193,
- 37, 77,188, 50, 27, 74,102,168,243, 94,198,104,136,103,224, 9,
- 33, 80,174,255,209,163, 21,223, 87, 86, 86, 54,129,119,253,135,
- 141, 23, 64,241, 13, 21, 0,255,112,105, 10,140, 31, 95,240, 95,
- 109,109,237, 23,197,199,107,115, 73, 50, 23,166,221,128, 26,221,
- 118, 52,234,119,187,252, 46,116,130,144, 51,122, 83, 53,116,198,
- 83, 48, 88, 90,209,109, 60,131, 94,115, 29, 12,150, 86,175,198,
- 38,132, 68, 85, 1, 52,138,116,104,149,185, 72, 82, 79,132, 70,
- 145,142,100,117,145, 95,226, 16, 40,215,191,163,163,189,121,238,
- 220, 75,158, 2, 80,143,161,157,148,169, 7,224, 7,116, 34,144,
- 0,188,172,117,119,204,189, 87,172, 88,177, 50,255,229,151, 95,
- 57,204, 48, 12,145,168, 26, 44,173,248,228,216, 50,151,181, 2,
- 0,217, 4, 33,214,110, 66, 91, 95, 25,218,251,202,208,214, 95,
- 134,246,190, 35, 48,219,244,126,157,147,191, 40,101,137, 72,139,
- 63, 31, 99,227,102, 34, 45,126, 38,198,198,207, 28,118,202,174,
- 175, 9, 63, 10, 70,139,159,157,183, 13, 26, 69, 58, 81,185, 86,
- 171,149,189,232,162, 11,127, 83, 85,117,162, 18,192, 25, 12, 77,
- 67,246, 88,159, 16, 13, 67,128,225,158, 8, 68, 61,128,192,192,
- 189,255,254,123,157, 15, 61,244,208, 23,227,199, 79, 32,218,243,
- 78,163, 72,199,133,185, 15,224,135,234,251, 93,126,247,213, 20,
- 232, 50,156, 64,125,247, 78, 52,232,119, 71, 68,135,161,217,166,
- 71, 67,119, 41, 26,186, 75, 7,127, 75,139,159,137,236,196,121,
- 200, 73, 90,232,177,122,111, 56,215,159,212,248, 1,224,208,161,
- 159,246, 86, 85,157,232, 4,223,241, 23,241, 6, 30,233, 80, 15,
- 128, 16, 47,235,221, 29, 30,128, 28, 64,252,185,115,213,255, 72,
- 79,207,184, 65, 34,145, 8,154,147,191,227,212,111, 61,154, 2,
- 18, 9,131,107, 38,191, 3,169, 68,142,234,174, 47,113,182,243,
- 83, 24, 44,173,163, 61,133,144,162, 81,164, 99,194,152,235, 80,
- 144,178, 20, 28,103,199,182, 19, 43, 61, 58,254,198, 37,206,195,
- 226,162,127, 9, 58, 46,199,113, 56,115,230,244, 87, 51,102, 76,
- 255, 45,248,185,255,142,168, 74, 94, 87, 40, 70,186, 23, 16,110,
- 15,128, 10, 0, 1, 94,140, 31, 24, 88,133,119,193, 5, 23,140,
- 249,230,155,157,187, 84, 42,255,122,204,124, 53, 5, 24,169, 10,
- 172,221,228, 95,133, 35, 12,111,231, 34,212,245,119,167,183,183,
- 167,225,150, 91,110, 89,252,213, 87, 95, 54,131,143, 14,228, 24,
- 6,116, 44, 6,138, 10, 17, 8,183, 0,208, 97,192, 17, 24,198,
- 248, 85, 71,142,148,221,182,123,247,158, 51,254, 26, 63, 48,212,
- 20,112, 39, 86,140, 31,240,126, 46, 23,230, 62,224,183,241, 3,
- 128, 86,155,144,253,254,251, 31, 28,221,187,119,223,111,224, 25,
- 75,193,249, 59, 34,183, 79,139, 20,168, 0, 12,195, 48,198,175,
- 169,171,171,223, 60,105, 82,241,243, 18,137, 68, 49,154, 50,186,
- 12, 39, 80,215,189,115, 52,135,136, 74,234,186,119,162,203,112,
- 98, 84,199, 96, 24, 70, 54,115,230,249, 79,159, 62,125,102, 51,
- 248, 8,195,206,155,168, 2, 84, 4, 70,132, 54, 1,124,224,195,
- 248,101, 0,226, 58, 59,117,223,170,213,234,243, 71,115,252, 46,
- 195, 9,148, 53,189,128, 58,221,142,209, 28, 38,234,201, 77, 94,
- 140,153, 89,119, 16,109,249, 53, 28, 61, 61,250,163, 25, 25,233,
- 87,128,239, 23,176,194,115,123, 51, 0,145,215, 28, 8,119, 19,
- 128, 10,128, 23,124,116,248,201, 0,104,245,250,222, 50,185, 92,
- 62,206,223, 99,155,109,122,252,212,176, 1,167,219, 63, 24,109,
- 53, 99,138,194,180, 27, 48, 59,123, 61,148, 50,226,149,196, 30,
- 152, 76,198,214,148,148,228, 25,224, 87, 5, 90,225, 58, 65, 40,
- 34, 69, 32,220, 2, 64,155, 0,110,248, 48,126,121,105,233,174,
- 43,251,250, 12,213,254, 26, 63,199,177,168,108,121, 5, 31, 86,
- 44,162,198,239,133,211,237, 31,224,195,138, 69,168,108,121,197,
- 99,180,128, 20,149, 74,157,222,211,211,123,110,251,246,175,175,
- 4, 31, 48,212, 57, 84, 24,109, 14,120,129, 10,128, 19,195, 24,
- 255,226,217,179, 75,182, 72,165,210,120,127,142,171, 55, 85,227,
- 243, 19,171,112,176,254, 9,143,222,126,202, 16, 22,182, 23, 7,
- 235,159,192,231, 39, 86,249, 61,131, 81, 38,147,107, 46,185,228,
- 146, 45, 31,126,248,209,213,160, 34, 48, 34, 84, 0, 6,240,213,
- 230, 47, 45,221,181,184,164,164,228, 93,169, 84,170,241,231,184,
- 21, 77,155,241,233,177,229,196, 1, 46, 40,252,148,225, 79,143,
- 45, 71, 69,211,102,191,242, 51,140, 76,121,229,149, 75,222,252,
- 248,227, 79,150,130,159,167, 65, 59, 6,125, 64, 5,192, 19,231,
- 14, 63,237,236,217,179,223,146, 72,164,130,163, 0, 27,173, 29,
- 248,250,228,109, 56,220,248,140, 40, 86,249, 5, 26, 59,103,197,
- 225,198,103,176,253,228,173, 48, 90, 59, 4,231,103, 24, 70,177,
- 112,225,194, 87, 1,140,193, 48, 34, 32,118,168, 0,192,235,155,
- 128, 1, 16,175,215,247,150, 75,165,110,107,119, 9,104,238,217,
- 143,207, 42,127,230,177, 27, 48, 69, 56,142,107,217,220,179, 95,
- 112, 94,185, 92, 17,215,209,209,121, 8,128, 22,158, 67,132, 0,
- 168, 23, 32,122, 1,240, 17,210, 74,211,213,165,219, 41,151,203,
- 179,132, 30,239, 68,219, 91,248,250,212,106,191,222, 90, 20,239,
- 24,173, 29,248,250,212,106,156,104,123, 75,112, 94,141, 38, 46,
- 173,161,161,105, 23,128, 56,184,134, 92,167, 77, 1,136, 92, 0,
- 124,197,179,171,173,173,123, 90,165, 82,207, 16,122,188,159,234,
- 55,224,199,218, 71,253,238,197,166,248,134,227, 88,252, 88,251,
- 40, 14,214, 63, 33, 56,111, 74, 74, 74,113, 89, 89,249, 11, 0,
- 84, 24,234, 20,164, 34, 0,145, 11,128, 19,142,155, 47, 63,114,
- 164,236,214,180,180,177,191, 17,146,217,206, 89,177,235,236, 58,
- 143,184,118,148,192, 83,217,242, 10,118,157, 93, 39,184, 95,165,
- 168,104,210,202,175,190,218,190, 22,252,200, 0,237, 15, 24, 64,
- 180, 2,224,171,221, 95, 84, 52,105,163,144,227,216, 57, 43, 74,
- 207,174, 67,117,215, 23,129,171, 28,101, 88,170,187,190,192,119,
- 103,238, 18, 44, 2,115,231, 94,250, 72, 97, 97, 97, 54, 60, 59,
- 5, 1,136,211, 11, 16,165, 0,120,113,253, 25, 0,113, 58,157,
- 126,175, 68, 34, 33,158, 98,101,231,172,248,238,204, 93, 1,157,
- 206, 27,175,204, 70,126,242, 18,140,137,155, 26,176, 99,134,155,
- 49,113, 83,145,159,188, 4,241,202,236,128, 29,179,190,123, 39,
- 190, 61,125,135, 32, 17, 96, 24, 70,190,123,247,158, 29,160,253,
- 1,131,136,125, 67, 16,199,205, 87, 52, 52, 52,254, 67,169, 84,
- 78, 20,146,249,135,234,251, 81, 31,160,133, 60, 83, 51,126,131,
- 233,153,107, 60,166,194,158,235,220,134, 3,117,127,245, 8, 53,
- 30,233,168,100, 41,184, 48,247, 1,140, 31,179,204,229,119,179,
- 77,143,138,230,205,168,108,121,101,212,101, 52,234,119,227,135,
- 234,251, 49,127, 60,185,211,150,144,144,144,125,236, 88,229, 43,
- 231,157, 55,245,102,120,134, 17,143,152, 41,194,161, 66,116, 30,
- 128, 55,215,255,142, 59,238,200, 74, 78, 78,185, 81,200,113, 14,
- 214, 63,129,115,157,219, 70, 93, 31,149, 44, 5,215, 76,222,130,
- 146,156,251,188,206,131, 31, 63,102, 25,126, 62,237, 75,140, 75,
- 156, 55,234,178, 66,197,184,196,121,248,217,180,109, 30,198, 15,
- 240, 91,137,149,228,220,135,107, 38,111,129, 74,150, 50,234,178,
- 206,117,110, 19,220, 49,152,159, 95,112,213,162, 69,139, 39, 99,
- 168, 41,224,130,152,188, 0,209, 9,128, 19, 14,215, 95,243,216,
- 99,143,127, 73, 26, 70, 27, 0,142,183,190, 30,144, 55, 24, 0,
- 44,152,248,236,136,155,128, 42,101,137, 88, 56,241,121, 36, 40,
- 137,246, 28, 13, 43, 9,202, 92, 44,152,248,236,136,198,157, 22,
- 63, 19,151, 23, 62, 31,144, 50, 43, 91, 94,193,241,214,215,137,
- 211, 75,165, 82,230,205, 55,223,124, 15,252,252, 0,175, 77, 1,
- 177, 32, 42, 1,112,219,212, 19, 0,228,245,245,141,207, 40,149,
- 202, 9,164,199,104,237, 59,132,159,234, 55, 4,164, 62, 5, 41,
- 87, 35, 67, 91, 66,148,150,145,170,130,178,101,120,160,153,157,
- 179, 30,114,194, 89,211,233,241,179, 80,144,114,117, 64,202,253,
- 169,126, 3, 90,251, 14, 17,167, 79, 72, 72,204, 41, 47,175,120,
- 1, 62, 70, 5,196,226, 5,136, 74, 0,220, 96, 0,104,146,147,
- 147,174, 39,205, 96,180,118,160,212,143,222,103, 95, 76, 24, 67,
- 180,127,232, 32, 57, 73, 11, 71,181, 92, 54,216, 40,101,137,200,
- 73, 90, 40, 40,143,208,107,224, 11, 59,103, 69,233,153,187, 4,
- 77,192,202,203,203, 95, 10, 32, 11, 62,102, 9,138, 1,209, 8,
- 128,151, 45,189,149,237,237, 29,159, 72,165, 12,241, 10,191, 31,
- 170,239, 15,232, 12,191,100,205, 36, 65,233, 37, 18, 6, 73, 42,
- 65,253,148, 33, 37, 73, 53, 17, 18, 9, 51,114, 66, 39,132, 94,
- 131,225, 48, 90, 59,176,251,220,189,196,233, 21, 10,133,250,220,
- 185,234,183, 0, 40,225,218, 12, 16,141, 23, 32, 26, 1,112,131,
- 249,247,191,255, 61, 53, 46, 46,126, 46,105,134,211,237, 31,120,
- 236,222, 59, 90,100,126, 44, 48,148, 49,126, 45, 74, 12, 9,254,
- 212,205,159,107, 48, 28, 77, 61,123, 5,237,183,144,145,145,121,
- 193, 93,119,221, 53, 15, 67, 94,128,168, 16,133, 0,120,121,251,
- 43,174,189,118,249,227,164,249,251, 45,205, 56, 80,247,215,128,
- 215,203,104,109,247, 35, 79,228,174, 49,240,167,110,254, 92,131,
- 145, 56, 80,247, 87,244, 91,154,137,211,175, 89,179,246, 33,240,
- 115, 3, 68,231, 5,136, 66, 0,220,144, 2, 80,199,199,107,231,
- 147,102,216, 87,251, 48,172,118,195,200, 9, 5, 34,116,181, 96,
- 191,165,121,212, 27,105, 6,147, 46,195, 9, 65,134, 7, 8,191,
- 6, 36, 88,237, 6,236,171,125,152, 56,125, 78, 78,238, 76,240,
- 125, 1,142, 17, 1,209, 32, 70, 1,144,215,215, 55,108,148, 16,
- 54, 86,221,163,223, 4,146,227,173,175, 11,234, 80, 20, 50,212,
- 21, 46,132,212,209,206, 89,131,118, 78, 66,238,155, 84, 42,101,
- 14, 28, 56,248, 24, 60, 71, 4, 98,158,152, 23, 0, 55,247, 95,
- 10, 64,149,156,156,242, 11,146,188, 28,199,226,112,227,179, 65,
- 171, 91,159,185,129,184,105,209,220,179, 31, 39, 90,223, 12, 90,
- 93, 2,197,137,214, 55,137,215,238, 31,168,251,171, 71,148,226,
- 64,114,184,241, 89,226,149,153, 69, 69, 69, 11, 1,100,192,203,
- 106,193, 88,110, 6,196,188, 0,184, 33,219,187,119,223,114,210,
- 189,253,106,187,191, 9,186,203, 93,213,246, 14,246,214,252,121,
- 216, 64, 32, 53,186,237,216, 41,112,222,123,184,176,115, 86,236,
- 60,125,199,176,139,163, 88,187, 9,123,107,254,140,170,182,119,
- 130, 90,151, 46,195, 9,212,118,127, 67,148, 86,161, 80,170, 55,
- 111,254,191, 21, 16,217,144,160, 88,214, 2, 12,110,240, 89, 84,
- 52,233, 46,210, 76,254,238, 73, 39,148, 83,237,239,161, 81,191,
- 27, 69,105, 55, 32, 43, 97, 46,100,140, 6,118,187, 21,221,166,
- 51, 56,219,241,105,212,237, 44,100,181, 27,176,235,236, 58,156,
- 110,255, 0, 19, 82,175, 67,146,106, 34,164, 82, 57,108,172, 1,
- 77, 61,123,112,170,253, 3,193,125, 5,254, 82,209,180, 25,249,
- 201, 75,136,210, 46, 93,186,244, 22, 0, 47, 3,232, 28,248,201,
- 33, 2, 49,187, 70, 32,166,227, 2,120,113,255,147,250,251,141,
- 45, 36,237,255,134,238, 82,124,115,122, 77,208,234, 70, 9, 29,
- 139, 10, 55, 35, 59,105,193,136,233,236,118,187, 61, 62, 94, 83,
- 2,224, 4,248,176,227, 65, 15, 55, 78,227, 2,132, 14, 89, 89,
- 89,249, 42,210,206,191,170,246, 45,193,174, 15, 37, 68,144,222,
- 75,169, 84, 42,125,227,141, 55,110,130,136,154, 1, 98, 17, 0,
- 9, 0, 89, 86, 86,214, 10,146,196, 6, 75,107,192, 39,253, 80,
- 194, 71,163,126, 55,113,120,245,146,146, 11, 23, 3, 72,128, 72,
- 118, 12, 18,131, 0, 12, 46,252, 81,171,201,246,249, 59,219,249,
- 41,221,215, 47,134,224, 56, 22,103, 58, 62, 38, 74,155,158,158,
- 94, 8, 32, 25, 34,217, 54, 76, 12, 2, 0,240,231,169, 96, 24,
- 89, 2, 73,226, 64,172,243,167, 68, 22,164, 91,182, 41,149,170,
- 56, 0, 41,112, 29, 14,140, 89, 98, 86, 0,220,198,110,153,178,
- 178,242,255, 32,201,215, 99,174,131,206,120, 42, 72,181,162,132,
- 11,157,241, 20,122,204,117, 68,105, 95,127,253,141,235,225,101,
- 109, 64, 44,206, 7,136, 89, 1,112, 66, 2, 64,150,153,153, 73,
- 180,240,188, 73,191, 39,200,213,161,132, 11,210,123, 59,107,214,
- 172,185,224,251, 1,128, 24,247, 2, 98, 93, 0, 6,195,124,169,
- 213,234,105, 36, 25,162,109,204,157, 66, 14,233,189, 29, 59, 54,
- 125, 2,128, 68,184, 26,126, 76,138, 64,172, 11, 0,192,159,163,
- 92, 38,147,141, 33, 73,220,222,119, 36,200,213,161,132, 11,210,
- 123,171,209,168, 19, 1, 36, 65, 4,253, 0, 98, 16, 0,201,103,
- 159,109,157, 13, 72, 70, 60, 87,131,165, 53,162,151,219, 82, 70,
- 135,209,218, 65, 52, 28, 40,145, 72, 37,235,215,223, 59, 11, 34,
- 176,143,168,154, 10,236,103, 39, 12,115,222,121,231,121,110, 79,
- 235,133, 78, 67,165, 31,135,167, 68, 19,157,134, 74,104, 20,233,
- 35,166, 91,178,100,201,101, 27, 54, 60,249, 14, 0,151, 5, 24,
- 66,158,193, 96,204, 28, 12, 52, 17, 41, 0, 2, 46,178,123, 58,
- 206,237,255, 36, 0, 24,141, 70,115, 30,201,193,244,166,106,194,
- 98, 41,209,138,222, 84,141, 28,130,116, 89, 89, 89,227, 1,196,
- 3,232,133,107, 51,192,253, 25,115,198,197,224,125, 61,199,145,
- 36, 12, 17, 35, 0,195, 24,189,227,226, 75,193,215, 87, 6,126,
- 227, 6,105, 70, 70, 6, 3, 0, 45, 45, 45,142,121,219, 54,240,
- 193, 30,216,129,127, 75, 1, 48, 10,133, 34,147,164, 14,253,230,
- 166,209,156, 2, 37, 10, 32,189,199, 90,173,118, 12, 0, 13,134,
- 158, 63,199,176, 32, 51,240,183, 52, 35, 35, 67, 6, 0, 45, 45,
- 45,142,231,205,241,236, 57,158, 67,103, 67, 31,252,219,249, 89,
- 191,213, 16,222,133, 70, 97, 23, 0, 47,134,239,188, 22, 91, 62,
- 240, 81, 28, 57, 82,118,195,184,113,227,150,171, 84,234,153, 12,
- 35, 77,150, 72,164,170,161, 44,156,205,110,231,140,102,179,233,
- 116,119,119,247,206,119,223,125,247,213, 7, 30,184,191, 25,252,
- 77, 80, 49,140, 44,149,164, 46,189,150,198, 64,156, 18, 37,130,
- 33,189,199,106,181, 58, 9,188, 7, 16, 7, 64,242,151,191, 60,
- 150,190,106,213,170, 91,146,146,146, 22, 42,149,170, 66,169, 84,
- 162, 6,134, 98, 73,112,156,221,196,178,108,151,193, 96, 56, 82,
- 95, 95,255, 73, 73,201,236, 79,192, 55, 31, 28, 31, 14,188, 72,
- 12,102, 1, 0,141, 70, 37, 1, 0,131,193, 20, 22, 33, 8,219,
- 106, 64,199,137, 59,215, 5, 67, 10,171,250,234,171,237, 23, 77,
- 159, 62,125,181, 86,155,112, 37,195, 48,201, 66,235,193,113,118,
- 179,209,104, 60,117,252,248,241, 45,231,159,127,254, 31, 25, 70,
- 54,226,238,147,159,159,184, 9,237,125,101, 66,139,162, 68, 17,
- 105,241, 51,113,205,228,145, 23, 7,153,205,102,243,231,159,111,
- 125,241,202, 43,151, 92,161,209,196, 21, 73,165, 82,161,203,239,
- 56,155,205,166,235,233,209,127, 83, 94, 94,254,210, 53,215, 92,
- 253, 35, 0, 51,134, 86, 25, 14,166,115,206, 68, 42, 4,129, 90,
- 13, 24, 22, 1,112, 51,126,199,223, 12, 0, 85,101,229,241,223,
- 101,103,103,223, 37,151, 43, 2, 22, 73,146,101, 89, 43,195, 48,
- 242,145,210,125,122,108, 57,157, 5, 24,227, 36,171,139,112,221,
- 121,159,141,152,206,106,181,218,228,114,121,192, 60,100,139,197,
- 220, 80, 95, 95,247,220,180,105,211,254, 9,192,136,161,184,132,
- 156,219, 55,145, 8, 4, 74, 0, 66,222, 4,240, 98,252, 14, 87,
- 63, 94,167,211,239, 86, 42,149, 1,223, 32,128,196,248, 1, 4,
- 101,227, 79, 74,100, 65,122,143, 3,105,252, 0,160, 80, 40,179,
- 39, 76, 40,124,178,179,179,235,246, 49, 99, 82,230, 1,232, 3,
- 223, 52,112,236, 57, 32,129, 83,179, 32, 84, 77,130,144,142,115,
- 122, 49,126, 6,128,250,216,177,202,181,253,253,134,250, 96, 24,
- 191, 16,130,185, 63, 29, 37, 50, 8,247, 61, 86,171, 53, 69,189,
- 189,253,117,101,101,229,107, 1,168,225, 35, 54,161,151, 38,114,
- 80, 8, 89, 19,192,139,241,203, 0,104,154,154,154, 95, 79, 74,
- 74,190, 54,160,149,160, 80,162,128,246,246,182, 47,243,242,114,
- 255, 3,128, 1,124,223, 0,231,244, 1,224,187, 57, 16, 85,125,
- 0, 62,222,252,241,221,221, 61, 7, 20, 10, 69,228,198,186,162,
- 80,130,140,193,208, 95,147,154, 58,166, 4,252,124, 3,199,208,
- 225,136, 34, 16, 53, 91,130,249, 48,254, 56,157,174,251, 7,106,
- 252, 20,177,163,209,196,229,183,182,182, 31, 4, 63,220, 24,242,
- 230, 64, 40,251, 0, 6,247,229,111,108,108,126, 69,169, 84, 77,
- 9, 97,217, 20, 74,196,162,213,106,243, 79,159, 62,243, 33, 0,
- 21,188,196, 37, 8, 38, 65, 21, 0, 39,229, 26, 92,150, 91, 81,
- 113,244,183,201,201,201, 63, 11,102,185, 20, 74,180, 49,110, 92,
- 246,130, 29, 59,118,220, 13,126, 68,204, 99,152, 60, 88, 94, 64,
- 80,251, 0,220, 4,128, 1,144,216,223,111,168,119,157,197, 71,
- 134,213,110, 64,179,126, 15,170,187,190, 68,143,185, 22, 58,195,
- 169,193, 64, 25, 9,202, 92,104, 20,233,200, 74,152,139,188,148,
- 37, 72, 84, 21,248, 85,247, 96,110, 81, 78,137, 28,252,221,138,
- 91,111,170, 70,109,215,118, 52,245,236,129,193,210, 58,184,195,
- 144, 84, 34, 71,178,166, 8,137,170, 2,228, 39, 47, 65,102,226,
- 92,200,253,136,122,204,178, 54,139, 86, 27, 95, 12,160, 25, 94,
- 58, 5,157,251, 2, 34,190, 19,208,205,248,165, 0, 52, 58,157,
- 254, 71,161, 67,125, 22,182, 23, 71, 26,158,193,169,142, 15,135,
- 141,158,227, 76, 90,252, 76, 92, 48,238,110,100, 38,204, 17, 82,
- 20, 21, 0,145, 32, 84, 0,154,123,246,227,112,227, 51,196,179,
- 68, 25,169, 10, 69,169,215,227,252,236,187,161, 96,180,130,202,
- 210,235,187,171, 51, 51, 51,102, 1,232,135,107, 92, 2, 23, 17,
- 136,154, 78,192, 1,152,242,242,138,219,132, 26,127,125,247, 78,
- 124, 88,177, 8, 39,218,222, 34, 54,126, 0,104,239, 43,195,246,
- 147,183,226,251,115,247,208,201, 61, 20,191,177,218, 13,248,254,
- 220, 61,216,126,242, 86, 65, 83,196, 89,187, 9, 39,218,222,194,
- 135, 21,139, 80,223,189, 83, 80,153,137,137, 73, 5, 91,183,110,
- 93, 7,207,166, 64, 80, 8,182, 0, 12,118,252,229,229,229,253,
- 94, 72,198,242,166, 77,248,246,244, 29, 48,219,244,126, 23,126,
- 174,115, 27,182, 85, 94, 31,178, 48, 84,148,216,161,223,210,140,
- 109,149,215,143,106,135,104,179, 77,143,111, 79,223,129,242,166,
- 77,130,242, 93,120,225, 69,183,195,115,103,226,160,136, 65, 80,
- 4,192,173,195, 66,250,221,119,165,151, 43, 20,202, 92,210,252,
- 199, 90, 94,194,145,198,231, 3, 82, 23,189,169, 26,219,171,110,
- 129,133,237, 13,200,241, 40,177,143,133,237,197,246,170, 91, 2,
- 182, 63,196,145,198,231, 5,197,153,212,106, 19, 50,158,121,230,
- 217,101, 24, 26, 22, 28, 36,208,157,129,161,104, 2,200,167, 78,
- 157, 74, 28,144,179,161,187, 20,135, 26,158, 10,104, 5,122,204,
- 117, 40, 61,115, 23, 13,246, 65, 25, 17,142, 99, 81,122,230, 46,
- 226, 45,196, 73, 57,220,248, 12,234,116, 59,136,211, 47, 93,186,
- 244,118,240,203,145,131, 58, 28, 24, 76, 1, 24, 92,232,163, 86,
- 107, 46, 32,201, 96,182,233,177,187,250,190,160, 24,106, 83,207,
- 94, 28,107,121, 41,224,199,165,196, 22,199, 90, 94, 10,218,206,
- 208,123,106, 30, 36,110,210,166,167,167, 23, 3, 72,133,107,116,
- 162,128, 11, 65, 40,250, 0, 20, 12,195, 16, 69,228, 41,111,218,
- 52,170, 54,255, 72, 84, 52,109,134,201,214, 21,180,227, 83,162,
- 27,147,173, 43,168, 33,225,205, 54, 61,113,127,128, 66,161,212,
- 0, 24,131,161,126,128,160, 16,108, 1,144, 85, 84, 28, 37,138,
- 200, 99,182,233,113,178,253,189,160, 86,198,106, 55,224, 68,235,
- 91, 65, 45,131, 18,189,156,104,125, 43,232,163, 70, 39,219,223,
- 35,126,201,109,217,242,238,141, 8,114,164,226,128, 11,128, 91,
- 39, 5,147,158,158,126, 13, 73,190, 90,221,118, 65, 67,125,254,
- 114,182,243,211,160,151, 65,137, 78, 66,241,108,176,118, 19,106,
- 117,219,137,210,206,152, 49,227, 18,184, 70, 42, 6, 16,216,142,
- 192, 96,247, 1,200, 73, 35,242, 52,132, 40, 28,119,159,185,129,
- 238,254, 75,241,160,219,120, 38,100,123, 5,212,119,151, 18,165,
- 75, 75, 27, 59, 30,124,164, 98, 32,202,250, 0, 6,183,249, 34,
- 141,200,211,209, 95, 17,164,170,132,183, 44, 74,116, 16,202,152,
- 16,164,101,169, 84, 42, 45, 60, 61,128,168, 25, 6,148,252,230,
- 55,183, 37,145, 68,228,177,115, 86,162,136, 45,129, 34,220,187,
- 194, 80, 34,143, 80, 62, 19, 6, 75,235,224, 58,150,225,144, 74,
- 165,210,169, 83,167,166, 33,136, 29,129, 65, 21,128, 37, 75,174,
- 28, 71,146, 48,212,147,116, 44,108, 95, 72,203,163, 68, 62, 86,
- 54,180, 83,198, 73,159,249,139, 46,186, 40, 11,174, 67,129, 1,
- 37,168, 2,144,144,144, 64,180,157, 55,107, 39,219, 74, 60, 80,
- 132,162,179,145, 18, 93,216, 66,188,102,132,244,153, 79, 79, 79,
- 215, 34,136,235, 2, 98, 62,248, 33,133, 18,205,216,237,156, 99,
- 61, 77, 80,160, 2, 64,161, 68, 62, 81, 57, 17, 40,102, 99,170,
- 83, 40,161,195,101,191,142,168,234, 3, 64,128,247, 26,161, 80,
- 196, 76, 84,245, 1,208,183, 63,133, 18, 56,162,114, 30, 0,133,
- 66,137,112,168, 0, 80, 40, 34,134, 10, 0,133, 18,193,112, 28,
- 23,212,230, 52, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21,
- 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80,
- 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12,
- 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196,
- 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68,
- 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,
- 196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80,
- 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10,
- 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160,
- 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0,
- 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,
- 160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21,
- 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80,
- 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12,
- 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 37,130,
- 145, 72, 36, 92, 48,143, 79, 5,128, 66, 17, 49, 84, 0, 40, 20,
- 17, 19, 44, 1, 8,170,219, 66,161,136, 12,206,199,223,163, 38,
- 152, 30, 0,215,210,210,220, 78,146, 80, 38,213, 4,177, 26,225,
- 47,143, 18,249, 68,234, 51, 88, 91, 91,219, 5,222,232,131,242,
- 82, 13,170, 0,124,255,253,247,109, 36, 9,229, 76,104, 47,190,
- 130,209,134,180, 60, 74,228, 19,234,103,144,180,188,178,178, 50,
- 61, 0,251,192, 63, 3, 46, 2, 65, 21,128,215, 94,123, 77,207,
- 113, 28, 59, 98, 37, 36,114,196, 43,179,131, 88, 21, 87,180,170,
- 220,144,149, 69,137, 14, 18, 84, 5, 33, 43, 43, 94,153, 13,169,
- 68, 62, 98, 58,150,101,237, 85, 85, 85,189, 0,172,193,170, 75,
- 176, 59, 1,109, 86,171,181,147, 36, 97,170,102,106,144,171, 50,
- 68, 90,220,244,144,149, 69,137, 14, 66,249, 76,144, 62,235, 6,
- 131, 65, 15,192,132, 40,109, 2, 0,128,205, 96,232,175, 32, 73,
- 56, 46,113, 94,144,171,194,147,160,204, 13,169,183, 65,137, 14,
- 226,149,217, 72, 80,134,198, 51, 36,125,214, 91, 91, 91,206, 0,
- 232, 65, 16, 59,213,131,218, 4, 0, 96,107,104,104,248,156, 36,
- 113, 94,202, 18,200, 67,208, 17, 51, 49,245, 23, 65, 47,131, 18,
- 157,132,226,217,144, 75, 53,200, 75, 89, 66,148,246,199, 31,247,
- 239, 5,160,119,250, 41,170,250, 0, 0,128,189,240,194,146,119,
- 72, 18, 42, 24, 45,166,101,254,103, 80, 43,163, 81,164, 99,114,
- 198,175,131, 90, 6, 37,122,153,156,241,107,104, 20,233, 65, 45,
- 99, 90,230,127, 18,117, 66,115, 28,135,223,254,246,183,223, 96,
- 200, 3,136,170, 38, 0,231,244,109,179,217,172,250,225, 18, 59,
- 8,246, 13,152,158,185, 38, 36, 94, 6, 37, 58,145, 75, 53,152,
- 158,185, 38,104,199, 23,242, 2, 50,153,140,125,224, 59,255,250,
- 17,173,243, 0, 6, 62,214,190,190,190, 67, 36, 25,228, 82, 13,
- 230,143,223, 72,212, 67, 42,148,156,164,133, 40, 30,187, 42,224,
- 199,165,196, 22,197, 99, 87, 33, 39,105, 97,192,143, 43,145, 48,
- 152,155,255, 23,226, 23, 80, 83, 83,211, 73, 0, 58,184,190, 76,
- 35,191, 9, 96, 48,152,220, 43,105, 61,120,240,192,115,164,249,
- 51,180, 37,152,147,247,167,128,214, 41, 89, 93,132,249, 19, 54,
- 6,244,152,148,216,101,254,132,141, 72, 86, 23, 5,244,152, 37,
- 57,247, 9,234,232,126,253,245,215,223,197,144, 0,184,216,148,
- 23, 27,243,155, 96,247, 1,112, 0,216,235,174,187,110,183,209,
- 104, 56, 71,154,169, 40,109, 37, 46, 45,120, 60, 32,158, 64,134,
- 182, 4, 87, 21,191, 65, 93,127, 10, 49,114,169, 6, 87, 21,191,
- 129, 12,109,201,168,143, 37,149,200,113,105,193,227,152,146, 78,
- 222,247,212,217,217,217,184, 97,195,147,229, 0, 58, 49, 36, 0,
- 81,213, 7,224,140, 29,128,121,223,190,125,235,133,100,154,152,
- 250,115, 44, 41,126,213,239, 33, 59,137,132,193,121, 25,171,113,
- 229,164,151,161,148, 37,250,117, 12,138,120, 81,202, 18,113,229,
- 164,151,113, 94,198,106, 72, 36,140, 95,199,136, 87,102,227,202,
- 73, 47, 99, 98,234,207, 5,229,219,180,233,249, 77, 0,154, 1,
- 24, 17, 68,227, 7, 0, 9,199, 5,246,216, 70,163, 25, 26,141,
- 74,226, 56, 62,120,145, 97, 0,104,218,218,218,119,197,199,107,
- 167, 9, 57,158,157,179,226,100,251,123, 40,107,124, 14,102, 27,
- 81, 95, 34,114,147, 23,227,130,113,119, 33, 73, 61, 81, 80,221,
- 95, 61, 88, 44, 40, 61, 37, 58,185,181,164, 74, 80,122,189,169,
- 26,135, 26,158, 66,157,110, 7, 81,122,165, 44, 17, 51,199,253,
- 15, 38,165,173, 20,236,197, 54, 55, 55,157,157, 48, 97,252, 29,
- 0,126, 2, 96, 0,255, 2,117,124, 56,128,111, 2,168,213, 74,
- 65,199,245, 69, 40, 4,192, 33, 2, 50, 0, 9,122,125,239, 57,
- 185, 92,238,151, 63,222,212,179, 23, 77,250, 61,104,238,221, 15,
- 0,232,236,175, 68,156, 34, 19, 42,121, 10, 52,242,116,228, 37,
- 47,198,184,196,121, 80,203, 83,253, 92,168,210,238, 0, 0, 19,
- 244, 73, 68, 65, 84,170, 59, 21, 0,113, 32, 84, 0, 28,152,108,
- 93,104,232,222,133, 90,221, 14, 24,172,173, 48, 89,187,208,111,
- 105,198,152, 56,126,102, 95,166,118, 14,178, 18,231, 34, 43,225,
- 18,191,142,111, 54,155,140,201,201, 73, 43, 0,156, 3, 80, 3,
- 79,227, 15,184, 0,200, 2,114, 20, 55, 12, 6, 19,231, 36, 2,
- 142,138,179, 0, 12,229,229,101,235,102,207, 46,217,236,207,113,
- 179, 18, 46,241,251,226, 82, 40,163, 69, 37, 75,193,196,212,159,
- 11,118,233, 73,121,237,181,215,254, 1,160, 3, 64, 29,124,180,
- 253, 3,217, 1, 8,132,166, 19,208,241,205, 1,176,206,159, 63,
- 239,189,186,186, 90,162,201, 65, 20,138, 88,168,168, 40,223,117,
- 247,221,119,125, 3,160, 26,174,111,252,168,239, 4, 4, 92,189,
- 0, 83,113,241,164,187,116,186,174, 35, 33, 42,155, 66,137,104,
- 154,155,155,206,206,153,115,209,223, 0,156, 6,208, 7, 47,110,
- 127,176, 8,154, 0, 56,185, 42,238, 94, 0, 11,160,127,220,184,
- 172,171,218,218, 90,127, 10, 86,249, 20, 74, 52, 80, 83, 83,125,
- 116,194,132,241,255, 13,160, 22, 64, 43, 60,223,254,128, 83,219,
- 63,208,229,135,218, 3,112,124,108, 0,250,242,243,243,174, 62,
- 121,178,234,189, 16,213,129, 66,137, 40, 14, 30, 60,176,125,202,
- 148,201,247, 2, 56, 11, 94, 0,220,223,252,209,235, 1, 0, 94,
- 21,203, 67, 4,206, 63,127,230,218,143, 63,254,240,191,204,102,
- 147, 33,152,117,161, 80, 34, 5,163,209,104,120,250,233,167,254,
- 114,217,101,243, 55, 2,168, 2,208, 0,239,198, 63, 72, 48,222,
- 254, 64,144, 70, 1,124,192,129, 31, 18,116, 62, 17, 22,128,241,
- 230,155,111,126, 3,192,151,213,213,181, 91,211,211,211,167,132,
- 176, 78, 20, 74, 72,105,108,108, 56, 89, 88, 56,113, 61,120,119,
- 191, 26,252, 98, 31, 95,198, 31,244,205,117,131,222, 4,112, 83,
- 46,111, 61,155, 44, 0, 11,128,182,130,130,188, 5,127,252,227,
- 253, 55,117,116,116,212, 5,178, 14, 54,155,205, 62,114, 42, 10,
- 101, 8,155,205, 26,208,103,166,173,173,173,238,246,219,111,251,
- 239,194,194,137,255, 3,190,179,239, 56,124, 27,191,139, 7, 16,
- 172,183, 63, 16,162, 62,128, 97, 68,192,238,244,109, 5,208,247,
- 244,211, 79,127,153,155,155,125,145, 70,163,186,248,199, 31,247,
- 111,237,234,234,108, 98, 89,118,196,125, 5,221, 49, 26,141,134,
- 170,170, 19, 63, 61,246,216,163,127,151, 72, 36, 35,103,160, 80,
- 92,144,224,207,127,254,211, 19,199,143, 87, 30, 50, 26, 13,130,
- 155,167, 54,155,141,237,232,232,104,218,183,111,239, 54,141, 70,
- 117, 93,126,126,238,237,111,191,253,118, 41,128, 3, 0,234,193,
- 191,248, 88,184,218, 64, 72,141, 31, 8,210, 76, 64, 95, 56, 77,
- 14, 2,248,230,128,227,219,249, 35, 29,248,102, 0,200, 1,140,
- 5,144,188,102,205,154, 11, 86,174,188,113,233,132, 9, 19,166,
- 39, 37, 37,101,112, 28,160, 80, 40, 20, 44,203,218, 89,150,181,
- 89,173, 22, 99, 75, 75, 75,205,225,195,135,247,223,114,203,175,
- 191, 2, 47, 40, 61, 0,108,125,125,253, 63, 72,165,204,136, 98,
- 71,103, 2,138, 3,146,153,128, 44,107,179,107,181,241,215, 3,
- 168, 4,144, 8, 32,233,245,215,223,184,254,130, 11, 46,152,147,
- 158,158, 94, 32,151, 43,212, 12,195,200, 24,134,145, 90, 44, 22,
- 11, 0,116,119,235, 90,206,156, 57,115,244,237,183,223,250,246,
- 229,151, 95, 62, 13,126, 42,175, 14, 64, 23,134, 22,246,248, 50,
- 120, 15,183,127, 56,227,143,232,169,192,195, 65, 40, 2,238, 31,
- 6,188, 48,168, 0, 36, 1, 72, 0,160, 85,169, 84,140,201,100,
- 82,128,111, 66, 88,192,111,160,216, 3,126, 27,165,254,129,188,
- 137,125,125,134,179, 82,169,116,196, 21, 29, 84, 0,196, 1,153,
- 0,176,118,173, 54,238, 58, 0,251, 49,100,172, 82, 0, 90,240,
- 130,160, 5,160, 80, 42,149, 10,179,217,204, 96,200,157,239, 6,
- 208, 59,240, 49,195,183,177,251,109,252, 64,224, 4, 32,148,157,
- 128, 0,188, 78, 19,134,211,223,206, 70, 15,167,191,237, 3,223,
- 86,240, 19, 37, 0, 64, 98, 50,153,220, 15,239,126,209,164,224,
- 221, 44, 10,197, 31, 28, 46,186,227,219, 14,254, 37,227, 8,120,
- 35, 49,155, 61, 94,120,238,243, 94,124, 25,186,207,206,190, 96,
- 187,253,206,132, 92, 0, 0, 15, 17, 0, 92, 71, 8,156,133,192,
- 241, 55,224, 41, 12,190,112,206,195, 1, 96,105, 23, 0,197, 79,
- 28,157,212,206, 2,224,248,125,164,103,208,241,237,107, 66,156,
- 123, 90, 0,161, 53,126, 32, 76, 2, 0, 12,157,168, 15,111,192,
- 241,111,231, 97, 67, 18,227,119,198,145,206, 78,158,133, 66,113,
- 193,238,229, 67,106,160,222,222,238, 62,135,247, 66,109,248, 14,
- 194, 38, 0, 14, 94,216,149,207, 1,192, 29,151,213,184,123, 4,
- 142,111,119,129, 16, 42, 0, 20,138,191,184,143, 88,249, 35, 0,
- 190,254, 13, 32,124,134,239, 32,236, 2,224,192, 33, 4,128, 79,
- 49,240,245,111,111,184, 47, 69,166, 80, 0, 0,113,138, 76,162,
- 116, 78,205,198,225,218,242,126,225,252,172,135,155,136, 17, 0,
- 103,134,187, 64,110,226,224, 11, 95,237, 45, 10,133,144,193,199,
- 204, 47,227,143, 36, 35, 31,142,136, 20,128,225, 32,185,176,110,
- 34, 65,236,182, 37, 40,115,209, 99, 14,232, 36, 68, 74,132,193,
- 16,110,209,197,241,227,227, 94,163,242, 70,139,113,147, 16,170,
- 213,128,225,196,206,178,108,223,200,201, 0,173, 42, 47,216,117,
- 161,132, 25,210,123,108,177,152, 13,224, 23,172,197,140,177,123,
- 35,214, 5,128, 3,192,154, 76,198,179, 36,137, 83,105,212,224,
- 152,135,244, 30,119,117,117, 53,130, 31,243,119, 16,147, 66, 16,
- 235, 2, 0, 0, 86,157, 78,247, 45, 73,194,188,228, 69,193,174,
- 11, 37,204,144,222,227,227,199,143, 31, 70,144,227,242, 69, 2,
- 177, 44, 0,142,155,102,127,246,217,103, 95, 37,201,144,162,153,
- 140,236,164, 5, 65,171, 16, 37,188,100, 39, 45, 64,138,102, 50,
- 81,218,135, 30,122,104, 27, 92, 35,243, 2, 49, 40, 4,177, 44,
- 0, 14,236, 47,188,176,169,157,101, 89,143,121,195,222,152,149,
- 189,206,239, 64, 16,148,200, 69, 34, 97, 48, 43,123, 29, 81, 90,
- 139,197, 98, 41, 43, 59,162, 3, 63,159, 63,230,140,222,153,152,
- 20, 0,167, 94, 90,135,251,102,179, 88,204, 53, 36,121,147,213,
- 69,184, 40,247,193, 96, 85,141, 18, 38, 46,202,125,144, 56,222,
- 159, 94,223,221, 12,126,205,137, 99, 29,201, 96, 51, 32,150, 70,
- 0,128, 24, 21, 0, 47, 88,154,154,154,136,247, 30, 44, 30,187,
- 10,211, 50,255, 51,152,245,161,132,144,233, 89,107, 4, 69,134,
- 254,241,199, 31,191,133,143,192,156,177,134, 24, 4,128, 3, 96,
- 155, 54,237,188, 77, 54,155,173,159, 52,211,172,236,117,184,180,
- 224,113, 26, 84, 52,138,145, 75, 53,184,180,224,113, 92, 48,238,
- 110,226, 60,102,179,201,184,114,229,138, 15, 16,130,192,156,145,
- 128, 24, 4, 0,224, 39,116, 24,187,186, 58, 63, 20,146,105, 98,
- 234,207,241,139,233, 95,163,120,236, 42, 42, 4, 81,132, 92,170,
- 65,241,216, 85,248,197,244,175, 5, 71,241, 57,118,236,216, 46,
- 240, 27,120,232, 17,227,198, 15, 68,225, 76, 64,129, 56, 47, 32,
- 178,230,231,231,253,161,171, 75,183, 88,165, 82,147, 77, 8, 7,
- 160,150,167, 98, 78,222, 67,184, 48,247, 1, 52,233,247, 64,103,
- 60,133, 67, 13, 79, 5,167,182,148, 81, 49, 43,123, 29,146,213,
- 69,200, 74,156,235, 87,104,121,189,190,187, 99,222,188, 75,159,
- 5, 31,153,215,219,250,253,152, 35,214, 5,192,129, 99, 93,183,
- 225,249,231,159, 91,254,135, 63,172,223, 79,178, 67,144, 51, 82,
- 137, 28,217, 73, 11,144,157,180, 64,112,255, 64,168,119, 26,242,
- 55,248,229, 72,196,202,121,120,131,101, 89,251,175,127,253,171,
- 245,224,141,191, 3, 34,112,255, 1,241, 52, 1,128,129,190,128,
- 135, 30,122,232, 84,117,245,185, 77,225,174, 12, 37,178,216,181,
- 171,244,253, 29, 59,118,156,133,103,108,190,152, 38,102, 5,192,
- 203, 80,160,227, 99,153, 54,237,188, 71,116, 58, 93,121,216, 42,
- 71,137, 40, 26, 27, 27, 79, 46, 91,118,205, 43,224,195,114, 91,
- 225, 99, 5, 96,172, 13, 1, 2, 49, 44, 0, 62, 24,108, 10,140,
- 27,151,121,165,193,208,223, 20,238, 10, 81,194,139, 78,167,107,
- 41, 44,156,240,123, 0, 53,224,135,254,132,110,252, 17,213,196,
- 180, 0, 12,227, 5,176, 0,250, 83, 83,199,156,223,210,210,114,
- 40, 92,245,163,132,151,154,154,234,163,227,198,101,222, 6,160,
- 17,252, 94,253, 62, 3,116,196,226,219, 31,136,113, 1,240,130,
- 243, 77,181, 2,232, 27, 63, 62,255,170,253,251,247, 61,203,178,
- 54, 91,120,171, 70, 9, 21, 54,155,205,182,109,219,214, 87,167,
- 76,153,188, 30,124, 96,206, 51, 24, 33, 54, 95,172, 34, 38, 1,
- 112,223,156,145, 3,191,222,187,127,225,194,203,255,119,193,130,
- 203,102,119,119,235, 26,194, 83, 53, 74,168,232,232,232,104,154,
- 50,165,248,151, 43, 87,174,120, 9, 64, 5,188, 7,230,116, 16,
- 243, 34, 16,243, 2,224,230,186,121,115,239, 88, 0,166, 67,135,
- 14,157,203,202,202,156,189,115,231,183,127,239,233,209,119,132,
- 161,170,148, 32,162,215,119,119,124,252,241, 71,255,204,205,205,
- 94,221,208,208, 80, 5,160, 28,252,100,159, 17, 99,243,197,170,
- 251, 15,136,100, 30,192, 11,187,242, 57,167,109,194,188,221, 76,
- 59,248,200, 66,236,178,101,215,252, 5,192,166, 59,239,188,115,
- 238, 47,127,121,243,205,185,185,185,231, 37, 36, 36,166,203,229,
- 114,225, 51, 75, 40, 97,195,106,181, 88,187,187,245,109,117,117,
- 53,199, 94,124,241,197,173,111,191,253,246, 89,240, 17,121,155,
- 193,175,242, 27,206,240, 69, 97,252,128, 72, 4, 0, 24, 86, 4,
- 56,184, 6, 34,177, 3,104,217,180,105,211,167,155, 54,109,250,
- 26, 64, 10,128,132,107,175, 93, 94,116,199, 29,107,175,203,205,
- 205,155,164,213,106, 83,237,118, 78, 18, 31, 31,151,164,209,196,
- 169, 66,122, 34, 1,194,110,183,163,185,185,169, 13, 0, 50, 51,
- 179,198, 74,165,209,233, 12,246,245,245,153,123,123,123,186,165,
- 82, 41,215,219,219,219, 81, 87, 87,119,234,217,103,159,217,190,
- 99,199,142, 70,240,225,186,186,193,191,233,117,224,251,125,134,
- 11,198, 41, 42,227, 7, 68, 36, 0, 0,145, 39, 0,184,134, 33,
- 179,129, 95, 22, 42,217,186,245,179,147, 91,183,126,246, 53,248,
- 216,132,113, 0, 82,186,186,186,183, 6,187,206,193,164,176,112,
- 226, 61, 0,244,125,125,134, 79,195, 93, 23,127,145, 72, 36,220,
- 132, 9,227,127, 7,126,254,190, 13,188,209, 59,226, 67,218, 64,
- 22,151,207, 89, 0, 0,136,195,248, 1, 17,244, 1,184,227,165,
- 79,192,241,237, 30, 1,134,117,251, 88,192,139, 65, 19,248, 9,
- 35,167, 24, 70, 26,208, 24,242, 97,192, 8,224,156, 68, 34,137,
- 218,135,125, 32,244,187, 17,192,201,129, 79, 45,248,169,188,102,
- 240, 2,224,126, 31,125, 69,250, 17,157,241, 3, 34, 20, 0,192,
- 103,199,160,227,111,231, 7,195,151, 24,216,248, 79,244, 6, 31,
- 26, 8,124,225, 56,151,168,101, 64, 0,236, 24,188, 39,195, 26,
- 189,251,253, 5, 68,232,246, 59, 35,170, 38,128, 51, 94, 66,146,
- 185,223,120,231,149,132,142,111,231, 88,133,118, 73, 84, 71, 29,
- 149, 0, 67, 6, 17,237,184, 27, 58,139, 97,220,123,120,222,107,
- 209, 25,190, 3,209, 10,128,131, 17, 98, 19,194,237, 55,231,240,
- 229,177,240,192, 56, 71,188,141, 74, 6, 52,216, 91, 19,142,104,
- 76, 95,172,134,239, 64,244, 2,224,224,133, 93,249,220,218,249,
- 213, 0, 0,137,235,171,221,215,176, 97,148,123, 0, 0, 98,192,
- 3, 24,232,191,240,230,222,251,156,205, 39,118,163,119, 70,148,
- 125, 0, 35,193,249, 0, 62,198,138,163,152, 88, 59, 15,151,207,
- 48,247,145, 50, 0, 21, 0,113, 67,141, 65,228, 80, 1,160, 80,
- 68, 12, 21, 0, 10, 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10,
- 69,196, 80, 1,160, 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160,
- 80, 68, 12, 21, 0, 10, 69,196, 80, 1,160,196,202,100,160, 88,
- 57,143,144, 66, 5,128, 66, 17, 49, 84, 0, 40, 81,206,224,178,
- 102,138, 31, 80, 1,160, 80,227, 17, 49, 84, 0,252,135,227, 56,
- 46,138,119,211,137,141, 85,113,118,187,221,121, 57,115, 76,156,
- 83, 40,161,251, 1, 56,241,226,247, 5, 66,146,115, 28,199, 89,
- 72, 18,230, 38, 47, 70,157,110,135,127,149, 18, 72,130, 50,151,
- 40,221,128,225,176, 0,236, 28,199,177, 18,137,100,196,103, 33,
- 65,153,139, 30,115,221, 40,107, 72, 70,110,242, 98,162,116,118,
- 59,107,197,208, 14, 64, 46, 8,188,159,162,132,122, 0,254,193,
- 1, 96,173, 86, 11, 81,112,209, 68, 85,232, 30, 68,173, 42,143,
- 40,157,217,108, 49, 98, 32, 22,130,205,102,235, 11,228,177, 3,
- 65,146,122, 2, 81, 58,189, 94,223, 6,215,125, 13,169, 23, 32,
- 0, 42, 0,254, 99,211,233,116,123, 73, 18,142,141,159, 25,236,
- 186, 8, 46,171,163,163,189, 30,252,110,186,172,193,208,127, 58,
- 144,199, 14, 4,105,113,211,137,210, 85, 87,159,171, 4,191, 21,
- 56, 64,141, 95, 48, 84, 0,132,227,120,200,216,111,190,249,230,
- 109,146, 12,233,218, 18, 48,210,208,196, 15, 25,151, 56,143, 40,
- 221,241,227,149, 63,129,223, 59,223,218,222,222,190, 51,144,199,
- 30, 45,140, 84,133,116,109, 9, 81,218,127,253,235, 95,219,193,
- 71,250, 17, 85, 76,191, 64, 65, 5,192,127,236,107,215,174, 57,
- 105,183,219,173, 35, 37, 84, 48, 90,228, 39, 47, 9,122,133,146,
- 213, 69, 72, 37,124,115,222,115,207, 61, 91, 49, 16, 60,227,222,
- 123,215,191, 70,146, 39, 53,110, 58,146,213, 69,163,168, 33, 25,
- 249,201, 75,160, 96,180, 35,166,179,217,172,182,247,222,123,175,
- 14,124, 32, 16,106,244,126, 64, 5, 64, 0, 78,155, 73, 14, 70,
- 23,182, 88, 44,245, 36,121,103,140,187, 19, 82, 73,112,195, 11,
- 206,202, 94, 71,148,206, 98, 49,155,207,157, 59,215,135,129, 24,
- 121,219,183,111,215,177, 44,107, 12,100, 25,254, 34,149,200, 49,
- 99,220,157, 68,105,245,250,158, 54,240,238,191, 67,132, 7,247,
- 56,164, 27,127,146, 65, 5, 96,116, 88,123,122,244, 7, 72, 18,
- 38, 40,115, 49, 41,109,101,208, 42,146, 30, 63, 11,217, 73, 11,
- 136,210,234,116,221, 77, 24, 10,144,201, 1,176,153, 76,198,106,
- 146,188,217, 73, 11,144, 65,232,158,251,195,164,180,149,196, 35,
- 25, 13, 13,245,149,224,189,152, 88,217,220, 52,228, 80, 1,240,
- 31, 14, 0,123,244,232,209,119, 72, 51,204,206, 89,143, 20,205,
- 228,128, 87, 68, 37, 75,193,101, 19,158, 34, 78, 95, 81, 81,190,
- 7,124,176, 76,135,225, 88,218,218,218, 62, 39,205, 63,127,252,
- 70,168,100, 41,130,235, 57, 18, 41,154,201,152,157,179,158, 56,
- 253, 71, 31,125,180, 3,174,238, 63, 21, 1,129, 80, 1, 24, 29,
- 236,181,215, 46,219, 99,177, 88, 58, 73, 18, 51, 82, 21, 22, 21,
- 110, 14,168,241, 72, 37,114, 92, 81,248, 2, 52,138,116,162,244,
- 44,203,218,175,187,110,249, 59, 24, 18, 0, 59, 0,235,212,169,
- 83,158,226, 56,142, 37, 57,134, 70,145,142, 43, 10, 95, 8,104,
- 147, 70, 37, 75,193,162,194,205,196,157,165,125,125,125,250, 13,
- 27,158, 60, 10,234, 1,140, 10, 42, 0,254, 49, 24, 30, 12,128,
- 185,185,185,233, 85,210,140, 26, 69, 58,150, 77,121, 47, 32,157,
- 105,106,121, 42,150, 20,191,138, 52, 1,195,115,245,245,117, 71,
- 193, 7, 57,213,195, 53,160,134,177,167, 71, 79, 52,172, 9, 0,
- 105,241, 51,177,180,248, 13,168,229,169, 2,107,237, 73,178,186,
- 8, 87, 79,217, 66, 44, 98, 0,176,127,255,190, 47, 0,180,129,
- 31,202, 4,168, 23,224, 23, 84, 0,252,199,241,160, 89, 39, 79,
- 46,254,155,209,104, 36,154, 20, 4, 0,241,202,108, 92, 61,101,
- 11,198,143, 89,230,119,225, 25,218, 18, 44,155,242, 62,210,227,
- 103, 17,231,177, 90,173,214, 41, 83, 38, 63, 8,160, 25,158, 17,
- 116, 44,153,153, 25, 43, 89,150, 37,154,221, 8,240, 34,176,108,
- 202,251,163,234, 19, 24, 63,102, 25,174,158,178,133,184,221, 15,
- 0,221,221,186,246,229,203,175,125, 29,252,121,248,138,255, 71,
- 33,128, 10,192,232, 24,124,123,214,212, 84, 63, 39, 36,163, 92,
- 170,193,252,241, 27,113,237,148, 15,145,153, 48,135, 56, 95,178,
- 186, 8,139, 10, 55,227,170,226, 55, 16,167,200, 20, 84,217, 51,
- 103, 78, 31, 0,239,250, 55,193, 51,146, 14, 11,192,168,215,119,
- 127, 33,228,152,113,138, 76, 92, 85,252, 6, 22, 21,110, 22,228,
- 213,100, 38,204,193,178, 41,239, 97,254,248,141,144, 75, 53, 66,
- 138,196,142, 29, 59, 62, 0,127, 14,206,238, 63, 53,126, 63,144,
- 4, 58, 82,146,209,104, 22,148,254,213,131,197, 1, 45, 63, 20,
- 12, 4, 18,117,254, 48, 0,226,154,154,154,119, 36, 37, 37, 95,
- 224,207, 49, 13,150, 86,212,117,239, 68,107,239, 65,244,152,107,
- 97,182,233,193,218, 77,208, 40,210,161,145,167, 35, 45,110, 58,
- 242, 82,150,248, 61,173,184,187,187,187, 61, 43, 43,227, 22, 0,
- 39, 49,228, 1, 56,135,201,150,128, 95, 27, 18,223,209,209,121,
- 68,163,137, 27,231, 79, 57,122, 83, 53,106,187,182,163,189,191,
- 2, 6,107, 43, 12,150, 86, 48, 82, 21,148,178, 68, 36, 40,243,
- 48, 86, 59, 11,121, 73,139, 4,185,251,206, 52, 52,212,159, 40,
- 42, 42,252, 61,128, 35,224, 59, 0, 61,226, 1, 70,211, 16,224,
- 173, 37, 85,126,229, 83,171,149, 1, 41,159, 46, 6,242, 31,231,
- 135,204, 14,192,152,149,149,121,117,119,119,207, 41,133, 66,145,
- 32,244, 96, 26, 69, 58,138,199,174, 66,241,216, 85,129,171,225,
- 0, 44,203,178, 55,222,184,226, 30,240,111,205, 22,248,142,160,
- 107, 3,208,255,224,131,127,188,114,227,198,167,202,165, 82,169,
- 224,231, 35, 81, 85,128,233, 89,107, 2, 81,109, 15,140, 70, 67,
- 95, 81, 81,225, 61, 0,106,193,247, 99,196, 98,188,198,144, 18,
- 118, 15, 32, 26,209,104, 84,142,176,192,206, 94,128, 20,128,226,
- 139, 47,190, 92,118,217,101, 11,222,150, 68, 80,232,224,119,222,
- 121,251,249,213,171,111,123, 15, 64, 57,248, 73, 51,238,111,127,
- 7,142,243, 80,238,221,187,111,237,204,153,231, 63, 17,218,154,
- 250,198,110,183,115, 79, 62,249,196, 67,143, 60,242,240,151, 0,
- 78, 96, 96, 37, 35,188, 68, 3, 54, 24, 76, 49, 47, 4,129,242,
- 0,168, 0,248,137, 23, 17,144, 14,124,212,223,127,191,123,205,
- 236,217, 37,143,135,173,114, 78,236,219,183,119,235, 21, 87, 44,
- 124, 30, 64, 5,124,184,204, 3, 73,221,155, 52,234,163, 71, 43,
- 159,153, 48, 97,194,175, 67, 95,107, 79, 6, 68,236, 35, 0, 71,
- 1, 24, 48,180, 4,216,197,147, 17,131,241, 3,129, 19, 0,218,
- 9, 24, 56, 28, 15,163,105,254,252,121,255,119,232,208, 79,127,
- 9,119, 40,234, 31,127,220,255,197, 21, 87, 44,252, 7,128, 42,
- 12,205,252,243,102,252,112,251,141, 5, 96,156, 54,109,234,186,
- 211,167, 79,189, 25,218, 90,187,194,113, 28,247,233,167,159,188,
- 188,122,245,109, 91,193,191,249, 13,240,222,124,161,248, 1, 21,
- 0, 63,113,122,211,184,183, 65,237, 0,140,243,230, 93,250,247,
- 47,190,216,246, 59,179,217,108, 8,117,221,108, 54, 27,251,238,
- 187, 91, 54, 95,126,249,130,103,193, 27, 77, 39, 60, 13,127,164,
- 143, 29,128, 97,198,140,233,119,237,221,187,231, 17,150,101,137,
- 38, 9, 5, 18,163,209,104,120,250,233,191, 63,186,106,213, 77,
- 111,130,127,243, 59, 60, 24,175,109,127,177,188,253, 3, 9,109,
- 2,140, 2,167,102, 0,224,217, 31, 32, 5, 32, 7,144, 86, 83,
- 83,187,109,236,216,244,192,207, 1,246, 66,119,183,174,117,233,
- 210,171,254, 80, 94, 94, 94, 7,224, 20, 60,223,252,206,109,127,
- 111,125, 0,142,111, 41,134,154, 3,202,235,175,191,126,226,166,
- 77, 47,110, 77, 72, 72,200, 8,246, 57, 0, 64, 99, 99,195,233,
- 194,194,137,235,192, 79,246,169, 6,191,232,199,155,219, 63,120,
- 14, 98, 18, 0,218, 7, 16, 33,184,245, 5, 56,190,157, 13, 72,
- 6, 32,110,207,158,189,127,157, 52,169,120,133, 70,163, 17, 60,
- 66, 64,130,197, 98,177,158, 58,117,114,255,133, 23,150,252, 13,
- 64, 35,120,163,177,129,220,248, 29,120, 19, 1,135,152,197, 31,
- 59, 86,249,122, 78, 78,238,124,185, 92,174, 8,198,121,244,247,
- 247,245, 28, 56,112,224,171,107,174,185,250, 21,240,189,253,117,
- 62,206,193,229, 60,196,100,252, 0, 21,128,136,193,139, 23,224,
- 248,118,127,139, 42, 0,100,148,149,149, 63, 91, 80, 80,176, 64,
- 46, 87, 4,196,128, 88,150,181,215,213,213, 30,157, 58,117,202,
- 159, 48, 52,201,167, 21,158,237,125,199,230,153, 94,223,154, 62,
- 188, 25, 56,157,131, 67,204,148, 0,178, 79,157, 58,253,114, 86,
- 214,184,243,165, 82,105, 64,154,145, 22,139,197, 82, 85,117, 98,
- 223,156, 57, 23,109, 0,255,214,111, 30, 56,159, 17,141,223,249,
- 60,196, 2, 21,128, 8, 98, 4, 17,112,247, 6, 20, 0, 50, 55,
- 109,218,116,253,194,133, 87,252, 34, 45,109,236,120,181, 90,173,
- 21, 50,106,104, 54,155, 76, 93, 93, 93, 77,165,165,223,125,181,
- 122,245,234,175,192,187,249,205,224,223,252,190, 12,102, 68,163,
- 17,120, 30, 74, 0,121,111,190,249,230,175, 46,185,100,238,181,
- 201,201, 41,227,148, 74, 37,241,182, 71, 28,199,193,104, 52,244,
- 182,181,181,215,110,219,246,217,231,247,222,123,239,247, 0,186,
- 193,207, 83,104, 27,205,121,136, 1, 42, 0, 17, 6,129,241,184,
- 247, 15,200, 0,196, 3, 72, 3,144,244,194, 11, 47, 46,187,248,
- 226,139,231,101,102,102, 77, 84,169, 84,241, 12,195,200, 36, 18,
- 137,196,102,179, 89,173, 86,139,177,189,189,163,161,188,188,236,
- 224,218,181,107,182,117,119,119,155,192,119,136,117, 3,232,128,
- 235,218,126,159,157,100, 32, 48, 26, 63,206, 67, 14, 32, 9, 64,
- 90, 90, 90, 90,202, 63,254,177,233,198, 25, 51,102,148,140, 25,
- 51, 38, 71, 46, 87,168,101, 50,153,156,227, 56,142,101, 89,155,
- 201,100,236,107,106,106, 58,179,111,223,190,125,119,222,121,199,
- 78,240,115, 18,116,224,167,244,118,194,181,135,127, 84,231, 17,
- 235, 80, 1,136, 64,220,140, 7,112,117,165,125, 25,145,227,155,
- 1,144,224,244, 81, 13,252, 6,240,187,247,154,193, 27,189, 30,
- 174, 6,239,236,226, 15,103, 44,196, 70, 51,140, 8,120, 59, 15,
- 169,219,223, 14, 65, 72, 0, 47,112,138,129,243,224, 6,206,195,
- 232,116, 30,253, 4,231,224,247,121,196, 50, 84, 0, 34, 20, 31,
- 34,224,254,237,237, 3, 47,127, 59,227,205, 16,134, 51, 22,175,
- 157,125,164, 70, 51,194,121,144,158,203, 72,231, 65,122, 46,126,
- 159, 71,172, 66, 5, 32,194, 33, 20, 2,199,247, 72, 70,227,192,
- 151, 81,140,104, 48,128,112,163,241,114, 14,222,234, 56, 92,253,
- 133,156,199,112,231, 54,136,216, 13,223, 1, 21,128, 40, 96, 4,
- 3,114,254,219,219,111,190,224,188,252,237,237,183, 65, 70,107,
- 52,177,114, 30,177, 4, 21,128, 40,131,192,136,134,251,205, 25,
- 111, 55,204,235, 77, 12,180,193,248, 56, 7, 32,136,231, 65,141,
- 222, 59, 84, 0,162,152, 97, 12,105,212,132,202, 96, 98,225, 28,
- 162, 25, 42, 0, 49,202, 72,134, 21, 45,198, 17, 43,231, 17,169,
- 4, 74, 0,254, 63, 34, 58,182, 52, 79,174,223,189, 0, 0, 0,
- 0, 73, 69, 78, 68,174, 66, 96,130
-};
-#endif /* CONFIG_DARWIN */
-
-static const unsigned char _data_android_icon_32_png[1321] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 32, 0, 0, 0, 32, 8, 6, 0, 0, 0,115,122,122,
- 244, 0, 0, 4,240, 73, 68, 65, 84, 88,133,237, 87, 91,108, 20,
- 85, 24,254,102,167, 51,237,238, 78,183,237,178,180,182,213,165,
- 110, 98, 35, 18,181, 41, 41, 18,185, 52, 1,251,162, 4, 98,212,
- 180, 38, 74,170,132, 7,170, 38, 26, 31, 20,130, 24,130,196,128,
- 190, 24,181, 38,120, 71,177, 82,110,106,212, 4,154, 0, 69,170,
- 98, 85,104,161, 8,180,118,183, 40,236,165,179,219,153,189,204,
- 206,238,204,244,248, 80,102,178,211,237,110,161, 53,242,226,151,
- 76,246, 59,255,249,207,255,127,123,230,159,115,161, 8, 33, 0,
- 0,138,162,144, 7, 84, 40,196, 47,103, 89,118,105, 58,157, 62,
- 89, 94,238, 58, 33, 73, 50,201,116,176,217,138, 44, 60, 31,121,
- 154, 97,152, 37,138,162,244,184, 92,206,143, 36, 73, 30,159, 28,
- 200,102, 43, 50, 56, 33, 4,212,117, 8,160, 68, 49,246, 5,195,
- 48, 45, 25, 3,131,137, 68,226, 89,139,197, 82, 14, 0,170,170,
- 122,237,118,251, 86,154,166, 27,116, 31, 77,211,122,139,139,237,
- 139,219,187,107, 76, 34,218, 26,125, 55, 38, 32, 20,226, 27, 57,
- 142, 59,158, 75, 93, 62, 72,146,180,190,115,160,254,131,124, 2,
- 44,211, 5, 97, 89,118,169,206,207,250,119, 33,154,186,156,215,
- 191,199,183,217,224,170,170,172,152, 46,254,180, 2,100, 89,246,
- 233,252,206,138, 39,208,119,229, 93, 16,162,129, 79,244,227,210,
- 104, 39, 46,141,118,226,106,244, 71,164, 84, 17,231,131,187,225,
- 113,174, 50,198,198,227, 9,170,173,209,151,183,184, 10,242,117,
- 242,124,228, 65,155,205,246,185,222, 38, 68, 67, 74, 19,241,217,
- 111,117, 24, 39, 74,150, 63, 87,120, 43, 86,222,209,110,180,171,
- 170,170, 90, 4, 33, 58, 84, 90,234,216,210,222, 93, 67,178, 6,
- 32,255, 12, 80, 69, 69, 69, 70, 52, 33, 57,132,175,206,173,194,
- 85,177, 7, 52,197, 76, 57, 64,213, 36,124, 51,240, 48, 46,132,
- 58, 12, 27,203,178,155, 71, 71,195, 15,228, 74, 50,165, 0, 66,
- 8, 34, 17,225,113,139,197, 50, 15, 0,164,116, 16,135, 47,182,
- 66, 74, 7,177,110, 73, 63,230, 87, 54,103,141,185,171, 98, 45,
- 30,187,247, 40, 8,209,240,243,200, 86,248,198, 14, 27,125,133,
- 133,133,175,111, 88,238,197,134,229,222,172,113, 89,175, 96,120,
- 216,231, 22,132,104, 27, 77,211,166,226, 75, 42, 60, 0,224,148,
- 119, 39, 46, 6, 15,101, 5,250, 51,252, 53, 34,210, 31, 70,251,
- 212,200, 54,184, 75, 87,192, 66, 49, 40, 40, 40, 88, 40, 8,209,
- 183,210,233,116, 23,128,239, 0, 24,175,195,244, 25, 10, 66,116,
- 19,203,178,219, 39, 7,239,236,107,132,148, 14, 78, 53, 89,121,
- 241,208,252, 47, 49,151,171, 51,217, 84, 85,253,214,225,224, 86,
- 3, 32,166,117, 32, 28, 30,107,176,217,108,191,220,112,150, 25,
- 64,150,229, 86,167,179,244, 83,147,128,104, 52,254, 49,195, 48,
- 173, 0,240,183,112, 28,231, 2, 31,162,204, 90,139, 6,247,203,
- 216,253,235,221, 51, 74,212,218,112, 1,222,200,247, 24, 8,124,
- 130,170,146,251, 81, 95,253, 60, 0,128, 16,146,176,219,173,197,
- 132, 16, 98, 20, 33, 77,211, 75,116,222,251,215, 14, 4, 98,189,
- 240,199,126,130, 37, 71,197, 95, 47,250,174,190, 3, 62,209,143,
- 203, 99, 71, 12, 27, 69, 81,246, 64, 32, 88, 15,152,191, 2,171,
- 78, 68,121,162, 90,133,228,240,172,146,103,198,152, 28,203,239,
- 15,184, 38, 11,248, 79,145, 74,201,244, 77, 21,160,105, 26,117,
- 83, 5,232,248, 95, 64,166,128,164, 78, 74,173, 30,211,239,108,
- 144, 43,150, 36, 37,227, 38, 1,154,166,245,232,188,225,182,141,
- 168,116, 44, 70,117, 73, 35, 8,209,102, 37,160,190,250, 5, 84,
- 112, 11,225,113,174, 54,108,170,170,202, 77, 77, 43, 79, 3, 25,
- 155,145,162, 40,237,250, 74, 88, 93,178, 12,213, 37,203,102,149,
- 88,135,187,172, 9,238,178, 38,147,237,216,177,163, 59, 0,152,
- 103,192,229,114,246,170,170,250,210,191,146, 53, 15,188, 94,239,
- 137, 53,107, 86,191,135,107, 59,162,169, 8, 29, 14,110,231,249,
- 243, 3,110, 65, 24,123, 67, 16,198,250,117,251, 76,102,195,237,
- 108, 52,181,207,156, 57,189,119,207,158, 61,235, 23, 44,152,223,
- 12, 32,172,219,167, 58, 21, 83,152,184, 7,188,202,113,220, 22,
- 221, 40,202, 94, 12,241,135,112,214,191, 11, 0, 96,101, 92,104,
- 174, 59, 9, 0, 56,233,221,136, 33,126,226,140, 80,193, 45,196,
- 34,247, 38,148,217,106,141,125, 36,153, 76,134,231,204, 41,171,
- 5, 16, 3, 48,126,237, 33,185, 78,197, 4,192,120, 60, 30,127,
- 155, 16,114, 69, 55,150, 20,221, 14, 59, 91,105, 56,101,110, 82,
- 86,102,174,193,153,130, 98,204,177, 47, 48,245,119,117, 29,217,
- 14, 64,108,239,174, 81, 0,104,200, 56,144,228, 92, 7, 60,158,
- 26, 62, 24, 12,214,137,162,240, 90, 46,159,233, 16, 10,133,134,
- 59, 58, 58,158,107,105,105,126, 31, 19,255, 58, 11,121, 23, 34,
- 143,167,134,103, 24,214,111, 56, 83,180,209, 71,153,120,206, 48,
- 193,117,235,158,218, 5, 64,154,201,169, 24, 0, 64, 8, 49,214,
- 135,185, 92, 29,104,203,196,221,174,210,177,216,240,185,165,120,
- 145,193, 43,139,239, 51,120, 32,224,255, 29,128, 50,249,122,150,
- 137,235,186, 27, 38, 18, 73,129,162, 40, 7, 0,164, 84, 17,177,
- 212, 8, 92,246,123, 76, 78, 73,133,135,172, 70, 80,102,173, 53,
- 108,251,247,239,123, 36, 62,239,149,131,153,126, 55,124, 53, 3,
- 64, 82,169,212, 51,122,163,176,160, 36, 43, 57, 48,241, 85,100,
- 38, 31, 28, 28,236, 90,187,246,201,227,211, 71, 39, 4,250, 44,
- 228, 1, 21, 14,143, 61, 42,138,177,139,146, 36, 19, 73,146, 73,
- 60, 46, 41, 7, 14, 28,124,179,187,251,135, 23, 5, 33,234,211,
- 237,162, 24, 75,236,221,219,185, 13, 64, 57, 0, 90,146,100,100,
- 62,147,115,255, 3, 56,204, 60,122,104, 43, 57,236, 0, 0, 0,
- 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-
-static const FileEntry _file_entries[] =
-{
-
- { "android_icon_16.png", _data_android_icon_16_png, 460 },
-#ifdef CONFIG_DARWIN
- { "android_icon_256.png", _data_android_icon_256_png, 13369 },
-#endif
- { "android_icon_32.png", _data_android_icon_32_png, 1321 },
- { NULL, NULL, 0 }
-};
diff --git a/android/main.c b/android/main.c
deleted file mode 100644
index e1d983c..0000000
--- a/android/main.c
+++ /dev/null
@@ -1,2889 +0,0 @@
-/* Copyright (C) 2006-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#ifdef _WIN32
-#include <process.h>
-#endif
-#include "libslirp.h"
-#include "sockets.h"
-
-#include "android/android.h"
-#include "qemu-common.h"
-#include "sysemu.h"
-#include "console.h"
-
-#include <SDL.h>
-#include <SDL_syswm.h>
-
-#include "math.h"
-
-#include "android/charmap.h"
-#include "modem_driver.h"
-#include "shaper.h"
-#include "proxy_http.h"
-
-#include "android/utils/debug.h"
-#include "android/resource.h"
-#include "android/config.h"
-#include "android/config/config.h"
-
-#include "android/skin/image.h"
-#include "android/skin/trackball.h"
-#include "android/skin/keyboard.h"
-#include "android/skin/file.h"
-#include "android/skin/window.h"
-#include "android/skin/keyset.h"
-
-#include "android/gps.h"
-#include "android/qemud.h"
-#include "android/hw-kmsg.h"
-#include "android/hw-control.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/dirscanner.h"
-#include "android/utils/path.h"
-#include "android/utils/timezone.h"
-#include "android/utils/display.h"
-
-#include "android/cmdline-option.h"
-#include "android/help.h"
-#include "hw/goldfish_nand.h"
-
-#include "android/globals.h"
-#include "tcpdump.h"
-
-#include "framebuffer.h"
-AndroidRotation android_framebuffer_rotation;
-
-#define STRINGIFY(x) _STRINGIFY(x)
-#define _STRINGIFY(x) #x
-
-#define VERSION_STRING STRINGIFY(ANDROID_VERSION_MAJOR)"."STRINGIFY(ANDROID_VERSION_MINOR)
-
-#define KEYSET_FILE "default.keyset"
-SkinKeyset* android_keyset;
-
-#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
-
-extern int control_console_start( int port ); /* in control.c */
-
-extern int qemu_milli_needed;
-
-/* the default device DPI if none is specified by the skin
- */
-#define DEFAULT_DEVICE_DPI 165
-
-static const AKeyCharmap* android_charmap;
-
-int android_base_port;
-
-#if 0
-static int opts->flashkeys; /* forward */
-#endif
-
-static void handle_key_command( void* opaque, SkinKeyCommand command, int param );
-
-#ifdef CONFIG_TRACE
-extern void start_tracing(void);
-extern void stop_tracing(void);
-#endif
-
-unsigned long android_verbose;
-
-int qemu_cpu_delay = 0;
-int qemu_cpu_delay_count;
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** U T I L I T Y R O U T I N E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-/*** APPLICATION DIRECTORY
- *** Where are we ?
- ***/
-
-const char* get_app_dir(void)
-{
- char buffer[1024];
- char* p = buffer;
- char* end = p + sizeof(buffer);
- p = bufprint_app_dir(p, end);
- if (p >= end)
- return NULL;
-
- return strdup(buffer);
-}
-
-/*** CONFIGURATION
- ***/
-
-static AConfig* emulator_config;
-static int emulator_config_found;
-static char emulator_configpath[256];
-
-void
-emulator_config_init( void )
-{
- char* end = emulator_configpath + sizeof(emulator_configpath);
- char* p;
- void* config;
-
- emulator_config = aconfig_node("","");
-
- p = bufprint_config_file(emulator_configpath, end, "emulator.cfg");
- if (p >= end) {
- dwarning( "emulator configuration path too long" );
- emulator_configpath[0] = 0;
- return;
- }
-
- config = path_load_file( emulator_configpath, NULL );
- if (config == NULL)
- D( "cannot load emulator configuration at '%s'\n",
- emulator_configpath );
- else {
- aconfig_load( emulator_config, config );
- emulator_config_found = 1;
- }
-}
-
-/* only call this function on normal exits, so that ^C doesn't save the configuration */
-void
-emulator_config_done( void )
-{
- int save = 0; /* only save config if we see changes */
- AConfig* guid_node;
- char guid_value[32];
- AConfig* window_node;
- int prev_x, prev_y, win_x, win_y;
-
- if (!emulator_configpath[0]) {
- D("no config path ?");
- return;
- }
-
- /* compare window positions */
- {
- SDL_WM_GetPos( &win_x, &win_y );
- prev_x = win_x - 1;
- prev_y = win_y - 1;
-
- window_node = aconfig_find( emulator_config, "window" );
- if (window_node == NULL) {
- aconfig_set( emulator_config, "window", "" );
- window_node = aconfig_find( emulator_config, "window" );
- save = 1;
- }
-
- prev_x = (int)aconfig_unsigned( window_node, "x", 0 );
- prev_y = (int)aconfig_unsigned( window_node, "y", 0 );
-
- save = (prev_x != win_x) || (prev_y != win_y);
-
- /* Beware: If the new window position is definitely off-screen,
- * we don't want to save it in the configuration file. This can
- * happen for example on Linux where certain window managers
- * will 'minimize' a window by moving it to coordinates like
- * (-5000,-5000)
- */
- if ( !SDL_WM_IsFullyVisible(0) ) {
- D( "not saving new emulator window position since it is not fully visible" );
- save = 0;
- }
- else if (save)
- D( "emulator window position changed and will be saved as (%d, %d)", win_x, win_y );
- }
-
- /* If there is no guid node, create one with the current time in
- * milliseconds. Thus, the value doesn't correspond to any system or
- * user-specific data
- */
-#define GUID_NAME "unique-id"
-
- guid_node = aconfig_find( emulator_config, GUID_NAME );
- if (!guid_node) {
- struct timeval tm;
- gettimeofday( &tm, NULL );
- sprintf( guid_value, "%lld", (long long)tm.tv_sec*1000 + tm.tv_usec/1000 );
- save = 1;
- aconfig_set( emulator_config, GUID_NAME, guid_value );
- }
-
- if (save) {
- char xbuf[16], ybuf[16];
-
- sprintf( xbuf, "%d", win_x );
- sprintf( ybuf, "%d", win_y );
-
- aconfig_set( window_node, "x", xbuf );
- aconfig_set( window_node, "y", ybuf );
-
- /* do we need to create the $HOME/.android directory ? */
- if ( !path_exists(emulator_configpath) ) {
- char* dir = path_parent(emulator_configpath, 1);
- if (dir == NULL) {
- D("invalid user-specific config directory: '%s'", emulator_configpath);
- return;
- }
- if ( path_mkdir_if_needed(dir, 0755) < 0 ) {
- D("cannot create directory '%s', configuration lost", dir);
- free(dir);
- return;
- }
- free(dir);
- }
- if ( aconfig_save_file( emulator_config, emulator_configpath ) < 0 ) {
- D( "cannot save configuration to %s", emulator_configpath);
- } else
- D( "configuration saved to %s", emulator_configpath );
- }
-}
-
-void *loadpng(const char *fn, unsigned *_width, unsigned *_height);
-void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
-
-#ifdef CONFIG_DARWIN
-# define ANDROID_ICON_PNG "android_icon_256.png"
-#else
-# define ANDROID_ICON_PNG "android_icon_16.png"
-#endif
-
-static void
-sdl_set_window_icon( void )
-{
- static int window_icon_set;
-
- if (!window_icon_set)
- {
-#ifdef _WIN32
- HANDLE handle = GetModuleHandle( NULL );
- HICON icon = LoadIcon( handle, MAKEINTRESOURCE(1) );
- SDL_SysWMinfo wminfo;
-
- SDL_GetWMInfo(&wminfo);
-
- SetClassLong( wminfo.window, GCL_HICON, (LONG)icon );
-#else /* !_WIN32 */
- unsigned icon_w, icon_h;
- size_t icon_bytes;
- const unsigned char* icon_data;
- void* icon_pixels;
-
- window_icon_set = 1;
-
- icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
- if ( !icon_data )
- return;
-
- icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
- if ( !icon_pixels )
- return;
-
- /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
- * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
- * on our CPU endianess
- */
- {
- unsigned* d = icon_pixels;
- unsigned* d_end = d + icon_w*icon_h;
-
- for ( ; d < d_end; d++ ) {
- unsigned pix = d[0];
-#if WORDS_BIGENDIAN
- /* R,G,B,A read as RGBA => ARGB */
- pix = ((pix >> 8) & 0xffffff) | (pix << 24);
-#else
- /* R,G,B,A read as ABGR => ARGB */
- pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
-#endif
- d[0] = pix;
- }
- }
-
- SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
- if (icon != NULL) {
- SDL_WM_SetIcon(icon, NULL);
- SDL_FreeSurface(icon);
- free( icon_pixels );
- }
-#endif /* !_WIN32 */
- }
-}
-
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** S K I N I M A G E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-void send_key_event(unsigned code, unsigned down)
-{
- if(code == 0) {
- return;
- }
- if (VERBOSE_CHECK(keys))
- printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " );
- kbd_put_keycode((code & 0x1ff) | (down ? 0x200 : 0));
-}
-
-
-
-typedef struct {
- AConfig* aconfig;
- SkinFile* layout_file;
- SkinLayout* layout;
- SkinKeyboard* keyboard;
- SkinWindow* window;
- int win_x;
- int win_y;
- int show_trackball;
- SkinTrackBall* trackball;
- int lcd_brightness;
- SkinImage* onion;
- SkinRotation onion_rotation;
- int onion_alpha;
-
- AndroidOptions opts[1]; /* copy of options */
-} QEmulator;
-
-static QEmulator qemulator[1];
-
-static void
-qemulator_done( QEmulator* emulator )
-{
- if (emulator->window) {
- skin_window_free(emulator->window);
- emulator->window = NULL;
- }
- if (emulator->trackball) {
- skin_trackball_destroy(emulator->trackball);
- emulator->trackball = NULL;
- }
- if (emulator->keyboard) {
- skin_keyboard_free(emulator->keyboard);
- emulator->keyboard = NULL;
- }
- emulator->layout = NULL;
- if (emulator->layout_file) {
- skin_file_free(emulator->layout_file);
- emulator->layout_file = NULL;
- }
-}
-
-
-static void
-qemulator_setup( QEmulator* emulator );
-
-static void
-qemulator_fb_update( void* _emulator, int x, int y, int w, int h )
-{
- QEmulator* emulator = _emulator;
-
- if (emulator->window)
- skin_window_update_display( emulator->window, x, y, w, h );
-}
-
-static void
-qemulator_fb_rotate( void* _emulator, int rotation )
-{
- QEmulator* emulator = _emulator;
-
- qemulator_setup( emulator );
-}
-
-
-
-static int
-qemulator_init( QEmulator* emulator,
- AConfig* aconfig,
- const char* basepath,
- int x,
- int y,
- AndroidOptions* opts )
-{
- emulator->aconfig = aconfig;
- emulator->layout_file = skin_file_create_from_aconfig(aconfig, basepath);
- emulator->layout = emulator->layout_file->layouts;
- emulator->keyboard = skin_keyboard_create_from_aconfig(aconfig, opts->raw_keys);
- emulator->window = NULL;
- emulator->win_x = x;
- emulator->win_y = y;
- emulator->opts[0] = opts[0];
-
- /* register as a framebuffer clients for all displays defined in the skin file */
- SKIN_FILE_LOOP_PARTS( emulator->layout_file, part )
- SkinDisplay* disp = part->display;
- if (disp->valid) {
- qframebuffer_add_client( disp->qfbuff,
- emulator,
- qemulator_fb_update,
- qemulator_fb_rotate,
- NULL );
- }
- SKIN_FILE_LOOP_END_PARTS
- return 0;
-}
-
-
-static AndroidKeyCode
-qemulator_rotate_keycode( QEmulator* emulator,
- AndroidKeyCode sym )
-{
- switch (skin_layout_get_dpad_rotation(emulator->layout)) {
- case SKIN_ROTATION_90:
- switch (sym) {
- case kKeyCodeDpadLeft: sym = kKeyCodeDpadDown; break;
- case kKeyCodeDpadRight: sym = kKeyCodeDpadUp; break;
- case kKeyCodeDpadUp: sym = kKeyCodeDpadLeft; break;
- case kKeyCodeDpadDown: sym = kKeyCodeDpadRight; break;
- default: ;
- }
- break;
-
- case SKIN_ROTATION_180:
- switch (sym) {
- case kKeyCodeDpadLeft: sym = kKeyCodeDpadRight; break;
- case kKeyCodeDpadRight: sym = kKeyCodeDpadLeft; break;
- case kKeyCodeDpadUp: sym = kKeyCodeDpadDown; break;
- case kKeyCodeDpadDown: sym = kKeyCodeDpadUp; break;
- default: ;
- }
- break;
-
- case SKIN_ROTATION_270:
- switch (sym) {
- case kKeyCodeDpadLeft: sym = kKeyCodeDpadUp; break;
- case kKeyCodeDpadRight: sym = kKeyCodeDpadDown; break;
- case kKeyCodeDpadUp: sym = kKeyCodeDpadRight; break;
- case kKeyCodeDpadDown: sym = kKeyCodeDpadLeft; break;
- default: ;
- }
- break;
-
- default: ;
- }
- return sym;
-}
-
-static int
-get_device_dpi( AndroidOptions* opts )
-{
- int dpi_device = DEFAULT_DEVICE_DPI;
-
- if (opts->dpi_device != NULL) {
- char* end;
- dpi_device = strtol( opts->dpi_device, &end, 0 );
- if (end == NULL || *end != 0 || dpi_device <= 0) {
- fprintf(stderr, "argument for -dpi-device must be a positive integer. Aborting\n" );
- exit(1);
- }
- }
- return dpi_device;
-}
-
-static double
-get_default_scale( AndroidOptions* opts )
-{
- int dpi_device = get_device_dpi( opts );
- int dpi_monitor = -1;
- double scale = 0.0;
-
- /* possible values for the 'scale' option are
- * 'auto' : try to determine the scale automatically
- * '<number>dpi' : indicates the host monitor dpi, compute scale accordingly
- * '<fraction>' : use direct scale coefficient
- */
-
- if (opts->scale) {
- if (!strcmp(opts->scale, "auto"))
- {
- /* we need to get the host dpi resolution ? */
- int xdpi, ydpi;
-
- if ( get_monitor_resolution( &xdpi, &ydpi ) < 0 ) {
- fprintf(stderr, "could not get monitor DPI resolution from system. please use -dpi-monitor to specify one\n" );
- exit(1);
- }
- D( "system reported monitor resolutions: xdpi=%d ydpi=%d\n", xdpi, ydpi);
- dpi_monitor = (xdpi + ydpi+1)/2;
- }
- else
- {
- char* end;
- scale = strtod( opts->scale, &end );
-
- if (end && end[0] == 'd' && end[1] == 'p' && end[2] == 'i' && end[3] == 0) {
- if ( scale < 20 || scale > 1000 ) {
- fprintf(stderr, "emulator: ignoring bad -scale argument '%s': %s\n", opts->scale,
- "host dpi number must be between 20 and 1000" );
- exit(1);
- }
- dpi_monitor = scale;
- scale = 0.0;
- }
- else if (end == NULL || *end != 0) {
- fprintf(stderr, "emulator: ignoring bad -scale argument '%s': %s\n", opts->scale,
- "not a number or the 'auto' keyword" );
- exit(1);
- }
- else if ( scale < 0.1 || scale > 3. ) {
- fprintf(stderr, "emulator: ignoring bad -window-scale argument '%s': %s\n", opts->scale,
- "must be between 0.1 and 3.0" );
- exit(1);
- }
- }
- }
-
- if (scale == 0.0 && dpi_monitor > 0)
- scale = dpi_monitor*1.0/dpi_device;
-
- if (scale == 0.0)
- scale = 1.0;
-
- return scale;
-}
-
-void
-android_emulator_set_window_scale( double scale, int is_dpi )
-{
- QEmulator* emulator = qemulator;
-
- if (is_dpi)
- scale /= get_device_dpi( emulator->opts );
-
- if (emulator->window)
- skin_window_set_scale( emulator->window, scale );
-}
-
-
-static void
-qemulator_set_title( QEmulator* emulator )
-{
- char temp[64];
-
- if (emulator->window == NULL)
- return;
-
- snprintf( temp, sizeof(temp), "Android Emulator (%s:%d)",
- avdInfo_getName( android_avdInfo ),
- android_base_port );
-
- skin_window_set_title( emulator->window, temp );
-}
-
-/* called by the emulated framebuffer device each time the content of the
- * framebuffer has changed. the rectangle is the bounding box of all changes
- */
-static void
-sdl_update(DisplayState *ds, int x, int y, int w, int h)
-{
- /* this function is being called from the console code that is currently inactive
- ** simple totally ignore it...
- */
- (void)ds;
- (void)x;
- (void)y;
- (void)w;
- (void)h;
-}
-
-
-
-static void
-qemulator_light_brightness( void* opaque, const char* light, int value )
-{
- QEmulator* emulator = opaque;
-
- VERBOSE_PRINT(hw_control,"%s: light='%s' value=%d window=%p", __FUNCTION__, light, value, emulator->window);
- if ( !strcmp(light, "lcd_backlight") ) {
- emulator->lcd_brightness = value;
- if (emulator->window)
- skin_window_set_lcd_brightness( emulator->window, value );
- return;
- }
-}
-
-
-static void
-qemulator_setup( QEmulator* emulator )
-{
- AndroidOptions* opts = emulator->opts;
-
- if ( !emulator->window && !opts->no_window ) {
- SkinLayout* layout = emulator->layout;
- double scale = get_default_scale(emulator->opts);
-
- emulator->window = skin_window_create( layout, emulator->win_x, emulator->win_y, scale, 0);
- if (emulator->window == NULL)
- return;
-
- {
- SkinTrackBall* ball;
- SkinTrackBallParameters params;
-
- params.diameter = 30;
- params.ring = 2;
- params.ball_color = 0xffe0e0e0;
- params.dot_color = 0xff202020;
- params.ring_color = 0xff000000;
-
- ball = skin_trackball_create( &params );
- emulator->trackball = ball;
- skin_window_set_trackball( emulator->window, ball );
-
- emulator->lcd_brightness = 128; /* 50% */
- skin_window_set_lcd_brightness( emulator->window, emulator->lcd_brightness );
- }
-
- if ( emulator->onion != NULL )
- skin_window_set_onion( emulator->window,
- emulator->onion,
- emulator->onion_rotation,
- emulator->onion_alpha );
-
- qemulator_set_title( emulator );
-
- skin_window_enable_touch ( emulator->window, android_hw->hw_touchScreen != 0 );
- skin_window_enable_dpad ( emulator->window, android_hw->hw_dPad != 0 );
- skin_window_enable_qwerty( emulator->window, android_hw->hw_keyboard != 0 );
- skin_window_enable_trackball( emulator->window, android_hw->hw_trackBall != 0 );
- }
-
- /* initialize hardware control support */
- {
- AndroidHwControlFuncs funcs;
-
- funcs.light_brightness = qemulator_light_brightness;
- android_hw_control_init( emulator, &funcs );
- }
-}
-
-
-/* called by the emulated framebuffer device each time the framebuffer
- * is resized or rotated */
-static void
-sdl_resize(DisplayState *ds, int w, int h)
-{
- fprintf(stderr, "weird, sdl_resize being called with framebuffer interface\n");
- exit(1);
-}
-
-
-static void sdl_refresh(DisplayState *ds)
-{
- QEmulator* emulator = ds->opaque;
- SDL_Event ev;
- SkinWindow* window = emulator->window;
- SkinKeyboard* keyboard = emulator->keyboard;
-
- /* this will eventually call sdl_update if the content of the VGA framebuffer
- * has changed */
- qframebuffer_check_updates();
-
- if (window == NULL)
- return;
-
- while(SDL_PollEvent(&ev)){
- switch(ev.type){
- case SDL_VIDEOEXPOSE:
- skin_window_redraw( window, NULL );
- break;
-
- case SDL_KEYDOWN:
-#ifdef _WIN32
- /* special code to deal with Alt-F4 properly */
- if (ev.key.keysym.sym == SDLK_F4 &&
- ev.key.keysym.mod & KMOD_ALT) {
- goto CleanExit;
- }
-#endif
-#ifdef __APPLE__
- /* special code to deal with Command-Q properly */
- if (ev.key.keysym.sym == SDLK_q &&
- ev.key.keysym.mod & KMOD_META) {
- goto CleanExit;
- }
-#endif
- skin_keyboard_process_event( keyboard, &ev, 1 );
- break;
-
- case SDL_KEYUP:
- skin_keyboard_process_event( keyboard, &ev, 0 );
- break;
-
- case SDL_MOUSEMOTION:
- skin_window_process_event( window, &ev );
- break;
-
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- {
- int down = (ev.type == SDL_MOUSEBUTTONDOWN);
- if (ev.button.button == 4)
- {
- /* scroll-wheel simulates DPad up */
- AndroidKeyCode kcode;
-
- kcode = qemulator_rotate_keycode(emulator, kKeyCodeDpadUp);
- send_key_event( kcode, down );
- }
- else if (ev.button.button == 5)
- {
- /* scroll-wheel simulates DPad down */
- AndroidKeyCode kcode;
-
- kcode = qemulator_rotate_keycode(emulator, kKeyCodeDpadDown);
- send_key_event( kcode, down );
- }
- else if (ev.button.button == SDL_BUTTON_LEFT) {
- skin_window_process_event( window, &ev );
- }
-#if 0
- else {
- fprintf(stderr, "... mouse button %s: button=%d state=%04x x=%d y=%d\n",
- down ? "down" : "up ",
- ev.button.button, ev.button.state, ev.button.x, ev.button.y);
- }
-#endif
- }
- break;
-
- case SDL_QUIT:
-#if defined _WIN32 || defined __APPLE__
- CleanExit:
-#endif
- /* only save emulator config through clean exit */
- qemulator_done( emulator );
- qemu_system_shutdown_request();
- return;
- }
- }
-
- skin_keyboard_flush( keyboard );
-}
-
-
-/* used to respond to a given keyboard command shortcut
- */
-static void
-handle_key_command( void* opaque, SkinKeyCommand command, int down )
-{
- static const struct { SkinKeyCommand cmd; AndroidKeyCode kcode; } keycodes[] =
- {
- { SKIN_KEY_COMMAND_BUTTON_CALL, kKeyCodeCall },
- { SKIN_KEY_COMMAND_BUTTON_HOME, kKeyCodeHome },
- { SKIN_KEY_COMMAND_BUTTON_BACK, kKeyCodeBack },
- { SKIN_KEY_COMMAND_BUTTON_HANGUP, kKeyCodeEndCall },
- { SKIN_KEY_COMMAND_BUTTON_POWER, kKeyCodePower },
- { SKIN_KEY_COMMAND_BUTTON_SEARCH, kKeyCodeSearch },
- { SKIN_KEY_COMMAND_BUTTON_MENU, kKeyCodeMenu },
- { SKIN_KEY_COMMAND_BUTTON_DPAD_UP, kKeyCodeDpadUp },
- { SKIN_KEY_COMMAND_BUTTON_DPAD_LEFT, kKeyCodeDpadLeft },
- { SKIN_KEY_COMMAND_BUTTON_DPAD_RIGHT, kKeyCodeDpadRight },
- { SKIN_KEY_COMMAND_BUTTON_DPAD_DOWN, kKeyCodeDpadDown },
- { SKIN_KEY_COMMAND_BUTTON_DPAD_CENTER, kKeyCodeDpadCenter },
- { SKIN_KEY_COMMAND_BUTTON_VOLUME_UP, kKeyCodeVolumeUp },
- { SKIN_KEY_COMMAND_BUTTON_VOLUME_DOWN, kKeyCodeVolumeDown },
- { SKIN_KEY_COMMAND_NONE, 0 }
- };
- int nn;
-#ifdef CONFIG_TRACE
- static int tracing = 0;
-#endif
- QEmulator* emulator = opaque;
-
-
- for (nn = 0; keycodes[nn].kcode != 0; nn++) {
- if (command == keycodes[nn].cmd) {
- unsigned code = keycodes[nn].kcode;
- if (down)
- code |= 0x200;
- kbd_put_keycode( code );
- return;
- }
- }
-
- // for the show-trackball command, handle down events to enable, and
- // up events to disable
- if (command == SKIN_KEY_COMMAND_SHOW_TRACKBALL) {
- emulator->show_trackball = (down != 0);
- skin_window_show_trackball( emulator->window, emulator->show_trackball );
- //qemulator_set_title( emulator );
- return;
- }
-
- // only handle down events for the rest
- if (down == 0)
- return;
-
- switch (command)
- {
- case SKIN_KEY_COMMAND_TOGGLE_NETWORK:
- {
- qemu_net_disable = !qemu_net_disable;
- if (android_modem) {
- amodem_set_data_registration(
- android_modem,
- qemu_net_disable ? A_REGISTRATION_UNREGISTERED
- : A_REGISTRATION_HOME);
- }
- D( "network is now %s", qemu_net_disable ? "disconnected" : "connected" );
- }
- break;
-
- case SKIN_KEY_COMMAND_TOGGLE_FULLSCREEN:
- if (emulator->window) {
- skin_window_toggle_fullscreen(emulator->window);
- }
- break;
-
- case SKIN_KEY_COMMAND_TOGGLE_TRACING:
- {
-#ifdef CONFIG_TRACE
- tracing = !tracing;
- if (tracing)
- start_tracing();
- else
- stop_tracing();
-#endif
- }
- break;
-
- case SKIN_KEY_COMMAND_TOGGLE_TRACKBALL:
- emulator->show_trackball = !emulator->show_trackball;
- skin_window_show_trackball( emulator->window, emulator->show_trackball );
- break;
-
- case SKIN_KEY_COMMAND_ONION_ALPHA_UP:
- case SKIN_KEY_COMMAND_ONION_ALPHA_DOWN:
- if (emulator->onion)
- {
- int alpha = emulator->onion_alpha;
-
- if (command == SKIN_KEY_COMMAND_ONION_ALPHA_UP)
- alpha += 16;
- else
- alpha -= 16;
-
- if (alpha > 256)
- alpha = 256;
- else if (alpha < 0)
- alpha = 0;
-
- emulator->onion_alpha = alpha;
- skin_window_set_onion( emulator->window, emulator->onion, emulator->onion_rotation, alpha );
- skin_window_redraw( emulator->window, NULL );
- //dprint( "onion alpha set to %d (%.f %%)", alpha, alpha/2.56 );
- }
- break;
-
- case SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV:
- case SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT:
- {
- SkinLayout* layout = NULL;
-
- if (command == SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT) {
- layout = emulator->layout->next;
- if (layout == NULL)
- layout = emulator->layout_file->layouts;
- }
- else if (command == SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV) {
- layout = emulator->layout_file->layouts;
- while (layout->next && layout->next != emulator->layout)
- layout = layout->next;
- }
- if (layout != NULL) {
- SkinRotation rotation;
-
- emulator->layout = layout;
- skin_window_reset( emulator->window, layout );
-
- rotation = skin_layout_get_dpad_rotation( layout );
-
- if (emulator->keyboard)
- skin_keyboard_set_rotation( emulator->keyboard, rotation );
-
- if (emulator->trackball) {
- skin_trackball_set_rotation( emulator->trackball, rotation );
- skin_window_set_trackball( emulator->window, emulator->trackball );
- skin_window_show_trackball( emulator->window, emulator->show_trackball );
- }
-
- skin_window_set_lcd_brightness( emulator->window, emulator->lcd_brightness );
-
- qframebuffer_invalidate_all();
- qframebuffer_check_updates();
- }
- }
- break;
-
- default:
- /* XXX: TODO ? */
- ;
- }
-}
-
-
-static void sdl_at_exit(void)
-{
- emulator_config_done();
- qemulator_done( qemulator );
- SDL_Quit();
-}
-
-
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
-{
- QEmulator* emulator = qemulator;
- SkinDisplay* disp = skin_layout_get_display(emulator->layout);
-
-// fprintf(stderr,"*** sdl_display_init ***\n");
- ds->opaque = emulator;
-
- if (disp->rotation & 1) {
- ds->width = disp->rect.size.h;
- ds->height = disp->rect.size.w;
- } else {
- ds->width = disp->rect.size.w;
- ds->height = disp->rect.size.h;
- }
-
- ds->dpy_update = sdl_update;
- ds->dpy_resize = sdl_resize;
- ds->dpy_refresh = sdl_refresh;
-
- skin_keyboard_enable( emulator->keyboard, 1 );
- skin_keyboard_on_command( emulator->keyboard, handle_key_command, emulator );
-}
-
-
-extern SkinKeyboard* android_emulator_get_keyboard(void)
-{
- return qemulator->keyboard;
-}
-
-static const char* skin_network_speed = NULL;
-static const char* skin_network_delay = NULL;
-
-/* list of skin aliases */
-static const struct {
- const char* name;
- const char* alias;
-} skin_aliases[] = {
- { "QVGA-L", "320x240" },
- { "QVGA-P", "240x320" },
- { "HVGA-L", "480x320" },
- { "HVGA-P", "320x480" },
- { "QVGA", "320x240" },
- { "HVGA", "320x480" },
- { NULL, NULL }
-};
-
-/* this is used by hw/events_device.c to send the charmap name to the system */
-const char* android_skin_keycharmap = NULL;
-
-void init_skinned_ui(const char *path, const char *name, AndroidOptions* opts)
-{
- char tmp[1024];
- AConfig* root;
- AConfig* n;
- int win_x, win_y, flags;
-
- signal(SIGINT, SIG_DFL);
-#ifndef _WIN32
- signal(SIGQUIT, SIG_DFL);
-#endif
-
- /* we're not a game, so allow the screensaver to run */
- putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");
-
- flags = SDL_INIT_NOPARACHUTE;
- if (!opts->no_window)
- flags |= SDL_INIT_VIDEO;
-
- if(SDL_Init(flags)){
- fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
- exit(1);
- }
-
- if (!opts->no_window) {
- SDL_EnableUNICODE(!opts->raw_keys);
- SDL_EnableKeyRepeat(0,0);
-
- sdl_set_window_icon();
- }
- else
- {
-#ifndef _WIN32
- /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
- * able to run the emulator in the background (e.g. "emulator &").
- * despite the fact that the emulator should not grab input or try to
- * write to the output in normal cases, we're stopped on some systems
- * (e.g. OS X)
- */
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
-#endif
- }
- atexit(sdl_at_exit);
-
- root = aconfig_node("", "");
-
- if(name) {
- /* Support skin aliases like QVGA-H QVGA-P, etc...
- But first we check if it's a directory that exist before applying
- the alias */
- int checkAlias = 1;
-
- if (path != NULL) {
- bufprint(tmp, tmp+sizeof(tmp), "%s/%s", path, name);
- if (path_exists(tmp)) {
- checkAlias = 0;
- } else {
- D("there is no '%s' skin in '%s'", name, path);
- }
- }
-
- if (checkAlias) {
- int nn;
-
- for (nn = 0; ; nn++ ) {
- const char* skin_name = skin_aliases[nn].name;
- const char* skin_alias = skin_aliases[nn].alias;
-
- if ( !skin_name )
- break;
-
- if ( !strcasecmp( skin_name, name ) ) {
- D("skin name '%s' aliased to '%s'", name, skin_alias);
- name = skin_alias;
- break;
- }
- }
- }
-
- /* Magically support skins like "320x240" */
- if(isdigit(name[0])) {
- char *x = strchr(name, 'x');
- if(x && isdigit(x[1])) {
- int width = atoi(name);
- int height = atoi(x + 1);
- sprintf(tmp,"display {\n width %d\n height %d\n}\n",
- width, height);
- aconfig_load(root, strdup(tmp));
- path = ":";
- goto found_a_skin;
- }
- }
-
- if (path == NULL) {
- derror("unknown skin name '%s'", name);
- exit(1);
- }
-
- sprintf(tmp, "%s/%s/layout", path, name);
- D("trying to load skin file '%s'", tmp);
-
- if(aconfig_load_file(root, tmp) >= 0) {
- sprintf(tmp, "%s/%s/", path, name);
- path = tmp;
- goto found_a_skin;
- } else {
- dwarning("could not load skin file '%s', using built-in one\n",
- tmp);
- }
- }
-
- {
- const unsigned char* layout_base;
- size_t layout_size;
-
- name = "<builtin>";
-
- layout_base = android_resource_find( "layout", &layout_size );
- if (layout_base != NULL) {
- char* base = malloc( layout_size+1 );
- memcpy( base, layout_base, layout_size );
- base[layout_size] = 0;
-
- D("parsing built-in skin layout file (size=%d)", (int)layout_size);
- aconfig_load(root, base);
- path = ":";
- } else {
- fprintf(stderr, "Couldn't load builtin skin\n");
- exit(1);
- }
- }
-
-found_a_skin:
- {
- AConfig* node = aconfig_find( emulator_config, "window" );
-
- win_x = 10;
- win_y = 10;
-
- if (node == NULL) {
- if (emulator_config_found)
- dwarning( "broken configuration file doesn't have 'window' element" );
- } else {
- win_x = aconfig_int( node, "x", win_x );
- win_y = aconfig_int( node, "y", win_y );
- }
- }
- if ( qemulator_init( qemulator, root, path, win_x, win_y, opts ) < 0 ) {
- fprintf(stderr, "### Error: could not load emulator skin '%s'\n", name);
- exit(1);
- }
-
- android_skin_keycharmap = skin_keyboard_charmap_name(qemulator->keyboard);
-
- /* the default network speed and latency can now be specified by the device skin */
- n = aconfig_find(root, "network");
- if (n != NULL) {
- skin_network_speed = aconfig_str(n, "speed", 0);
- skin_network_delay = aconfig_str(n, "delay", 0);
- }
-
-#if 0
- /* create a trackball if needed */
- n = aconfig_find(root, "trackball");
- if (n != NULL) {
- SkinTrackBallParameters params;
-
- params.x = aconfig_unsigned(n, "x", 0);
- params.y = aconfig_unsigned(n, "y", 0);
- params.diameter = aconfig_unsigned(n, "diameter", 20);
- params.ring = aconfig_unsigned(n, "ring", 1);
-
- params.ball_color = aconfig_unsigned(n, "ball-color", 0xffe0e0e0);
- params.dot_color = aconfig_unsigned(n, "dot-color", 0xff202020 );
- params.ring_color = aconfig_unsigned(n, "ring-color", 0xff000000 );
-
- qemu_disp->trackball = skin_trackball_create( &params );
- skin_trackball_refresh( qemu_disp->trackball );
- }
-#endif
-
- /* add an onion overlay image if needed */
- if (opts->onion) {
- SkinImage* onion = skin_image_find_simple( opts->onion );
- int alpha, rotate;
-
- if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
- alpha = (256*alpha)/100;
- } else
- alpha = 128;
-
- if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
- rotate &= 3;
- } else
- rotate = SKIN_ROTATION_0;
-
- qemulator->onion = onion;
- qemulator->onion_alpha = alpha;
- qemulator->onion_rotation = rotate;
- }
-}
-
-int qemu_main(int argc, char **argv);
-
-/* this function dumps the QEMU help */
-extern void help( void );
-extern void emulator_help( void );
-
-#define VERBOSE_OPT(str,var) { str, &var }
-
-#define _VERBOSE_TAG(x,y) { #x, VERBOSE_##x, y },
-static const struct { const char* name; int flag; const char* text; }
-verbose_options[] = {
- VERBOSE_TAG_LIST
- { 0, 0, 0 }
-};
-
-int
-android_parse_network_speed(const char* speed)
-{
- int n;
- char* end;
- double sp;
-
- if (speed == NULL || speed[0] == 0) {
- speed = DEFAULT_NETSPEED;
- }
-
- for (n = 0; android_netspeeds[n].name != NULL; n++) {
- if (!strcmp(android_netspeeds[n].name, speed)) {
- qemu_net_download_speed = android_netspeeds[n].download;
- qemu_net_upload_speed = android_netspeeds[n].upload;
- return 0;
- }
- }
-
- /* is this a number ? */
- sp = strtod(speed, &end);
- if (end == speed) {
- return -1;
- }
-
- qemu_net_download_speed = qemu_net_upload_speed = sp*1000.;
- if (*end == ':') {
- speed = end+1;
- sp = strtod(speed, &end);
- if (end > speed) {
- qemu_net_download_speed = sp*1000.;
- }
- }
-
- if (android_modem)
- amodem_set_data_network_type( android_modem,
- android_parse_network_type(speed) );
- return 0;
-}
-
-
-int
-android_parse_network_latency(const char* delay)
-{
- int n;
- char* end;
- double sp;
-
- if (delay == NULL || delay[0] == 0)
- delay = DEFAULT_NETDELAY;
-
- for (n = 0; android_netdelays[n].name != NULL; n++) {
- if ( !strcmp( android_netdelays[n].name, delay ) ) {
- qemu_net_min_latency = android_netdelays[n].min_ms;
- qemu_net_max_latency = android_netdelays[n].max_ms;
- return 0;
- }
- }
-
- /* is this a number ? */
- sp = strtod(delay, &end);
- if (end == delay) {
- return -1;
- }
-
- qemu_net_min_latency = qemu_net_max_latency = (int)sp;
- if (*end == ':') {
- delay = (const char*)end+1;
- sp = strtod(delay, &end);
- if (end > delay) {
- qemu_net_max_latency = (int)sp;
- }
- }
- return 0;
-}
-
-
-static int
-load_keyset(const char* path)
-{
- if (path_can_read(path)) {
- AConfig* root = aconfig_node("","");
- if (!aconfig_load_file(root, path)) {
- android_keyset = skin_keyset_new(root);
- if (android_keyset != NULL) {
- D( "keyset loaded from: %s", path);
- return 0;
- }
- }
- }
- return -1;
-}
-
-static void
-parse_keyset(const char* keyset, AndroidOptions* opts)
-{
- char kname[MAX_PATH];
- char temp[MAX_PATH];
- char* p;
- char* end;
-
- /* append .keyset suffix if needed */
- if (strchr(keyset, '.') == NULL) {
- p = kname;
- end = p + sizeof(kname);
- p = bufprint(p, end, "%s.keyset", keyset);
- if (p >= end) {
- derror( "keyset name too long: '%s'\n", keyset);
- exit(1);
- }
- keyset = kname;
- }
-
- /* look for a the keyset file */
- p = temp;
- end = p + sizeof(temp);
- p = bufprint_config_file(p, end, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->system, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint_app_dir(p, end);
- p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- return;
-}
-
-static void
-write_default_keyset( void )
-{
- char path[MAX_PATH];
-
- bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
-
- /* only write if there is no file here */
- if ( !path_exists(path) ) {
- int fd = open( path, O_WRONLY | O_CREAT, 0666 );
- int ret;
- const char* ks = skin_keyset_get_default();
-
-
- D( "writing default keyset file to %s", path );
-
- if (fd < 0) {
- D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
- return;
- }
- CHECKED(ret, write(fd, ks, strlen(ks)));
- close(fd);
- }
-}
-
-#ifdef CONFIG_NAND_LIMITS
-
-static uint64_t
-parse_nand_rw_limit( const char* value )
-{
- char* end;
- uint64_t val = strtoul( value, &end, 0 );
-
- if (end == value) {
- derror( "bad parameter value '%s': expecting unsigned integer", value );
- exit(1);
- }
-
- switch (end[0]) {
- case 'K': val <<= 10; break;
- case 'M': val <<= 20; break;
- case 'G': val <<= 30; break;
- case 0: break;
- default:
- derror( "bad read/write limit suffix: use K, M or G" );
- exit(1);
- }
- return val;
-}
-
-static void
-parse_nand_limits(char* limits)
-{
- int pid = -1, signal = -1;
- int64_t reads = 0, writes = 0;
- char* item = limits;
-
- /* parse over comma-separated items */
- while (item && *item) {
- char* next = strchr(item, ',');
- char* end;
-
- if (next == NULL) {
- next = item + strlen(item);
- } else {
- *next++ = 0;
- }
-
- if ( !memcmp(item, "pid=", 4) ) {
- pid = strtol(item+4, &end, 10);
- if (end == NULL || *end) {
- derror( "bad parameter, expecting pid=<number>, got '%s'",
- item );
- exit(1);
- }
- if (pid <= 0) {
- derror( "bad parameter: process identifier must be > 0" );
- exit(1);
- }
- }
- else if ( !memcmp(item, "signal=", 7) ) {
- signal = strtol(item+7,&end, 10);
- if (end == NULL || *end) {
- derror( "bad parameter: expecting signal=<number>, got '%s'",
- item );
- exit(1);
- }
- if (signal <= 0) {
- derror( "bad parameter: signal number must be > 0" );
- exit(1);
- }
- }
- else if ( !memcmp(item, "reads=", 6) ) {
- reads = parse_nand_rw_limit(item+6);
- }
- else if ( !memcmp(item, "writes=", 7) ) {
- writes = parse_nand_rw_limit(item+7);
- }
- else {
- derror( "bad parameter '%s' (see -help-nand-limits)", item );
- exit(1);
- }
- item = next;
- }
- if (pid < 0) {
- derror( "bad paramater: missing pid=<number>" );
- exit(1);
- }
- else if (signal < 0) {
- derror( "bad parameter: missing signal=<number>" );
- exit(1);
- }
- else if (reads == 0 && writes == 0) {
- dwarning( "no read or write limit specified. ignoring -nand-limits" );
- } else {
- nand_threshold* t;
-
- t = &android_nand_read_threshold;
- t->pid = pid;
- t->signal = signal;
- t->counter = 0;
- t->limit = reads;
-
- t = &android_nand_write_threshold;
- t->pid = pid;
- t->signal = signal;
- t->counter = 0;
- t->limit = writes;
- }
-}
-#endif /* CONFIG_NAND_LIMITS */
-
-void emulator_help( void )
-{
- STRALLOC_DEFINE(out);
- android_help_main(out);
- printf( "%.*s", out->n, out->s );
- stralloc_reset(out);
- exit(1);
-}
-
-static int
-add_dns_server( const char* server_name )
-{
- SockAddress addr;
-
- if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
- fprintf(stderr,
- "### WARNING: can't resolve DNS server name '%s'\n",
- server_name );
- return -1;
- }
-
- D( "DNS server name '%s' resolved to %s", server_name, sock_address_to_string(&addr) );
-
- if ( slirp_add_dns_server( &addr ) < 0 ) {
- fprintf(stderr,
- "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
- return -1;
- }
- return 0;
-}
-
-
-enum {
- REPORT_CONSOLE_SERVER = (1 << 0),
- REPORT_CONSOLE_MAX = (1 << 1)
-};
-
-static int
-get_report_console_options( char* end, int *maxtries )
-{
- int flags = 0;
-
- if (end == NULL || *end == 0)
- return 0;
-
- if (end[0] != ',') {
- derror( "socket port/path can be followed by [,<option>]+ only\n");
- exit(3);
- }
- end += 1;
- while (*end) {
- char* p = strchr(end, ',');
- if (p == NULL)
- p = end + strlen(end);
-
- if (memcmp( end, "server", p-end ) == 0)
- flags |= REPORT_CONSOLE_SERVER;
- else if (memcmp( end, "max=", 4) == 0) {
- end += 4;
- *maxtries = strtol( end, NULL, 10 );
- flags |= REPORT_CONSOLE_MAX;
- } else {
- derror( "socket port/path can be followed by [,server][,max=<count>] only\n");
- exit(3);
- }
-
- end = p;
- if (*end)
- end += 1;
- }
- return flags;
-}
-
-static void
-report_console( const char* proto_port, int console_port )
-{
- int s = -1, s2;
- int maxtries = 10;
- int flags = 0;
- signal_state_t sigstate;
-
- disable_sigalrm( &sigstate );
-
- if ( !strncmp( proto_port, "tcp:", 4) ) {
- char* end;
- long port = strtol(proto_port + 4, &end, 10);
-
- flags = get_report_console_options( end, &maxtries );
-
- if (flags & REPORT_CONSOLE_SERVER) {
- s = socket_loopback_server( port, SOCKET_STREAM );
- if (s < 0) {
- fprintf(stderr, "could not create server socket on TCP:%ld: %s\n",
- port, errno_str);
- exit(3);
- }
- } else {
- for ( ; maxtries > 0; maxtries-- ) {
- D("trying to find console-report client on tcp:%d", port);
- s = socket_loopback_client( port, SOCKET_STREAM );
- if (s >= 0)
- break;
-
- sleep_ms(1000);
- }
- if (s < 0) {
- fprintf(stderr, "could not connect to server on TCP:%ld: %s\n",
- port, errno_str);
- exit(3);
- }
- }
- } else if ( !strncmp( proto_port, "unix:", 5) ) {
-#ifdef _WIN32
- fprintf(stderr, "sorry, the unix: protocol is not supported on Win32\n");
- exit(3);
-#else
- char* path = strdup(proto_port+5);
- char* end = strchr(path, ',');
- if (end != NULL) {
- flags = get_report_console_options( end, &maxtries );
- *end = 0;
- }
- if (flags & REPORT_CONSOLE_SERVER) {
- s = socket_unix_server( path, SOCKET_STREAM );
- if (s < 0) {
- fprintf(stderr, "could not bind unix socket on '%s': %s\n",
- proto_port+5, errno_str);
- exit(3);
- }
- } else {
- for ( ; maxtries > 0; maxtries-- ) {
- s = socket_unix_client( path, SOCKET_STREAM );
- if (s >= 0)
- break;
-
- sleep_ms(1000);
- }
- if (s < 0) {
- fprintf(stderr, "could not connect to unix socket on '%s': %s\n",
- path, errno_str);
- exit(3);
- }
- }
- free(path);
-#endif
- } else {
- fprintf(stderr, "-report-console must be followed by a 'tcp:<port>' or 'unix:<path>'\n");
- exit(3);
- }
-
- if (flags & REPORT_CONSOLE_SERVER) {
- int tries = 3;
- D( "waiting for console-reporting client" );
- do {
- s2 = socket_accept(s, NULL);
- } while (s2 < 0 && --tries > 0);
-
- if (s2 < 0) {
- fprintf(stderr, "could not accept console-reporting client connection: %s\n",
- errno_str);
- exit(3);
- }
-
- socket_close(s);
- s = s2;
- }
-
- /* simply send the console port in text */
- {
- char temp[12];
- snprintf( temp, sizeof(temp), "%d", console_port );
-
- if (socket_send(s, temp, strlen(temp)) < 0) {
- fprintf(stderr, "could not send console number report: %d: %s\n",
- errno, errno_str );
- exit(3);
- }
- socket_close(s);
- }
- D( "console port number sent to remote. resuming boot" );
-
- restore_sigalrm (&sigstate);
-}
-
-/* this function is used to perform auto-detection of the
- * system directory in the case of a SDK installation.
- *
- * we want to deal with several historical usages, hence
- * the slightly complicated logic.
- *
- * NOTE: the function returns the path to the directory
- * containing 'fileName'. this is *not* the full
- * path to 'fileName'.
- */
-static char*
-_getSdkImagePath( const char* fileName )
-{
- char temp[MAX_PATH];
- char* p = temp;
- char* end = p + sizeof(temp);
- char* q;
- char* app;
-
- static const char* const searchPaths[] = {
- "", /* program's directory */
- "/lib/images", /* this is for SDK 1.0 */
- "/../platforms/android-1.1/images", /* this is for SDK 1.1 */
- NULL
- };
-
- app = bufprint_app_dir(temp, end);
- if (app >= end)
- return NULL;
-
- do {
- int nn;
-
- /* first search a few well-known paths */
- for (nn = 0; searchPaths[nn] != NULL; nn++) {
- p = bufprint(app, end, "%s", searchPaths[nn]);
- q = bufprint(p, end, "/%s", fileName);
- if (q < end && path_exists(temp)) {
- *p = 0;
- goto FOUND_IT;
- }
- }
-
- /* hmmm. let's assume that we are in a post-1.1 SDK
- * scan ../platforms if it exists
- */
- p = bufprint(app, end, "/../platforms");
- if (p < end) {
- DirScanner* scanner = dirScanner_new(temp);
- if (scanner != NULL) {
- int found = 0;
- const char* subdir;
-
- for (;;) {
- subdir = dirScanner_next(scanner);
- if (!subdir) break;
-
- q = bufprint(p, end, "/%s/images/%s", subdir, fileName);
- if (q >= end || !path_exists(temp))
- continue;
-
- found = 1;
- p = bufprint(p, end, "/%s/images", subdir);
- break;
- }
- dirScanner_free(scanner);
- if (found)
- break;
- }
- }
-
- /* I'm out of ideas */
- return NULL;
-
- } while (0);
-
-FOUND_IT:
- //D("image auto-detection: %s/%s", temp, fileName);
- return qemu_strdup(temp);
-}
-
-static char*
-_getSdkImage( const char* path, const char* file )
-{
- char temp[MAX_PATH];
- char *p = temp, *end = p + sizeof(temp);
-
- p = bufprint(temp, end, "%s/%s", path, file);
- if (p >= end || !path_exists(temp))
- return NULL;
-
- return qemu_strdup(temp);
-}
-
-static char*
-_getSdkSystemImage( const char* path, const char* optionName, const char* file )
-{
- char* image = _getSdkImage(path, file);
-
- if (image == NULL) {
- derror("Your system directory is missing the '%s' image file.\n"
- "Please specify one with the '%s <filepath>' option",
- file, optionName);
- exit(2);
- }
- return image;
-}
-
-static void
-_forceAvdImagePath( AvdImageType imageType,
- const char* path,
- const char* description,
- int required )
-{
- if (path == NULL)
- return;
-
- if (required && !path_exists(path)) {
- derror("Cannot find %s image file: %s", description, path);
- exit(1);
- }
- android_avdParams->forcePaths[imageType] = path;
-}
-
-#ifdef _WIN32
-#undef main /* we don't want SDL to define main */
-#endif
-
-int main(int argc, char **argv)
-{
- char tmp[MAX_PATH];
- char* tmpend = tmp + sizeof(tmp);
- char* args[128];
- int n;
- char* opt;
- int use_sdcard_img = 0;
- int serial = 0;
- int gps_serial = 0;
- int radio_serial = 0;
- int qemud_serial = 0;
- int shell_serial = 0;
- int dns_count = 0;
- unsigned cachePartitionSize = 0;
-
- AndroidHwConfig* hw;
-
- //const char *appdir = get_app_dir();
- char* android_build_root = NULL;
- char* android_build_out = NULL;
-
- AndroidOptions opts[1];
-
- args[0] = argv[0];
-
- if ( android_parse_options( &argc, &argv, opts ) < 0 ) {
- exit(1);
- }
-
- while (argc-- > 1) {
- opt = (++argv)[0];
-
- if(!strcmp(opt, "-qemu")) {
- argc--;
- argv++;
- break;
- }
-
- if (!strcmp(opt, "-help")) {
- emulator_help();
- }
-
- if (!strncmp(opt, "-help-",6)) {
- STRALLOC_DEFINE(out);
- opt += 6;
-
- if (!strcmp(opt, "all")) {
- android_help_all(out);
- }
- else if (android_help_for_option(opt, out) == 0) {
- /* ok */
- }
- else if (android_help_for_topic(opt, out) == 0) {
- /* ok */
- }
- if (out->n > 0) {
- printf("\n%.*s", out->n, out->s);
- exit(0);
- }
-
- fprintf(stderr, "unknown option: -help-%s\n", opt);
- fprintf(stderr, "please use -help for a list of valid topics\n");
- exit(1);
- }
-
- if (opt[0] == '-') {
- fprintf(stderr, "unknown option: %s\n", opt);
- fprintf(stderr, "please use -help for a list of valid options\n");
- exit(1);
- }
-
- fprintf(stderr, "invalid command-line parameter: %s.\n", opt);
- fprintf(stderr, "Hint: use '@foo' to launch a virtual device named 'foo'.\n");
- fprintf(stderr, "please use -help for more information\n");
- exit(1);
- }
-
- android_charmap = android_charmaps[0];
-
- if (opts->version) {
- printf("Android emulator version %s\n"
- "Copyright (C) 2006-2008 The Android Open Source Project and many others.\n"
- "This program is a derivative of the QEMU CPU emulator (www.qemu.org).\n\n",
-#if defined ANDROID_BUILD_ID
- VERSION_STRING " (build_id " STRINGIFY(ANDROID_BUILD_ID) ")" );
-#else
- VERSION_STRING);
-#endif
- printf(" This software is licensed under the terms of the GNU General Public\n"
- " License version 2, as published by the Free Software Foundation, and\n"
- " may be copied, distributed, and modified under those terms.\n\n"
- " This program is distributed in the hope that it will be useful,\n"
- " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- " GNU General Public License for more details.\n\n");
-
- exit(0);
- }
-
- if (opts->timezone) {
- if ( timezone_set(opts->timezone) < 0 ) {
- fprintf(stderr, "emulator: it seems the timezone '%s' is not in zoneinfo format\n", opts->timezone);
- }
- }
-
- /* If no AVD name was given, try to find the top of the
- * Android build tree
- */
- if (opts->avd == NULL) {
- do {
- char* out = getenv("ANDROID_PRODUCT_OUT");
-
- if (out == NULL || out[0] == 0)
- break;
-
- if (!path_exists(out)) {
- derror("Can't access ANDROID_PRODUCT_OUT as '%s\n"
- "You need to build the Android system before launching the emulator",
- out);
- exit(2);
- }
-
- android_build_root = path_parent( out, 4 );
- if (android_build_root == NULL || !path_exists(android_build_root)) {
- derror("Can't find the Android build root from '%s'\n"
- "Please check the definition of the ANDROID_PRODUCT_OUT variable.\n"
- "It should point to your product-specific build output directory.\n",
- out );
- exit(2);
- }
- android_build_out = out;
- D( "found Android build root: %s", android_build_root );
- D( "found Android build out: %s", android_build_out );
- } while (0);
- }
- /* if no virtual device name is given, and we're not in the
- * Android build system, we'll need to perform some auto-detection
- * magic :-)
- */
- if (opts->avd == NULL && !android_build_out)
- {
- char dataDirIsSystem = 0;
-
- if (!opts->system) {
- opts->system = _getSdkImagePath("system.img");
- if (!opts->system) {
- derror(
- "You did not specify a virtual device name, and the system\n"
- "directory could not be found.\n\n"
- "If you are an Android SDK user, please use '@<name>' or '-avd <name>'\n"
- "to start a given virtual device (see -help-avd for details).\n\n"
-
- "Otherwise, follow the instructions in -help-disk-images to start the emulator\n"
- );
- exit(2);
- }
- D("autoconfig: -system %s", opts->system);
- }
-
- if (!opts->image) {
- opts->image = _getSdkSystemImage(opts->system, "-image", "system.img");
- D("autoconfig: -image %s", opts->image);
- }
-
- if (!opts->kernel) {
- opts->kernel = _getSdkSystemImage(opts->system, "-kernel", "kernel-qemu");
- D("autoconfig: -kernel %s", opts->kernel);
- }
-
- if (!opts->ramdisk) {
- opts->ramdisk = _getSdkSystemImage(opts->system, "-ramdisk", "ramdisk.img");
- D("autoconfig: -ramdisk %s", opts->ramdisk);
- }
-
- /* if no data directory is specified, use the system directory */
- if (!opts->datadir) {
- opts->datadir = qemu_strdup(opts->system);
- dataDirIsSystem = 1;
- D("autoconfig: -datadir %s", opts->system);
- }
-
- if (!opts->data) {
- /* check for userdata-qemu.img in the data directory */
- bufprint(tmp, tmpend, "%s/userdata-qemu.img", opts->datadir);
- if (!path_exists(tmp)) {
- derror(
- "There is no file named 'userdata-qemu.img' in your %s directory.\n"
- "You should specify one with the '-data <filepath>' option.",
- dataDirIsSystem ? "system" : "data"
- );
- exit(2);
- }
-
- opts->data = qemu_strdup(tmp);
- D("autoconfig: -data %s", opts->data);
- }
-
- if (!opts->sdcard && opts->datadir) {
- bufprint(tmp, tmpend, "%s/sdcard.img", opts->datadir);
- if (path_exists(tmp)) {
- opts->sdcard = qemu_strdup(tmp);
- D("autoconfig: -sdcard %s", opts->sdcard);
- }
- }
- }
-
- /* setup the virtual device parameters from our options
- */
- if (opts->nocache) {
- android_avdParams->flags |= AVDINFO_NO_CACHE;
- }
- if (opts->wipe_data) {
- android_avdParams->flags |= AVDINFO_WIPE_DATA | AVDINFO_WIPE_CACHE;
- }
-
- /* if certain options are set, we can force the path of
- * certain kernel/disk image files
- */
- _forceAvdImagePath(AVD_IMAGE_KERNEL, opts->kernel, "kernel", 1);
- _forceAvdImagePath(AVD_IMAGE_SYSTEM, opts->image, "system", 1);
- _forceAvdImagePath(AVD_IMAGE_RAMDISK, opts->ramdisk,"ramdisk", 1);
- _forceAvdImagePath(AVD_IMAGE_USERDATA,opts->data, "user data", 0);
- _forceAvdImagePath(AVD_IMAGE_CACHE, opts->cache, "cache", 0);
- _forceAvdImagePath(AVD_IMAGE_SDCARD, opts->sdcard, "SD Card", 0);
-
- /* we don't accept -skindir without -skin now
- * to simplify the autoconfig stuff with virtual devices
- */
- if (opts->noskin) {
- opts->skin = "320x480";
- opts->skindir = NULL;
- }
-
- if (opts->skindir) {
- if (!opts->skin) {
- derror( "the -skindir <path> option requires a -skin <name> option");
- exit(1);
- }
- }
- else {
- if (!opts->skin && android_build_out) {
- /* select default skin based on product type */
- const char* p = strrchr(android_build_out,'/');
- if (p) {
- if (p[1] == 's') {
- opts->skin = "HVGA"; /* used to be QVGA-L */
- } else if (p[1] == 'd') {
- opts->skin = "HVGA";
- }
- }
- D("autoconfig: -skin %s", opts->skin);
- }
- android_avdParams->skinName = opts->skin;
- }
- /* setup the virtual device differently depending on whether
- * we are in the Android build system or not
- */
- if (opts->avd != NULL)
- {
- android_avdInfo = avdInfo_new( opts->avd, android_avdParams );
- if (android_avdInfo == NULL) {
- /* an error message has already been printed */
- dprint("could not find virtual device named '%s'", opts->avd);
- exit(1);
- }
- }
- else
- {
- if (!android_build_out) {
- android_build_out = android_build_root = opts->system;
- }
- android_avdInfo = avdInfo_newForAndroidBuild(
- android_build_root,
- android_build_out,
- android_avdParams );
-
- if(android_avdInfo == NULL) {
- D("could not start virtual device\n");
- exit(1);
- }
- }
-
- if (!opts->skindir) {
- /* get the skin from the virtual device configuration */
- opts->skin = (char*) avdInfo_getSkinName( android_avdInfo );
- opts->skindir = (char*) avdInfo_getSkinDir( android_avdInfo );
-
- if (opts->skin) {
- D("autoconfig: -skin %s", opts->skin);
- }
- if (opts->skindir) {
- D("autoconfig: -skindir %s", opts->skindir);
- }
- }
-
- /* Read hardware configuration */
- hw = android_hw;
- if (avdInfo_getHwConfig(android_avdInfo, hw) < 0) {
- derror("could not read hardware configuration ?");
- exit(1);
- }
-
-#ifdef CONFIG_NAND_LIMITS
- if (opts->nand_limits)
- parse_nand_limits(opts->nand_limits);
-#endif
-
- if (opts->keyset) {
- parse_keyset(opts->keyset, opts);
- if (!android_keyset) {
- fprintf(stderr,
- "emulator: WARNING: could not find keyset file named '%s',"
- " using defaults instead\n",
- opts->keyset);
- }
- }
- if (!android_keyset) {
- parse_keyset("default", opts);
- if (!android_keyset) {
- android_keyset = skin_keyset_new_from_text( skin_keyset_get_default() );
- if (!android_keyset) {
- fprintf(stderr, "PANIC: default keyset file is corrupted !!\n" );
- fprintf(stderr, "PANIC: please update the code in android/skin/keyset.c\n" );
- exit(1);
- }
- if (!opts->keyset)
- write_default_keyset();
- }
- }
-
- if (opts->audio) {
- if (opts->audio_in || opts->audio_out) {
- derror( "you can't use -audio with -audio-in or -audio-out\n" );
- exit(1);
- }
- if ( !audio_check_backend_name( 0, opts->audio ) ) {
- derror( "'%s' is not a valid audio output backend. see -help-audio-out\n",
- opts->audio);
- exit(1);
- }
- opts->audio_out = opts->audio;
- opts->audio_in = opts->audio;
-
- if ( !audio_check_backend_name( 1, opts->audio ) ) {
- fprintf(stderr,
- "emulator: warning: '%s' is not a valid audio input backend. audio record disabled\n",
- opts->audio);
- opts->audio_in = "none";
- }
- }
-
- if (opts->audio_in) {
- static char env[64]; /* note: putenv needs a static unique string buffer */
- if ( !audio_check_backend_name( 1, opts->audio_in ) ) {
- derror( "'%s' is not a valid audio input backend. see -help-audio-in\n",
- opts->audio_in);
- exit(1);
- }
- bufprint( env, env+sizeof(env), "QEMU_AUDIO_IN_DRV=%s", opts->audio_in );
- putenv( env );
-
- if (!hw->hw_audioInput) {
- dwarning( "Emulated hardware doesn't have audio input.");
- }
- }
- if (opts->audio_out) {
- static char env[64]; /* note: putenv needs a static unique string buffer */
- if ( !audio_check_backend_name( 0, opts->audio_out ) ) {
- derror( "'%s' is not a valid audio output backend. see -help-audio-out\n",
- opts->audio_out);
- exit(1);
- }
- bufprint( env, env+sizeof(env), "QEMU_AUDIO_OUT_DRV=%s", opts->audio_out );
- putenv( env );
- if (!hw->hw_audioOutput) {
- dwarning( "Emulated hardware doesn't have audio output");
- }
- }
-
- if (opts->cpu_delay) {
- char* end;
- long delay = strtol(opts->cpu_delay, &end, 0);
- if (end == NULL || *end || delay < 0 || delay > 1000 ) {
- fprintf(stderr, "option -cpu-delay must be an integer between 0 and 1000\n" );
- exit(1);
- }
- if (delay > 0)
- delay = (1000-delay);
-
- qemu_cpu_delay = (int) delay;
- }
-
- emulator_config_init();
- init_skinned_ui(opts->skindir, opts->skin, opts);
-
- if (!opts->netspeed) {
- if (skin_network_speed)
- D("skin network speed: '%s'", skin_network_speed);
- opts->netspeed = (char*)skin_network_speed;
- }
- if (!opts->netdelay) {
- if (skin_network_delay)
- D("skin network delay: '%s'", skin_network_delay);
- opts->netdelay = (char*)skin_network_delay;
- }
-
- if ( android_parse_network_speed(opts->netspeed) < 0 ) {
- fprintf(stderr, "invalid -netspeed parameter '%s', see emulator -usage\n", opts->netspeed);
- emulator_help();
- }
-
- if ( android_parse_network_latency(opts->netdelay) < 0 ) {
- fprintf(stderr, "invalid -netdelay parameter '%s', see emulator -usage\n", opts->netdelay);
- emulator_help();
- }
-
- if (opts->netfast) {
- qemu_net_download_speed = 0;
- qemu_net_upload_speed = 0;
- qemu_net_min_latency = 0;
- qemu_net_max_latency = 0;
- }
-
- if (opts->trace) {
- char* tracePath = avdInfo_getTracePath(android_avdInfo, opts->trace);
- int ret;
-
- if (tracePath == NULL) {
- derror( "bad -trace parameter" );
- exit(1);
- }
- ret = path_mkdir_if_needed( tracePath, 0755 );
- if (ret < 0) {
- fprintf(stderr, "could not create directory '%s'\n", tmp);
- exit(2);
- }
- opts->trace = tracePath;
- }
-
- if (opts->tcpdump) {
- if (qemu_tcpdump_start(opts->tcpdump) < 0) {
- dwarning( "could not start packet capture: %s", strerror(errno));
- }
- }
-
- if (opts->nocache)
- opts->cache = 0;
-
- if (opts->dns_server) {
- char* x = strchr(opts->dns_server, ',');
- dns_count = 0;
- if (x == NULL)
- {
- if ( add_dns_server( opts->dns_server ) == 0 )
- dns_count = 1;
- }
- else
- {
- x = strdup(opts->dns_server);
- while (*x) {
- char* y = strchr(x, ',');
-
- if (y != NULL)
- *y = 0;
-
- if (y == NULL || y > x) {
- if ( add_dns_server( x ) == 0 )
- dns_count += 1;
- }
-
- if (y == NULL)
- break;
-
- x = y+1;
- }
- }
- if (dns_count == 0)
- fprintf( stderr, "### WARNING: will use system default DNS server\n" );
- }
-
- if (dns_count == 0)
- dns_count = slirp_get_system_dns_servers();
-
- n = 1;
- /* generate arguments for the underlying qemu main() */
- args[n++] = "-kernel";
- args[n++] = (char*) avdInfo_getImageFile(android_avdInfo, AVD_IMAGE_KERNEL);
-
- args[n++] = "-initrd";
- args[n++] = (char*) avdInfo_getImageFile(android_avdInfo, AVD_IMAGE_RAMDISK);
-
- {
- const char* filetype = "file";
-
- if (avdInfo_isImageReadOnly(android_avdInfo, AVD_IMAGE_SYSTEM))
- filetype = "initfile";
-
- bufprint(tmp, tmpend,
- "system,size=0x4200000,%s=%s", filetype,
- avdInfo_getImageFile(android_avdInfo, AVD_IMAGE_SYSTEM));
-
- args[n++] = "-nand";
- args[n++] = strdup(tmp);
- }
-
- bufprint(tmp, tmpend,
- "userdata,size=0x4200000,file=%s",
- avdInfo_getImageFile(android_avdInfo, AVD_IMAGE_USERDATA));
-
- args[n++] = "-nand";
- args[n++] = strdup(tmp);
-
- if (hw->disk_cachePartition) {
- opts->cache = (char*) avdInfo_getImageFile(android_avdInfo, AVD_IMAGE_CACHE);
- cachePartitionSize = hw->disk_cachePartition_size;
- }
- else if (opts->cache) {
- dwarning( "Emulated hardware doesn't support a cache partition" );
- opts->cache = NULL;
- opts->nocache = 1;
- }
-
- if (opts->cache) {
- /* use a specific cache file */
- sprintf(tmp, "cache,size=0x%0x,file=%s", cachePartitionSize, opts->cache);
- args[n++] = "-nand";
- args[n++] = strdup(tmp);
- }
- else if (!opts->nocache) {
- /* create a temporary cache partition file */
- sprintf(tmp, "cache,size=0x%0x", cachePartitionSize);
- args[n++] = "-nand";
- args[n++] = strdup(tmp);
- }
-
- if (hw->hw_sdCard != 0)
- opts->sdcard = (char*) avdInfo_getImageFile(android_avdInfo, AVD_IMAGE_SDCARD);
- else if (opts->sdcard) {
- dwarning( "Emulated hardware doesn't support SD Cards" );
- opts->sdcard = NULL;
- }
-
- if(opts->sdcard) {
- uint64_t size;
- if (path_get_size(opts->sdcard, &size) == 0) {
- /* see if we have an sdcard image. get its size if it exists */
- if (size < 8*1024*1024ULL) {
- fprintf(stderr, "### WARNING: SD Card files must be at least 8 MB, ignoring '%s'\n", opts->sdcard);
- } else {
- args[n++] = "-hda";
- args[n++] = opts->sdcard;
- use_sdcard_img = 1;
- }
- } else {
- D("no SD Card image at '%s'", opts->sdcard);
- }
- }
-
- if (!opts->logcat || opts->logcat[0] == 0) {
- opts->logcat = getenv("ANDROID_LOG_TAGS");
- if (opts->logcat && opts->logcat[0] == 0)
- opts->logcat = NULL;
- }
-
-#if 0
- if (opts->console) {
- derror( "option -console is obsolete. please use -shell instead" );
- exit(1);
- }
-#endif
-
- /* we always send the kernel messages from ttyS0 to android_kmsg */
- {
- AndroidKmsgFlags flags = 0;
-
- if (opts->show_kernel)
- flags |= ANDROID_KMSG_PRINT_MESSAGES;
-
- android_kmsg_init( flags );
- args[n++] = "-serial";
- args[n++] = "android-kmsg";
- serial++;
- }
-
- /* XXXX: TODO: implement -shell and -logcat through qemud instead */
- if (!opts->shell_serial) {
-#ifdef _WIN32
- opts->shell_serial = "con:";
-#else
- opts->shell_serial = "stdio";
-#endif
- }
- else
- opts->shell = 1;
-
- if (opts->shell || opts->logcat) {
- args[n++] = "-serial";
- args[n++] = opts->shell_serial;
- shell_serial = serial++;
- }
-
- if (opts->old_system)
- {
- if (opts->radio) {
- args[n++] = "-serial";
- args[n++] = opts->radio;
- radio_serial = serial++;
- }
- else {
- args[n++] = "-serial";
- args[n++] = "android-modem";
- radio_serial = serial++;
- }
- if (opts->gps) {
- args[n++] = "-serial";
- args[n++] = opts->gps;
- gps_serial = serial++;
- }
- }
- else /* !opts->old_system */
- {
- args[n++] = "-serial";
- args[n++] = "android-qemud";
- qemud_serial = serial++;
-
- if (opts->radio) {
- CharDriverState* cs = qemu_chr_open(opts->radio);
- if (cs == NULL) {
- derror( "unsupported character device specification: %s\n"
- "used -help-char-devices for list of available formats\n", opts->radio );
- exit(1);
- }
- android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
- }
- else if ( hw->hw_gsmModem != 0 ) {
- if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
- derror( "could not initialize qemud 'gsm' channel" );
- exit(1);
- }
- }
-
- if (opts->gps) {
- CharDriverState* cs = qemu_chr_open(opts->gps);
- if (cs == NULL) {
- derror( "unsupported character device specification: %s\n"
- "used -help-char-devices for list of available formats\n", opts->gps );
- exit(1);
- }
- android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
- }
- else if ( hw->hw_gps != 0 ) {
- if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
- derror( "could not initialize qemud 'gps' channel" );
- exit(1);
- }
- }
- }
-
- if (opts->memory) {
- char* end;
- long ramSize = strtol(opts->memory, &end, 0);
- if (ramSize < 0 || *end != 0) {
- derror( "-memory must be followed by a positive integer" );
- exit(1);
- }
- if (ramSize < 32 || ramSize > 4096) {
- derror( "physical memory size must be between 32 and 4096 MB" );
- exit(1);
- }
- }
- if (!opts->memory) {
- bufprint(tmp, tmpend, "%d", hw->hw_ramSize);
- opts->memory = qemu_strdup(tmp);
- }
-
- if (opts->noaudio) {
- args[n++] = "-noaudio";
- }
-
-#if 0
- if (opts->mic) {
- if (path_can_read(opts->mic)) {
- args[n++] = "-mic";
- args[n++] = opts->mic;
- } else {
- dprint("could not find or access audio input at '%s'", opts->mic);
- }
- }
-#endif
-
- if (opts->trace) {
- args[n++] = "-trace";
- args[n++] = opts->trace;
- args[n++] = "-tracing";
- args[n++] = "off";
- }
-
- args[n++] = "-append";
-
- if (opts->bootchart) {
- char* end;
- int timeout = strtol(opts->bootchart, &end, 10);
- if (timeout == 0)
- opts->bootchart = NULL;
- else if (timeout < 0 || timeout > 15*60) {
- derror( "timeout specified for -bootchart option is invalid.\n"
- "please use integers between 1 and 900\n");
- exit(1);
- }
- }
-
- {
- static char params[1024];
- char *p = params, *end = p + sizeof(params);
-
- p = bufprint(p, end, "qemu=1 console=ttyS0" );
-
- if (opts->shell || opts->logcat) {
- p = bufprint(p, end, " androidboot.console=ttyS%d", shell_serial );
- }
-
- if (opts->trace) {
- p = bufprint(p, end, " android.tracing=1");
- }
-
- if (!opts->nojni) {
- p = bufprint(p, end, " android.checkjni=1");
- }
-
- if (opts->no_boot_anim) {
- p = bufprint( p, end, " android.bootanim=0" );
- }
-
- if (opts->logcat) {
- char* q = bufprint(p, end, " androidboot.logcat=%s", opts->logcat);
-
- if (q < end) {
- /* replace any space by a comma ! */
- {
- int nn;
- for (nn = 1; p[nn] != 0; nn++)
- if (p[nn] == ' ' || p[nn] == '\t')
- p[nn] = ',';
- p += nn;
- }
- }
- p = q;
- }
-
- if (opts->old_system)
- {
- p = bufprint(p, end, " android.ril=ttyS%d", radio_serial);
-
- if (opts->gps) {
- p = bufprint(p, end, " android.gps=ttyS%d", gps_serial);
- }
- }
- else
- {
- p = bufprint(p, end, " android.qemud=ttyS%d", qemud_serial);
- }
-
- if (dns_count > 0) {
- p = bufprint(p, end, " android.ndns=%d", dns_count);
- }
-
- if (opts->bootchart) {
- p = bufprint(p, end, " androidboot.bootchart=%s", opts->bootchart);
- }
-
- if (p >= end) {
- fprintf(stderr, "### ERROR: kernel parameters too long\n");
- exit(1);
- }
-
- args[n++] = strdup(params);
- }
-
- /* physical memory */
- args[n++] = "-m";
- args[n++] = opts->memory;
-
- /* on Linux, the 'dynticks' clock sometimes doesn't work
- * properly. this results in the UI freezing while emulation
- * continues, for several seconds...
- */
-#ifdef __linux__
- args[n++] = "-clock";
- args[n++] = "unix";
-#endif
-
- while(argc-- > 0) {
- args[n++] = *argv++;
- }
- args[n] = 0;
-
- if(VERBOSE_CHECK(init)) {
- int i;
- for(i = 0; i < n; i++) {
- fprintf(stdout, "emulator: argv[%02d] = \"%s\"\n", i, args[i]);
- }
- }
- return qemu_main(n, args);
-}
-
-/* this function is called from qemu_main() once all arguments have been parsed
- * it should be used to setup any Android-specific items in the emulation before the
- * main loop runs
- */
-void android_emulation_setup( void )
-{
- int tries = 16;
- int base_port = 5554;
- int success = 0;
- int s;
- uint32_t guest_ip;
-
- AndroidOptions* opts = qemulator->opts;
-
- inet_strtoip("10.0.2.15", &guest_ip);
-
-#if 0
- if (opts->adb_port) {
- fprintf( stderr, "option -adb-port is obsolete, use -port instead\n" );
- exit(1);
- }
-#endif
-
- if (opts->port && opts->ports) {
- fprintf( stderr, "options -port and -ports cannot be used together.\n");
- exit(1);
- }
-
- if (opts->ports) {
- char* comma_location;
- char* end;
- int console_port = strtol( opts->ports, &comma_location, 0 );
-
- if ( comma_location == NULL || *comma_location != ',' ) {
- derror( "option -ports must be followed by two comma separated positive integer numbers" );
- exit(1);
- }
-
- int adb_port = strtol( comma_location+1, &end, 0 );
-
- if ( end == NULL || *end ) {
- derror( "option -ports must be followed by two comma separated positive integer numbers" );
- exit(1);
- }
-
- if ( console_port == adb_port ) {
- derror( "option -ports must be followed by two different integer numbers" );
- exit(1);
- }
-
- slirp_redir( 0, adb_port, guest_ip, 5555 );
- if ( control_console_start( console_port ) < 0 ) {
- slirp_unredir( 0, adb_port );
- }
-
- base_port = console_port;
- } else {
- if (opts->port) {
- char* end;
- int port = strtol( opts->port, &end, 0 );
- if ( end == NULL || *end ||
- (unsigned)((port - base_port) >> 1) >= (unsigned)tries ) {
- derror( "option -port must be followed by an even integer number between %d and %d\n",
- base_port, base_port + (tries-1)*2 );
- exit(1);
- }
- if ( (port & 1) != 0 ) {
- port &= ~1;
- dwarning( "option -port must be followed by an even integer, using port number %d\n",
- port );
- }
- base_port = port;
- tries = 1;
- }
-
- for ( ; tries > 0; tries--, base_port += 2 ) {
-
- /* setup first redirection for ADB, the Android Debug Bridge */
- if ( slirp_redir( 0, base_port+1, guest_ip, 5555 ) < 0 )
- continue;
-
- /* setup second redirection for the emulator console */
- if ( control_console_start( base_port ) < 0 ) {
- slirp_unredir( 0, base_port+1 );
- continue;
- }
-
- D( "control console listening on port %d, ADB on port %d", base_port, base_port+1 );
- success = 1;
- break;
- }
-
- if (!success) {
- fprintf(stderr, "it seems too many emulator instances are running on this machine. Aborting\n" );
- exit(1);
- }
- }
-
- if (opts->report_console) {
- report_console(opts->report_console, base_port);
- }
-
- android_modem_init( base_port );
-
- android_base_port = base_port;
- /* send a simple message to the ADB host server to tell it we just started.
- * it should be listening on port 5037. if we can't reach it, don't bother
- */
- do
- {
- SockAddress addr;
- char tmp[32];
-
- s = socket_create_inet( SOCKET_STREAM );
- if (s < 0) {
- D("can't create socket to talk to the ADB server");
- break;
- }
-
- sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, 5037 );
- if (socket_connect( s, &addr ) < 0) {
- D("can't connect to ADB server: %s", errno_str );
- break;
- }
-
- sprintf(tmp,"0012host:emulator:%d",base_port+1);
- socket_send(s, tmp, 18+4);
- D("sent '%s' to ADB server", tmp);
- }
- while (0);
-
- if (s >= 0)
- socket_close(s);
-
- /* setup the http proxy, if any */
- if (VERBOSE_CHECK(proxy))
- proxy_set_verbose(1);
-
- if (!opts->http_proxy) {
- opts->http_proxy = getenv("http_proxy");
- }
-
- do
- {
- const char* env = opts->http_proxy;
- int envlen;
- ProxyOption option_tab[4];
- ProxyOption* option = option_tab;
- char* p;
- char* q;
- const char* proxy_name;
- int proxy_name_len;
- int proxy_port;
-
- if (!env)
- break;
-
- envlen = strlen(env);
-
- /* skip the 'http://' header, if present */
- if (envlen >= 7 && !memcmp(env, "http://", 7)) {
- env += 7;
- envlen -= 7;
- }
-
- /* do we have a username:password pair ? */
- p = strchr(env, '@');
- if (p != 0) {
- q = strchr(env, ':');
- if (q == NULL) {
- BadHttpProxyFormat:
- dprint("http_proxy format unsupported, try 'proxy:port' or 'username:password@proxy:port'");
- break;
- }
-
- option->type = PROXY_OPTION_AUTH_USERNAME;
- option->string = env;
- option->string_len = q - env;
- option++;
-
- option->type = PROXY_OPTION_AUTH_PASSWORD;
- option->string = q+1;
- option->string_len = p - (q+1);
- option++;
-
- env = p+1;
- }
-
- p = strchr(env,':');
- if (p == NULL)
- goto BadHttpProxyFormat;
-
- proxy_name = env;
- proxy_name_len = p - env;
- proxy_port = atoi(p+1);
-
- D( "setting up http proxy: server=%.*s port=%d",
- proxy_name_len, proxy_name, proxy_port );
-
- if ( proxy_http_setup( proxy_name, proxy_name_len, proxy_port,
- option - option_tab, option_tab ) < 0 )
- {
- dprint( "http proxy setup failed, check your $http_proxy variable");
- }
- }
- while (0);
-
- /* cool, now try to run the "ddms ping" command, which will take care of pinging usage
- * if the user agreed for it. the emulator itself never sends anything to any outside
- * machine
- */
- {
-#ifdef _WIN32
-# define _ANDROID_PING_PROGRAM "ddms.bat"
-#else
-# define _ANDROID_PING_PROGRAM "ddms"
-#endif
-
- char tmp[PATH_MAX];
- const char* appdir = get_app_dir();
-
- if (snprintf( tmp, PATH_MAX, "%s%s%s", appdir, PATH_SEP,
- _ANDROID_PING_PROGRAM ) >= PATH_MAX) {
- dprint( "Application directory too long: %s", appdir);
- return;
- }
-
- /* if the program isn't there, don't bother */
- D( "ping program: %s", tmp);
- if (path_exists(tmp)) {
-#ifdef _WIN32
- STARTUPINFO startup;
- PROCESS_INFORMATION pinfo;
-
- ZeroMemory( &startup, sizeof(startup) );
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = SW_SHOWMINIMIZED;
-
- ZeroMemory( &pinfo, sizeof(pinfo) );
-
- char* comspec = getenv("COMSPEC");
- if (!comspec) comspec = "cmd.exe";
-
- // Run
- char args[PATH_MAX + 30];
- if (snprintf( args, PATH_MAX, "/C \"%s\" ping emulator " VERSION_STRING,
- tmp) >= PATH_MAX ) {
- D( "DDMS path too long: %s", tmp);
- return;
- }
-
- CreateProcess(
- comspec, /* program path */
- args, /* command line args */
- NULL, /* process handle is not inheritable */
- NULL, /* thread handle is not inheritable */
- FALSE, /* no, don't inherit any handles */
- DETACHED_PROCESS, /* the new process doesn't have a console */
- NULL, /* use parent's environment block */
- NULL, /* use parent's starting directory */
- &startup, /* startup info, i.e. std handles */
- &pinfo );
-
- D( "ping command: %s %s", comspec, args );
-#else
- int pid = fork();
- if (pid == 0) {
- int fd = open("/dev/null", O_WRONLY);
- dup2(fd, 1);
- dup2(fd, 2);
- execl( tmp, _ANDROID_PING_PROGRAM, "ping", "emulator", VERSION_STRING, NULL );
- }
- /* don't do anything in the parent or in case of error */
- strncat( tmp, " ping emulator " VERSION_STRING, PATH_MAX - strlen(tmp) );
- D( "ping command: %s", tmp );
-#endif
- }
- }
-}
-
-
-void android_emulation_teardown( void )
-{
-}
diff --git a/android/qemud.c b/android/qemud.c
deleted file mode 100644
index b127fc9..0000000
--- a/android/qemud.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/qemud.h"
-#include "android/utils/debug.h"
-#include "android/utils/misc.h"
-#include "qemu-char.h"
-#include "charpipe.h"
-#include "cbuffer.h"
-
-#define D(...) VERBOSE_PRINT(qemud,__VA_ARGS__)
-#define D_ACTIVE VERBOSE_CHECK(qemud)
-
-/* the T(...) macro is used to dump traffic */
-#define T_ACTIVE 0
-
-#if T_ACTIVE
-#define T(...) VERBOSE_PRINT(qemud,__VA_ARGS__)
-#else
-#define T(...) ((void)0)
-#endif
-
-#define MAX_PAYLOAD 4000
-#define MAX_CHANNELS 8
-
-#define CHANNEL_CONTROL_INDEX 0
-
-/** packets
- **/
-#define HEADER_SIZE 6
-
-typedef struct Packet {
- struct Packet* next;
- int len;
- uint8_t header[HEADER_SIZE];
- uint8_t data[MAX_PAYLOAD];
-} Packet;
-
-static Packet* _free_packets;
-
-static void
-packet_free( Packet* p )
-{
- p->next = _free_packets;
- _free_packets = p;
-}
-
-static Packet*
-packet_alloc( void )
-{
- Packet* p = _free_packets;
- if (p != NULL) {
- _free_packets = p->next;
- } else {
- p = malloc(sizeof(*p));
- if (p == NULL) {
- derror("%s: not enough memory", __FUNCTION__);
- exit(1);
- }
- }
- p->next = NULL;
- p->len = 0;
- return p;
-}
-
-/** channels
- **/
-typedef void (*EnqueueFunc)( void* user, Packet* p );
-
-typedef struct {
- const char* name;
- int index;
- CharDriverState* cs;
- EnqueueFunc enq_func;
- void* enq_user;
-} Channel;
-
-
-static int
-channel_can_read( void* opaque )
-{
- Channel* c = opaque;
-
- return c->index < 0 ? 0 : MAX_PAYLOAD;
-}
-
-
-/* here, the data comes from the emulated device (e.g. GSM modem) through
- * a charpipe, we simply need to send it through the multiplexer */
-static void
-channel_read( void* opaque, const uint8_t* from, int len )
-{
- Channel* c = opaque;
-
- if (c->enq_func != NULL) {
- Packet* p = packet_alloc();
-
- if (len > MAX_PAYLOAD)
- len = MAX_PAYLOAD;
-
- memcpy( p->data, from, len );
- p->len = len + HEADER_SIZE;
- int2hex( p->header+0, 4, len );
- int2hex( p->header+4, 2, c->index );
-
- c->enq_func( c->enq_user, p );
- }
- else
- {
- D("%s: discarding %d bytes for channel '%s'",
- __FUNCTION__, len, c->name);
- }
-}
-
-static void
-channel_init( Channel* c, const char* name, CharDriverState* peer_cs )
-{
- c->name = name;
- c->index = -1;
- c->enq_func = NULL;
- c->enq_user = NULL;
- c->cs = peer_cs;
-}
-
-
-static void
-channel_set_peer( Channel* c, int index, EnqueueFunc enq_func, void* enq_user )
-{
- c->index = index;
- qemu_chr_add_handlers( c->cs,
- channel_can_read,
- channel_read,
- NULL,
- c );
- c->enq_func = enq_func;
- c->enq_user = enq_user;
-}
-
-
-static int
-channel_write( Channel*c , const uint8_t* buf, int len )
-{
- return qemu_chr_write( c->cs, buf, len );
-}
-
-/** multiplexer
- **/
-#define IN_BUFF_SIZE (2*MAX_PAYLOAD)
-
-typedef struct {
- CharDriverState* cs;
-
- CBuffer in_cbuffer[1];
- int in_datalen;
- int in_channel;
-
- int count;
- Channel channels[MAX_CHANNELS];
- uint8_t in_buff[ IN_BUFF_SIZE + HEADER_SIZE ];
-} Multiplexer;
-
-
-/* called by channel_read when data comes from an emulated
- * device, and needs to be multiplexed through the serial
- * port
- */
-static void
-multiplexer_enqueue( Multiplexer* m, Packet* p )
-{
- T("%s: sending %d bytes: '%s'", __FUNCTION__,
- p->len - HEADER_SIZE, quote_bytes( p->data, p->len - HEADER_SIZE ) );
-
- qemu_chr_write( m->cs, p->header, HEADER_SIZE );
- qemu_chr_write( m->cs, p->data, p->len - HEADER_SIZE );
- packet_free(p);
-}
-
-/* called when we received a channel registration from the
- * qemud daemon
- */
-static void
-multiplexer_register_channel( Multiplexer* m,
- const char* name,
- int index )
-{
- Channel* c = m->channels;
- Channel* c_end = c + m->count;
-
- for ( ; c < c_end; c++ ) {
- if ( !strcmp(c->name, name) )
- break;
- }
-
- if (c >= c_end) {
- D( "%s: unknown channel name '%s'",
- __FUNCTION__, name );
- return;
- }
-
- if (c->index >= 0) {
- D( "%s: channel '%s' re-assigned index %d",
- __FUNCTION__, name, index );
- c->index = index;
- return;
- }
- channel_set_peer( c, index, (EnqueueFunc) multiplexer_enqueue, m );
- D( "%s: channel '%s' registered as index %d",
- __FUNCTION__, c->name, c->index );
-}
-
-
-/* handle answers from the control channel */
-static void
-multiplexer_handle_control( Multiplexer* m, Packet* p )
-{
- int len = p->len - HEADER_SIZE;
-
- /* for now, the only supported answer is 'ok:connect:<name>:<XX>' where
- * <XX> is a hexdecimal channel numner */
- D( "%s: received '%s'", __FUNCTION__, quote_bytes( (const void*)p->data, (unsigned)len ) );
- if ( !memcmp( p->data, "ok:connect:", 11 ) ) do {
- char* name = (char*)p->data + 11;
- char* q = strchr( name, ':' );
- int index;
-
- if (q == NULL)
- break;
-
- q[0] = 0;
- if (q + 3 > (char*)p->data + len)
- break;
-
- index = hex2int( (uint8_t*)q+1, 2 );
- if (index < 0)
- break;
-
- multiplexer_register_channel( m, name, index );
- goto Exit;
- }
- while(0);
-
- D( "%s: unsupported message !!", __FUNCTION__ );
-Exit:
- packet_free(p);
-}
-
-
-static int
-multiplexer_can_read( void* opaque )
-{
- Multiplexer* m = opaque;
-
- return cbuffer_write_avail( m->in_cbuffer );
-}
-
-/* the data comes from the serial port, we need to reconstruct packets then
- * dispatch them to the appropriate channel */
-static void
-multiplexer_read( void* opaque, const uint8_t* from, int len )
-{
- Multiplexer* m = opaque;
- CBuffer* cb = m->in_cbuffer;
- int ret = 0;
-
- T("%s: received %d bytes from serial: '%s'",
- __FUNCTION__, len, quote_bytes( from, len ));
-
- ret = cbuffer_write( cb, from, len );
- if (ret == 0)
- return;
-
- for (;;) {
- int len = cbuffer_read_avail( cb );
-
- if (m->in_datalen == 0) {
- uint8_t header[HEADER_SIZE];
-
- if (len < HEADER_SIZE)
- break;
-
- cbuffer_read( cb, header, HEADER_SIZE );
- m->in_datalen = hex2int( header+0, 4 );
- m->in_channel = hex2int( header+4, 2 );
- }
- else
- {
- Packet* p;
-
- if (len < m->in_datalen)
- break;
-
- /* a full packet was received */
- p = packet_alloc();
- cbuffer_read( cb, p->data, m->in_datalen );
- p->len = HEADER_SIZE + m->in_datalen;
-
- /* find the channel for this packet */
- if (m->in_channel == CHANNEL_CONTROL_INDEX)
- multiplexer_handle_control( m, p );
- else {
- Channel* c = m->channels;
- Channel* c_end = c + m->count;
-
- for ( ; c < c_end; c++ ) {
- if (c->index == m->in_channel) {
- channel_write( c, p->data, m->in_datalen );
- break;
- }
- }
- packet_free(p);
- }
- m->in_datalen = 0;
- }
-
- }
- return;
-}
-
-static void
-multiplexer_query_channel( Multiplexer* m, const char* name )
-{
- Packet* p = packet_alloc();
- int len;
-
- len = snprintf( (char*)p->data, MAX_PAYLOAD, "connect:%s", name );
-
- int2hex( p->header+0, 4, len );
- int2hex( p->header+4, 2, CHANNEL_CONTROL_INDEX );
- p->len = HEADER_SIZE + len;
-
- multiplexer_enqueue( m, p );
-}
-
-
-static Channel*
-multiplexer_find_channel( Multiplexer* m, const char* name )
-{
- int n;
- for (n = 0; n < m->count; n++)
- if ( !strcmp(m->channels[n].name, name) )
- return m->channels + n;
-
- return NULL;
-}
-
-
-static Multiplexer _multiplexer[1];
-static CharDriverState* android_qemud_cs;
-
-extern void
-android_qemud_init( void )
-{
- Multiplexer* m = _multiplexer;
-
- if (android_qemud_cs != NULL)
- return;
-
- m->count = 0;
-
- cbuffer_reset( m->in_cbuffer, m->in_buff, sizeof(m->in_buff) );
- m->in_datalen = 0;
- m->in_channel = 0;
-
- if (qemu_chr_open_charpipe( &android_qemud_cs, &m->cs ) < 0) {
- derror( "%s: can't create charpipe to serial port",
- __FUNCTION__ );
- exit(1);
- }
-
- qemu_chr_add_handlers( m->cs, multiplexer_can_read,
- multiplexer_read, NULL, m );
-}
-
-
-CharDriverState* android_qemud_get_cs( void )
-{
- if (android_qemud_cs == NULL)
- android_qemud_init();
-
- return android_qemud_cs;
-}
-
-
-extern int
-android_qemud_get_channel( const char* name, CharDriverState** pcs )
-{
- Multiplexer* m = _multiplexer;
- Channel* c;
- CharDriverState* peer_cs;
- int ret;
-
- if (m->cs == NULL)
- android_qemud_init();
-
- c = multiplexer_find_channel( m, name );
- if (c) {
- derror( "%s: trying to get already-opened qemud channel '%s'",
- __FUNCTION__, name );
- return -1;
- }
-
- if (m->count >= MAX_CHANNELS) {
- derror( "%s: too many registered channels (%d)",
- __FUNCTION__, m->count );
- return -1;
- }
-
- c = m->channels + m->count;
-
- ret = qemu_chr_open_charpipe( &peer_cs, pcs );
- if (ret == 0) {
- channel_init(c, name, peer_cs);
- m->count += 1;
- multiplexer_query_channel( m, c->name );
- }
-
- return ret;
-}
-
-extern int
-android_qemud_set_channel( const char* name, CharDriverState* peer_cs )
-{
- Multiplexer* m = _multiplexer;
- Channel* c;
-
- if (m->cs == NULL)
- android_qemud_init();
-
- c = multiplexer_find_channel(m, name);
- if (c != NULL) {
- derror( "%s: trying to set opened qemud channel '%s'",
- __FUNCTION__, name );
- return -1;
- }
-
- if (m->count >= MAX_CHANNELS) {
- derror( "%s: too many registered channels (%d)",
- __FUNCTION__, m->count );
- return -1;
- }
-
- c = m->channels + m->count;
- channel_init(c, name, peer_cs);
- m->count += 1;
- multiplexer_query_channel( m, c->name );
-
- return 0;
-}
diff --git a/android/qemud.h b/android/qemud.h
deleted file mode 100644
index 4fa71d0..0000000
--- a/android/qemud.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_qemud_h
-#define _android_qemud_h
-
-#include "qemu-common.h"
-
-/* recent versions of the emulated Android system contains a background
- * daemon, named 'qemud', which runs as root and opens /dev/ttyS0
- *
- * its purpose is to multiplex several communication channels between
- * the emulator and the system through a single serial port.
- *
- * each channel will be connected to a qemud-created unix socket on the
- * system, and to either a emulated character device or other facility in
- * the emulator.
- *
- * +--------> /dev/socket/qemud_gsm
- * emulated GSM <-----+ ______|_
- * | emulated | |
- * +====> /dev/ttyS0 <===>| qemud |------> /dev/socket/qemud_gps
- * | |________|
- * emulated GPS <-----+ |
- * | +---------> other
- * |
- * other <--------------+
- *
- *
- * this is done to overcome specific permission problems, as well as to add various
- * features that would require special kernel drivers otherwise even though they
- * only need a simple character channel.
- */
-
-/* initialize the qemud support code in the emulator
- */
-
-extern void android_qemud_init( void );
-
-/* return the character driver state object that needs to be connected to the
- * emulated serial port where all multiplexed channels go through.
- */
-extern CharDriverState* android_qemud_get_cs( void );
-
-/* return the character driver state corresponding to a named qemud communication
- * channel. this can be used to send/data the channel.
- * returns 0 on success, or -1 in case of error
- */
-extern int android_qemud_get_channel( const char* name, CharDriverState* *pcs );
-
-/* set the character driver state for a given qemud communication channel. this
- * is used to attach the channel to an external char driver device directly.
- * returns 0 on success, -1 on error
- */
-extern int android_qemud_set_channel( const char* name, CharDriverState* peer_cs );
-
-/* list of known qemud channel names */
-#define ANDROID_QEMUD_GSM "gsm"
-#define ANDROID_QEMUD_GPS "gps"
-#define ANDROID_QEMUD_CONTROL "control"
-
-/* add new channel names here when you need them */
-
-#endif /* _android_qemud_h */
diff --git a/android/resource.c b/android/resource.c
deleted file mode 100644
index 1327ea0..0000000
--- a/android/resource.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/resource.h"
-#include "config-host.h"
-#include <string.h>
-
-typedef struct {
- const char* name;
- const unsigned char* base;
- size_t size;
-} FileEntry;
-
-const unsigned char*
-_resource_find( const char* name,
- const FileEntry* entries,
- size_t *psize )
-{
- const FileEntry* e = entries;
-
- for ( ; e->name != NULL; e++ ) {
- //dprint("SCAN %s\n", e->name);
- if ( strcmp(e->name, name) == 0 ) {
- *psize = e->size;
- return e->base;
- }
- }
- return NULL;
-}
-
-#undef _file_entries
-#define _file_entries _skin_entries
-const unsigned char*
-android_resource_find( const char* name,
- size_t *psize )
-{
-# include "android/skin/default.h"
- return _resource_find( name, _file_entries, psize );
-}
-
-#undef _file_entries
-#define _file_entries _icon_entries
-
-const unsigned char*
-android_icon_find( const char* name,
- size_t *psize )
-{
-#ifdef _WIN32
- return NULL;
-#else
-# include "android/icons.h"
- return _resource_find( name, _file_entries, psize );
-#endif
-}
-
-
diff --git a/android/resource.h b/android/resource.h
deleted file mode 100644
index 00453af..0000000
--- a/android/resource.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_RESOURCE_H
-#define _ANDROID_RESOURCE_H
-
-#include <stddef.h>
-
-extern const unsigned char*
-android_resource_find( const char* name,
- size_t *psize );
-
-extern const unsigned char*
-android_icon_find( const char* name,
- size_t *psize );
-
-#endif /* END */
-
diff --git a/android/skin/argb.h b/android/skin/argb.h
deleted file mode 100644
index b3f0a6d..0000000
--- a/android/skin/argb.h
+++ /dev/null
@@ -1,856 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/* this file contains template code and may be included multiple times */
-
-#ifndef ARGB_T_DEFINED
-#define ARGB_T_DEFINED
-
-#if USE_MMX
-#include <mmintrin.h>
-
-typedef __m64 mmx_t;
-typedef mmx_t argb_t;
-
-static inline mmx_t
-mmx_load8888( unsigned value, mmx_t zero )
-{
- return _mm_unpacklo_pi8( _mm_cvtsi32_si64 (value), zero);
-}
-
-static inline unsigned
-mmx_save8888( mmx_t argb, mmx_t zero )
-{
- return (unsigned) _mm_cvtsi64_si32( _mm_packs_pu16( argb, zero ) );
-}
-
-static inline mmx_t
-mmx_expand16( int value )
-{
- mmx_t t1 = _mm_cvtsi32_si64( value );
- return _mm_packs_pi32( t1, t1 );
-}
-
-static inline int
-mmx_makescale( double s )
-{
- return (int)(s*(1 << 16));
-}
-
-static inline mmx_t
-mmx_mulshift( mmx_t argb, int multiplier, int rshift, mmx_t zero )
-{
- mmx_t ar = _mm_unpackhi_pi16(argb, zero );
- mmx_t gb = _mm_unpacklo_pi16(argb, zero );
- mmx_t mult = mmx_expand16(multiplier);
-
- ar = _mm_srli_pi32( _mm_madd_pi16( ar, mult ), rshift );
- gb = _mm_srli_pi32( _mm_madd_pi16( gb, mult ), rshift );
-
- return _mm_packs_pi32( gb, ar );
-}
-
-static inline mmx_t
-mmx_interp255( mmx_t m1, mmx_t m2, mmx_t zero, int alpha )
-{
- mmx_t mult, mult2, t1, t2, r1, r2;
-
- // m1 = [ a1 | r1 | g1 | b1 ]
- // m2 = [ a2 | r2 | g2 | b2 ]
- alpha = (alpha << 16) | (alpha ^ 255);
- mult = _mm_cvtsi32_si64( alpha ); // mult = [ 0 | 0 | a | 1-a ]
- mult2 = _mm_slli_si64( mult, 32 ); // mult2 = [ a | 1-a | 0 | 0 ]
- mult = _mm_or_si64( mult, mult2 ); // mults = [ a | 1-a | a | 1-a ]
-
- t1 = _mm_unpackhi_pi16( m1, m2 ); // t1 = [ a2 | a1 | r2 | r1 ]
- r1 = _mm_madd_pi16( t1, mult ); // r1 = [ ra | rr ]
-
- t2 = _mm_unpacklo_pi16( m1, m2 ); // t1 = [ g2 | g1 | b2 | b1 ]
- r2 = _mm_madd_pi16( t2, mult ); // r2 = [ rg | rb ]
-
- r1 = _mm_srli_pi32( r1, 8 );
- r2 = _mm_srli_pi32( r2, 8 );
-
- return _mm_packs_pi32( r2, r1 );
-}
-
-#define ARGB_DECL_ZERO() mmx_t _zero = _mm_setzero_si64()
-#define ARGB_DECL(x) mmx_t x
-#define ARGB_DECL2(x1,x2) mmx_t x1, x2
-#define ARGB_ZERO(x) x = _zero
-#define ARGB_UNPACK(x,v) x = mmx_load8888((v), _zero)
-#define ARGB_PACK(x) mmx_save8888(x, _zero)
-#define ARGB_COPY(x,y) x = y
-#define ARGB_SUM(x1,x2,x3) x1 = _mm_add_pi32(x2, x3)
-#define ARGB_REDUCE(x,red) \
- ({ \
- int _red = (red) >> 8; \
- if (_red < 256) \
- x = mmx_mulshift( x, _red, 8, _zero ); \
- })
-
-#define ARGB_INTERP255(x1,x2,x3,alpha) \
- x1 = mmx_interp255( x2, x3, _zero, (alpha))
-
-#define ARGB_ADDW_11(x1,x2,x3) \
- ARGB_SUM(x1,x2,x3)
-
-#define ARGB_ADDW_31(x1,x2,x3) \
- ({ \
- mmx_t _t1 = _mm_add_pi16(x2, x3); \
- mmx_t _t2 = _mm_slli_pi16(x2, 1); \
- x1 = _mm_add_pi16(_t1, _t2); \
- })
-
-#define ARGB_ADDW_13(x1,x2,x3) \
- ({ \
- mmx_t _t1 = _mm_add_pi16(x2, x3); \
- mmx_t _t2 = _mm_slli_pi16(x3, 1); \
- x1 = _mm_add_pi16(_t1, _t2); \
- })
-
-#define ARGB_SHR(x1,x2,s) \
- x1 = _mm_srli_pi16(x2, s)
-
-
-#define ARGB_MULSHIFT(x1,x2,v,s) \
- x1 = mmx_mulshift(x2, v, s, _zero)
-
-#define ARGB_DONE _mm_empty()
-
-#define ARGB_RESCALE_SHIFT 10
-#define ARGB_DECL_SCALE(s2,s) int s2 = (int)((s)*(s)*(1 << ARGB_RESCALE_SHIFT))
-#define ARGB_RESCALE(x,s2) x = mmx_mulshift( x, s2, ARGB_RESCALE_SHIFT, _zero )
-
-#else /* !USE_MMX */
-
-typedef uint32_t argb_t;
-
-#define ARGB_DECL_ZERO() argb_t _zero = 0
-#define ARGB_DECL(x) argb_t x##_ag, x##_rb
-#define ARGB_DECL2(x1,x2) argb_t x1##_ag, x1##_rb, x2##_ag, x2##_rb
-#define ARGB_ZERO(x) (x##_ag = x##_rb = 0)
-#define ARGB_COPY(x,y) (x##_ag = y##_ag, x##_rb = y##_rb)
-
-#define ARGB_UNPACK(x,v) \
- ({ \
- argb_t _v = (argb_t)(v); \
- x##_ag = (_v >> 8) & 0xff00ff; \
- x##_rb = (_v) & 0xff00ff; \
- })
-
-#define ARGB_PACK(x) (uint32_t)(((x##_ag) << 8) | x##_rb)
-
-#define ARGB_SUM(x1,x2,x3) \
- ({ \
- x1##_ag = x2##_ag + x3##_ag; \
- x1##_rb = x2##_rb + x3##_rb; \
- })
-
-#define ARGB_REDUCE(x,red) \
- ({ \
- int _red = (red) >> 8; \
- if (_red < 256) { \
- x##_ag = ((x##_ag*_red) >> 8) & 0xff00ff; \
- x##_rb = ((x##_rb*_red) >> 8) & 0xff00ff; \
- } \
- })
-
-#define ARGB_INTERP255(x1,x2,x3,alpha) \
- ({ \
- int _alpha = (alpha); \
- int _ialpha; \
- _alpha += _alpha >> 8; \
- _ialpha = 256 - _alpha; \
- x1##_ag = ((x2##_ag*_ialpha + x3##_ag*_alpha) >> 8) & 0xff00ff; \
- x1##_rb = ((x2##_rb*_ialpha + x3##_rb*_alpha) >> 8) & 0xff00ff; \
- })
-
-#define ARGB_ADDW_11(x1,x2,x3) \
- ({ \
- x1##_ag = (x2##_ag + x3##_ag); \
- x1##_rb = (x2##_rb + x3##_rb); \
- })
-
-#define ARGB_ADDW_31(x1,x2,x3) \
- ({ \
- x1##_ag = (3*x2##_ag + x3##_ag); \
- x1##_rb = (3*x2##_rb + x3##_rb); \
- })
-
-#define ARGB_ADDW_13(x1,x2,x3) \
- ({ \
- x1##_ag = (x2##_ag + 3*x3##_ag); \
- x1##_rb = (x2##_rb + 3*x3##_rb); \
- })
-
-#define ARGB_MULSHIFT(x1,x2,v,s) \
- ({ \
- unsigned _vv = (v); \
- x1##_ag = ((x2##_ag * _vv) >> (s)) & 0xff00ff; \
- x1##_rb = ((x2##_rb * _vv) >> (s)) & 0xff00ff; \
- })
-
-#define ARGB_SHR(x1,x2,s) \
- ({ \
- int _s = (s); \
- x1##_ag = (x2##_ag >> _s) & 0xff00ff; \
- x1##_rb = (x2##_rb >> _s) & 0xff00ff; \
- })
-
-#define ARGB_DONE ((void)0)
-
-#define ARGB_RESCALE_SHIFT 8
-#define ARGB_DECL_SCALE(s2,s) int s2 = (int)((s)*(s)*(1 << ARGB_RESCALE_SHIFT))
-#define ARGB_RESCALE(x,scale2) ARGB_MULSHIFT(x,x,scale2,ARGB_RESCALE_SHIFT)
-
-#endif /* !USE_MMX */
-
-#define ARGB_ADD(x1,x2) ARGB_SUM(x1,x1,x2)
-#define ARGB_READ(x,p) ARGB_UNPACK(x,*(uint32_t*)(p))
-#define ARGB_WRITE(x,p) *(uint32_t*)(p) = ARGB_PACK(x)
-
-#endif /* !ARGB_T_DEFINED */
-
-
-
-#ifdef ARGB_SCALE_GENERIC
-static void
-ARGB_SCALE_GENERIC( ScaleOp* op )
-{
- int dst_pitch = op->dst_pitch;
- int src_pitch = op->src_pitch;
- uint8_t* dst_line = op->dst_line;
- uint8_t* src_line = op->src_line;
- ARGB_DECL_SCALE(scale2, op->scale);
- int h;
- int sx = op->sx;
- int sy = op->sy;
- int ix = op->ix;
- int iy = op->iy;
-
- src_line += (sx >> 16)*4 + (sy >> 16)*src_pitch;
- sx &= 0xffff;
- sy &= 0xffff;
-
- for ( h = op->rd.h; h > 0; h-- ) {
- uint8_t* dst = dst_line;
- uint8_t* src = src_line;
- uint8_t* dst_end = dst + 4*op->rd.w;
- int sx1 = sx;
- int sy1 = sy;
-
- for ( ; dst < dst_end; ) {
- int sx2 = sx1 + ix;
- int sy2 = sy1 + iy;
-
- ARGB_DECL_ZERO();
- ARGB_DECL(spix);
- ARGB_DECL(pix);
- ARGB_ZERO(pix);
-
- /* the current destination pixel maps to the (sx1,sy1)-(sx2,sy2)
- * source square, we're going to compute the sum of its pixels'
- * colors... simple box filtering
- */
- {
- int gsy, gsx;
- for ( gsy = 0; gsy < sy2; gsy += 65536 ) {
- for ( gsx = 0; gsx < sx2; gsx += 65536 ) {
- uint8_t* s = src + (gsx >> 16)*4 + (gsy >> 16)*src_pitch;
- int xmin = gsx, xmax = gsx + 65536, ymin = gsy, ymax = gsy + 65536;
- unsigned ww, hh;
- unsigned red;
-
- if (xmin < sx1) xmin = sx1;
- if (xmax > sx2) xmax = sx2;
- if (ymin < sy1) ymin = sy1;
- if (ymax > sy2) ymax = sy2;
-
- ww = (unsigned)(xmax-xmin);
- red = ww;
-
- hh = (unsigned)(ymax-ymin);
- red = (hh < 65536) ? (red*hh >> 16U) : red;
-
- ARGB_READ(spix,s);
- ARGB_REDUCE(spix,red);
- ARGB_ADD(pix,spix);
- }
- }
- }
-
- ARGB_RESCALE(pix,scale2);
- ARGB_WRITE(pix,dst);
-
- sx1 = sx2;
- src += (sx1 >> 16)*4;
- sx1 &= 0xffff;
- dst += 4;
- }
-
- sy += iy;
- src_line += (sy >> 16)*src_pitch;
- sy &= 0xffff;
-
- dst_line += dst_pitch;
- }
- ARGB_DONE;
-}
-#endif
-#undef ARGB_SCALE_GENERIC
-
-
-#ifdef ARGB_SCALE_05_TO_10
-static inline int cross( int x, int y ) {
- if (x == 65536 && y == 65536)
- return 65536;
-
- return (int)((unsigned)x * (unsigned)y >> 16U);
-}
-
-static void
-scale_05_to_10( ScaleOp* op )
-{
- int dst_pitch = op->dst_pitch;
- int src_pitch = op->src_pitch;
- uint8_t* dst_line = op->dst_line;
- uint8_t* src_line = op->src_line;
- ARGB_DECL_SCALE(scale2, op->scale);
- int h;
- int sx = op->sx;
- int sy = op->sy;
- int ix = op->ix;
- int iy = op->iy;
-
- src_line += (sx >> 16)*4 + (sy >> 16)*src_pitch;
- sx &= 0xffff;
- sy &= 0xffff;
-
- for ( h = op->rd.h; h > 0; h-- ) {
- uint8_t* dst = dst_line;
- uint8_t* src = src_line;
- uint8_t* dst_end = dst + 4*op->rd.w;
- int sx1 = sx;
- int sy1 = sy;
-
- for ( ; dst < dst_end; ) {
- int sx2 = sx1 + ix;
- int sy2 = sy1 + iy;
-
- ARGB_DECL_ZERO();
- ARGB_DECL2(spix, pix);
-
- int off = src_pitch;
- int fx1 = sx1 & 0xffff;
- int fx2 = sx2 & 0xffff;
- int fy1 = sy1 & 0xffff;
- int fy2 = sy2 & 0xffff;
-
- int center_x = ((sx1 >> 16) + 1) < ((sx2-1) >> 16);
- int center_y = ((sy1 >> 16) + 1) < ((sy2-1) >> 16);
-
- ARGB_ZERO(pix);
-
- if (fx2 == 0) {
- fx2 = 65536;
- }
- if (fy2 == 0) {
- fy2 = 65536;
- }
- fx1 = 65536 - fx1;
- fy1 = 65536 - fy1;
-
- /** TOP BAND
- **/
-
- /* top-left pixel */
- ARGB_READ(spix,src);
- ARGB_REDUCE(spix,cross(fx1,fy1));
- ARGB_ADD(pix,spix);
-
- /* top-center pixel, if any */
- ARGB_READ(spix,src + 4);
- if (center_x) {
- ARGB_REDUCE(spix,fy1);
- ARGB_ADD(pix,spix);
- ARGB_READ(spix,src + 8);
- }
-
- /* top-right pixel */
- ARGB_REDUCE(spix,cross(fx2,fy1));
- ARGB_ADD(pix,spix);
-
- /** MIDDLE BAND, IF ANY
- **/
- if (center_y) {
- /* left-middle pixel */
- ARGB_READ(spix,src + off);
- ARGB_REDUCE(spix,fx1);
- ARGB_ADD(pix,spix);
-
- /* center pixel, if any */
- ARGB_READ(spix,src + off + 4);
- if (center_x) {
- ARGB_ADD(pix,spix);
- ARGB_READ(spix,src + off + 8);
- }
-
- /* right-middle pixel */
- ARGB_REDUCE(spix,fx2);
- ARGB_ADD(pix,spix);
-
- off += src_pitch;
- }
-
- /** BOTTOM BAND
- **/
- /* left-bottom pixel */
- ARGB_READ(spix,src + off);
- ARGB_REDUCE(spix,cross(fx1,fy2));
- ARGB_ADD(pix,spix);
-
- /* center-bottom, if any */
- ARGB_READ(spix,src + off + 4);
- if (center_x) {
- ARGB_REDUCE(spix,fy2);
- ARGB_ADD(pix,spix);
- ARGB_READ(spix,src + off + 8);
- }
-
- /* right-bottom pixel */
- ARGB_REDUCE(spix,cross(fx2,fy2));
- ARGB_ADD(pix,spix);
-
- /** WRITE IT
- **/
- ARGB_RESCALE(pix,scale2);
- ARGB_WRITE(pix,dst);
-
- sx1 = sx2;
- src += (sx1 >> 16)*4;
- sx1 &= 0xffff;
- dst += 4;
- }
-
- sy += iy;
- src_line += (sy >> 16)*src_pitch;
- sy &= 0xffff;
-
- dst_line += dst_pitch;
- }
- ARGB_DONE;
-}
-#endif
-#undef ARGB_SCALE_05_TO_10
-
-
-#ifdef ARGB_SCALE_UP_BILINEAR
-static void
-scale_up_bilinear( ScaleOp* op )
-{
- int dst_pitch = op->dst_pitch;
- int src_pitch = op->src_pitch;
- uint8_t* dst_line = op->dst_line;
- uint8_t* src_line = op->src_line;
- int sx = op->sx;
- int sy = op->sy;
- int ix = op->ix;
- int iy = op->iy;
- int xlimit, ylimit;
- int h, sx0;
-
- /* the center pixel is at (sx+ix/2, sy+iy/2), we then want to get */
- /* the four nearest source pixels, which are at (0.5,0.5) offsets */
-
- sx = sx + ix/2 - 32768;
- sy = sy + iy/2 - 32768;
-
- xlimit = (op->src_w-1);
- ylimit = (op->src_h-1);
-
- sx0 = sx;
-
- for ( h = op->rd.h; h > 0; h-- ) {
- uint8_t* dst = dst_line;
- uint8_t* dst_end = dst + 4*op->rd.w;
-
- sx = sx0;
- for ( ; dst < dst_end; ) {
- int ex1, ex2, ey1, ey2, alpha;
- uint8_t* s;
-
- ARGB_DECL_ZERO();
- ARGB_DECL2(spix1,spix2);
- ARGB_DECL2(pix3,pix4);
- ARGB_DECL(pix);
-
- /* find the four neighbours */
- ex1 = (sx >> 16);
- ey1 = (sy >> 16);
- ex2 = (sx+65535) >> 16;
- ey2 = (sy+65535) >> 16;
-
- if (ex1 < 0) ex1 = 0; else if (ex1 > xlimit) ex1 = xlimit;
- if (ey1 < 0) ey1 = 0; else if (ey1 > ylimit) ey1 = ylimit;
- if (ex2 < 0) ex2 = 0; else if (ex2 > xlimit) ex2 = xlimit;
- if (ey2 < 0) ey2 = 0; else if (ey2 > ylimit) ey2 = ylimit;
-
- ex2 = (ex2-ex1)*4;
- ey2 = (ey2-ey1)*src_pitch;
-
- /* interpolate */
- s = src_line + ex1*4 + ey1*src_pitch;
- ARGB_READ(spix1, s);
- ARGB_READ(spix2, s+ex2);
-
- alpha = (sx >> 8) & 0xff;
- ARGB_INTERP255(pix3,spix1,spix2,alpha);
-
- s += ey2;
- ARGB_READ(spix1, s);
- ARGB_READ(spix2, s+ex2);
-
- ARGB_INTERP255(pix4,spix1,spix2,alpha);
-
- alpha = (sy >> 8) & 0xff;
- ARGB_INTERP255(pix,pix3,pix4,alpha);
-
- ARGB_WRITE(pix,dst);
-
- sx += ix;
- dst += 4;
- }
-
- sy += iy;
- dst_line += dst_pitch;
- }
- ARGB_DONE;
-}
-#endif
-#undef ARGB_SCALE_UP_BILINEAR
-
-#ifdef ARGB_SCALE_UP_QUICK_4x4
-static void
-ARGB_SCALE_UP_QUICK_4x4( ScaleOp* op )
-{
- int dst_pitch = op->dst_pitch;
- int src_pitch = op->src_pitch;
- uint8_t* dst_line = op->dst_line;
- uint8_t* src_line = op->src_line;
- int sx = op->sx;
- int sy = op->sy;
- int ix = op->ix;
- int iy = op->iy;
- int xlimit, ylimit;
- int h, sx0;
-
- /* the center pixel is at (sx+ix/2, sy+iy/2), we then want to get */
- /* the four nearest source pixels, which are at (0.5,0.5) offsets */
-
- sx = sx + ix/2 - 32768;
- sy = sy + iy/2 - 32768;
-
- xlimit = (op->src_w-1);
- ylimit = (op->src_h-1);
-
- sx0 = sx;
-
- for ( h = op->rd.h; h > 0; h-- ) {
- uint8_t* dst = dst_line;
- uint8_t* dst_end = dst + 4*op->rd.w;
-
- sx = sx0;
- for ( ; dst < dst_end; ) {
- int ex1, ex2, ey1, ey2;
- uint8_t* p;
- ARGB_DECL_ZERO();
- ARGB_DECL(pix);
- ARGB_DECL2(spix1, spix2);
- ARGB_DECL2(pix3, pix4);
-
- /* find the four neighbours */
- ex1 = (sx >> 16);
- ey1 = (sy >> 16);
- ex2 = (sx+65535) >> 16;
- ey2 = (sy+65535) >> 16;
-
- if (ex1 < 0) ex1 = 0; else if (ex1 > xlimit) ex1 = xlimit;
- if (ey1 < 0) ey1 = 0; else if (ey1 > ylimit) ey1 = ylimit;
- if (ex2 < 0) ex2 = 0; else if (ex2 > xlimit) ex2 = xlimit;
- if (ey2 < 0) ey2 = 0; else if (ey2 > ylimit) ey2 = ylimit;
-
- /* interpolate */
- p = (src_line + ex1*4 + ey1*src_pitch);
-
- ex2 = (ex2-ex1)*4;
- ey2 = (ey2-ey1)*src_pitch;
-
- switch (((sx >> 14) & 3) | ((sy >> 12) & 12)) {
- case 0:
- *(uint32_t*)dst = *(uint32_t*)p;
- break;
-
- /* top-line is easy */
- case 1:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix,spix1,spix2);
- ARGB_SHR(pix,pix,2);
- ARGB_WRITE(pix, dst);
- break;
-
- case 2:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix, spix1, spix2);
- ARGB_SHR(pix,pix,1);
- ARGB_WRITE(pix, dst);
- break;
-
- case 3:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix,spix1,spix2);
- ARGB_SHR(pix,pix,2);
- ARGB_WRITE(pix, dst);
- break;
-
- /* second line is harder */
- case 4:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ey2);
- ARGB_ADDW_31(pix,spix1,spix2);
- ARGB_SHR(pix,pix,2);
- ARGB_WRITE(pix, dst);
- break;
-
- case 5:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix4,spix1,spix2);
-
- ARGB_ADDW_31(pix,pix3,pix4);
- ARGB_SHR(pix,pix,4);
- ARGB_WRITE(pix,dst);
- break;
-
- case 6:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix4,spix1,spix2);
-
- ARGB_ADDW_31(pix,pix3,pix4);
- ARGB_SHR(pix,pix,3);
- ARGB_WRITE(pix,dst);
- break;
-
- case 7:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix4,spix1,spix2);
-
- ARGB_ADDW_31(pix,pix3,pix4);
- ARGB_SHR(pix,pix,4);
- ARGB_WRITE(pix,dst);
- break;
-
- /* third line */
- case 8:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ey2);
- ARGB_ADDW_11(pix,spix1,spix2);
- ARGB_SHR(pix,pix,1);
- ARGB_WRITE(pix, dst);
- break;
-
- case 9:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix4,spix1,spix2);
-
- ARGB_ADDW_11(pix,pix3,pix4);
- ARGB_SHR(pix,pix,3);
- ARGB_WRITE(pix,dst);
- break;
-
- case 10:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix4,spix1,spix2);
-
- ARGB_ADDW_11(pix,pix3,pix4);
- ARGB_SHR(pix,pix,2);
- ARGB_WRITE(pix,dst);
- break;
-
- case 11:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix4,spix1,spix2);
-
- ARGB_ADDW_11(pix,pix3,pix4);
- ARGB_SHR(pix,pix,3);
- ARGB_WRITE(pix,dst);
- break;
-
- /* last line */
- case 12:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ey2);
- ARGB_ADDW_13(pix,spix1,spix2);
- ARGB_SHR(pix,pix,2);
- ARGB_WRITE(pix, dst);
- break;
-
- case 13:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_31(pix4,spix1,spix2);
-
- ARGB_ADDW_13(pix,pix3,pix4);
- ARGB_SHR(pix,pix,4);
- ARGB_WRITE(pix,dst);
- break;
-
- case 14:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_11(pix4,spix1,spix2);
-
- ARGB_ADDW_13(pix,pix3,pix4);
- ARGB_SHR(pix,pix,3);
- ARGB_WRITE(pix,dst);
- break;
-
- default:
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix3,spix1,spix2);
- p += ey2;
- ARGB_READ(spix1, p);
- ARGB_READ(spix2, p+ex2);
- ARGB_ADDW_13(pix4,spix1,spix2);
-
- ARGB_ADDW_13(pix,pix3,pix4);
- ARGB_SHR(pix,pix,4);
- ARGB_WRITE(pix,dst);
- }
- sx += ix;
- dst += 4;
- }
-
- sy += iy;
- dst_line += dst_pitch;
- }
- ARGB_DONE;
-}
-#endif
-#undef ARGB_SCALE_UP_QUICK_4x4
-
-
-#ifdef ARGB_SCALE_NEAREST
-/* this version scales up with nearest neighbours - looks crap */
-static void
-ARGB_SCALE_NEAREST( ScaleOp* op )
-{
- int dst_pitch = op->dst_pitch;
- int src_pitch = op->src_pitch;
- uint8_t* dst_line = op->dst_line;
- uint8_t* src_line = op->src_line;
- int sx = op->sx;
- int sy = op->sy;
- int ix = op->ix;
- int iy = op->iy;
- int xlimit, ylimit;
- int h, sx0;
-
- /* the center pixel is at (sx+ix/2, sy+iy/2), we then want to get */
- /* the four nearest source pixels, which are at (0.5,0.5) offsets */
-
- sx = sx + ix/2 - 32768;
- sy = sy + iy/2 - 32768;
-
- xlimit = (op->src_w-1);
- ylimit = (op->src_h-1);
-
- sx0 = sx;
-
- for ( h = op->rd.h; h > 0; h-- ) {
- uint8_t* dst = dst_line;
- uint8_t* dst_end = dst + 4*op->rd.w;
-
- sx = sx0;
- for ( ; dst < dst_end; ) {
- int ex1, ex2, ey1, ey2;
- unsigned* p;
-
- /* find the top-left neighbour */
- ex1 = (sx >> 16);
- ey1 = (sy >> 16);
- ex2 = ex1+1;
- ey2 = ey1+1;
-
- if (ex1 < 0) ex1 = 0; else if (ex1 > xlimit) ex1 = xlimit;
- if (ey1 < 0) ey1 = 0; else if (ey1 > ylimit) ey1 = ylimit;
- if (ex2 < 0) ex2 = 0; else if (ex2 > xlimit) ex2 = xlimit;
- if (ey2 < 0) ey2 = 0; else if (ey2 > ylimit) ey2 = ylimit;
-
- p = (unsigned*)(src_line + ex1*4 + ey1*src_pitch);
- if ((sx & 0xffff) >= 32768)
- p += (ex2-ex1);
- if ((sy & 0xffff) >= 32768)
- p = (unsigned*)((char*)p + (ey2-ey1)*src_pitch);
-
- *(unsigned*)dst = p[0];
-
- sx += ix;
- dst += 4;
- }
-
- sy += iy;
- dst_line += dst_pitch;
- }
-}
-#endif
-#undef ARGB_SCALE_NEAREST
diff --git a/android/skin/composer.c b/android/skin/composer.c
deleted file mode 100644
index 6076449..0000000
--- a/android/skin/composer.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/composer.h"
-#include <stddef.h>
-#include "android/utils/system.h"
-
-/* forwards */
-static void skin_plate_get_region ( SkinPlate* p, SkinRegion *pregion );
-static void skin_plate_get_opaque_region( SkinPlate* p, SkinRegion *pregion );
-
-/* recompute region if needed */
-static void
-skin_plate_ensure_region( SkinPlate* p )
-{
- if (p->any.type == SKIN_PLATE_SURFACE || p->group.hasRegion)
- return;
- else {
- int n, count = areflist_count( p->group.children );
-
- skin_region_reset(p->any.region);
-
- for (n = 0; n < count; n++) {
- SkinRegion r[1];
- SkinPlate* child = areflist_get( p->group.children, n );
-
- skin_plate_get_region( child, r );
- skin_region_translate( r, child->any.pos.x, child->any.pos.y );
- skin_region_union( p->any.region, r );
- }
-
- p->group.hasRegion = 1;
- }
-}
-
-/* return region in 'region' */
-static void
-skin_plate_get_region( SkinPlate* p, SkinRegion* region )
-{
- if ( p->any.type != SKIN_PLATE_SURFACE && !p->group.hasRegion ) {
- skin_plate_ensure_region(p);
- }
- skin_region_init_copy( region, p->any.region );
-}
-
-
-/* recompute opaque region is needed */
-static void
-skin_plate_ensure_opaque_region( SkinPlate* p )
-{
- if (p->any.type != SKIN_PLATE_SURFACE && !p->group.hasOpaqueRegion) {
- int n, count = areflist_count( p->group.children );
-
- skin_region_reset(p->group.opaqueRegion);
-
- for (n = 0; n < count; n++) {
- SkinRegion r[1];
- SkinPlate* child = areflist_get( p->group.children, n );
-
- skin_plate_get_opaque_region(child, r);
- skin_region_translate(r, child->any.pos.x, child->any.pos.y);
- skin_region_union( p->group.opaqueRegion, r);
- }
-
- p->group.hasOpaqueRegion = 1;
- }
-}
-
-
-/* return opaque pixels region */
-static void
-skin_plate_get_opaque_region( SkinPlate* p, SkinRegion *pregion )
-{
- if ( p->any.type == SKIN_PLATE_SURFACE ) {
- if (p->any.isOpaque)
- skin_region_init_copy(pregion, p->any.region);
- else
- skin_region_reset(pregion);
- } else {
- skin_plate_ensure_opaque_region(p);
- skin_region_init_copy(pregion, p->group.opaqueRegion);
- }
-}
-
-
-/* invalidate region in parent groups */
-static void
-skin_plate_invalidate_parent( SkinPlate* p )
-{
- if (!p->any.isVisible)
- return;
-
- while (p) {
- if (p->any.type != SKIN_PLATE_SURFACE) {
- p->group.hasRegion = 0;
- p->group.hasOpaqueRegion = 0;
- }
- p = p->any.parent;
- }
-}
-
-
-static void
-skin_plate_invalidate_( SkinPlate* p, SkinRegion* r, SkinPlate* child )
-{
- if (p->any.type != SKIN_PLATE_SURFACE) {
- int n = areflist_count( p->group.children );
- if (child != NULL) {
- n = areflist_indexOf( p->group.children, child );
- }
- while (n > 0) {
- n -= 1;
- child = areflist_get( p->group.children, n );
- skin_region_translate( r, child->any.pos.x, child->any.pos.y );
- skin_plate_invalidate_( p, r, NULL );
- skin_region_translate( r, -child->any.pos.x, -child->any.pos.y );
- if (skin_region_is_empty(r))
- return;
- }
- if (p->any.type != SKIN_PLATE_SPACE) {
- SkinPlate* parent = p->any.parent;
- skin_region_translate(r, parent->any.pos.x, parent->any.pos.y );
- skin_plate_invalidate_(parent, r, p);
- } else {
- /* send to viewports */
- int n, count = areflist_count( p->space.viewports );
- for (n = 0; n < count; n++) {
- SkinViewport* v = areflist_get( p->space.viewports, n );
- skin_viewport_invalidate(v, r);
- }
- }
- }
-}
-
-static void
-skin_plate_invalidate_region( SkinPlate* p )
-{
- SkinRegion r[1];
-
- skin_plate_get_region( p, r );
- skin_plate_invalidate_(p->any.parent, r, p);
- skin_region_reset(r);
-}
-
-/* change visibility */
-void
-skin_plate_set_visible( SkinPlate* p, int isVisible )
-{
- isVisible = !!isVisible;
- if (isVisible == p->any.isVisible)
- return;
-
- skin_plate_invalidate_parent(p);
- skin_plate_invalidate_region(p);
- p->any.isVisible = isVisible;
-}
-
-void
-skin_plate_set_opaque( SkinPlate* p, int isOpaque )
-{
- isOpaque = !!isOpaque;
- if (isOpaque == p->any.isOpaque)
- return;
-
- skin_plate_invalidate_parent(p);
- skin_plate_invalidate_region(p);
- p->any.isOpaque = isOpaque;
-}
-
-
-
-extern SkinPlate*
-skin_plate_surface( SkinPlate* parent,
- SkinPos* pos,
- SkinRegion* region,
- void* surface,
- SkinPlateDrawFunc draw,
- SkinPlateDoneFunc done )
-{
- SkinPlate* p;
-
- ANEW0(p);
- p->any.type = SKIN_PLATE_SURFACE;
- p->any.parent = parent;
- p->any.pos.x = pos->x;
- p->any.pos.y = pos->y;
- p->any.isVisible = 1;
- p->any.isOpaque = 1;
-
- skin_region_init_copy( p->any.region, region );
- return p;
-}
-
-
-SkinPlate*
-skin_plate_group( SkinPlate* parent, SkinPos* pos )
-{
- SkinRegion r[1];
- SkinPlate* p;
-
- skin_region_reset(r);
- p = skin_plate_surface( parent, pos, r, NULL, NULL, NULL );
- p->any.type = SKIN_PLATE_GROUP;
- p->group.hasOpaqueRegion = 0;
- skin_region_init_empty( p->group.opaqueRegion );
-
- areflist_init( p->group.children );
- return p;
-}
-
-
-SkinPlate*
-skin_plate_space( void )
-{
- SkinPos pos;
- SkinPlate* p;
-
- pos.x = pos.y = 0;
- p = skin_plate_group( NULL, &pos );
- p->any.type = SKIN_PLATE_SPACE;
- areflist_init( p->space.viewports );
- return p;
-}
-
-
-extern void
-skin_plate_free( SkinPlate* p )
-{
- if (p->any.type >= SKIN_PLATE_SPACE) {
- while ( areflist_count( p->space.viewports ) )
- skin_viewport_free( areflist_get( p->space.viewports, 0 ) );
- }
- if (p->any.type >= SKIN_PLATE_GROUP) {
- skin_region_reset( p->group.opaqueRegion );
- p->group.hasOpaqueRegion = 0;
- p->group.hasRegion = 0;
-
- while ( areflist_count( p->group.children ) )
- skin_plate_free( areflist_get( p->group.children, 0 ) );
- }
- if (p->any.type == SKIN_PLATE_SURFACE) {
- if (p->surface.done)
- p->surface.done( p->surface.user );
- }
-
- skin_region_reset( p->any.region );
-
- if (p->any.parent) {
- areflist_del( p->any.parent->group.children, p );
- }
-}
-
-void
-skin_plate_invalidate( SkinPlate* plate, SkinRegion* region )
-{
- SkinRegion r[1];
- skin_region_init_copy( r, region );
-}
-
-
-/* we use two regions to manage the front-to-back composition here
- *
- * 'updated' initially contains the update region, in parent coordinates
- *
- * 'drawn' is initially empty, and will be filled with the region of translucent
- * pixels that have been
- *
- * for a given surface plate, we translate the regions to plate coordinates,
- * then we do an opaque blit of 'intersection(updated,region)', then removing it from 'updated'
- *
- * after that, we make a DSTOVER blit of 'intersection(drawn,region)'
- * if the plate is not opaque, we add this intersection to 'drawn'
- *
- */
-static void
-skin_plate_redraw( SkinPlate* plate, SkinRegion* updated, SkinRegion* drawn, SkinPos* apos, SkinViewport* viewport )
-{
- SkinPos pos = plate->any.pos;
-
- if (!plate->any.isVisible)
- return;
-
- if (skin_region_is_empty(updated) && skin_region_is_empty(drawn))
- return;
-
- /* translate regions to plate coordinates */
- skin_region_translate( updated, pos.x, pos.y );
- skin_region_translate( drawn, pos.y, pos.y );
- apos->x += pos.x;
- apos->y += pos.y;
-
- if (plate->any.type == SKIN_PLATE_SURFACE) {
- SkinRegion r[1];
-
- /* inter(updated,region) => opaque blit + remove 'region' from 'updated'*/
- skin_plate_get_region(plate, r);
- skin_region_intersect(r, updated);
- if (!skin_region_is_empty(r)) {
- plate->surface.draw( plate->surface.user, r, apos, viewport, 1 );
- skin_region_substract(updated, r);
- skin_region_reset(r);
- }
-
- /* inter(drawn,region) => DSTOVER blit + if non-opaque add it to 'drawn' */
- skin_plate_get_region(plate, r);
- skin_region_intersect(r, drawn);
- if (!skin_region_is_empty(r)) {
- plate->surface.draw( plate->surface.user, r, apos, viewport, 0);
- if (!plate->any.isOpaque)
- skin_region_union(drawn, r);
- skin_region_reset(r);
- }
-
- } else {
- int n, count = areflist_count(plate->group.children);
- for (n = 0; n < count; n++) {
- SkinPos pos;
-
- pos.x = apos->x + plate->any.pos.x;
- pos.y = apos->y + plate->any.pos.y;
-
- skin_plate_redraw( areflist_get(plate->group.children, n ), updated, drawn, &pos, viewport );
- if (skin_region_is_empty(updated) && skin_region_is_empty(drawn))
- break;
- }
- }
-
- /* convert back to parent coordinates */
- apos->x -= pos.x;
- apos->y -= pos.y;
- skin_region_translate( updated, -pos.x, -pos.y );
- skin_region_translate( drawn, -pos.x, -pos.y );
-}
-
-
-extern SkinViewport*
-skin_viewport( SkinPlate* space, SkinRect* rect, void* surface, int sx, int sy )
-{
- SkinViewport* v;
-
- ANEW0(v);
- v->space = space;
- v->rect = rect[0];
- v->spos.x = sx;
- v->spos.y = sy;
- v->surface = surface;
-
- skin_region_init_empty( v->update );
- return v;
-}
-
-extern void
-skin_viewport_free( SkinViewport* v )
-{
- SkinPlate* space = v->space;
- if (space != NULL) {
- areflist_del( space->space.viewports, v );
- v->space = NULL;
- }
- skin_region_reset( v->update );
- AFREE(v);
-}
-
-extern void
-skin_viewport_invalidate( SkinViewport* v, SkinRegion* region )
-{
- SkinRegion r[1];
- skin_region_init_copy(r,region);
- skin_region_translate(r, -v->spos.x, -v->spos.y);
- skin_region_intersect_rect(r,&v->rect);
- skin_region_union( v->update, r );
- skin_region_reset(r);
-}
-
-extern void
-skin_viewport_redraw( SkinViewport* v )
-{
- if (v->space && !skin_region_is_empty(v->update)) {
- SkinRegion update[1];
- SkinRegion drawn[1];
- SkinPos apos;
-
- skin_region_copy(update, v->update);
- skin_region_reset(drawn);
- skin_region_reset( v->update );
-
- apos.x = apos.y = 0;
- skin_plate_redraw( v->space, update, drawn, &apos, v );
-
- skin_region_reset(update);
- skin_region_reset(drawn);
- }
-}
diff --git a/android/skin/composer.h b/android/skin/composer.h
deleted file mode 100644
index a52a972..0000000
--- a/android/skin/composer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_COMPOSER_H
-#define _ANDROID_SKIN_COMPOSER_H
-
-#include "android/skin/rect.h"
-#include "android/skin/region.h"
-#include "android/utils/reflist.h"
-
-/* the composer displays stacked surfaces on a target window/SDL_Surface */
-
-typedef enum {
- SKIN_PLATE_SURFACE = 0,
- SKIN_PLATE_GROUP,
- SKIN_PLATE_SPACE
-} SkinPlateType;
-
-typedef union SkinPlate SkinPlate;
-typedef struct SkinViewport SkinViewport;
-
-struct SkinPlateAny {
- SkinPlateType type; /* class pointer */
- SkinPlate* parent; /* parent container */
- SkinPos pos; /* position relative to parent */
- SkinRegion region[1]; /* the plate's region */
- char isVisible; /* flag: TRUE iff the region is visible */
- char isOpaque; /* flag: TRUE iff the region is opaque */
-};
-
-
-typedef void (*SkinPlateDrawFunc)( void* user, SkinRegion* region, SkinPos* apos, SkinViewport* viewport, int opaque );
-typedef void (*SkinPlateDoneFunc)( void* user );
-
-struct SkinPlateSurface {
- struct SkinPlateAny any;
- void* user;
- SkinPlateDrawFunc draw;
- SkinPlateDoneFunc done;
-};
-
-struct SkinPlateGroup {
- struct SkinPlateAny any;
- char hasRegion;
- char hasOpaqueRegion;
- SkinRegion opaqueRegion[1];
- ARefList children[1];
-};
-
-struct SkinPlateSpace {
- struct SkinPlateGroup group;
- ARefList viewports[1];
-};
-
-
-union SkinPlate {
- struct SkinPlateAny any;
- struct SkinPlateSurface surface;
- struct SkinPlateGroup group;
- struct SkinPlateSpace space;
-};
-
-
-extern SkinPlate* skin_plate_surface( SkinPlate* parent,
- SkinPos* pos,
- SkinRegion* region,
- void* user,
- SkinPlateDrawFunc draw,
- SkinPlateDoneFunc done );
-
-extern SkinPlate* skin_plate_group( SkinPlate* parent, SkinPos* pos );
-
-extern SkinPlate* skin_plate_space( void );
-
-extern void skin_plate_free( SkinPlate* plate );
-extern void skin_plate_invalidate( SkinPlate* plate, SkinRegion* region );
-extern void skin_plate_set_pos( SkinPlate* plate, int x, int y );
-extern void skin_plate_set_visible( SkinPlate* plate, int isVisible );
-extern void skin_plate_set_opaque( SkinPlate* plate, int isOpaque );
-
-struct SkinViewport {
- SkinPlate* space;
- SkinRect rect;
- void* surface;
- SkinPos spos;
- SkinRegion update[1];
-};
-
-extern SkinViewport* skin_viewport( SkinPlate* space, SkinRect* rect, void* surface, int sx, int sy );
-extern void skin_viewport_free( SkinViewport* v );
-extern void skin_viewport_invalidate( SkinViewport* v, SkinRegion* r );
-extern void skin_viewport_redraw( SkinViewport* v );
-
-#endif /* _ANDROID_SKIN_COMPOSER_H */
diff --git a/android/skin/default.h b/android/skin/default.h
deleted file mode 100644
index 8ab0c01..0000000
--- a/android/skin/default.h
+++ /dev/null
@@ -1,7414 +0,0 @@
-/* automatically generated, do not touch */
-
-
-static const unsigned char _data_arrow_down_png[3438] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 98, 0, 0, 0, 31, 16, 6, 0, 0, 0, 76,137,196,
- 82, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 2,
- 153, 73, 68, 65, 84,120,218,236,156, 59, 75,195, 80, 24,134,163,
- 184,104,113, 18, 20, 68,135, 90,169,163, 93,189, 45, 90,156, 26,
- 208,165, 46, 29,252, 13,222, 6, 23, 69, 71, 47,163,179, 66, 39,
- 65,112,238,170, 80, 71, 69, 23,171, 78,186, 40, 56,137, 56,198,
- 225,203, 43, 36,161,164,177, 39,151,230,188,207,242,129, 96, 27,
- 206,121,159,156,227,151, 99,186, 44,203,178, 44,203, 48,102,231,
- 170,213,151,103, 35, 38, 6, 22,157,149,232,201,103,205, 89,163,
- 227,250,170, 82,201,141, 27, 70, 79, 50, 6, 98,189,223, 22,162,
- 159,161,208, 90, 8,123,254,183, 99,187,130,238,120, 7, 96, 97,
- 139, 43, 3,241,238, 20,144, 11,109,132,232,173, 74, 45,237, 48,
- 4,196, 11,114,129,156,164, 94,136,242,152,212,190, 42, 39,159,
- 120, 65, 46,144,147,212, 10, 49,242, 33,117,250,158,147, 78,252,
- 65, 78,144,155,212, 9,177, 50,206, 73, 38, 73,206, 77, 68, 66,
- 20, 10, 82,243, 7,156, 92, 18, 28,228, 6, 57,234,120, 33,202,
- 57, 78, 42,233,132, 28,133, 44,132, 57, 44,149,109, 85,162, 2,
- 228, 8,185,234, 24, 33,112,225,243, 79,156, 68,162, 30,228, 74,
- 253,141, 54,164, 39,213,165, 93,169,186,180, 85,207, 95,164,190,
- 14,198,123, 29,163, 31,122,108, 81,145, 43,228,236,172,150, 80,
- 33,242,135, 82,117,107,171,226, 65,210,209,183,212,183,136,197,
- 64, 91,178,148,177,127,160,201,141, 8, 57,171,219,185,107,108,
- 36,108,203,100,238,233,185,132,227,142,181,158,113, 6, 52, 42,
- 17,240,189,186, 62,232, 84,151, 59, 69, 66, 76, 61,216, 43,132,
- 230,109,213,168,196,160, 8,174,157,201,129, 51,135,177, 9,129,
- 179, 38, 38,207, 36, 69, 34, 6, 69,240, 89, 41,218, 62, 3,213,
- 166, 16, 69,158, 86,141, 68, 12,138,208, 26,200, 97,113, 43, 98,
- 33,240,197, 60,173, 26,174, 24, 20,161,189, 38, 71,240, 27,245,
- 63,133, 40,243, 76, 82,168, 98, 80, 4, 53, 4,207,105, 64, 33,
- 208, 86, 45, 76,114,176,195, 16,131, 34,168, 5, 57, 69,110,149,
- 11,193,149, 33, 92, 49, 40, 66,220, 43, 69,139, 66,160,157, 53,
- 250,206,193, 13, 83, 12,138, 16, 14,200,173,127, 91,214, 71, 8,
- 180,175,202, 89, 14, 42, 73,193, 74,145,117,230,218,139,207,209,
- 13,115,215,190,115,125,115, 48, 73,122, 86, 98,211,126,144,119,
- 222,234, 10,241,247,246,131, 77, 14, 34, 73, 31,200,181,183, 45,
- 219, 68,136,213, 27, 14, 26, 73, 63,222,156,187,182, 76,104, 79,
- 229,249,194, 48,162, 1, 56, 3,149,255,146,218,216,112,173, 16,
- 171,117, 14, 18,209,112,165,168, 55,217, 50,237, 47, 75, 61,157,
- 145,122,123,199,193, 34,233, 3,185, 70,206,145,123,207,150,233,
- 167, 34, 21,194,184, 23, 12,108,169, 38,142,165,142, 44, 73, 69,
- 159,151,135,252, 72,156,224, 37,201,175, 67, 82,223, 46,165, 62,
- 174, 97, 75,228,250,133, 19,159,191, 33,252,192, 7, 54,154,125,
- 224,133, 83, 28, 0,129, 8, 81, 1, 2,238,206,101, 83, 90,254,
- 79,186, 95, 0, 0, 0,255,255, 3, 0,243,175,157,107, 47,151,
- 202,243, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_arrow_left_png[4122] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 47, 0, 0, 0, 87, 16, 6, 0, 0, 0,196,198,192,
- 67, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 5,
- 69, 73, 68, 65, 84,120,218,236, 93, 61, 76, 20, 65, 20, 62, 47,
- 52,136,216,144, 0, 49, 88, 32, 8,141,198, 43, 5,172, 60, 67,
- 37,137,132,228,108,136,208, 25, 40, 1, 41,140, 9,168, 9, 5,
- 63,150, 98, 9, 66, 35,137,129, 4, 42, 5, 59, 14, 74,136, 54,
- 30,160,197, 17,140, 38, 52,138, 71,107, 49,243,173,238,122,199,
- 238,236,205,223,238,204,215, 12,176,100,127,190,121,251,189,247,
- 102,222,204,158,235,184,181,176,176,191,151, 48, 4, 53,157,164,
- 77,127, 33,109,126,133,180, 91,215,100,223, 73, 69,188,137,110,
- 153, 38,109,215, 51,250,123,143,251,120,161,145,180, 59,139,164,
- 61,237,181,196,135, 66, 42, 69,218, 76, 19,181,240,106,122, 96,
- 170,248,255,159,167,132,119,209,227, 75,210,238, 52, 25, 15,139,
- 30,190, 72,218,129, 1,183,164, 4, 69,250, 17,105, 27,126, 88,
- 226,139,162,146, 90,104, 95,150, 18, 78, 45,186,101,138,207,249,
- 239, 55, 91,226,139, 74,200, 68, 55,105,219, 63, 10,122,131,166,
- 220,215, 51,142,120, 88,118,166,217, 45, 33,208,100,209,128,143,
- 48,134,120,104,243,240, 5,183,246,170,186,143,174, 75, 49, 39,
- 30, 78,237,201, 50,105, 47,127,215,227,190,110,239,185,223,192,
- 216,132,147,109,159, 72,219,191,172,167,228, 65,218, 50,215, 73,
- 59, 31,117,139,119, 8,223,140,134,115,135, 51, 71,248, 26, 57,
- 226,163, 70,184, 23,200,128, 35, 67,124,212, 9,247,134,155,120,
- 30,109,137,135,211,140, 58,225,255, 89,254, 88,185, 78, 87, 16,
- 241, 78, 88, 88,149,136, 37,240,124,119, 70, 53, 35,126, 96, 80,
- 110,194,163, 58,220,100, 29, 27,226, 78, 60, 50, 77, 93,226,112,
- 105,225,102,179, 34,226, 49,182,161, 42,211, 84,141,212, 13,214,
- 112,179, 76,226,157,209,194,205,132, 5,147,229,151, 73,124,215,
- 184, 25, 90, 30, 20,144, 88,255,112, 51, 36,241, 8, 19, 77,149,
- 22, 95,203,111,244, 11, 55, 67, 18, 47,111,194, 32,218, 78,183,
- 116,184,201, 72, 60,156, 7,175, 25,159,184,227,238, 88,169,112,
- 147,145,120,126, 99, 21,102,161,127,219,251,151, 10, 70, 75,175,
- 182, 36,134, 1, 20,162,229, 23,105,115, 35, 1, 45, 30, 5, 64,
- 22,101, 90,254, 86, 64,139,135, 54, 33, 65,176, 40, 15, 78, 37,
- 91, 83, 69,176,140,212,130, 13, 5, 90,145,150,163,225,246,225,
- 138,251,120,126,200,135,248,244, 1,253,161,201,146,121, 22,178,
- 116,106,112,131,134,217,135,126,163,178, 35, 21,103, 39, 72, 53,
- 203,150,212,179,136, 94,163,153,251,241, 67,214, 51,148, 32,190,
- 117,218, 90,122, 49,233,152,157,165, 18,210, 94,238, 25, 75, 68,
- 53,169, 87,150,236, 68, 34,145,200,215,145,246,241, 50,194, 64,
- 94,103, 78,158, 29,119,154, 78,248,204, 9,105,249,151,111, 39,
- 139, 39, 74,166, 75,138, 56,194, 75, 16,223,250, 34, 26,196, 28,
- 191, 19,115,126,104,184,248, 5, 10, 30,226, 27,238,105,110,137,
- 191, 41,241,239,249,158,127,103,151,183,134, 51, 18,175,219,132,
- 134,151,240,195, 90, 49,215, 89,218,151,253,100, 73, 61,157,170,
- 44,194, 17,143,139,146, 46,230,168, 38,238,132, 3,187,131,170,
- 158, 52,169, 71, 52, 35,155,112, 71,219,119, 20, 19,111, 26,225,
- 57,229,115,197, 73,179, 8,119, 18,164, 90,195,136, 87, 77, 56,
- 112, 90, 48,140,120, 36, 40,135,202, 45,206, 48,226, 81,105, 85,
- 185,104,137,151, 10, 84, 90, 97, 85,159,185, 29,160,200,185,170,
- 238,128,150, 19, 67,137, 87,221, 1, 13,223, 52, 33, 62, 95,111,
- 86, 7, 96, 76, 74,222,166, 17, 37,136,151,183, 79,139, 94, 29,
- 144,222, 87, 76,188,147, 88,212,153,213, 1,168, 23,146,239,228,
- 61,196,203, 31,165, 83,219, 1,206, 70, 65,227,138,137,247, 22,
- 222,104,219, 1,175, 57, 75,142,234,141,130, 62, 15,233, 29,253,
- 162, 3, 68, 45,110,235,207,202,146, 30,175,198,215, 39,140, 6,
- 58, 20, 29, 32,141,120, 68, 55,186, 56, 89, 85,128,211,237, 19,
- 246, 6,148, 72,160,228, 77,250,234, 13,236,218, 1,223,194,190,
- 144,152,145,248,108,214,146, 94, 76,130,176,145, 81,122, 84, 16,
- 241, 24,182,213, 45,188, 84, 13,103, 37, 55,173, 41,157,232,113,
- 119, 68,112, 73,242, 41,211, 70,189, 73,186,211,146, 94, 12,144,
- 158, 12,253, 61, 67, 39,120,114,116, 31,204, 28,149, 40,204,120,
- 97, 34,168,240,192,135,248,141, 43,148,120,203, 49, 19,156, 53,
- 79, 37,142,175,165,124,136,135,212,228,182,221, 39,180, 8, 7,
- 88,252,122, 85,192, 97, 97,235,108,249, 96,233, 43,194,246,128,
- 196, 99,155,111,235,108,195, 1,121,209,223,237,210, 25, 39, 66,
- 86,159, 90, 18, 67, 89,250,126,192,112,210, 90, 62, 31,160, 54,
- 243,255,132, 52,228,212,223, 92,155, 37, 53,136, 19,197,226,180,
- 192, 9,148, 31,208,131,136,243, 45,220,248,112,213, 79, 25,202,
- 156,236,134,118, 21,122, 45,217,255, 18,189, 62, 25,114,200,128,
- 245, 66,107,214,233, 18, 67, 60, 64,184, 40,152,120, 39,195,157,
- 52, 91,122, 80,125, 28,188,236,155,115, 93,205, 92,187,153, 81,
- 207, 27,230,106, 5,206,196,227, 21,123, 57,107,134,246, 35, 92,
- 100, 47,194, 21, 84, 73,134, 27, 65,138, 28,215,112,113, 41,244,
- 62, 62,130, 75,248,144,112,193,233,196, 45, 92, 12, 95, 8, 38,
- 169,118, 18,206, 23,175,102,212,195,197,213,163,114,207, 36,185,
- 104,117,190, 61,218, 29,192, 47, 99, 87, 84, 45,140, 14,136,138,
- 4, 33, 92, 20,190,123,135, 44, 64,130,230, 58, 52,183,244,155,
- 188,207,168,201, 71, 22,225,132,243,180,132, 14, 27,254,171, 94,
- 226,191, 65,103,220,142,185, 87, 21,107,182,178, 27, 97,168,179,
- 49,143,162,245,168, 8, 23, 87,199, 69, 93, 65,211, 79,206, 33,
- 76,155,249, 73, 90,217, 99, 65,184,158,180,253,106,116, 5,194,
- 183,231,221, 98,223, 4, 76,209,109, 76,138,126,162,136,125, 86,
- 20, 82,132, 55, 1, 78,153,215,208,132,188,237, 83, 34,254, 33,
- 93, 56,101,248, 4, 72, 4,107, 71, 40,223, 40, 40,170,128, 22,
- 67,146,188, 29,225, 55, 90, 42,127,163,160,152,126, 44,221,233,
- 8,248,136,183,164, 77,209,132,173,141, 38,112, 88, 1,115,124,
- 36,251, 14,255, 12, 0,112,186,137,242,235,201, 20,157, 0, 0,
- 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_arrow_right_png[4147] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 47, 0, 0, 0, 87, 16, 6, 0, 0, 0,196,198,192,
- 67, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 5,
- 94, 73, 68, 65, 84,120,218,236,157, 59, 76, 20, 65, 24,199,199,
- 11,141,248,104, 72,208, 24, 40, 4, 61, 26,141,103, 39,167,149,
- 24, 43, 72, 32, 38,216,144,120,157,129, 22,206,194,168,128, 38,
- 22, 60, 44,197, 18,149, 70, 18,131, 9, 84, 42,118,128,229, 33,
- 52,242,178,128, 96, 48,161, 81, 30,173,197,204,127,143,221,123,
- 176,183, 59,175,221,153,175,249, 2, 7,251,248,125,179,223, 99,
- 118,230,187, 19, 55,111,189,127,191,182, 74, 20, 73,243, 50,213,
- 245,237, 84,207, 54, 80,189,251,153,196, 92,170,212,156,246,228,
- 4,213,157, 23,169,174,206, 82,221,194, 62, 95,249, 78,245,244,
- 51,246,115,159, 5,207, 69,218, 6, 24,240,253,226,159, 39,135,
- 169,238,101, 63,239,222,163,122,114,157,234, 92, 46,234,224, 19,
- 114, 79, 87,115,151,141,236,108,176,255,235,238,102, 6, 57,203,
- 12, 52, 98,193,251,146,204,119, 62,199,113,158,136, 51, 84, 63,
- 152,119,187, 48, 11,158, 73, 42,229, 6,198, 91,210, 75, 84,191,
- 236,112,159,207,120,240,157,141,114,206, 83, 61,225,118, 73,157,
- 151,116,125, 18, 4,131,111,187,224,246,209,178, 5,177,164,247,
- 180,218,235,144, 6, 30, 35,236,246,170, 30,183, 89,191, 67,245,
- 147, 41,170,235,254,196, 20,124,103,131,251,209,215, 69,112, 61,
- 79,167,220, 5, 92,228,193, 35,189, 67,176,211, 93, 50,115,170,
- 12,192, 25,124,219,243,104,102,213,242, 13,192,169,114,197, 5,
- 39,231,162, 93, 79,194, 0,132,221,207,194, 21, 77, 71, 60,130,
- 104, 91, 63,137,149,192, 0,226,130,112, 72,240,119, 30,233,150,
- 166,241,149,222, 83,162,238, 47, 32,120, 92,136, 46,233,162,240,
- 130,172, 71, 19,240,168, 8,171, 39,136, 17,130, 58, 0,247, 45,
- 29, 60,210,197,212, 53, 98,164,160, 18, 14, 63, 23,148, 8, 54,
- 210, 77,151, 7,115,238,228, 66, 24,120,231, 21,221,142,133,126,
- 212,197,226,133, 14,119,240,222, 87,116, 86,138,187,158,202,211,
- 206,132,191,116,209,148, 32, 26, 84,238, 95,226, 4, 30,233, 98,
- 107,191,133,234, 43,233, 24,118, 39, 31,129,193,243,122, 69,103,
- 154,248,159,171,170, 42,158, 46, 38,207, 88,136,161, 70,254, 63,
- 170, 75, 47, 75,241,140,248,204,130,133,199, 37,232,110,248,116,
- 53, 45, 49,159,115,145, 45, 40, 48, 75,243,100,224, 55,107,169,
- 158, 25,116,235,220, 34,213, 7, 93, 22,102, 16, 73, 47, 31,227,
- 227,225,139, 86,188,159,191,118,107,228,171, 45,107,236,192, 75,
- 22,110,217,194,179,153,234,233,143, 33,167, 12,182,216,147,241,
- 54, 77,245, 99,118,192,249,171, 22,114,185,180,188,176,192, 10,
- 57, 31,143, 85,189, 48,196,232, 63,235,154,138, 73,211, 8,103,
- 240, 94,129,203,122,204,222,226,111,158,179,208, 9, 33, 36,245,
- 70, 48,120,200, 33, 27,241,163,123,214, 0, 71,243,123,225,224,
- 75, 25,192,116, 23,148,159, 82,144,180,118, 18, 6, 24, 27, 19,
- 115,124,196, 26,221, 13,219,244, 74, 50,120,111, 12,224,157, 5,
- 237,126, 97, 79,214,190,222, 6,168,107, 87, 4, 30, 50, 51, 32,
- 230,184, 72,119,117, 53, 64,126,122, 93, 17,120,184, 6, 81,249,
- 191,174, 6,200, 7,217,132,218, 11, 89,236, 17,123,124,125,159,
- 0,197,224,101,109, 34,211,205, 0,201,145,132, 30,246, 95,201,
- 154,102, 0, 77,192, 99,118, 84,150,168, 55,128, 38,224, 15, 15,
- 212,156, 87,157, 1, 52, 1,175, 90, 96, 0, 81, 5, 94,161, 84,
- 89,232,132, 28, 89, 63,196, 54,169,145, 29, 59,226,165, 0,199,
- 174, 64,121, 43,229, 52, 1,159,220, 51, 5,184,102,224,235,126,
- 155, 2, 92, 19,240,120, 37, 38,122,137,160, 62,192, 89,250,124,
- 94, 49,120,188, 52, 55, 5,184,147, 62,119, 41, 2, 15, 32,162,
- 54, 56,232, 10, 60,255, 38, 78, 81, 58,233,172, 66,222, 55, 3,
- 56, 36,223,242, 75, 50,120,248,244,214, 41,206,192,223, 49,224,
- 68, 79,224, 78,161,246, 73, 50,120,140,196,204,188,152,227, 71,
- 101,167,138, 51, 39,181, 45,201,199, 3,184,233, 91,121,126,246,
- 9, 30,241, 78, 9,206,186,120,164, 12, 95,234,135,160,122,216,
- 46, 8,188,211,180, 13,193,205,174,173, 36,132, 20, 91, 39,207,
- 201,213, 96,153, 55, 26,241,216,221,129,110,153, 47,136,109, 21,
- 142,120,184,144,244, 15, 6,156,245,129,172, 65,207, 49,187, 73,
- 173,104,250,184,245,176, 4,120,167,116,127,231, 46,225,235,217,
- 239, 49,137,149, 68,222,221,232,209, 86,138, 10,246, 23, 20, 10,
- 3,127, 61,197,242,107,236,242,235,182,208,120, 8,122, 37,147,
- 181, 18, 62,254,235, 16,213,118,121, 53,167, 96,154,245, 86,170,
- 37,192, 99,109,227,228, 47, 11, 77, 76, 48, 61, 38,171, 65, 43,
- 40, 89,203, 45,226, 26, 76,143,111,169, 85, 34,157, 68,251,112,
- 43,149,201,244,160,223,191, 76,148, 79,248,237,222, 38,222, 35,
- 221,103, 1,133, 85,189, 54,232,150,151,241,230, 74,255, 35,225,
- 207,146,223, 46, 91,184,229,242,244,202,191,209,193,231,148, 1,
- 210,205,248,127,119,135, 63,129, 7,152, 12,252,234,210, 39,120,
- 39,221, 92,183,208, 9,201,239,124, 15, 62, 16, 43,156, 36,195,
- 178,106, 83,211, 77,184,150,217,161,176, 71, 10, 56, 59,249, 97,
- 205, 44,224, 24,217,227,105, 94, 71, 12, 8, 30,139, 60, 77, 73,
- 55, 95,143,185, 93,174, 50,240,144,201,141,120,167,155,227, 55,
- 221, 3,141,159,132, 4,143, 17, 16,183,116, 19, 73,132,182,221,
- 180,157, 82,121, 59, 30,233, 38, 92,103,248,224, 41, 9,124,240,
- 10, 78, 47,224,111,211,178,206, 40,168,123, 71, 84,210, 77,228,
- 227,242,128, 11, 2,239,140,252, 27,209, 8,154,112,145,242, 69,
- 16,120,248,250,217, 97, 61, 64, 35,235, 66, 35, 35,113, 65, 83,
- 49,120, 39,232, 14,168, 77, 55,225,242,208,184, 72,159,175, 39,
- 149,212,175,102,102, 80,238,109,225,124,163,127,121, 23, 62, 17,
- 1, 15, 65,122, 38,170, 83, 19, 70,246,139, 14,213,190, 91, 51,
- 240, 78, 97,194,105,142, 7,174, 11, 65, 18, 35,123,171,150, 68,
- 68, 36,175,143,135,143,205,177,174, 29,126,119,132, 28,120, 42,
- 228,175,167,116,117, 33,154,130,247,142,252, 82,224,157,119,152,
- 11, 30,208,112, 33,145,159, 27, 82, 4, 30, 96,103, 88, 11, 88,
- 180,140, 90, 96,235, 81, 10,218,169,196,110, 18,238,255, 0, 9,
- 225,144,193,153,103,176,249, 0, 0, 0, 0, 73, 69, 78, 68,174,
- 66, 96,130
-};
-
-static const unsigned char _data_arrow_up_png[3493] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 98, 0, 0, 0, 31, 16, 6, 0, 0, 0, 76,137,196,
- 82, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 2,
- 208, 73, 68, 65, 84,120,218,236,156,189, 79,219, 80, 20,197, 93,
- 43, 75, 17,116,161,130,165,153,160,233, 2,123, 9, 48, 85,160,
- 142,176, 91, 85,214,238,237, 86,137, 34,161, 14, 41,255, 0, 27,
- 66, 89,200, 2, 18, 12,136,143, 46,109,194,154, 74, 93, 26, 1,
- 75,171, 74, 84,101, 65, 5, 70, 51,188,123, 2, 54,114, 18,219,
- 239,197, 78,114,126,203,145,162,248, 35,215,231,216,126,247,217,
- 121,228,186,174,235,186,150, 53, 51, 91, 42,157,158, 88,154,121,
- 246, 87,233,192,134,247,243,225,215, 74,159,206, 91,132, 4,242,
- 111, 95,233,197,158,247,243,235, 55, 74,127,143,232,218,210,183,
- 175,142, 51, 54,110, 89,153,112,139, 61, 46, 41,125,177,170, 52,
- 43,134,207,253, 23,163,207,137,194,232, 91,162, 67,190, 21, 85,
- 68,151,120,208, 73, 19, 42, 1,254,129,175,214, 36, 48, 8,206,
- 129,210,250,160,210, 95, 18,152,159,239,148,222, 56,173, 54,152,
- 105,126,102,207,231,197,240, 8,192,185,124,225, 45,143, 21, 73,
- 15, 56, 1, 67,115,254, 47, 92, 73, 64,182, 37, 48, 18,144,106,
- 213,127,165,241, 5,226,131, 44,144, 69, 2,223,139,158,179,232,
- 164,251,193, 9, 61, 43,190,126,181,229, 13,202,202,130,237, 93,
- 224,104,156, 69, 35,253,199,157,239,125,129, 56,158,144,196,140,
- 178, 72,164,247,129,207,225,251, 7,129, 0,229, 19, 22,139,244,
- 62, 15,125, 30, 16, 8, 12, 58,106,223, 89, 52,210,123,192,215,
- 240,121,203, 64,248, 19,116,237,176,136,164,251,129,143,131,239,
- 128, 90, 4, 2,253,221, 47,207, 89, 76,210,253,192,199,240,117,
- 232, 64,128,195, 98,171, 21, 17,146, 94,224, 91,248, 56,152, 54,
- 3,129, 25,190,157,101, 22,215, 4,235,211, 94, 37,122,129,111,
- 35,207, 84, 7,129,246, 84,254,137,210,220,103, 22, 91, 71, 16,
- 238,218,126,194, 15, 37,133, 10,107, 20,135,186, 76,192, 29, 95,
- 182,187,132, 29,109, 67,155,108,203,154, 9,130,239,196,195, 43,
- 70, 60,194,251, 52, 98, 32,240,236, 71,117,146, 69,215, 25, 4,
- 6, 67, 15,240,101,248,167, 97,237,120, 27, 46,159, 41,101, 91,
- 86,111, 16, 24,140,104, 52,218,170,103, 81,215, 16, 51, 16, 24,
- 164,176, 45,107, 38, 8, 12, 70, 56,224,195, 27, 39,161, 64, 52,
- 70,241,127,148,178, 45,107, 38, 8, 12, 70,115,224, 59,248, 48,
- 58,182,222, 29, 43,159, 50, 8, 38,131,192, 96,152,246,157,230,
- 64,212,106, 74,209,238, 98, 16, 24, 12,147,192,103,240, 93,124,
- 50,134, 12,242, 82,233,167, 62, 57, 48,152, 47, 40,172, 37,188,
- 35,125, 54,111, 1,159, 89,218,110,213,109, 51, 59,138,123,186,
- 35, 78,220, 17, 3,192, 87,250,199,172,182,217, 29,223,249,168,
- 148,109, 89,162, 3,248, 8,190,210,143,225, 64,160,253,181,203,
- 103,160,136, 6,118,219,126, 38, 41,165,129,104, 92,226,248,180,
- 44,209,113, 11, 94, 52,189, 37,187,179, 63,108,125,138, 7,151,
- 164,217, 55, 29, 14, 4, 95, 77, 37, 97, 8,126,213,179, 71, 2,
- 1,248, 39, 6, 36,157, 62, 73, 40, 16,184, 39,228, 96,155, 52,
- 27, 60,119,126,204,105, 39,251,195,241, 74, 31,219,178,228,190,
- 15, 14,139, 73,237, 65, 38,217, 2,160,125,182,226,251,111, 78,
- 210,159, 92, 44,138, 47, 18,235, 70,222, 2, 0, 0,255,255, 3,
- 0,166,247,214, 91, 44,122,150,205, 0, 0, 0, 0, 73, 69, 78,
- 68,174, 66, 96,130
-};
-
-static const unsigned char _data_back_png[3564] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 46, 0, 0, 0, 47, 16, 6, 0, 0, 0,204,117, 36,
- 209, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 3,
- 23, 73, 68, 65, 84,120,218,236,155, 59,108, 19, 65, 16,134, 23,
- 43, 13, 78, 66, 67, 20, 40,156, 34,194,144, 6,228,107, 19, 83,
- 97,100,165,177,196, 67, 10,141, 37,232, 34,187, 4, 76,129, 16,
- 226,209,133,164,141, 41, 19,146, 42,141,145,160, 66, 28, 93, 28,
- 74, 35,165,193, 9,105, 28,129,176,148, 6,129,211, 82,236,252,
- 129, 59,251,228,123,236,173,207,246,252,205, 40,241,227,124,223,
- 206,254, 59,123,119,115, 42,125,117, 99, 99,127, 79, 68, 92,151,
- 150,189,189,191,113, 94,198,227,124,212,206,100,164,183,135, 63,
- 189, 41,163, 97, 16,216, 95, 50,206,172,200,120, 54,235,243,139,
- 255,200,208,162, 88, 47, 81, 28,147,177, 86,147,241,232,195,128,
- 3, 71,166,102, 14, 8, 52, 1, 17,219,182, 55,102,213, 28, 47,
- 142, 1, 77, 81,164,255, 47, 92,160, 1,248, 44, 99,181, 42,227,
- 206,229, 62, 7, 14,192,185, 23,244,247, 56,189,144,138,136, 85,
- 189,162, 72, 3,158,187, 45,227,214, 55,235, 76, 80,167, 88, 56,
- 22,177,144,148,241,193,184,245,196,162, 46, 88, 88,161, 64,191,
- 255, 76, 64,107, 11, 11,120,162, 73, 63,144, 60, 50, 83, 18, 3,
- 33, 36,202,147,138,117,173,233, 25,240, 19,208,163, 50, 78,253,
- 20, 3, 41,172, 5,200,252,217, 93,205, 30,142,145, 46, 84,196,
- 80,234, 30, 22,249, 93,175,139,109,204, 95, 70,223,221, 22,172,
- 255,192,187,207,120,151,192,177, 24,194, 58, 48,197, 88, 86,240,
- 72,200,192,192,139, 69, 6,237,138, 83,193,154,160,158,129, 99,
- 170,244, 75, 89, 23,149,178, 50,247,204, 35,240,147,122,122,154,
- 33,250, 17,202,226,118,139,113, 0,126,253, 17, 91,136, 10,221,
- 73,186, 4,126,109,143, 97,169,220, 56,253,219,169,198, 58,123,
- 54,103,182, 98,139, 57,112, 0,110,172, 50,156, 48,100,164, 28,
- 128,115, 53, 18,110,245,146,104, 18,112, 92, 70,101, 43, 9, 87,
- 51,203, 4,124,170,201, 48,116, 40,113, 35,198,153,173, 83, 19,
- 243,176,148,223, 12, 67, 75,134,255,136, 49, 4,157,138,111, 50,
- 112,205, 98,224, 12,124, 40,128, 55, 38, 25,133, 14,213, 75, 4,
- 252,232, 22,195,208,161, 86,158, 51, 92,171, 14,223, 18,240,250,
- 67,134,161, 67, 95,239,219, 30,147,168,125,145,209, 72, 49, 28,
- 181, 86, 66,137, 61,106,171, 82,106, 69,134, 19,134,144,200,109,
- 101, 33, 30, 94,108,229, 25,146, 74,153, 73, 7,224,120,128,253,
- 211, 69,134,164,166, 12,164,197,114,178,203,198,231,227, 18,103,
- 186, 10,189,123,234,114,167,137, 76,127,255,156,161, 5,241,236,
- 246,234,175,203,214,222,164, 76,111,156, 99,136, 94,170,145,181,
- 185, 46, 91,251,110, 42,175,178,197,184,209,122,218,234, 16,190,
- 129,163,249,168, 92,102,168,157, 4,235,237,222,162,226,241,106,
- 33, 60,105, 45,205,144,133, 16,162,122,133, 22,199,239,110, 63,
- 225,243,242, 44, 30, 64, 31, 86,240, 38, 61, 78,178, 62,231,245,
- 147, 1,175,135, 3,252,203,155,195,225,241, 72,176,173,125,191,
- 223,160,232, 6, 4, 10,251,199, 21,251, 86,182,191,133,234, 12,
- 9, 21,188,143, 83,113,159, 38, 86,103,172,173,232, 5, 66, 35,
- 170,186,246,187,112,203, 58, 44,130,230,162,234, 35,132,220, 24,
- 139, 85, 27,113,150, 78, 36, 67, 83,178,215, 93,111,168,190, 76,
- 74,136, 42,205,208,227,165,176,142,168,185,245, 27, 83,114, 71,
- 88, 51, 30, 51,193,120, 45,163,234,103, 28, 97, 13,168,178,208,
- 234,125,184,168,123,136, 71, 34,146, 97,136,120,129, 64,160,131,
- 32,254,134, 6,104, 94,198,137,108,103, 43,176,223,185,114,188,
- 177,210,179, 59, 92,127, 7, 0,162,170,196, 84,182,147,226,216,
- 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_end_png[3562] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 46, 0, 0, 0, 47, 16, 6, 0, 0, 0,204,117, 36,
- 209, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 3,
- 21, 73, 68, 65, 84,120,218,236,156, 61, 72, 91, 81, 20,199, 95,
- 31, 89,140,208, 69,209, 82,226,208,150,218,197,162, 99,243,236,
- 166,136,131, 1, 69,112, 10,146,173,152,177,126, 76,173, 70, 40,
- 29,172,174,149,110, 17, 51, 9,146,130, 29, 74, 81, 55,147,142,
- 79,236,162,141,237,160,180, 24,234, 98, 75,178, 58,220,115,132,
- 119,227,235,251,186,247,230, 37, 57,255,229,228,227,230, 37,249,
- 221,115,207, 61,231,230,222,220, 25,124,190,185, 89,250,174,133,
- 92, 29, 35, 86,107,167,202, 52,179,231, 93, 97,253, 38,145,112,
- 124,140,129, 1,102,123,255,129, 93,101,182,231,194,227,133,242,
- 96, 63, 48,115,214, 13, 22, 58,224,228, 46,179,166,201,108, 53,
- 217,228,192, 99,101,102,135, 74, 0,186,159,217,104,142,107,120,
- 33,230,253,176,195,208, 26,220,243,102,154,217,189,135,208, 33,
- 115, 13, 14, 28, 67, 64,234, 43,120,110,158,107,112, 84,231,145,
- 5, 29, 14, 3,236,102, 4,236, 44,202,234, 0, 73,192, 19,247,
- 153, 29,155,132, 7, 38,181,134, 80,239, 59,102,103,185, 17,144,
- 53, 68,133,160,136, 88, 79,158, 73,251,140,189, 33, 21,142,128,
- 183, 19,204,174,149,131, 78,202,186,152,152,252, 42,223, 92,160,
- 121,225, 28,243, 26,190,103,252,155, 98,224, 8,122,182,221,102,
- 210,107,114,165, 14,252,130,215, 9,180, 90,240, 46,129,183, 1,
- 216,244, 12,129,190, 77, 83, 15,172, 14, 25, 24,120,170,224,174,
- 210,107, 85, 69, 57,135,108,203,249, 4,142, 21, 32,206,214, 36,
- 119,217, 90, 34,227, 17, 56,246,208,212, 35,130,232, 71, 67,243,
- 118, 17,193, 6,248,240, 2,133, 16, 17, 26,203,184, 4, 30,143,
- 19, 44, 17, 50,142,120,199,213,111,143,217,228,217,130, 67,204,
- 15, 27,224,253,239, 9,142,204, 37,130, 90, 15,167,108, 68,106,
- 246, 18, 43,235,214,132,157, 10, 26,185,122,178,170,227, 13,130,
- 161, 66,177,113,157, 60, 91,165, 58, 71, 1, 56,254,150, 72,146,
- 236,225,191,117,130,160, 82,209, 28, 1, 87, 44, 2, 78,192, 91,
- 2,248, 89, 23,161, 80,161,147,121, 0, 94,173, 16, 12, 21,170,
- 36, 1,248,241, 75,130,161, 66,231, 31, 1,184,252, 45, 94, 36,
- 230,216,220, 70, 32,243,144, 89, 90,196, 18, 29, 74,192,177,219,
- 185, 44, 5,183,118,145,196, 10, 29,185, 38, 45,196,109,188,149,
- 36, 65, 18,169, 98, 1,111,113, 33, 5, 55, 43,154,208,192, 32,
- 86, 1,211, 64,176, 87, 14,133,207,167, 12,121,186, 8,225,182,
- 103,199, 74,243,242, 11,179,251,143, 9, 90, 32,207,158,243, 88,
- 218,239,252,130, 74,180,155, 32,122,201, 70,178,207, 28, 74,123,
- 39,225,134,116, 10, 49,255,215,214, 79,107,132,240, 13, 28, 55,
- 160,227, 5, 73, 86,237,193,201,137, 98,159, 83, 75,143,171,133,
- 120,193,236, 32, 65,214, 52, 77, 43, 60, 5, 71, 44,185,125,133,
- 207,229,217, 86, 7,143,160, 55, 60,231,205, 1,215,195, 17,252,
- 250,122,107,196,248,173, 83,191,160, 5, 1,231, 43,212, 55, 19,
- 214,180,168,209,133,147,223,218, 95,136,213, 43, 65,175, 24,145,
- 244, 1,225,126, 28, 66, 78, 98,137,217,176,239, 89,196, 17,138,
- 245,199,238,138,181, 2, 15, 46,201, 7, 99, 49,228, 20,177, 3,
- 150,195,213, 1, 53,128,225,236, 82, 21,234, 15, 77,120,136, 84,
- 124,244,155,239,128, 24,196,126, 3, 98,162,239, 51,246, 46, 71,
- 222, 49,156,120, 61,132, 85, 81,243, 5,215, 80,250, 28, 84,231,
- 63, 55,184,201,239,241,129,113,235,243,216, 1,184, 51,172,199,
- 225,208,210, 31, 0,123,249, 25, 42,228,123,224,177,219,208, 96,
- 187,222, 65,235,122, 0,217,217,201, 30, 62,205,111,211, 0, 0,
- 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_home_png[3578] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 46, 0, 0, 0, 47, 16, 6, 0, 0, 0,204,117, 36,
- 209, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 3,
- 37, 73, 68, 65, 84,120,218,236,155, 61,108, 19, 49, 20,199,143,
- 136, 5, 10, 12,128,130,144,154, 1, 40, 97, 41, 52, 43, 41, 19,
- 65,136, 1,164, 10,164,176, 68,148, 13,114,107, 10, 27, 95, 18,
- 83, 18,214, 68,108,169,218, 41, 75,145,202,128, 42,194,150,118,
- 228, 16, 44,164,133,165, 21, 31, 17,217, 10, 93, 25,252, 94, 42,
- 91,181,236,107,206,190, 75,238,253,151,167,228, 46,185,228,231,
- 231,191,159,239,236, 3,211, 87, 22, 22, 54,214,157,136,234,208,
- 34,139,169, 95,254, 62,215,153,139,234, 63, 58, 24,238,229, 79,
- 92,103, 49,147, 97, 49,189, 13,177,194,226, 97, 0,238, 28,245,
- 249,197,175, 89,232,173,176,248,181, 4, 13,113,140, 69,207, 99,
- 113,167, 48,226,192, 47,127, 97, 49,155, 5,176,119, 36, 39, 46,
- 6,219,160,217,207, 16,133,227,158,203, 98,235,172,173,158, 97,
- 24, 56,102,110,254, 28, 0,104,195,129, 74, 52, 58,120,102, 10,
- 162,195,247,128,229,167,166, 26, 32, 97,198, 34, 74,240,195,139,
- 69,254,253,168, 11,173,172, 4, 22,150,159,224,199,146,200,100,
- 56,102,242,236,146,224,189, 67,174,220, 35,104,136, 35, 44, 54,
- 186, 44,110, 37, 67,202,112,244,100,204,228, 81, 1, 45, 42,245,
- 27, 50,127,140,197,241,174,101,224, 8,250,126,219,137,149, 48,
- 161,158, 44,241, 61,219, 24,240,184,130,150,105,182,237, 55,227,
- 53,129,227, 23, 18,232,189, 51, 30,173, 70, 61,184, 38,244,102,
- 122,110,145,224,234,128,119,221, 1,129,223,122, 62, 92,101, 93,
- 84,202, 74,180, 94,109,224,104, 33, 88, 22,145,252, 41,127, 70,
- 102, 49, 18,224,119, 39, 8, 90, 16, 22,115,237,177, 2, 56, 90,
- 71,186, 66,208,130,208,213,117, 5,240,220,119,130,100, 34,211,
- 119, 61, 93, 0,142, 55,115, 72,193, 42, 83, 19,128,227, 32, 73,
- 213,136, 33,224, 83, 2,240, 11, 85,130, 98,165,108,172, 98,134,
- 207, 16, 12, 27, 74,117, 1,248,201, 27, 4,195,206, 32,138, 25,
- 254,147, 96, 88,177,148,237, 4, 95,190,144, 76, 43, 65, 8, 8,
- 120, 28,128,255, 43, 16, 10,171,192,183, 78, 19, 10, 27,218, 76,
- 82,134, 91, 85,239, 54,102,248, 27,130, 97, 53,195, 63,122, 4,
- 195,134, 58,115,152,225, 73,178, 22,147,242, 62, 73,202,194,221,
- 3,164, 64,129,187, 18,224, 45,122,180, 22,168,208, 49,188,190,
- 101, 11,107, 11,209, 90,112, 21, 41, 61,106, 27, 76, 31,206,179,
- 184,243, 67, 49,211,196,229,186,164,193, 50,251,125, 89,115,106,
- 143,235,162,201,211,247,167,183, 47, 32,179, 11,154,192, 81,141,
- 44, 85, 47,190,234,236, 83, 48, 22,150, 21, 83,123,153,176,133,
- 230,167, 9,166,142,133,212,107,170, 51, 53,239, 22,226, 40,139,
- 93,133,196,171, 94,135,169,251,138,234, 76,159, 59, 32,150, 97,
- 180, 61,126,145, 69,220,172, 20, 87, 53,160,231,119, 38,117, 63,
- 177,207,251,225,243,224,237,173, 74,188, 65,175, 77,250,253,228,
- 128,123,124,154, 27, 48, 88,192, 15, 24,213,245,227,232,209,175,
- 254,242,243, 21,255, 10,104, 83, 21,182,244, 38, 46,220, 95,101,
- 17,247,198, 12,237,148, 28,202,226,198,152,172,204, 11, 9,184,
- 56, 83,125, 9,175,115,176,122,244,230, 51, 22,163,254,176, 26,
- 7,189,230, 55, 97, 74, 94, 11,234, 10,134, 55,198, 98, 61,186,
- 122, 9, 6, 89,248, 35, 57,136, 97, 47,173,235,215,205,112, 15,
- 105,237,129,233, 43, 90,218,250,141, 93,177,229,240,113, 28,202,
- 169,254, 86,240,170, 25, 43,234,192,198, 2,239, 33,159,185,234,
- 50,110, 72,129,171, 44,168,137,111,204,240,199,211,194,154,199,
- 84,119,111,107,250, 3,224,122,239, 96,144,187, 39, 25,220,202,
- 97,155,214,255, 1, 0,168,120,199,110, 67,179,158,126, 0, 0,
- 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_key_png[2857] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 35, 0, 0, 0, 34, 16, 6, 0, 0, 0,133, 21,188,
- 191, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 0,
- 84, 73, 68, 65, 84,120,218,236,208, 49, 1, 0, 16, 16, 0, 64,
- 212,250,112,212, 48,107, 32,207, 23,177,153,101,112, 23,225,106,
- 236,117,114,142, 94,120, 52, 5, 98,196,136, 17, 35, 70,140, 24,
- 49, 98,196,136, 65,140, 24, 49, 98,196,136, 17, 35, 70,140, 24,
- 49,136, 17, 35, 70,140, 24, 49, 98,196,136, 17,243,159, 11, 0,
- 0,255,255, 3, 0, 56,171, 5, 65,131,211,234, 11, 0, 0, 0,
- 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_layout[7714] = {
- 112, 97,114,116,115, 32,123, 10, 32, 32, 32, 32,100,101,118,105,
- 99,101, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 99,
- 107,103,114,111,117,110,100, 32,123, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32, 32,100,101,
- 118,105, 99,101, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,115,112,108,
- 97,121, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,119,105,100,116,104, 32, 32, 32, 51, 50, 48, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101,105,103,104,116, 32,
- 32, 52, 56, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,120, 32, 32, 32, 32, 32, 32, 32, 51, 49, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 32, 32, 32, 32, 32, 32,
- 55, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 98,117,116,116,111,110,115, 32,123, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111,102,116,
- 45,108,101,102,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32,109,101,110,117, 46,112,110,103, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120,
- 32, 49, 52, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 53, 53, 53, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,104,111,109,101, 32,123, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32,104,111,109,101, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,120, 32, 52, 56, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 53, 57, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 98, 97, 99,107, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101,
- 32, 98, 97, 99,107, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32,
- 50, 56, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 53, 57, 48, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,100,112, 97,100, 45,117,112, 32,
- 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 97,114,114,111,
- 119, 95,117,112, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49,
- 52, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,121, 32, 53, 57, 53, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,100,112, 97,100, 45,100,111,119,110,
- 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 97,114,114,
- 111,119, 95,100,111,119,110, 46,112,110,103, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 120, 32, 49, 52, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 54, 53, 54, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100,112, 97,100, 45,108,
- 101,102,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32,
- 97,114,114,111,119, 95,108,101,102,116, 46,112,110,103, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 49, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 53,
- 57, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100,112, 97,
- 100, 45,114,105,103,104,116, 32,123, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109,
- 97,103,101, 32, 97,114,114,111,119, 95,114,105,103,104,116, 46,
- 112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 50, 50, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,121, 32, 53, 57, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,100,112, 97,100, 45, 99,101,110,116,101,114, 32,123, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32,115,101,108,101, 99,116,
- 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 52, 50, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,121, 32, 54, 50, 54, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,112,104,111,110,101, 45,100,105, 97,108, 32,123, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32,115,101,110,100, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,120, 32, 52, 56, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 54, 52, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 112,104,111,110,101, 45,104, 97,110,103,117,112, 32,123, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,105,109, 97,103,101, 32,101,110,100, 46,112,110,103,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,120, 32, 50, 56, 54, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121,
- 32, 54, 52, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 112,111,119,101,114, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32,112,111,119,101,114, 46,112,110,103, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 120, 32, 45, 51, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 53, 50, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,118,111,108,117,109,101,
- 45,117,112, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32,
- 118,111,108,117,109,101, 95,117,112, 46,112,110,103, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,120, 32, 51, 54, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 50, 54,
- 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,118,111,108,
- 117,109,101, 45,100,111,119,110, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,
- 109, 97,103,101, 32,118,111,108,117,109,101, 95,100,111,119,110,
- 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 51, 54, 50, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,121, 32, 51, 49, 48, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32,125,
- 10, 32, 32, 32, 32,125, 10, 10, 32, 32, 32, 32,107,101,121, 98,
- 111, 97,114,100, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98,
- 97, 99,107,103,114,111,117,110,100, 32,123, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32, 32,
- 107,101,121, 98,111, 97,114,100, 46,112,110,103, 10, 32, 32, 32,
- 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98,
- 117,116,116,111,110,115, 32,123, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 49, 32,123, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,
- 107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 32, 48, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 32,
- 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 50, 32,123, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120,
- 32, 51, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,121, 32, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 51, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121,
- 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,120, 32, 55, 52, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 48, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 52, 32,123, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 49, 49,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 53,
- 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,
- 103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,120, 32, 49, 52, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 48, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 54, 32,123, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32,
- 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 56, 53, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121,
- 32, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 55, 32,123,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 120, 32, 50, 50, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,121, 32, 48, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 56, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,
- 101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 53, 57, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 48,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 57, 32,123, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,
- 109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32,
- 50, 57, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,121, 32, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 48, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121,
- 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,120, 32, 51, 51, 51, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 48, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,113, 32,123, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109,
- 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 32,
- 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,121, 32, 32, 51, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,119, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121,
- 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,120, 32, 51, 55, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 51, 54, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,101, 32,123, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,
- 103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 55, 52,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 51, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 114, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 49, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 51, 54, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,116, 32,123, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 52, 56,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 51, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 49, 56, 53, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 51, 54, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,117, 32,123, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 50, 50,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 51, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 105, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 50, 53, 57, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 51, 54, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,111, 32,123, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 57, 54,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 51, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 112, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 51, 51, 51, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 51, 54, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 97, 32,123, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,
- 103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 32, 48,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 32, 55, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,115, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,
- 112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,120, 32, 51, 55, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 55, 50, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,100, 32,123, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,
- 101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 55, 52, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 55, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102,
- 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,
- 103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,120, 32, 49, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 55, 50, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,103, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101,
- 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 52, 56, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 55, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,
- 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,
- 103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,120, 32, 49, 56, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 55, 50, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,106, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101,
- 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 50, 50, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 55, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,107,
- 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,
- 103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,120, 32, 50, 53, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 55, 50, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,108, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101,
- 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 57, 54, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 55, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 68,
- 69, 76, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,
- 112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,120, 32, 51, 51, 51, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 55, 50, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 67, 65, 80, 32,123, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120,
- 32, 32, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,121, 32, 32, 49, 48, 56, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,122, 32,123, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,
- 107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 51, 55, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 49,
- 48, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32,123,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 120, 32, 55, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,121, 32, 49, 48, 56, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 99, 32,123, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,
- 107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 49, 49, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32,
- 49, 48, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,118, 32,
- 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,103,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,120, 32, 49, 52, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,121, 32, 49, 48, 56, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 98, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101,
- 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 56, 53, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 49, 48, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 110, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 50, 50, 50, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 49, 48, 56, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,109, 32,123, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,
- 103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 53,
- 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,121, 32, 49, 48, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 80, 69, 82, 73, 79, 68, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101,
- 32, 32,107,101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 50, 57, 54, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 121, 32, 49, 48, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 69, 78, 84, 69, 82, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,
- 101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,120, 32, 51, 51, 51, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 49,
- 48, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125,
- 10, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 65, 76,
- 84, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,
- 110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,120, 32, 32, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 32, 49, 52, 52, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 83, 89, 77, 32,123, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,
- 109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32,
- 51, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,121, 32, 49, 52, 52, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 65, 84, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,
- 101,121, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,120, 32, 55, 52, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 49, 52,
- 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 83, 80, 65, 67,
- 69, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,105,109, 97,103,101, 32, 32,115,112, 97, 99,101,
- 98, 97,114, 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 49, 49, 49, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32,
- 49, 52, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 125, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 83, 76,
- 65, 83, 72, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121,
- 46,112,110,103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,120, 32, 50, 53, 57, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 49, 52, 52,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 67, 79, 77, 77, 65,
- 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32,105,109, 97,103,101, 32, 32,107,101,121, 46,112,110,
- 103, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32,120, 32, 50, 57, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,121, 32, 49, 52, 52, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 65, 76, 84, 50, 32,123, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,
- 109, 97,103,101, 32, 32,107,101,121, 46,112,110,103, 10, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32,
- 51, 51, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,121, 32, 49, 52, 52, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,125, 10, 10, 32, 32, 32, 32, 32, 32, 32,
- 32,125, 10, 32, 32, 32, 32,125, 10,125, 10, 10,108, 97,121,111,
- 117,116,115, 32,123, 10, 32, 32, 32, 32,112,111,114,116,114, 97,
- 105,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,105,100,
- 116,104, 32, 32, 32, 32, 32, 57, 48, 48, 10, 32, 32, 32, 32, 32,
- 32, 32, 32,104,101,105,103,104,116, 32, 32, 32, 32, 55, 51, 48,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,108,111,114, 32, 32,
- 32, 32, 32, 48,120,101, 48,101, 48,101, 48, 10, 32, 32, 32, 32,
- 32, 32, 32, 32,101,118,101,110,116, 32, 32, 32, 32, 32, 69, 86,
- 95, 83, 87, 58, 48, 58, 49, 10, 10, 32, 32, 32, 32, 32, 32, 32,
- 32,112, 97,114,116, 49, 32,123, 10, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32,110, 97,109,101, 32, 32, 32, 32,100,101,118,
- 105, 99,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 120, 32, 32, 32, 32, 32, 32, 32, 52, 48, 10, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32,121, 32, 32, 32, 32, 32, 32, 32, 45,
- 49, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32,
- 32, 32, 32, 32, 32,112, 97,114,116, 50, 32,123, 10, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 32, 32, 32,
- 32,107,101,121, 98,111, 97,114,100, 10, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32,120, 32, 32, 32, 32, 32, 32, 32, 52, 56,
- 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,121, 32,
- 32, 32, 32, 32, 32, 32, 50, 48, 48, 10, 32, 32, 32, 32, 32, 32,
- 32, 32,125, 10, 32, 32, 32, 32,125, 10, 10, 32, 32, 32, 32,108,
- 97,110,100,115, 99, 97,112,101, 32,123, 10, 32, 32, 32, 32, 32,
- 32, 32, 32,119,105,100,116,104, 32, 32, 32, 32, 32, 57, 48, 48,
- 10, 32, 32, 32, 32, 32, 32, 32, 32,104,101,105,103,104,116, 32,
- 32, 32, 32, 54, 55, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,
- 111,108,111,114, 32, 32, 32, 32, 32, 48,120,101, 48,101, 48,101,
- 48, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,118,101,110,116, 32,
- 32, 32, 32, 32, 69, 86, 95, 83, 87, 58, 48, 58, 48, 10, 10, 32,
- 32, 32, 32, 32, 32, 32, 32,112, 97,114,116, 49, 32,123, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 32,
- 32, 32, 32, 32, 32,100,101,118,105, 99,101, 10, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 53, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32,121, 32, 32, 32, 32, 32, 32, 32, 32, 32, 52, 52, 48, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,111,116, 97,116,
- 105,111,110, 32, 32, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32,125,
- 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,116, 50, 32,123,
- 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,
- 101, 32, 32, 32, 32, 32,107,101,121, 98,111, 97,114,100, 10, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,120, 32, 32, 32, 32,
- 32, 32, 32, 32, 50, 53, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32,121, 32, 32, 32, 32, 32, 32, 32, 32, 52, 55, 48,
- 10, 32, 32, 32, 32, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,125,
- 10,125, 10, 10,107,101,121, 98,111, 97,114,100, 32,123, 10, 32,
- 32, 32, 32, 99,104, 97,114,109, 97,112, 32,113,119,101,114,116,
- 121, 50, 10,125, 10, 10,110,101,116,119,111,114,107, 32,123, 10,
- 32, 32, 32, 32,115,112,101,101,100, 32, 32,102,117,108,108, 10,
- 32, 32, 32, 32,100,101,108, 97,121, 32, 32,110,111,110,101, 10,
- 125, 10
-};
-
-static const unsigned char _data_menu_png[3079] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 84, 0, 0, 0, 34, 16, 6, 0, 0, 0,145,128, 34,
- 94, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 1,
- 50, 73, 68, 65, 84,120,218,236,220,161, 78,195, 80, 20,128, 97,
- 70, 48, 44, 72, 50, 5, 10,130, 6, 75,192,162,120,132, 62,193,
- 44, 40, 12, 15, 64,176,224, 73, 61,104, 44, 4, 11,154, 48, 53,
- 12, 36, 56,194,228, 69,220, 94,193, 72, 89, 41, 91, 90,146,239,
- 51, 39, 89,167, 78,254,220,110,230,118, 66, 8, 33,132, 57,104,
- 165,121, 43,160,205, 22,198, 63,216,217,205,243,193, 83,217,215,
- 87, 94,227,220,218,180, 58,234,187,127,136,243,185, 55,254,228,
- 246, 38,203,214,214,127, 8,244,171,197, 60,206,131,165, 56, 87,
- 47,139, 7,199,150, 76,125,251, 69, 71,195,171, 56, 79,223,227,
- 28,101,191,124,197,247,251, 69,152, 47,150,202,244,165,174, 82,
- 103,149,127,131,166, 87,249,198,137, 37, 50,123,169,179,212,221,
- 196, 64,187, 23,150, 70, 3, 39,106,213, 64,161, 9,203,123, 2,
- 229, 95, 17, 40, 2, 5,129, 34, 80, 16, 40, 8, 20,129,130, 64,
- 17, 40, 8, 20, 4,138, 64, 65,160, 8, 20, 4, 10, 2, 69,160,
- 32, 80, 4, 10, 13,251,200, 4, 74,139, 13,123, 21, 3,125, 60,
- 140,243,237,218,210,152,189,212, 89,234,174,242, 9,122,118, 94,
- 118,244,194,244, 94,233,169,179,239, 38,220,205,148, 46,119, 58,
- 42,238,104,218, 30,196,217,205, 45,151,191,135,121, 87,220,209,
- 52, 42, 61, 0, 59,238, 7,197,191,120,168,233, 19, 0, 0,255,
- 255, 3, 0, 6, 52, 60,111, 44, 61, 74,153, 0, 0, 0, 0, 73,
- 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_power_png[3782] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 58, 0, 0, 0, 67, 16, 6, 0, 0, 0,157, 6,202,
- 98, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 3,
- 241, 73, 68, 65, 84,120,218,236, 93, 63, 76, 83, 65, 28, 46,196,
- 5, 84, 22,140, 70, 3,139,104, 93, 76, 90,199, 86, 93,108, 36,
- 14,152, 72, 76,152, 72, 96, 51,178, 22, 54, 19, 37, 49, 14, 10,
- 107,113,172,166, 19,137,209,164, 14, 6,197, 77,234, 38, 68, 22,
- 234, 31, 6,136, 9, 70, 28, 20,203, 88,135,187,175,205, 93,251,
- 120,175,237, 81, 30,119,223,183,252,104, 31,247,238,253,238,235,
- 239,254,126,247,174,163, 92, 46,151,203,229, 8, 97, 9,142,224,
- 143, 43, 87,115,185,111, 95, 89, 32, 42,250,126, 10,123, 97, 70,
- 216,238, 92,107,247, 43,141, 10,187, 54, 41,236,230,201,125, 35,
- 212,109,244, 14, 10,155,250, 46,108, 98, 69, 35,112, 64,218,251,
- 134, 50,124, 41, 9,254, 39,108, 33, 38,236,226, 89, 97,183, 23,
- 72,104, 83,184,121, 70,216,161,219,218,133, 92,123,242,199, 15,
- 38, 53, 37,173,252,254,245,170,176,249, 31, 36,116, 79,116,201,
- 2, 76, 31, 19,182,127, 43,156,207, 57, 36,107,130,216, 41, 97,
- 103,119,132,221, 29,245, 75,217,233, 86, 91,248,104, 56,220, 68,
- 234,192,115,226,185,225,135,179,132, 34, 34,199,151,204,116,106,
- 14, 10,221,154, 31, 93, 57, 71, 9, 69, 1, 28,150,136, 12, 26,
- 177,240,203, 25, 66,227,113,105, 99,150,250, 23, 83,253,180,158,
- 208,145, 1, 55,250, 6,181,126, 90, 70,104,116, 70, 29, 87,186,
- 50,126,134,223,214, 17, 26,127,234,230,120,186,234,183,165, 17,
- 234, 26,172,141, 80, 91,122,179,205,251,221, 25, 33,172, 2, 9,
- 181,172,234, 37,161,140, 80,130,132, 18, 36,148, 8, 21,161,174,
- 142, 7,173, 35, 52,221, 35,237,113, 97,199,150, 88,196,135,154,
- 208,232, 19,245,243,137, 27, 44, 98,182,161, 4, 9, 37,154, 36,
- 20,210,135, 49, 95, 41,196,222, 72,172,182,150,158,240, 66, 64,
- 213, 31,196, 73,233,163,194, 66,227,242,123, 90,216,124,131,189,
- 223,241, 15,194, 66,127,154,145,247, 55, 47, 60,102,132, 6, 34,
- 18,184,246,165,177,236, 32,100, 6,176, 64,139,251,251,171,218,
- 136,150, 8,157,184, 91,159,200, 13,169, 23,125, 56,220, 88,118,
- 249, 7,106,122, 64, 87,181, 17,134, 9, 69, 27,167, 75, 57, 54,
- 52,225,111,163,146,125, 84,169, 94,233,177,174,135,252, 9, 67,
- 132,166, 60,182, 45,205,203,239,253, 21,220,123, 3,233,243,211,
- 245,175,199, 51,164,198, 40,161,250,202, 63, 34,179, 56,105, 54,
- 251,194,197,250,145,106,171,252,178,237,132,122,205,193,154, 38,
- 82,199,246, 91, 82,209,214,113,232,110, 41, 32, 49, 11, 44,210,
- 80,141, 67, 43,132,104,219,235,162, 59,193,110,151,153, 19,246,
- 82, 92,216, 79,104,139,125,198,151, 93,207,229, 31, 91,164,196,
- 104,132,130,208,146,214,233,193,164,187,159,128, 25,189, 88,236,
- 107,244,155, 40,192,253,188,218,108,194, 80,149, 91,240,232,148,
- 140,156, 51,155,253,248,199,250,223,175, 76,144, 26,163,132, 98,
- 107,184, 30,169,232,125,182,186,206,137,244,250,114, 27,242,123,
- 247,152,212, 24, 37, 20, 85,239,252,122,253,235,201,207,194, 98,
- 65,187,118, 23,148,246, 67,144,215,239,189, 82,211,215,140,115,
- 215,205,140,115,217, 41,242, 25, 39,246,203,170, 22,239, 2,208,
- 219,214,104,208,252, 60, 58, 61,217,203,106,126,196, 62, 15, 91,
- 48, 67, 52, 55,103,102,120,130,244,179,127, 73,100, 91, 35, 84,
- 199,242,178,106, 19,114,234, 46,250, 71, 88, 47,201,201,175, 55,
- 106,103, 7,233, 35, 47, 72,193,129, 18,234, 85, 37, 23,252,254,
- 49,201,162, 14, 85,149, 75,144, 80,130,132, 18, 36,148, 32,161,
- 36,148, 32,161, 4, 9, 37, 72, 40,161,163, 56, 73, 66, 25,161,
- 97,134,171,154,166,170,223,150, 17,186,150,118,147,208,170,223,
- 150, 17, 90,236,113,180,237,236,177,148, 80,172,254,148, 28, 81,
- 60,192,207,234,122,178,165,157,162,247,231,221, 32,180,214, 79,
- 75, 9,133,140,212, 86, 57, 40,252,170, 61, 6,196,242, 97, 75,
- 54,105, 87, 21, 12, 63,178, 73, 71, 39, 22, 32,244,246, 82, 47,
- 30, 54,192, 15,111, 1,187, 35, 7,241,160,211,176, 27, 23,118,
- 76,190, 18, 32,236,199,126, 32, 34,159, 73, 85,228,242, 29,199,
- 38, 22,252, 0,113, 26,118,158, 23,167, 66, 58, 12,153, 82,159,
- 179, 34,170,243,133,163,103,159, 85,100,164,242,115, 66, 70, 0,
- 54, 58,183,251,205,216,232,228, 44, 74,253,115, 65,170, 40, 35,
- 13,207,124,241,116, 66,165, 74,134,122, 17, 47,239,192, 46,186,
- 190, 91,106, 21,221,123, 93,218,193, 96, 85,230,230,105,245,115,
- 81,158,189,102,254,216,201, 14, 30, 8,107, 23, 72,168,101,248,
- 63, 0,179,160, 16,217,188,199, 69, 53, 0, 0, 0, 0, 73, 69,
- 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_select_png[3374] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 98, 0, 0, 0, 33, 16, 6, 0, 0, 0,114,249,162,
- 143, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 2,
- 89, 73, 68, 65, 84,120,218,236,156, 59, 79,219, 96, 20,134, 67,
- 196, 2, 20,150, 86, 97, 33, 83, 43,179, 80, 53, 43,208,141,170,
- 98,233, 90,150, 72,229, 55,132,203,136, 84,196, 68,163,142,204,
- 69,176, 20, 9, 21, 41, 75, 85, 53, 35, 9, 99, 16, 83,211,192,
- 18,166, 8,150,150,203,202,112,206, 73, 20, 87, 86, 76,108, 82,
- 98, 63,207,242,202, 78,236, 47, 58, 62,175,191,139,227, 51, 48,
- 251,122,103,167,246, 59,241, 64, 60,125, 43,234,124, 86,253, 35,
- 250,108,190,253,123,206,167, 4, 64,147,234, 74,251,246,197,119,
- 221, 63,166,154, 19,189,252, 17,118,203, 3,225, 26,194,201,139,
- 190, 91, 39,209,161,119,198, 41,172,233,246,114,208, 51, 14, 6,
- 59,124,162, 33,186,240, 66, 13, 48,170, 31, 96, 4,232, 1,118,
- 195, 93, 74,180,247, 32, 95,107,162,231,169, 30,245, 16,115,171,
- 162,239,159,115, 81,224,241,178,119, 42, 90,220,244,123, 68,242,
- 126, 13,124, 40, 97, 4,232, 31, 44, 79, 45,111, 67, 51,132,157,
- 112,230,132, 32, 67,255, 97,121,219,217, 24, 73,127, 67, 35,140,
- 0, 81, 50,134,229,181,111, 67,216,114, 41, 67, 35,136,242, 80,
- 202, 22,133, 58, 26, 98,241,136,160, 65,244,177,213,209, 22,174,
- 101, 87,123,142,208, 92, 62, 5,136, 48,182,108,235,252, 21,173,
- 46,187,122,136,185, 51,130, 4,241,163,149,247,218, 67, 12,237,
- 138,102,174, 9, 14,196,143,204, 43,243,129,246, 16,147,121,130,
- 2, 48,153, 87, 67,164, 27, 4, 3, 32,221, 80, 67, 56, 87, 4,
- 3,192,185, 74, 18, 4,128, 22, 24, 2, 0, 67, 0, 96, 8, 0,
- 191,134,168,167, 8, 5, 64, 61,101,134, 56, 32, 24, 0,245, 3,
- 53,132,189,180, 13, 16,103,170, 57, 53,132, 85, 47,112, 87, 59,
- 0,136,133, 17, 86,204, 7,174, 73,117,169, 68,112, 32,126,180,
- 242,222,101,136,242,148,142,165,198, 9, 18, 68, 31, 27, 25, 89,
- 222,123, 46,187,238,213, 8, 22, 68,159, 47,211,238, 61, 30,134,
- 176,130, 79, 69,234, 43, 65, 4,177,188,254,183,176, 89,135, 7,
- 115,214, 83, 48,217,134, 40, 77,158,189, 71, 64, 62,159, 84,111,
- 109, 49,183,128,254,197,242,214,242,216, 27,159,165, 44,111,179,
- 162, 27,186, 77,157, 38,232, 7, 74, 47, 69,183,103,252, 30,209,
- 101,109, 87,107,224, 56,163, 6, 57, 20, 29,222,229, 34,192,255,
- 227, 70,111,220,219,179,162,149,202,125,207, 16,176,216,177, 53,
- 248,235,155,232,155,143,162,211, 58,123,183,250, 78, 0, 15, 65,
- 115,217,180, 44,250,115, 68, 71, 52,149,110,207, 56, 24,206, 15,
- 179, 33, 85, 65,183, 11,251,162, 25, 45, 54,107,111,228,217,171,
- 170,148,201,135,110, 38,195,246, 39,212,234, 19,143, 30, 32, 27,
- 180,165, 59, 0, 0, 0,255,255, 3, 0, 97,168,142, 82, 14,236,
- 17,113, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_send_png[3561] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 46, 0, 0, 0, 47, 16, 6, 0, 0, 0,204,117, 36,
- 209, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 3,
- 20, 73, 68, 65, 84,120,218,236,156, 61,108,211, 64, 20,199, 15,
- 171, 75,194,199, 66, 21, 22, 60, 32,192, 93, 64,201, 72, 93,182,
- 34,196,208, 74, 32,164, 78, 29,186, 33, 58, 66,202, 80, 33, 8,
- 31, 98, 32,201, 74,214, 64, 59, 69,170,130,212, 76, 72, 97,107,
- 186, 6,193, 66, 40, 48, 36,226,163, 18, 75, 33,237,202,112,239,
- 165,178, 19,247, 92,251,238,156,212,239,191,188,184, 57,217,201,
- 239,222, 61,191,119,125,206,177,169,171, 43, 43, 91, 95,216,144,
- 235,236, 54,183,201, 55, 7,143,251,243,206,105,135, 79, 99,209,
- 94, 62,177,202,109, 38,195,173,181,195,173, 9,128,205,223, 48,
- 176, 10,246,164,224,132,183,157,182,125,134,219, 86, 22,236, 9,
- 110,155,205,152, 0,183, 10,220, 78,127, 3,208, 93,120, 99, 67,
- 205,245,112,194,204, 37,184, 46,252,125,119, 30,192,127,224,182,
- 126,129,219, 78,106,196,129, 35,224,217,167,112,140, 30,154,142,
- 118,101, 37, 97,101,217,112,108,127,132, 21,112,138,219,242, 21,
- 85,161,105, 76, 77,136, 88,104,128, 7, 35,224, 60, 27, 9, 89,
- 240, 57, 95,192,113,237, 19,183,235, 63,134, 12, 56,222,212,238,
- 31, 7, 15,234,178, 35,161,153,199,176, 32,225, 94, 80,122, 21,
- 214,243, 67, 2,159, 4, 15, 88,168,178, 35, 45,188, 23, 60,132,
- 239, 89,236, 6,141,249, 70, 72,208, 27, 44, 86,194,216,143, 43,
- 25, 87,182, 50,224,113, 5, 45, 15,188, 79,224,120,194,185,115,
- 140, 52, 0,252,226, 93,103,210, 16, 24,120,194,117,194,228, 42,
- 65, 30,164,211,215,157,217, 89, 96,224,179, 57,231, 9, 73, 7,
- 43,147,118, 86,206,190,129, 35,224,233, 37,130, 24, 68,115,231,
- 189, 66,140, 7,240,153, 28, 65,147, 17, 98,174, 61, 16, 0,199,
- 129, 88,234,146, 66,214, 41,147, 2,224,184,169, 68,146,235,233,
- 251, 49,221, 24, 28,244, 73,146, 61,221,118, 1,199, 60,155,178,
- 17, 53,178,242, 46,224, 19, 5,130,162,163, 64,178, 10,232,225,
- 55, 9,138, 14,153,219, 0,124,252, 6,193,208,227,233,232,225,
- 63, 9,134,150, 88,254,207,112,198, 24,146,106, 25,132,128,128,
- 19,112,146,116,224, 45,218, 21,212,162,118, 10,128, 99, 99, 12,
- 73,173,246,118, 1,120,231, 45,193,208,161,207,247, 12,124, 65,
- 48,116,168,149,197, 24,158,165,208,162, 82,216,195,216,151,165,
- 236,191, 65,146, 10,124,209, 3,248,102,131,224,200, 84,175, 75,
- 183,233, 1,188,215, 71, 77,105,162,212, 80,178, 55, 47, 40,124,
- 214, 31, 17, 44, 25,158, 93,203,249,172, 52,201,211,195,233,253,
- 69,110,251,187,108, 5,165, 61, 54,166, 83,246,226,179,146,132,
- 182,102,239,126,114, 1,112,156,161,202,119,130,233, 39,132,148,
- 109,209, 72,159,155, 87,155,151,184,173,231, 9,238, 32,161, 67,
- 138,251,197, 15,185, 91, 88,217,226,182,113,153, 32, 51,198, 88,
- 121,202,233,144, 98, 5,220,158,125,109,199, 27,252,225, 65,135,
- 4,238, 6, 95,249, 26,143, 24, 93, 42, 5, 5, 45, 9, 56,170,
- 254,146,219,226, 95,175,116,104, 52,133,105,241,243, 91,238,138,
- 49, 98,224,238,252,253, 25,124,192,218,147,209, 74, 43,209, 81,
- 48,100, 20,119,100, 59,144,162,127,177, 97, 41,139,249,232,114,
- 117, 56, 39,192, 13,120,121, 45,108,200, 16, 73,211,163,223,189,
- 9,192,173, 3,120, 24, 9,187, 74,211,240,252,227, 68,145, 91,
- 217, 61,142,238,103,238, 27,176, 73,215,185, 3, 3,214,116, 77,
- 113,196, 63,110,128, 49,177,233, 42, 24, 18, 16,146,204, 95, 48,
- 1,208, 25, 54, 46,152,136,118,202,185,130, 16,112,159, 82, 81,
- 125,227,255, 3, 0,233,237,207,153, 62,209, 88,144, 0, 0, 0,
- 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_spacebar_png[2916] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0,145, 0, 0, 0, 34, 16, 6, 0, 0, 0, 15, 22,231,
- 187, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 0,
- 143, 73, 68, 65, 84,120,218,236,212, 49, 1, 0, 32, 12,192, 48,
- 192,214,196,129, 13,110, 28,160,103, 70,248,144,177, 39,145,208,
- 163, 61,238,121,185,215,108, 0, 69,134, 4,128, 17, 1, 70, 36,
- 1, 96, 68,128, 17, 73, 0, 24, 17, 96, 68, 18, 0, 70, 4, 24,
- 145, 4,128, 17, 1, 70, 36, 1, 96, 68,128, 17, 73, 0, 24, 17,
- 96, 68, 18, 0, 70, 4, 24,145, 4,128, 17, 1, 70, 36, 1, 96,
- 68,128, 17, 73, 0, 24, 17, 96, 68, 18, 0, 70, 4, 24,145, 4,
- 128, 17, 1, 70, 36, 1, 96, 68,128, 17, 73, 0, 24, 17, 96, 68,
- 18, 0, 70, 4, 24,145, 4, 64,181, 15, 0, 0,255,255, 3, 0,
- 87,196, 5, 65, 55,106, 37, 28, 0, 0, 0, 0, 73, 69, 78, 68,
- 174, 66, 96,130
-};
-
-static const unsigned char _data_volume_down_png[3586] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 67, 0, 0, 0, 49, 16, 6, 0, 0, 0,209,176,200,
- 250, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 3,
- 45, 73, 68, 65, 84,120,218,236,157,191,111,211, 64, 20,199, 13,
- 234, 82, 68,197, 64, 21, 33,148, 12, 80, 4, 11,136,172,117, 97,
- 138,132, 24, 26, 9,150,178, 88, 34, 27,136, 17, 8,107, 11, 35,
- 16,254,134, 84,242, 66, 36, 36,134, 14,168, 82, 38,136, 25, 88,
- 140,202,210,136, 76,141, 16, 32,178, 80, 53,108,152,225,222,139,
- 100,171,174,206,241, 97,159,115,223,239,242,106,183,138,239,221,
- 125,242,238,221, 15, 95,143, 5, 65, 16, 4,129,101, 93,187,238,
- 186,131,175,150, 98,205,187,194, 86,190, 11,123,233, 85,186,207,
- 219,125, 40,236,222, 25, 97,255, 56, 22,100, 89,150,101,125,120,
- 239, 56, 75, 23,212,125,222,156, 90, 0,170, 85, 97,107,132, 88,
- 229, 7,253,193, 2,217,245,116,207, 89,229, 31, 14, 8,144,183,
- 194,118,169, 74,124, 31,192,104, 1,198,242, 23, 97,215,206, 9,
- 123,194,205,182,248, 12, 94,131,236,152,128,232, 80,185, 62, 94,
- 70, 19,103, 2, 6, 71,134,134, 71, 17,162, 71,191,232,233,225,
- 14,131,217,160,235,234, 3, 97,219, 54, 34, 73, 50, 29, 79, 6,
- 196,163,147, 84,225, 87,139,225, 30,151,147,203, 61,239,162,201,
- 149,128, 17, 5, 98,146, 51, 20, 76, 92,110, 0,162, 8,140,250,
- 70,177,129,136, 3,132,253,130, 18,230, 24, 23, 95,210,232, 98,
- 97, 54,221,174, 53,105, 20,179, 47,108,255, 49, 80,144,138, 24,
- 245,103,102,184,111,138,159,169,193, 40,255,164,136,241,194, 12,
- 247,217, 79,246, 27,138, 1,195,182,205,172, 6, 83,253,150, 6,
- 163, 98,232, 55,135,115, 42, 40, 6, 12, 83,186,144,184,209, 10,
- 36, 57, 92,133, 0, 6,132, 46, 5, 96,196,118, 41, 57,231, 88,
- 188, 40, 89, 63, 11, 48,180,210, 94, 41, 95, 32, 26, 61, 93,106,
- 2, 96,104, 17, 33,244, 1,130, 53,135,198,201, 67,119,105,219,
- 130,221,211,181,132,136, 24,249, 0,177,163,123, 73, 17, 49, 82,
- 73, 54, 73, 44,223, 18,182,186,163, 22,176,197,155,194,182,126,
- 3, 12,173,180,186,158,237,243,120, 79,237, 36,226,208,132,228,
- 242,138,176,234,182, 50,162, 43, 41,148,120,179,115,191, 25,190,
- 175,126,173, 7, 96, 20, 82,158, 23,190, 86,191,148, 1, 48, 10,
- 169,209, 59,140, 74,160, 67, 20,157,161, 29, 59, 0,195,104,241,
- 38,230,218, 32,124, 63,154,115, 0, 12,211, 34, 5,189,234,121,
- 250, 70,248,126,247, 60,134,171, 90,169,181,159, 44,244,175, 45,
- 165,123, 30,111, 90,110,211, 84,250, 34, 1,210,255, 6, 48,180,
- 146,236,238,242, 62,231, 2,138,214, 70,254,255,171,151,232, 74,
- 50, 21, 55,104,123, 69,247,146, 2,140, 92, 1,225,174,104,236,
- 0, 12,232,144,174,168,117,160, 27, 32, 0, 67, 11, 13, 75, 97,
- 64,126,109,231, 93, 34, 36,159, 33,157,122,162, 7, 32, 67, 68,
- 12,189,244,233, 47,234, 0, 96, 64,242, 96,168,159, 90, 45, 72,
- 18,216, 4, 10, 71,130,225,223, 55,179, 26, 76,245, 91, 30, 12,
- 223, 80, 48,124,160,112, 36, 24, 35, 26, 38,121, 87,204,112,159,
- 253, 28,109, 3, 5,169,228,115,107, 67,216,241,140,158,114,199,
- 126,177,159,144, 36, 24,252, 13,218,122, 58,155,110,179, 95,136,
- 20, 83, 14, 87,187,207,103,171,107, 97, 63,216, 47,104, 74, 48,
- 88,155,118,177, 1,225,114,111,226,228, 28,181, 96, 68, 1,233,
- 12,138,213,101, 0,136,164,154,114,173,132, 67,241, 46,237, 76,
- 186, 67,135,188,231,125, 34, 15, 79, 84,189,166, 67,238,135,247,
- 208,196,153,130,193,154,172, 10,210,117,249,182,176,252, 2, 12,
- 31,217, 28,221,163,152, 86,156, 52,250,159,169,171,240, 34, 32,
- 148,208,180,185,130, 17, 7, 74,135,174, 59,252, 31, 80,222, 80,
- 68, 73,121, 98, 77,236, 86, 58,128,160, 88,255, 6, 0,161,232,
- 198,240, 68,249,103, 76, 0, 0, 0, 0, 73, 69, 78, 68,174, 66,
- 96,130
-};
-
-static const unsigned char _data_volume_up_png[3856] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 67, 0, 0, 0, 49, 16, 6, 0, 0, 0,209,176,200,
- 250, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 10, 79,105, 67, 67, 80, 80,104,
- 111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,
- 105,108,101, 0, 0,120,218,157, 83,103, 84, 83,233, 22, 61,247,
- 222,244, 66, 75,136,128,148, 75,111, 82, 21, 8, 32, 82, 66,139,
- 128, 20,145, 38, 42, 33, 9, 16, 74,136, 33,161,217, 21, 81,193,
- 17, 69, 69, 4, 27,200,160,136, 3,142,142,128,140, 21, 81, 44,
- 12,138, 10,216, 7,228, 33,162,142,131,163,136,138,202,251,225,
- 123,163,107,214,188,247,230,205,254,181,215, 62,231,172,243,157,
- 179,207, 7,192, 8, 12,150, 72, 51, 81, 53,128, 12,169, 66, 30,
- 17,224,131,199,196,198,225,228, 46, 64,129, 10, 36,112, 0, 16,
- 8,179,100, 33,115,253, 35, 1, 0,248,126, 60, 60, 43, 34,192,
- 7,190, 0, 1,120,211, 11, 8, 0,192, 77,155,192, 48, 28,135,
- 255, 15,234, 66,153, 92, 1,128,132, 1,192,116,145, 56, 75, 8,
- 128, 20, 0, 64,122,142, 66,166, 0, 64, 70, 1,128,157,152, 38,
- 83, 0,160, 4, 0, 96,203, 99, 98,227, 0, 80, 45, 0, 96, 39,
- 127,230,211, 0,128,157,248,153,123, 1, 0, 91,148, 33, 21, 1,
- 160,145, 0, 32, 19,101,136, 68, 0,104, 59, 0,172,207, 86,138,
- 69, 0, 88, 48, 0, 20,102, 75,196, 57, 0,216, 45, 0, 48, 73,
- 87,102, 72, 0,176,183, 0,192,206, 16, 11,178, 0, 8, 12, 0,
- 48, 81,136,133, 41, 0, 4,123, 0, 96,200, 35, 35,120, 0,132,
- 153, 0, 20, 70,242, 87, 60,241, 43,174, 16,231, 42, 0, 0,120,
- 153,178, 60,185, 36, 57, 69,129, 91, 8, 45,113, 7, 87, 87, 46,
- 30, 40,206, 73, 23, 43, 20, 54, 97, 2, 97,154, 64, 46,194,121,
- 153, 25, 50,129, 52, 15,224,243,204, 0, 0,160,145, 21, 17,224,
- 131,243,253,120,206, 14,174,206,206, 54,142,182, 14, 95, 45,234,
- 191, 6,255, 34, 98, 98,227,254,229,207,171,112, 64, 0, 0,225,
- 116,126,209,254, 44, 47,179, 26,128, 59, 6,128,109,254,162, 37,
- 238, 4,104, 94, 11,160,117,247,139,102,178, 15, 64,181, 0,160,
- 233,218, 87,243,112,248,126, 60, 60, 69,161,144,185,217,217,229,
- 228,228,216, 74,196, 66, 91, 97,202, 87,125,254,103,194, 95,192,
- 87,253,108,249,126, 60,252,247,245,224,190,226, 36,129, 50, 93,
- 129, 71, 4,248,224,194,204,244, 76,165, 28,207,146, 9,132, 98,
- 220,230,143, 71,252,183, 11,255,252, 29,211, 34,196, 73, 98,185,
- 88, 42, 20,227, 81, 18,113,142, 68,154,140,243, 50,165, 34,137,
- 66,146, 41,197, 37,210,255,100,226,223, 44,251, 3, 62,223, 53,
- 0,176,106, 62, 1,123,145, 45,168, 93, 99, 3,246, 75, 39, 16,
- 88,116,192,226,247, 0, 0,242,187,111,193,212, 40, 8, 3,128,
- 104,131,225,207,119,255,239, 63,253, 71,160, 37, 0,128,102, 73,
- 146,113, 0, 0, 94, 68, 36, 46, 84,202,179, 63,199, 8, 0, 0,
- 68,160,129, 42,176, 65, 27,244,193, 24, 44,192, 6, 28,193, 5,
- 220,193, 11,252, 96, 54,132, 66, 36,196,194, 66, 16, 66, 10,100,
- 128, 28,114, 96, 41,172,130, 66, 40,134,205,176, 29, 42, 96, 47,
- 212, 64, 29, 52,192, 81,104,134,147,112, 14, 46,194, 85,184, 14,
- 61,112, 15,250, 97, 8,158,193, 40,188,129, 9, 4, 65,200, 8,
- 19, 97, 33,218,136, 1, 98,138, 88, 35,142, 8, 23,153,133,248,
- 33,193, 72, 4, 18,139, 36, 32,201,136, 20, 81, 34, 75,145, 53,
- 72, 49, 82,138, 84, 32, 85, 72, 29,242, 61,114, 2, 57,135, 92,
- 70,186,145, 59,200, 0, 50,130,252,134,188, 71, 49,148,129,178,
- 81, 61,212, 12,181, 67,185,168, 55, 26,132, 70,162, 11,208,100,
- 116, 49,154,143, 22,160,155,208,114,180, 26, 61,140, 54,161,231,
- 208,171,104, 15,218,143, 62, 67,199, 48,192,232, 24, 7, 51,196,
- 108, 48, 46,198,195, 66,177, 56, 44, 9,147, 99,203,177, 34,172,
- 12,171,198, 26,176, 86,172, 3,187,137,245, 99,207,177,119, 4,
- 18,129, 69,192, 9, 54, 4,119, 66, 32, 97, 30, 65, 72, 88, 76,
- 88, 78,216, 72,168, 32, 28, 36, 52, 17,218, 9, 55, 9, 3,132,
- 81,194, 39, 34,147,168, 75,180, 38,186, 17,249,196, 24, 98, 50,
- 49,135, 88, 72, 44, 35,214, 18,143, 19, 47, 16,123,136, 67,196,
- 55, 36, 18,137, 67, 50, 39,185,144, 2, 73,177,164, 84,210, 18,
- 210, 70,210,110, 82, 35,233, 44,169,155, 52, 72, 26, 35,147,201,
- 218,100,107,178, 7, 57,148, 44, 32, 43,200,133,228,157,228,195,
- 228, 51,228, 27,228, 33,242, 91, 10,157, 98, 64,113,164,248, 83,
- 226, 40, 82,202,106, 74, 25,229, 16,229, 52,229, 6,101,152, 50,
- 65, 85,163,154, 82,221,168,161, 84, 17, 53,143, 90, 66,173,161,
- 182, 82,175, 81,135,168, 19, 52,117,154, 57,205,131, 22, 73, 75,
- 165,173,162,149,211, 26,104, 23,104,247,105,175,232,116,186, 17,
- 221,149, 30, 78,151,208, 87,210,203,233, 71,232,151,232, 3,244,
- 119, 12, 13,134, 21,131,199,136,103, 40, 25,155, 24, 7, 24,103,
- 25,119, 24,175,152, 76,166, 25,211,139, 25,199, 84, 48, 55, 49,
- 235,152,231,153, 15,153,111, 85, 88, 42,182, 42,124, 21,145,202,
- 10,149, 74,149, 38,149, 27, 42, 47, 84,169,170,166,170,222,170,
- 11, 85,243, 85,203, 84,143,169, 94, 83,125,174, 70, 85, 51, 83,
- 227,169, 9,212,150,171, 85,170,157, 80,235, 83, 27, 83,103,169,
- 59,168,135,170,103,168,111, 84, 63,164,126, 89,253,137, 6, 89,
- 195, 76,195, 79, 67,164, 81,160,177, 95,227,188,198, 32, 11, 99,
- 25,179,120, 44, 33,107, 13,171,134,117,129, 53,196, 38,177,205,
- 217,124,118, 42,187,152,253, 29,187,139, 61,170,169,161, 57, 67,
- 51, 74, 51, 87,179, 82,243,148,102, 63, 7,227,152,113,248,156,
- 116, 78, 9,231, 40,167,151,243,126,138,222, 20,239, 41,226, 41,
- 27,166, 52, 76,185, 49,101, 92,107,170,150,151,150, 88,171, 72,
- 171, 81,171, 71,235,189, 54,174,237,167,157,166,189, 69,187, 89,
- 251,129, 14, 65,199, 74, 39, 92, 39, 71,103,143,206, 5,157,231,
- 83,217, 83,221,167, 10,167, 22, 77, 61, 58,245,174, 46,170,107,
- 165, 27,161,187, 68,119,191,110,167,238,152,158,190, 94,128,158,
- 76,111,167,222,121,189,231,250, 28,125, 47,253, 84,253,109,250,
- 167,245, 71, 12, 88, 6,179, 12, 36, 6,219, 12,206, 24, 60,197,
- 53,113,111, 60, 29, 47,199,219,241, 81, 67, 93,195, 64, 67,165,
- 97,149, 97,151,225,132,145,185,209, 60,163,213, 70,141, 70, 15,
- 140,105,198, 92,227, 36,227,109,198,109,198,163, 38, 6, 38, 33,
- 38, 75, 77,234, 77,238,154, 82, 77,185,166, 41,166, 59, 76, 59,
- 76,199,205,204,205,162,205,214,153, 53,155, 61, 49,215, 50,231,
- 155,231,155,215,155,223,183, 96, 90,120, 90, 44,182,168,182,184,
- 101, 73,178,228, 90,166, 89,238,182,188,110,133, 90, 57, 89,165,
- 88, 85, 90, 93,179, 70,173,157,173, 37,214,187,173,187,167, 17,
- 167,185, 78,147, 78,171,158,214,103,195,176,241,182,201,182,169,
- 183, 25,176,229,216, 6,219,174,182,109,182,125, 97,103, 98, 23,
- 103,183,197,174,195,238,147,189,147,125,186,125,141,253, 61, 7,
- 13,135,217, 14,171, 29, 90, 29,126,115,180,114, 20, 58, 86, 58,
- 222,154,206,156,238, 63,125,197,244,150,233, 47,103, 88,207, 16,
- 207,216, 51,227,182, 19,203, 41,196,105,157, 83,155,211, 71,103,
- 23,103,185,115,131,243,136,139,137, 75,130,203, 46,151, 62, 46,
- 155, 27,198,221,200,189,228, 74,116,245,113, 93,225,122,210,245,
- 157,155,179,155,194,237,168,219,175,238, 54,238,105,238,135,220,
- 159,204, 52,159, 41,158, 89, 51,115,208,195,200, 67,224, 81,229,
- 209, 63, 11,159,149, 48,107,223,172,126, 79, 67, 79,129,103,181,
- 231, 35, 47, 99, 47,145, 87,173,215,176,183,165,119,170,247, 97,
- 239, 23, 62,246, 62,114,159,227, 62,227, 60, 55,222, 50,222, 89,
- 95,204, 55,192,183,200,183,203, 79,195,111,158, 95,133,223, 67,
- 127, 35,255,100,255,122,255,209, 0,167,128, 37, 1,103, 3,137,
- 129, 65,129, 91, 2,251,248,122,124, 33,191,142, 63, 58,219,101,
- 246,178,217,237, 65,140,160,185, 65, 21, 65,143,130,173,130,229,
- 193,173, 33,104,200,236,144,173, 33,247,231,152,206,145,206,105,
- 14,133, 80,126,232,214,208, 7, 97,230, 97,139,195,126, 12, 39,
- 133,135,133, 87,134, 63,142,112,136, 88, 26,209, 49,151, 53,119,
- 209,220, 67,115,223, 68,250, 68,150, 68,222,155,103, 49, 79, 57,
- 175, 45, 74, 53, 42, 62,170, 46,106, 60,218, 55,186, 52,186, 63,
- 198, 46,102, 89,204,213, 88,157, 88, 73,108, 75, 28, 57, 46, 42,
- 174, 54,110,108,190,223,252,237,243,135,226,157,226, 11,227,123,
- 23,152, 47,200, 93,112,121,161,206,194,244,133,167, 22,169, 46,
- 18, 44, 58,150, 64, 76,136, 78, 56,148,240, 65, 16, 42,168, 22,
- 140, 37,242, 19,119, 37,142, 10,121,194, 29,194,103, 34, 47,209,
- 54,209,136,216, 67, 92, 42, 30, 78,242, 72, 42, 77,122,146,236,
- 145,188, 53,121, 36,197, 51,165, 44,229,185,132, 39,169,144,188,
- 76, 13, 76,221,155, 58,158, 22,154,118, 32,109, 50, 61, 58,189,
- 49,131,146,145,144,113, 66,170, 33, 77,147,182,103,234,103,230,
- 102,118,203,172,101,133,178,254,197,110,139,183, 47, 30,149, 7,
- 201,107,179,144,172, 5, 89, 45, 10,182, 66,166,232, 84, 90, 40,
- 215, 42, 7,178,103,101, 87,102,191,205,137,202, 57,150,171,158,
- 43,205,237,204,179,202,219,144, 55,156,239,159,255,237, 18,194,
- 18,225,146,182,165,134, 75, 87, 45, 29, 88,230,189,172,106, 57,
- 178, 60,113,121,219, 10,227, 21, 5, 43,134, 86, 6,172, 60,184,
- 138,182, 42,109,213, 79,171,237, 87,151,174,126,189, 38,122, 77,
- 107,129, 94,193,202,130,193,181, 1,107,235, 11, 85, 10,229,133,
- 125,235,220,215,237, 93, 79, 88, 47, 89,223,181, 97,250,134,157,
- 27, 62, 21,137,138,174, 20,219, 23,151, 21,127,216, 40,220,120,
- 229, 27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,
- 102,210,102,233,230,222, 45,158, 91, 14,150,170,151,230,151, 14,
- 110, 13,217,218,180, 13,223, 86,180,237,245,246, 69,219, 47,151,
- 205, 40,219,187,131,182, 67,185,163,191, 60,184,188,101,167,201,
- 206,205, 59, 63, 84,164, 84,244, 84,250, 84, 54,238,210,221,181,
- 97,215,248,110,209,238, 27,123,188,246, 52,236,213,219, 91,188,
- 247,253, 62,201,190,219, 85, 1, 85, 77,213,102,213,101,251, 73,
- 251,179,247, 63,174,137,170,233,248,150,251,109, 93,173, 78,109,
- 113,237,199, 3,210, 3,253, 7, 35, 14,182,215,185,212,213, 29,
- 210, 61, 84, 82,143,214, 43,235, 71, 14,199, 31,190,254,157,239,
- 119, 45, 13, 54, 13, 85,141,156,198,226, 35,112, 68,121,228,233,
- 247, 9,223,247, 30, 13, 58,218,118,140,123,172,225, 7,211, 31,
- 118, 29,103, 29, 47,106, 66,154,242,154, 70,155, 83,154,251, 91,
- 98, 91,186, 79,204, 62,209,214,234,222,122,252, 71,219, 31, 15,
- 156, 52, 60, 89,121, 74,243, 84,201,105,218,233,130,211,147,103,
- 242,207,140,157,149,157,125,126, 46,249,220, 96,219,162,182,123,
- 231, 99,206,223,106, 15,111,239,186, 16,116,225,210, 69,255,139,
- 231, 59,188, 59,206, 92,242,184,116,242,178,219,229, 19, 87,184,
- 87,154,175, 58, 95,109,234,116,234, 60,254,147,211, 79,199,187,
- 156,187,154,174,185, 92,107,185,238,122,189,181,123,102,247,233,
- 27,158, 55,206,221,244,189,121,241, 22,255,214,213,158, 57, 61,
- 221,189,243,122,111,247,197,247,245,223, 22,221,126,114, 39,253,
- 206,203,187,217,119, 39,238,173,188, 79,188, 95,244, 64,237, 65,
- 217, 67,221,135,213, 63, 91,254,220,216,239,220,127,106,192,119,
- 160,243,209,220, 71,247, 6,133,131,207,254,145,245,143, 15, 67,
- 5,143,153,143,203,134, 13,134,235,158, 56, 62, 57, 57,226, 63,
- 114,253,233,252,167, 67,207,100,207, 38,158, 23,254,162,254,203,
- 174, 23, 22, 47,126,248,213,235,215,206,209,152,209,161,151,242,
- 151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198,
- 30,190,201,120, 51, 49, 94,244, 86,251,237,193,119,220,119, 29,
- 239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,
- 208,167,251,147, 25,147,147,255, 4, 3,152,243,252, 99, 51, 45,
- 219, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,
- 131, 0, 0,249,255, 0, 0,128,233, 0, 0,117, 48, 0, 0,234,
- 96, 0, 0, 58,152, 0, 0, 23,111,146, 95,197, 70, 0, 0, 4,
- 59, 73, 68, 65, 84,120,218,236,157, 61, 76, 20, 65, 20,199, 87,
- 67,163, 6, 27, 8, 24,195, 53, 66,176, 17,185, 82, 78,109,196,
- 24, 11, 76, 52, 36, 84, 68,175,195,163,148,143, 82,161,177, 16,
- 177, 4,236, 78,115, 21,141,197, 81,153, 80, 41,123,150,103,176,
- 1, 65, 11,136, 2,209, 6,149, 43,207, 98,222,255,200, 12,187,
- 183,115,183,115, 31,187,251,254,205,228,150,185,189,121, 55,191,
- 155,247,222,124, 44,167,138,197, 98,177, 88,180,172, 27, 55, 51,
- 153,237, 45,171,198,234,125,233,239,253,155,147, 22,171,166,250,
- 248, 97,116,180,187,199,178, 90,204,222,182,237,142, 40, 7,191,
- 201, 32,196,246, 13,125,192,107, 81,236,116,202,160,172, 94, 18,
- 229,239,247,220,181,102,212, 98, 6,132,228, 39, 2, 97, 88,169,
- 176, 95,155,102, 3,180,216, 20,129,136, 17,133,218,145,190,198,
- 160, 52, 4,140,193,105, 81,142,116,211,133,225,230, 48,167,119,
- 78,148,207,233,245,114,156, 70,148, 23,220,213,149,233,116,101,
- 213, 31,217, 10, 16, 77, 46,180, 19,237,102, 25, 6, 3, 95,108,
- 98, 61,152,102,162,221, 12,136, 33, 48,224, 50,130, 10,132, 27,
- 32,176,139, 85, 33, 24, 8, 42,135,158,133,211,108,216, 5, 59,
- 89,154, 96, 12,205,136,242,108, 38,156,102,195, 46,216,201,242,
- 0, 3,191,160,176,184, 14, 93,215,194, 35,135, 7, 24,241,120,
- 52,191,134,168,218,173, 15,198, 82, 68,193, 88, 98, 20,202,130,
- 209,245, 51,154, 95, 3, 38,198, 88, 46, 96,132, 53,216,100, 25,
- 202, 74,162,170,174,131,112,219,165, 31, 75, 49, 24,242,136,249,
- 182, 57, 58,112,224,139,217,251, 77,156, 19,101, 42,165,251, 3,
- 96, 48,154,234, 23,141, 14,108, 55,148, 62, 23, 70,157,175,143,
- 19, 32,103, 50, 12,134,150, 98, 7,141, 5,194,111,140,167,142,
- 56,216,118,176,184, 40,215,195,188,205,237,105, 6, 67, 75, 59,
- 29,245,249, 28,116,156,105, 32,112,191,228, 26,101, 91,180, 81,
- 10, 27,154,236, 62,249,125,183,190,186,141, 28, 12, 70, 93, 5,
- 32,208,113,166,178, 64,140, 12,133,135,242,245,100, 78,126,189,
- 50,227,156,133,158, 12, 74, 91,184,179,252, 72,119, 15, 43, 92,
- 212,200,154, 89,192, 16,139,100, 41,150, 72, 83,123, 38, 20,151,
- 49, 48, 43,202,220, 21, 81,230,123, 8,136,126, 81, 38, 18,244,
- 119, 6,195,140, 38, 90, 53, 43,182,154, 5, 17, 35,142, 69,171,
- 196, 27,127,100,151,177,121,158,234,211,196, 93,124, 65,238,248,
- 252, 56, 93, 95,147,235, 89, 99,236, 74,130, 25, 3, 93,144, 93,
- 7,132,205,215, 80,254,177, 2,212,156, 94, 44,117,156,198, 50,
- 24,129, 18,210,207,213,238,202, 58, 30,177, 4,130,204, 93, 23,
- 48,142,231,113, 24,140, 80,100, 79,106, 16,139,145,229, 68,172,
- 179,167,251, 9, 12, 70, 32,213,118,215, 35,216,221, 43,159,189,
- 48, 24, 33, 21,178, 8,104,115,170,252, 8,162,130,225,189, 49,
- 137,193, 8,148, 48,223,160,198, 20,182,178,251,189,127, 65,113,
- 45,157,206,233,179,170,227, 35,160,156,174,250,210,202,172, 94,
- 189,174,251,242,188, 65,181,202,231, 9, 4,154,193,108, 39,151,
- 146, 59,148, 71, 2,117,107,102,206, 13,156,117,103,112, 24, 12,
- 159,202,254,208,172, 72, 29, 97,234,124,206,155,132,243,117, 28,
- 21,197,201,192, 35,202, 98,236,119,114, 86, 82, 2,116, 93, 29,
- 41, 24,140,134,168,212,161,134, 15,112,149, 92, 76,202,121, 68,
- 43,208, 17,205,123, 23, 41, 6,249, 39,215,195,161,112,107,139,
- 99, 12,231,104,254,160,190,128,232,186, 34, 93, 23,147,190, 46,
- 187, 26,156,217,133,139,193,162, 89, 41, 54,233,115,203, 86,120,
- 196, 40, 59, 63, 80, 47, 87,244,139, 58, 52,233,115, 45, 5,107,
- 33,202,218,153,149, 26,151,179, 21,184,152,149, 7,110,119, 98,
- 48,154, 66,232, 80, 11,139, 99,134,238,235,246,124,146,229,239,
- 94,243, 26, 12,134,164, 35, 44, 91, 79, 54, 24, 16, 67, 66, 80,
- 153, 38,224, 98,148, 29,229,198,188,222,201, 96, 72,218,237, 8,
- 167, 93,110, 46,198, 93, 28,124,178,116,192, 56, 57,209, 17,145,
- 160,179,147, 81, 40, 11, 70, 84,159,138,199, 79, 3,244, 0,195,
- 142,232, 19,103,108,126,210, 78,121, 48, 16,124,169,171,117,161,
- 29, 41,166,194, 29,116, 26, 3, 3,202, 62,141,134,249, 81,177,
- 211, 24, 24,165, 7,171,134,244, 20, 56,236,226,216,162,202,116,
- 53, 59, 19,174,168, 29,118,192, 46, 86,149, 96, 96,243,233,252,
- 223, 96, 3,130,118,195, 14,183, 51,157, 44, 77, 48,220, 0,201,
- 127, 14, 86,112,201, 64,212, 8, 12, 21,144, 69,218,120,178,188,
- 45,202,163, 38,249,194,209, 14,180,107,254,144,129,168, 78, 62,
- 215, 74,176,222,111, 95, 21,101,130, 58,100,128,246, 27,196,246,
- 107,219,124,184, 8,108, 93,195, 78,165, 2, 63, 59,188,177, 96,
- 168, 35,201,170, 37,151,216, 32,130,242,242, 43,127,159,179,241,
- 68,148, 88, 46,230,255, 46, 80, 43,253, 31, 0,165, 77, 46,225,
- 17, 27,221, 39, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_device_png[45511] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 1,149, 0, 0, 3, 34, 8, 2, 0, 0, 0, 41,105,201,
- 136, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,216,
- 1, 30, 13, 5, 29,169,182, 54, 49, 0, 0, 32, 0, 73, 68, 65,
- 84,120,218,236,189, 89,112,100, 87,122,231,247,157,115,111,174,
- 88, 10, 40, 84, 21,139,100, 85,145, 44,146, 93,100, 55, 91,205,
- 110,182,122,139,222,212,148,186, 37,185,229,112, 43, 36,217,150,
- 34, 70,114,132,165,152,241,131, 61,178,159,198, 49,143, 19,158,
- 183,113,204,219,196,232,101,244, 48, 19, 99, 43, 28,154,113,104,
- 108,105, 70,106,141,130, 82,111, 86,179, 91, 18,155,108, 54,151,
- 34,107, 97, 85,161, 10, 64, 1,185,220,229, 44,159, 31,238,118,
- 238,205, 4,144, 0, 18,185, 0,255, 31, 73, 48,145,184,153,121,
- 51,145,249,195,255,251,238,185,231,136,183,223,185, 78, 0,140,
- 1, 30,121, 75,129, 23, 11,140, 5, 31, 47,193,137,209, 7, 51,
- 49, 91,230,170, 83,152, 89, 41,165,148,178,150,247,208, 13, 51,
- 71, 81,212,237,118,149, 82, 7,213, 20,239,103,177,122,189,190,
- 184,184,216,104, 52,132,216, 75, 94, 66,136, 90,173, 94,171,213,
- 164, 20,131, 63,147, 66,208,222,183,135, 58,225, 47, 48, 21,251,
- 88,203,204,169,110,180,209, 42,142,141,177, 68,100,173, 9,130,
- 160,215,235, 25, 99,146, 77,181,214,253, 94,175, 31, 4,198,232,
- 92, 26,177, 82, 58,140, 60,102,203,182, 98, 18,107,237,114,171,
- 85,243,188, 76,109,187, 6,165,154,239,175, 46, 44,202, 97,110,
- 28,118,113,168, 21,134,171, 76, 17, 95,239,245,148,209,187, 27,
- 36,217, 90, 40,163, 59, 81, 40,165, 28,212,151,149,162,214,108,
- 214,234,245,252, 74,207,243,218,237,246, 66,123,193,243,189,244,
- 13,237,251,237,118,187,213,106,121,158, 71, 68, 82,202,122,189,
- 238,251, 62, 9, 65, 68, 82, 8, 33, 68,114,249,224, 38,131,251,
- 102, 14,129,250,241,216,210, 80,138, 49, 38,142, 99,109,140, 53,
- 38, 8,130,126,175,175,141,214, 90,247,251,253,126,191,111,140,
- 49,198,132,253,126,141,200, 38,194, 98,219,170,213,219,245, 6,
- 103, 2, 88,104, 52, 23,155,205,226, 35, 78,180,208,108, 46, 54,
- 91,156,185, 68, 12, 81, 13, 15, 10,136,121,224, 35, 40,178,228,
- 54,112,181,171,172, 34,224,141, 94, 65, 86,247,131,247, 80,128,
- 16,130,119, 83,227,174,185, 46,189, 69, 47, 10,123, 81,228, 94,
- 223,139,162,228,154,228,193, 2, 21,135, 70, 11, 33,137,200,147,
- 82,123,178,217,110,123,158,151,184,175,221,110,251,190,159, 91,
- 79,122,158,239,121,245,122,221,243, 60, 33, 68,146,249,136, 68,
- 190,227, 2,178,131,191, 78,134,155,140,177,113, 28, 41,173, 85,
- 28,119, 58,157, 40,138,162, 40,218,217,217,137,227, 56, 12, 3,
- 161, 12, 89,107,217,122, 66,158,105,183, 83, 19, 53,155, 11,141,
- 102,230,160,214, 98,171, 85,124,104,139,255,115,102, 16, 30, 30,
- 130,202, 91, 14, 90,131,137,197, 96, 86,202,237,197,251, 60,185,
- 210,157,187, 15,199, 44, 70,214, 23,237,225,163,106, 9,200,123,
- 239, 18, 31,224,237, 44, 10,167, 11,226, 93,238, 34,255,206,117,
- 95, 47,138,250,113,122,185, 19,133,134, 88, 10, 73, 82,138,102,
- 189,217,108,213,235,245,229,229,229, 70,163,209,104, 52,150,150,
- 150,106,181,122,173,230,215,235,117,233,121,105,166, 27, 48,156,
- 128,224,224,175, 41, 26,202, 88,107,180,142,227, 56, 12,195, 78,
- 167,211,235,245,146,196,212,235,245,132,214,100,173, 49,230,220,
- 210,114,242,121,121,100,117, 53,185,221,197,213,179,197, 71, 87,
- 164,159,149,146,137,184,144, 78, 38, 32, 87, 67,188,107,118,201,
- 220, 52,236, 74, 55, 55,177,123,189,112,219, 99,195,101, 48,164,
- 17, 54,240, 19,222, 87, 74,213, 29,216,199, 51, 98, 4, 43,241,
- 208,102, 23, 15,127, 92, 49,228,233,141,214, 43,227,234, 19, 24,
- 242, 35,102,190,223,221, 73,174,186,223,237, 36, 27,110, 6,125,
- 207,243,132,231,137, 70,125, 97, 97,161,213,110, 47, 44, 44, 44,
- 44, 44, 44, 45, 45, 53,154,205,122,173,238,251,158,148, 94,214,
- 203, 19, 21,119, 9,216, 13,254, 58,154,164,200, 90,163,181, 14,
- 195,176,219,237,118,187,221, 78,167,211,235,118,183,183,183,235,
- 68, 74,233, 86,173,214,110, 52,137,248,145,213,179,196,188,216,
- 106, 45, 54, 91,236,124, 74,133, 83, 92, 17,231, 63,201, 63, 74,
- 69,213,198,196,185,167, 74,185,137,185,242,109,238, 29,102, 46,
- 55,158,184,106,146,129,107,134,110, 86,242, 14,243,222, 42, 24,
- 182, 25,237, 91, 63,138,189, 67, 20, 15,126,126,197,174,162, 97,
- 222,213, 59, 98,151,155, 15,181,149,112, 30,125,183, 31, 21,226,
- 203, 54,221, 93,121,188,223,149,189, 56,173, 91,239,119, 59,130,
- 40, 80, 42,178,218,247,107,166, 94, 59,115,230,204,162, 67,179,
- 217,244,253, 90, 18,221,134,239, 19,212, 6,127,185,111, 51,107,
- 173, 82, 42,241,212,195, 12, 82,138,141,109,214,106,237, 70, 99,
- 177,217, 90,104, 54, 27,181,218,217,165,229,236,131,202, 68,130,
- 28,137,184, 98, 74,138,169,212, 79,133,151,184,164, 39,215, 77,
- 204,101,211,229,183,229,146, 99,184, 26,202,220,123,168,214,140,
- 21,247, 81,249, 81,134, 74,118,223, 78, 22,243, 64,206,226,145,
- 162,215, 40,149,158, 99,135,146, 40,134, 89, 99,200,167, 88, 12,
- 223, 94, 36, 79,177,116,231, 98,247,199, 21,187,238,149,168, 62,
- 82,169, 8, 29, 8, 80,206, 37,167,106,173,100,232,236,133,121,
- 24,244,149,214,189, 56, 14, 84, 28,104, 21, 91, 35,253,154,215,
- 106,174,172,174,158, 57,115,102,101,101, 37,241, 90,173, 86,147,
- 82,150,119, 82,140,150,218, 4,252,117,114, 84,213,239, 7,157,
- 206,206,195,135, 15, 55, 54, 54, 58,219,219, 62,115,221,247, 23,
- 26,205,133,102,115,177,213, 58,187,180, 92,247,125,215, 11, 84,
- 169,188,242,203, 37,239,148, 37,149, 27,138,157,219,231, 55, 41,
- 93, 40, 4,151, 89,136,221,138,176, 48,102,122, 57,251,105,245,
- 178,107, 52, 46,212,199, 60,216,185,114, 36, 85,190,135, 61,234,
- 193,193,155,140,104,174, 81,219, 83,187,186, 67,236, 37, 50, 87,
- 49, 98,136,190,242,123,174, 4, 52,231, 74,225,124,250,179,221,
- 112,182,174,228, 32,177,187, 4,157, 99,151,156,109,195,196, 69,
- 142, 27,144, 32, 19,103, 7, 40,200,253,146,108,175,140,121, 24,
- 244,123,113, 20, 40, 21,106,165,152,185, 81, 95, 94, 89, 89, 91,
- 91, 59,115,102,101,121,121,169,221,110, 39, 82, 27,216, 35, 49,
- 66, 94, 19,240,215, 76,219,202, 24, 27, 69, 97,183,219,221,216,
- 216,216,220,220,220,220,220,240, 13,215, 61,175,221,104,156, 93,
- 90,174,215,252,139,171,107,121, 84, 17,206,199,184,106,168,178,
- 110, 50,215,148, 37,149, 93,200,111, 91,186, 80,140,127, 56,200,
- 173,156, 58,145,203,138, 44, 41,111, 80,100,217, 13,135,199,186,
- 129,166, 91,165,167,182, 71,147,107,247, 10,148,119,251,108,140,
- 244, 41, 17,229,207,218,208, 44, 86,232,108,160, 29,238, 72,167,
- 106,171,172,125,158,109,146, 29, 50,204,190, 21,149,252,149, 59,
- 72,228,251, 36,202,114,204, 4, 38,202,138, 20,101,163,186, 30,
- 20, 69, 95,111,184,139, 69,222,161, 19,110, 93, 91,241, 90,254,
- 18,223,239,117,149,214,219, 97, 16, 26,173,136, 68,163,190,178,
- 182,118,254,252,249,179,103,215,150,150, 22, 27,141,134,231,121,
- 238,179, 28, 89,106, 2,254,154,102, 91, 61, 86,170,215,237,222,
- 191,127,255,222,189,123,219, 91, 91,210,218,165,102,107,161,217,
- 60,187,188,188,182,180, 92,243,125, 81,201, 26,185, 92, 92, 73,
- 37, 67, 57, 19, 95,176,165,194, 27, 54, 21,141,107, 25,203,142,
- 206,242, 13,153, 42, 55, 73,175, 76, 15, 79,146,107, 52,203,185,
- 215,152,152,172,107,180,226, 2,115,177, 99,121, 76,203,246,194,
- 186,165,107, 85,115,236, 20,168, 21, 59,239,110,180,161, 86,114,
- 111,184,119,231, 75, 12,205,109,187, 21,133, 21, 49,149, 5, 82,
- 114,217, 96, 2,114,135,107, 13,202,168, 16, 77,201, 50, 34,137,
- 85,206,205,156,156,149, 95, 46, 76,148,222,133,112, 30,216, 29,
- 46,155, 63,174, 40, 30, 37,185,151,194,128,162, 16,100,250, 20,
- 132, 72,235,218,194,116, 92,186,156,121,173,168,241,139, 2,148,
- 216,141,211, 68,177, 49,219, 65,176, 29, 5,129, 86,129, 49,178,
- 213, 92, 89, 91,187,112,225,194,249,243, 23, 22, 23, 23,106,181,
- 122,113,160, 64, 12,171,117, 79,162,209,102,220, 95,204,204,113,
- 28,239,236,116,214,215,239,221,186,117, 75,245,251,237, 90,189,
- 221,104, 92, 60,187,118,118,121,185,238,215,200,173,188, 28, 53,
- 148,180,101, 45, 19,101,198,201,174, 79, 68,145,248, 34,253,202,
- 185,152,216, 50, 37,222, 98,231, 38,217,215,193, 11,213,159, 22,
- 119, 69,108,237,128,212, 50, 7, 13, 83,103,177,217,174, 25,205,
- 113, 49,187,250,226, 82, 95,172, 92,150, 14,145,218, 80,175,237,
- 114,229,208,177,102,163, 84,140,149, 2, 80,148,107, 49, 81,201,
- 47,174, 32, 92, 69,185,201, 72,148,243, 85, 58,122, 65, 20,121,
- 73, 56,242,202, 77,147,125, 83,186, 38,151, 86,225, 65, 81,186,
- 57, 13, 92,147,252, 39, 75,119, 91,185,183,178,245,178,125, 22,
- 206,147,116, 29,231,170, 37,201, 99,217,229,244, 53,207, 74,212,
- 138,209,152, 40,214,122, 59, 10, 55,250,189,200,152, 88, 80,251,
- 236,202,165,199, 47,157,191,240,200,242,242, 82,189, 94,207, 6,
- 175,237, 98,180, 19,161,179, 25,244, 23,107,173, 59,157,238,221,
- 187,119,110,220,184,145, 8,107,101,113,241,236,242,153, 71,207,
- 174, 13, 85, 85,242,201, 31, 34, 20,235, 58, 37, 75, 73,201, 56,
- 247,252,250,204, 86,204,214,221,158,152,147, 17,241,197, 64,212,
- 244, 91,170,108, 89,217, 44, 55, 87,246,136,214,121,136,170,230,
- 202,215,228, 10, 43, 5, 58, 87,199, 60,172,218,229, 97,141,185,
- 189,155,104, 60,228,176,230,240,107,152,246, 75, 89,251,246,185,
- 68,165,232,162,161, 1,106, 96,195, 82,149,151,121,161,148,170,
- 210,248, 51,196, 77, 85, 79,165,114, 41,162,147, 16, 85, 85, 57,
- 1, 45, 27,207, 37,164,115, 71, 66, 86,239,202,185, 67, 33,179,
- 8, 39, 68,105, 63, 51,205, 13, 23,101,245, 66,201,226, 36,170,
- 7, 37, 72,136,226,119, 34, 68,209,131,205,255,130, 17, 61,232,
- 247,118,162,176,171, 98, 37, 69,123,117,245,242,149, 43, 23, 47,
- 94, 92, 90, 90,242,125,223,121,225, 69, 53,242,206,173,206,102,
- 194, 95,204, 28,199,209,131, 7, 15,110,221,186,117,239,206,157,
- 166,244,206,180,219, 23,215,206, 61,186,182, 86, 42,178,114,103,
- 229, 95, 43, 2,226,236,202,196, 26, 92,182, 76, 98,174,212, 35,
- 169,131,138, 45, 45, 91,107,137,243,109,138,123,200,110,232,126,
- 101,103,203,236,202, 92,142,249,206,100,143, 80, 85, 94, 98, 40,
- 215,113,101,153,230,230, 74,246,161,200,137,142,197,156, 38,157,
- 83, 84, 38, 42,119, 43,202,234, 49, 80,183,215, 50, 36,142,141,
- 82, 99,238,253,182, 22, 67,251, 86, 67,107, 64, 81,237,181,187,
- 193,101, 72,245, 87,117, 83, 57, 34,185, 22,203, 21, 67, 36,164,
- 44, 46,184,186,145,194,181, 76,113,101, 73,112, 14, 50, 81, 88,
- 182,181,112, 12, 85, 92, 87,186, 9, 13,123,172,106,124, 19,162,
- 178,231, 78,137,234,244, 10, 69, 54,212,163,120,125, 57, 55, 90,
- 126,188, 60, 63,166,147,252, 34, 55,250,189,141,176, 31, 88,195,
- 173,230,197,199, 31,191,244,248,165,181,115,107,217, 89,168,135,
- 208,153,128,191,138, 15,135, 82,234,193,131, 7,215,223,125,247,
- 193,250,250, 98,189,241,200,217,179,143,158, 93, 91,108,181,137,
- 170, 29,116,102, 75,182, 28,118, 42,194,178, 54,119, 4, 91,155,
- 41, 35,221,192, 90, 75, 37,133,101,150, 73,111,101, 51,121,177,
- 181,150,172,181,169, 89,216, 26, 91,186,243,252,230,165,123, 96,
- 102,203,198,114, 69,118,217,157,184,254, 26,154,221, 92, 5, 23,
- 249,142, 6,116,198,165,230,218, 94,205,126,167, 85,230,182,224,
- 121,216,224, 47, 30,126,210,207,190,103,100, 31, 96,164,196,110,
- 209, 76, 8,177,107,139,166,170,179,129,246, 86, 94, 48, 58,230,
- 26, 76, 73, 37,161, 56,238, 16, 50,191, 94,230, 95, 40,243,148,
- 227, 44, 33,132, 36,231,178,115,129,132,144,233, 13,147,155, 12,
- 220, 48,125,208,202,198,249,163, 16,145,115, 19, 26,178,219, 89,
- 53,234, 22,167,187, 27,141,179,226,147,139, 97,124,156, 29,254,
- 225,158,138, 55,195,224, 97, 28,233,122,237,194,165,199,159,122,
- 234,169,115,231,206,213,106,181,188, 39,184,107,177, 57,195, 46,
- 155,176,191,216, 90,238,245,186,215,175, 95,127,255,189,247,234,
- 36, 46,157, 63,255,216,185,243,201,105, 52,121, 7,138, 42,129,
- 101,184,116,152,172, 45,164,195,108, 19,173,152,138, 98,172, 53,
- 214,241,148,181, 54,251,169,205,175,201, 54, 54,229,111,243,203,
- 249, 77, 56,191, 55, 46,174,103,107,179,157, 25,180,103,113,185,
- 146,212,156,203,238,177,203,129, 60, 53, 80,250,237,209,204, 58,
- 160,105,120,215,111, 70,127,251, 28,250,237, 44, 14,252,131, 1,
- 235, 85, 71, 19,184,253, 44, 55,232,229, 81,173,154,215,100,166,
- 188, 84, 53,101, 1,201,226,130,116,180, 85,124, 21, 50,255, 81,
- 105,179, 98, 99, 41,203,130, 19, 66,122, 50,243,154, 99,183,236,
- 135,249,110, 16,145, 24, 80, 91,226, 95,114, 52, 77,197,209,135,
- 188, 77, 86,209, 89,250,215, 45, 63, 32,149,188,223,122, 42,222,
- 140,194,205, 56,146, 75, 11, 79, 94,125,250,169,171, 79, 45, 44,
- 44, 56,227,206,118,143,102, 51,230,178,201,248,139,173,181, 91,
- 91, 91,111,188,241,198,195, 7, 15, 86,218,237,103, 47, 63,177,
- 182,188, 92, 77, 19,238, 71,189, 82,178, 25, 91,146, 84, 69, 61,
- 201,101,227, 92,105, 74, 63,181,198, 36,247,105,173,101, 99,202,
- 215, 23,146, 42,127,107,115, 33,218,129,135,179, 21,169, 89,155,
- 164,188,129, 2,147,220, 10,177, 84,241,177,155,154, 70, 27, 89,
- 186,183,128, 14,245,123, 57,202,143,197, 17, 36,117,244,219,236,
- 54, 80,108,143, 59, 25,140,126,110,172, 27,108,135,185, 53,160,
- 168, 90, 70, 74, 47,243,139, 39, 11, 85,201,221, 47, 75, 33,165,
- 20, 66, 14, 94,206,197, 39,115,247,165, 63,173,154,148,156,244,
- 71,133,127,243, 98, 83,148,189,150,232, 76, 20,127, 6,201,105,
- 177, 80,250, 22,222, 81,209,221,160, 23,249,222,133, 39, 46, 63,
- 247,220,243,171,171,171,201,212, 29,123,230,178,221,106, 76,113,
- 162,252,101,173,125,248,112,235,245,215, 95,223, 92, 95,191,114,
- 225,145, 39, 31,125,116,177,213, 46, 26, 58,110,255,200,173,209,
- 74,202, 48,105,170,178,156, 94,206,124,148,234, 38,253, 90,136,
- 41,149, 84,118,125,113,193, 14,217,222, 26,147, 61,156,177, 38,
- 123,196,108, 7,108,217,131,105,254, 42,165,194,162, 75,197,165,
- 145, 16,187,142,255,228,145,181,194, 71,212, 18,211,172, 35, 14,
- 255,150,223, 55,249,137,145,196, 39,118,219,184,146,242,132,219,
- 128,207,186,105, 78, 85, 88,216, 45,245,154,148,169,143,178,175,
- 66, 10, 41,189,226, 74, 79, 58,194,114,190, 77,172,231,201,146,
- 212,156, 12, 40,165,164, 97,106,171, 30, 88, 16, 84,209, 89,114,
- 122, 91,222, 75,206, 44,150,254,229,181,108,251, 74, 61,136,195,
- 109,193,143, 60,245,228,135, 63,252,225,149,149,149, 60,145, 13,
- 186,108,191, 80, 38,230,216, 95, 76, 28, 6,193,155,111,190,121,
- 253,157,119,174, 62,114,241,201,199, 30, 91,108,181,203,206,114,
- 242, 75,102,156, 60, 58,185, 57, 40,245,139, 49,169, 86, 82, 49,
- 177, 53, 58,117, 80,162, 45, 99,172,179,153,209,154,141,181,214,
- 88, 99,178,205,210,111,243, 59,201,228,149, 92, 40,197,177,172,
- 243,101,171, 45,170,193,154,142,246,152,247,133, 71,116, 8, 31,
- 202, 53,135,171, 25,231,232,200,248,161,243,155, 24, 73,124, 98,
- 223, 15, 92,165,133, 39,134, 9,206, 61,168, 90, 4,185,212,108,
- 110, 33,233,196, 49,175,240,154,244, 50,163,121, 82, 74,207,181,
- 152,244, 60, 87,127,123, 8, 46, 79,115,148, 94, 40,106,210,172,
- 137, 38,243, 3,184,204,197, 16,179,124, 88, 99,214,196, 77,255,
- 208,247,181,218, 80,209,118,205,123,230, 35, 31,190,118,237, 90,
- 171,213,114,250,253, 21,149, 85, 67,153, 16, 19, 21,217,152,253,
- 197,108, 55, 55, 55,255,250,123,223,171,147,120,225,233,167,215,
- 206,172, 84, 14,225, 85,138,178,212, 32,198,186,122, 42, 89, 38,
- 189,172,109,241,213, 88,157,125,171,141,181,198,106, 51,240,173,
- 177, 38,187,144, 95, 83,122,184,129, 10,212, 61, 2,232,182,198,
- 75,126, 25, 41,217,240,168, 17,139,199,250, 55,227,164, 72,107,
- 172,247, 39,142,176,145,216,175, 44,221, 67,112,238,103,221,237,
- 194,201,244, 24,130,148, 78,225,153, 75, 45,215, 89,122,193,243,
- 164, 87,254,182,162,182,228,130, 87, 14,122,110, 73, 43, 4,101,
- 241,144,178, 35,176,238, 65,128,124, 16, 70,214,181,205,106, 21,
- 107,181, 49, 93,163,239,153,184,241,200,249,159,254,236,103,207,
- 158, 61, 91,137, 99,101,147,149, 69, 54,169, 68, 54, 54,127, 89,
- 107,110,221,186,245, 55,175,190,122,113,245,236, 79, 61,243,108,
- 221,247,147,126,188, 91, 9,218,193, 36,101,140,209,169,107, 56,
- 19,141,209,186,176, 79, 98, 37, 99,172,214, 70, 39,230,202,182,
- 209,218,106, 99, 76,118,165,123,219,226,223,114, 93,233, 30, 58,
- 28,108, 69,237,217,126,218, 55, 37, 29, 78, 73, 39, 53, 62,205,
- 161, 7,247,158,217,122, 88, 64,219, 83,112,165, 22,248, 64,106,
- 43,186,242,233,144,142, 82, 11, 44, 79, 91,137,161,164,231,101,
- 255,166, 49, 77,122,158,148,158,244,188, 92,124,153,203,188,193,
- 188,150, 29, 70,112,142, 84, 8, 73,162, 24, 69,156,157, 36,146,
- 156, 0, 98,211,201,163,108, 50,183,166,137,140,185,103, 84,124,
- 102,241,165,207,125,246,210,165,203,217,180, 25, 3,199, 75,134,
- 38,178,221, 78,111,154, 29,127, 49,219,251,247,239,127,231,175,
- 254,234,218,229, 43,215,158,120,210, 29, 28,144,215,101, 73, 8,
- 50,131,162, 73, 28, 84,185,172,181,213,218,100,194, 50,217,183,
- 182,122, 77,106, 46,199, 89, 78, 69, 89, 58, 26,152, 31,120, 33,
- 103, 6, 7, 30, 93, 79, 60,178,103,224,163,147,237, 59,177,235,
- 20,178,123, 53,247,134,122,109, 31,169,149, 15, 89, 74, 41, 7,
- 228, 37,165,231, 73,223,247,188,220, 95,158,244,189,220,101,137,
- 239, 6, 75, 81,183,176,117,206, 16,160,188, 45,146, 30,147,226,
- 36, 93, 24,109,180,214,198, 24,179, 73,166,187,178,244,249,159,
- 125,249,194,249, 11, 89,251,207, 21,217,224,209,223, 99,183,216,
- 17,253,197, 65, 16,188,242, 23,127,113,182,213,254,228, 71, 94,
- 200, 14, 35,166,135,231,172, 49,108,147, 23, 32,247,145, 54,170,
- 226, 35,109,148,182,233,245,202, 42, 99,180,114,174,209, 70,169,
- 210,246,201,205,147, 56,150, 23,131, 69,191,204, 29, 17,234,230,
- 41,222,187,178, 27, 49, 58,193, 77,112,220, 33,236, 54,108,242,
- 177,170,215,134, 74, 45,183,129, 59,170, 67, 10, 33, 60, 79, 10,
- 81,142,102, 82,122,158,231,121,210,247,165, 39, 61,207,151, 94,
- 234, 50, 47,151, 90, 97, 52,175,148,203,178,222,127,158, 20,211,
- 166, 88,122, 4, 43,249, 4, 27,173,149,210,218, 24,179,238,139,
- 198,213, 43, 95,252,202, 87, 90,173,118, 90, 14,151,162, 36, 13,
- 251, 58,180, 59, 38,166,233, 47,107,237, 27,111,188,254,193,245,
- 235,159,249,232,199,150,218,109,119,152,123,210,141, 50, 73,158,
- 82,202,104,173,149, 50, 42,249,154,252,171,139,175, 90,155, 56,
- 46,174,209,233, 6,201,198, 73, 34, 51, 74, 23,133,100,126,108,
- 177, 24,169,192, 92, 58,213,153, 15, 45, 41, 24, 10, 28,143,221,
- 196,158,199, 7,246,144, 90,213,104,162, 66,214, 64,171, 84,154,
- 158,231, 75, 79,122,190, 47,253,228,178,231,249,158,244,156,176,
- 230,121, 89, 91, 77,150,134,170,101, 3, 47,138,118,152, 49,198,
- 24,173,181,210, 90, 41,165,180,138,152, 31, 44, 53, 95,248,242,
- 23,175, 61,247,188,231, 57,227,212,168,116,226,131,107,177,210,
- 137,251,227,179,216,225,252,197,113, 28,255,233,127,252,143,207,
- 95,186,242,212,227,143,167, 51,249,185,230, 82,218,106,173,149,
- 54, 42,214, 74,233, 56,249, 55,185, 28,155,228,114,172,140,138,
- 77,172,180, 82, 38, 86, 90,197, 70,105, 19, 43,163, 84, 17,193,
- 116,214,146, 55,206,192,174, 52, 91,101,211,212, 12,158,125,188,
- 159,136, 32, 41, 48, 35,106, 27,172,171,196,176,164, 38,134,101,
- 180,161, 58,115,143,108,230,170,242, 60,223,243,147, 74,211,243,
- 124, 63, 19, 89, 22,208, 60, 95,122,178,200,101,249, 64,217,196,
- 98,201,216,162,180,142, 74, 21, 22, 43, 21, 43,213,175,251,244,
- 252,211, 63,247,139,191,152,157, 43, 94, 29,111,187, 71,105, 57,
- 174,138,242, 16,254,226,173,173,173, 87,254,252,207,191,252,241,
- 151,150, 22, 22,136, 40, 29,119,154, 55,182,148, 74,157, 21,197,
- 58,142, 84, 28,235, 40,214,113,172,162, 88, 69, 81,114, 65,199,
- 177,137,227, 68,106, 38,142,203,129, 43,105,105, 25,174,180,177,
- 156,105,101,170, 11, 88,192, 83,224,228, 74, 77,136,225, 58,171,
- 4,180,138,206,210,227, 0,206, 65, 0,207, 79, 83,152,231,251,
- 137,209, 60,223,175,232,204,243, 60,247, 56,102, 50, 7, 70,242,
- 1, 52,214,106,163,181,210, 74,235, 88,197,113,172, 98, 21,199,
- 68,219, 79, 60,250,213, 95,249,229,124,176,216, 32, 35, 91, 76,
- 28,187,191,152,248,198,251,239, 95,127,253,141,207,124,244,167,
- 234,181,154,200, 78, 69, 76, 14, 20, 38, 1, 74,199,177,142, 99,
- 21, 70, 42, 10, 85, 24,199, 81,168,194, 72, 69, 81,250, 53,138,
- 18,139,233, 40, 54, 74,101,129, 75, 27,109,138, 33, 93,110, 39,
- 139,120,248, 28, 47, 80, 21, 56, 53, 82,115, 63,230, 98, 96,162,
- 124, 55,157, 9, 18,123,187,204, 75, 19, 89, 26,196, 82,151,213,
- 252,204,101,190,231,229,135, 8,100,118,154,122, 58, 94,219, 24,
- 109,140,209, 74,199, 74,197, 42,142,149,138,162, 40,102,219,121,
- 100,237, 51,191,250,141,203,151, 47,167,227,220,134,121,108,224,
- 112,229,174,167,129, 29,151,191,152,237,107,175,189,182,125,231,
- 238,231,126,234, 99,148,159,172,103, 44, 91,155,116,181,116, 20,
- 167,158, 10,195, 56, 8,227, 48,140,131, 64,133, 81, 28,134,113,
- 24,230,254, 74, 4,151, 52,188, 74, 45,173, 98, 10, 7, 34,226,
- 253, 58, 89, 0,156, 82,163, 13,213,217, 96,177, 57,232,178,236,
- 196, 39, 41, 18,145, 73,233,101, 69,165, 95,243, 61,207,247, 19,
- 145, 37,245,166, 87,196,177,188,150, 76,122, 97, 74,171, 56, 86,
- 113, 28, 71,113, 28,169, 56,138,227,238, 99,231, 63,250, 75,191,
- 240,252,135, 63,236, 73, 47, 59,111, 93, 10, 57, 74, 28, 59, 82,
- 16, 27,213, 95,204,246,123,223,251,222, 50,211,135,174, 60,145,
- 62, 66, 50, 74, 36, 57, 38,168,148, 10, 67, 21, 69,113, 16,196,
- 253, 48,238,247,163,126, 16, 5, 65, 28, 4,137,200, 84, 24,170,
- 40, 86,113,164,227,172,127,111, 12, 59,227,221, 43, 67, 70,161,
- 42, 0, 14,173, 51,215,101,110,247, 92,150,102,199, 72, 90,101,
- 194,203,154,250,190,239,123,190,159,126,117, 69,150, 40, 44,233,
- 235,103, 41, 76,169,204, 95,113, 28,197,113, 24, 71,209,217,149,
- 167,190,241,139,159,120,233,165,100,233,223, 52,244,185,231,141,
- 86,210,216,240, 6,255,193, 20,230,143, 38, 47,126,237,181,215,
- 150, 12, 63,115,229, 74,209,173, 55, 54, 25,168,165,163, 56, 14,
- 66, 21, 4, 81, 16, 68,189,126,212,235, 71,253, 94,212, 15,162,
- 94, 63, 14,195, 56, 8,211,216,165,148,206,142, 39,186,141,173,
- 161,163,177, 0, 0,251, 86, 30,217, 50, 34,238,100, 71,217,105,
- 219,196,197,100,174,156,207,179,207,130, 51,145, 25,147, 72, 70,
- 107,157,100, 49,157,212,150,169,196, 10,151,165, 69,101, 62,248,
- 158,173,176,236, 49,249, 36, 44, 9,195,100,152,124, 38,117,103,
- 253,237, 63,248,247,126,173,246,209, 23, 94,144,158,199,150,133,
- 20, 44, 89,112,114,211,100, 61, 96,145, 75, 53, 23, 46, 39,203,
- 155, 48,113,145,200,120, 68,133,249, 35,188,100,124,227,198,251,
- 15,111,127,240,233, 15,127,132,242,179,215,147,110,189, 82, 42,
- 138, 84, 16,196,253, 32,234,245,194,110, 47,236,246,194, 94, 47,
- 234,245,163, 32,136,250,129, 10,195, 36,104, 22,227,182, 6, 3,
- 23, 0,224,200, 58,219,195,101,233, 44,135, 68,194, 21, 25, 9,
- 193,198,178, 16, 66, 88,107,165,144, 70,106, 41,165,167, 61,157,
- 228,174, 76,100,190,163,176,164,150, 20,150,133,101,201,228, 17,
- 249, 66, 24, 34,159,201,183,172,111,221,125,237,255,252,119, 11,
- 11, 11, 79, 62,249,164,148, 82,178,100,102, 41,153, 89, 72, 41,
- 89,144,116, 39, 99,115,151,124, 74,213,197,204, 7, 83,216,190,
- 254,226,173,205,205,183,255,246,239, 62,255,209,159,202,229, 69,
- 214, 90,173, 77,172, 84, 24,170,126, 16,245,131,176,211, 13,187,
- 221,176,219, 13, 58,221,168,223,143,250, 65, 28,132,113, 20,169,
- 56, 50, 74,235,108,124,124,113,226,206, 1, 39,138, 1, 0, 28,
- 218,101,204,105,113,198,196,105,129,153,137, 76, 16, 11, 22, 44,
- 132, 37, 43, 88, 74,107,211, 1, 95,210,120, 90, 26,207, 55,190,
- 103,124,223,243, 18,139,121, 73,123,139,136,200, 90,193, 86, 50,
- 121, 76, 73, 22,171,145,208, 66,154,235, 55,191,245,111,255, 96,
- 233,191,255,239, 86,207,158,245,164,199,146, 89,178,148,169,200,
- 178, 18, 86, 74,105,157,234,150,184,112,216,193, 20,230,253,143,
- 255,211, 63,220,227, 53,137,227,248, 79,255,159,255,247, 43, 47,
- 126, 60, 61, 93,221, 90, 50,198, 42,109,162, 88, 7, 97,220,235,
- 71,157,110,184,179, 19,108,239, 4,219,219,253,237, 78,208,233,
- 132,157,110,212,235,199, 65, 16,135,161,138, 99,163, 84,118,122,
- 35,115,101,185, 86, 48,153,119, 54,179, 37, 50,217,192, 57, 49,
- 116, 29,198,108, 54, 2,195,108,152,147,191,221, 98,151, 51, 2,
- 45,167,155,101,127,132,134,111,152, 28, 66,206,142,203,236,241,
- 184, 35,237, 30, 24, 83,203, 76, 56,225, 44, 17, 71,218,117,206,
- 150, 96,160,129, 9, 23,210,137,249, 40,155, 51,134,146,182,143,
- 97, 74,102,142, 49,150,181,177,198, 48,145,101,226,245,141,183,
- 59, 15,159,254,200,135,165, 20,233,212,137,229, 79,124,117, 73,
- 60, 42, 45,102, 55,228,108,240, 67,229, 47,182,214,254,167, 63,
- 249,147,207, 61,247, 97,107,173, 76, 15,162,178,213,218,102,201,
- 43,236,246,194, 78, 39,216,233, 4,157, 78,208,233,134,189, 94,
- 212, 79,181,165,149, 74, 99,151,205,231,231,152,155,105,169, 78,
- 144,185,200,176, 13,140,238, 25, 21, 26, 67, 68, 13,207, 91,244,
- 106, 45,207,247,202, 11,145, 25,230,200,152,174, 86,129,213,150,
- 185, 38,229,130, 87,107,123,126,178, 24,180,235,154,200,218,158,
- 86,125,163, 52,179, 39, 68,219,243, 23,252, 90, 93,122, 94,121,
- 51,197,182,175,117,207,168,216, 90, 73,212,244,252, 5,191,214,
- 148,222,224,227, 6, 70,119,181, 10,141, 38,162,134,244, 22,252,
- 90,203,243,124, 33, 97,177,241,230,178,106,129,201, 34, 47, 45,
- 147, 56, 38, 4, 49,147, 48,134,165,100, 33, 44,179, 21, 50,153,
- 25,207, 26,207,250,214, 26,227, 39, 3, 47,146, 9, 45, 44,147,
- 101, 73,228, 17,121, 68,190,148, 62,179, 47,217,176, 53,175,190,
- 246,103, 23,254,248,231,126,225, 23,253, 26,123, 82,178,244,216,
- 115, 22,173,145, 44, 73, 74, 65,182, 88,125, 32, 95, 49, 47,111,
- 135, 9, 22,249, 76, 63,226,160,254, 98, 38,122,227,141, 55,174,
- 174,174,181, 27,117, 50,217,250, 99,198,152, 88,153, 40, 82,253,
- 126,212,233,133,157, 78,176,189,147,248, 43,236,245,195, 36,115,
- 69,177,214,202, 24, 99,141, 53,214,112,121, 73, 8,200,107,146,
- 24,182,219, 42,190, 19,246, 54,226,112, 51,142, 60, 33, 26,158,
- 119,181,189,124,174,209, 92,244,235,126,246, 7,208, 50,247,180,
- 186, 23,246,215,163, 96, 83,133,150,185, 38,189, 71,155,237, 71,
- 155, 11, 43,181,122, 67,122,233, 42,211,204,161, 53,247,163,224,
- 78,208,219, 80, 81,108,141, 47,228, 90,189,113,185,181,180, 90,
- 111,180, 60, 63, 55,157, 98,187, 25,135, 31, 4,253,141, 56,232,
- 106,237, 9,177, 84,171, 61,209, 90, 90,107,180, 22, 60,223,203,
- 30,215, 48,239,168,248,110,216,187, 31, 5,155, 42,146, 36, 26,
- 158,247, 68,123,233, 92,189,185, 92,171,215, 8, 10, 59, 46,145,
- 57,139,184,164,245,100,201, 98,214,178, 16, 44, 4, 39,195, 87,
- 61,201,238,217,129,214,114, 58, 82,159, 18,133, 9,102,143,200,
- 19,210,151,214,103,161,133,148, 97,188,253,202,119,223,188,122,
- 245, 67,215,174, 89,207,243, 60,246, 88,178,231,177, 27,197, 4,
- 137,108, 77, 21, 34,153,239,154,171, 48,218,175,144,244,119,123,
- 166, 65,191,255,254, 27, 63,254,252,135, 95, 32, 99, 57,153,247,
- 44, 57,107, 58,140,226,126, 16,117,187,225, 78, 42,175,126,167,
- 147, 37,175, 40,142, 99,173,149,209,198,102,230,130,188,166, 88,
- 54,134,214,220,139,250,215,251, 59, 55,131, 94,100, 77,114,253,
- 205,160,251,213, 11,151,155, 73, 4, 35, 65, 68,202,218,205, 56,
- 188, 25,116,223,233,237,116,141, 74, 54,123,167,183,243,169,213,
- 11,139,203,103,107, 68,146, 73, 8, 50,204,219, 42,250, 32,232,
- 253,164,247,112, 35,142,146,205,222,234,209, 67, 21,127,246,236,
- 197,186, 76, 75,206,196,134,119,195,254,187,189,237,219, 81,223,
- 102,111,128, 59, 97,255,203,231, 30,111,121,158, 71,156,124, 98,
- 34,163,215,163,254,205,160,251,118,111,199,221,189,207,157,189,
- 184,224,215,124, 65,176,215,241,137,172, 20,199, 6, 44,150,188,
- 127, 88,202,236, 4,227,108,206, 97,203,108, 45,121, 54, 57, 5,
- 156,152, 5,179, 96,146, 68,158, 16,158,144,190, 96, 95, 90,205,
- 66,221,223,250,193, 31,255,167,199, 30,123,108, 97, 97,145, 45,
- 179, 39, 37,179,231,121,196,204,228,229, 41,140,136,164,144,148,
- 182,195,100, 69, 97,251,246,194,228,208,103,103, 45,127,243, 79,
- 255,244,167,159,126,150,141, 33,107,217,104,214,218,196,202,132,
- 145,234, 7,113,175, 23,117,186, 97,167, 27,118, 58, 97,167, 19,
- 117,123, 73,195, 94,197,145, 78,166,139,176, 38, 25, 32, 65,144,
- 215,244,176,196, 61,173, 58, 42,190, 17,116,115, 59, 16, 81, 71,
- 171,255,252,224,131,154, 40, 10,195,200,154,109, 21,223, 14,123,
- 185,188,136, 72,179,253,235,135,235,145, 53, 50,139, 75,138,237,
- 142, 82,247,162,126, 46,175,132, 31,119, 31,222,137,250,126, 86,
- 24,106,182, 93,173, 54,227,232, 3, 71, 94, 68,116, 47, 10, 94,
- 239,108,122, 89, 97,200,196,129, 49, 59, 42,126,199,145, 87,178,
- 123,127,181,121,183, 38,164, 32,129, 99, 60,199,106,177, 98,122,
- 115,202, 87,106, 78, 47, 91,102, 75,156,204,185,110,172,213,214,
- 170, 98, 46,157,164, 57,164,141,214, 73, 34, 19,196,201, 34, 75,
- 94,250,175, 76, 46,200, 55,222,121,229,155,223, 76, 50, 77,178,
- 189, 78,102,226, 73,166,237, 75, 7, 35,216,124,233,136,172,209,
- 84, 44,103, 89, 89,170,116, 20,127, 17, 17,221,189,123,231,188,
- 95,247,132, 32,203,172, 13, 43, 99, 99,101,227, 88, 7,161, 10,
- 130,184,219,139, 58,221,112,167, 19,238,116,195, 94, 63, 31, 39,
- 161,149, 74,167, 72,205, 23,251, 26,120,165,192, 4,139, 71, 86,
- 214,238,104, 21, 91, 91,249,209, 70, 28,238, 8,235,249,126,242,
- 6, 73,122,231, 15,226,176,178, 89,108,237,219, 65,167,214,168,
- 39,198,177,233,102,209,224, 99,253,168,187, 85,111, 54,211,129,
- 218, 76,134,121, 83, 69,102, 64, 63,127,183,179,217,168,215,165,
- 231, 37,159, 25,205,182,111,116,232,200, 43,161,171,213,186,137,
- 189,154,143,242,113,194, 22,203, 39,243, 76,215,122, 38, 78,142,
- 213, 20, 34, 75,228, 99,141,214,201, 60,162, 38, 25, 14, 37, 4,
- 73, 18,146, 74, 10, 35, 99,182,190,255,183,119,239,222, 81,201,
- 180, 21,249, 36, 90,153,192,114,139,241, 16,133, 13, 91, 90,121,
- 63,127, 49, 17, 25, 99,191,243,151,127,249,204, 35, 23,147,163,
- 141,108, 12,107,109,226, 88,135,145, 10,130,184,215,143,186,189,
- 100,192, 68,212,239,199,253, 64, 69,145,202,202, 70, 99,109,101,
- 158, 64,152,107, 90, 72, 18, 53, 41, 3,171,135,219,205,247,252,
- 122, 45,155, 29, 93,216, 93,126, 81, 94,173,230, 55, 82,227, 72,
- 33,106, 82,122,195,164, 34,165, 87,107, 54,164,239, 39, 45,216,
- 154,148, 53, 57,252, 79,227, 29,171,252, 90, 45, 89,147,218, 43,
- 141, 2, 42,241,129, 10,235,141,134,220,229, 78,192, 49, 89,172,
- 48, 87, 42,175,116, 22,157, 68, 97, 58, 61,207,185, 80, 88, 62,
- 171,113,242,123, 79, 78,152,244, 10,139, 9,186,125,239,187,255,
- 249, 47,162, 40, 82, 90,105,149,228, 54,157, 26, 76,167, 45,242,
- 1,133, 13,134,176, 93, 87,123,144, 21,121, 49,209,173, 91, 55,
- 47, 47, 46, 91, 99, 41, 57,155, 90,235, 52,124,133,161, 10,194,
- 184,219,139,186,189,168,215,143,123,253, 56,200,228,165,180, 53,
- 198, 50,228, 53, 67,120, 66, 46,250,181,203,173,197,225,141,207,
- 90, 93,250,105,205,215,144,242,145, 70,123,248,157,248,190, 95,
- 171, 37,135,182,125, 33,151,252,225,161, 72, 72,233,213,211,152,
- 230, 9,185,224,213, 26,210, 27,122,135,207,158,127, 68,250, 30,
- 9,146, 68, 45,207,111,123,195,143, 32, 61,115,238,130, 87,175,
- 145, 68, 0,155,116, 95,140,156, 37,253,152,210,225, 20, 54, 11,
- 233,198,178,225,108,250,119,107,147,252,197,249,192, 23, 74, 21,
- 150,254, 75,194, 19, 34,250,241,219,183,111,223, 86,177, 82, 42,
- 171, 60,181,214, 38,115, 88,118,164,207, 81,152, 45, 2,152,179,
- 234,233,208, 42,178,250,247,205, 26,251,215,223,254,206,149,149,
- 179,233,200, 14,109, 56,153,198, 43,138,117, 24,169,126, 63,238,
- 7,113,175, 23,247,251,113, 16,170, 48, 82,113,108,180, 54, 69,
- 240, 98,198,201, 64,179,129, 16,212,242,252,103, 23, 87,150,252,
- 90,229, 71,143, 46,157,121,250,220,133,252,247, 84,151,222,106,
- 189,241,161,197,149,202,102, 77,191,246,201, 75, 79,230, 17,222,
- 23,242, 76,173,241,226,202,185,193,199,250,252,147, 79, 39,237,
- 86, 34,242,132, 88,244,107, 31, 59,179, 86, 31, 80,216, 75,143,
- 93, 17,158, 76,198, 22, 9, 33,154,158,127,109,105,117,173,222,
- 172,108,182,218,106, 63,189,118, 33, 89, 52, 15,191,199,153, 80,
- 88,210, 17, 99, 54,233, 74, 22, 54, 93, 26,167, 88, 89, 62,121,
- 203, 37,107, 31, 9, 73, 34, 91,167,151,104,125,227, 7,223,250,
- 118, 28, 71,233,228,135, 74,107,173, 76,230,176,244,140,112, 71,
- 97, 92, 14, 97, 89, 25, 57,124,192,123, 62,126, 53,141, 75, 31,
- 124,112, 91, 60,216, 90,110,182, 4,179,176, 76,214,178,214, 54,
- 138,211,206,125,183, 31,118,187, 97,183, 23,246,250, 81, 16,196,
- 201, 56, 47,227, 62,178, 51,234, 23,111,135,233, 43, 76, 52,164,
- 255,196,210,202,123,253, 78,100,210, 66,242,177,229,149, 95,251,
- 169, 79, 54,153,162,126,223, 40,149,111,246,228,226,153,187,113,
- 184,157,181,183,154,181,218,127,253,177, 79, 62,214, 94,140,186,
- 61, 29,199,105, 97,232,121,143,180, 22,164,231,221,236,117,242,
- 71,249,194, 83,207,126,238,210,147, 81,175,175,194, 40, 85,152,
- 148, 75,181,250,249,246,226,123,189, 29,205,105,247,237,233,181,
- 243,191,242,209, 79,112, 24,199,253,192, 90,155, 20,164, 13,207,
- 191,180,184,124, 55,238,247, 84,122,232, 96,181,189,240,247, 94,
- 250,108,147, 41,236,245,140, 82,248, 37, 78,231,157,147,126,117,
- 230, 76, 21,165, 63,141,206,114, 29,233,117,201,231,221, 50,167,
- 181,103, 54, 22,218, 18,199, 65,112,230,233, 39,219,237,118,101,
- 122,198,236,159, 98,225,224,252,254,203,139, 13, 87,150, 8, 41,
- 30, 54,159,127, 34, 61,236,248,127,255,187, 63,252,233,179, 23,
- 132, 16, 30, 9,201, 44,172,101,165, 77, 20,171, 32,136, 58,221,
- 96,167,211,127,184,221,223,217, 9,186,189, 40, 8,162, 40, 82,
- 74,233, 34, 68, 22,254,130,188,102,165, 11,230,121,126,189, 86,
- 111,181,110, 71,193,142, 81,107, 11,139, 79,173,174,197, 65, 16,
- 236,116,226, 94,223,102,173,125, 33,165, 95,171,213,154,205, 77,
- 214,247,163, 96,109,113,233,209,165, 51,190,181,193, 78, 39,234,
- 246,140,214,185, 16,165,239,213, 26,205,192, 19, 15, 84, 36,125,
- 239,177,229,149,229, 90, 61,236,116,131,157, 78,162,185,228,157,
- 41, 60, 89,107, 52,108,163,182,161,227, 29, 21, 63,190,178,122,
- 113, 97, 41,234,245,251, 59, 59, 42, 8,243, 63,166,210,243,252,
- 90,173,222,106,221,142,251, 59, 70,175, 45, 44, 94, 93, 61, 23,
- 7, 65,176,179, 19, 57,187, 7,166,171, 48,145,157,186,232,101,
- 199, 25,125, 41, 61, 33,124,233,249, 66,120,153, 88, 44,179,102,
- 171,172,141,172, 9,141, 9,141, 9,173, 14,141,137,172,105,253,
- 204,231,190,244,179, 47,215,106, 53,223,247,125, 63,253,127, 54,
- 229, 69, 58, 67,172, 39,179,127,210, 89,100,221, 89, 43, 6,166,
- 220, 73,218, 32,110,248,234,247,123,173, 72, 25, 99,124,145, 78,
- 77,200,198,218, 88,153, 40, 54, 97,164,195, 72, 39, 51,225,132,
- 81, 50, 25,180,209, 38, 63,191, 0,242,154,209,138,192, 90, 29,
- 43, 34,122,180,209,184,220, 94, 36, 33,186, 27,155, 42, 8,117,
- 28,187,118, 72, 38,113, 35,162,213, 70,253,252,210,170,144,210,
- 236,116,194, 40,210, 81,156,203, 43, 9,241, 86, 27, 77, 81,171,
- 209,120,170,181, 40, 61,143,195,184,187,221, 85, 81,228,102, 37,
- 38,174, 62, 35,195, 0, 0, 32, 0, 73, 68, 65, 84, 38,107,117,
- 28,251, 68,143, 54, 26,151,154, 11,100,168,243, 96, 83,133,161,
- 86,202,173, 4,172,177,154,146,221,107, 94,110,215, 72,136,206,
- 198, 70,242, 6,131,188,166, 94, 75,138,236, 76,239,100,230, 10,
- 98,178,130, 4,145, 37, 50,108,133,240, 44, 91, 75, 50, 27,126,
- 90,204, 60,150, 86,145, 73,168, 34, 18, 68, 59,111,191,219,253,
- 244,167, 22,151,150,242, 37,117,138, 97,104,162,136,122,121, 36,
- 147, 76,204,146,178, 19, 54,147,193,105, 34,249, 82,236,157, 59,
- 126,149,249,205, 55,223,124,116, 97,137,141, 97, 33,153,217, 26,
- 75,218,216, 56, 54,113,164,163, 72, 71,145, 10, 28,121, 37,171,
- 162, 57, 29,123,136,107, 22,223,133,204,108, 76, 28, 88, 21,197,
- 201,225,188,228,136,209,224,150,214, 90, 27, 69, 90, 41, 33,250,
- 66,136,100, 9,173,193,223, 41, 51, 39,163,252,226, 32, 72,122,
- 94,156,117,112, 43,155, 37, 51,142,168, 48, 20,178, 24,192, 61,
- 68,176,198,196,198,170,120,159,221, 3, 83, 84, 88,113,214, 36,
- 177,205, 78,182,182,214, 90, 41, 13, 89, 33,146, 65,244,249,218,
- 222,148,205,146, 35,164, 72,207,162, 16,247, 55,223,123,239,189,
- 107,207, 61,231,188,161,156,117,116,139, 10,178,152,120,145,136,
- 165,180,204,210, 45, 90, 43,227, 88,253,108,166, 83,178,204,239,
- 189,245,214,139, 75,171,172, 13, 11,203, 76,100, 12, 39,107,106,
- 36,147,217,135, 81, 50,147,189,206,103,124,182, 54,159, 8,199,
- 61, 4, 11,102,209, 99,150,205, 8, 94, 72, 15,134,143,166,197,
- 145, 54, 75, 78,251, 31,211,238,129, 41,137, 44,201, 97,204, 44,
- 88,144, 77, 38,174, 32,178,204,146,132, 77,198,239,151,187, 87,
- 233,140,209, 89,175,140,251,193,141,183,222,126,234,234, 85, 87,
- 16,197,242,228,130,132, 32, 35,132, 48,133,201,152,137, 89, 50,
- 115,169,225, 85, 12,202,103, 34, 81,228,175, 48, 8, 90,177,177,
- 218, 72,201,150, 4, 49, 11, 99, 88,105,171,148, 73,150,219,200,
- 102,127, 54, 74, 39, 3,236, 43,167, 7, 65, 94, 0,156,200, 8,
- 86,104, 76, 16, 23, 99, 92,133, 37,182,130, 5,145, 76,227, 87,
- 113,114, 82,218, 50,163,108, 97, 73, 18,225, 7,119,251,189,158,
- 88,204, 58,246,238,146,145,105,209,153,152,204, 80,102,192,228,
- 4, 76, 34, 33, 68,126, 84,176, 52,126,199,207, 42, 81,254,224,
- 131, 15,150,125,159, 77, 22,169, 44,179, 49,156, 44,215,152, 68,
- 48, 85, 76,253, 92,156,222,152,141,209,192,152, 9, 0, 78, 65,
- 21, 89,138, 96,146, 68, 30,193,178,179,237, 83, 15, 8, 55, 97,
- 37,183,220,233,222,191,127,191,209,104, 8,167,192, 44, 45,206,
- 43,132,169, 76,150,111,147, 42, 50, 31, 97,150,252, 87, 68, 48,
- 63,139,239,244,238,187,239, 94,246,235,108, 12, 91,145,204, 81,
- 72,218,176,214, 54, 89,155, 67,101, 10, 43,102,197,169,154, 11,
- 2, 3,224, 68,167,176,116, 90,155, 44,130,165,218,226,100,134,
- 196,116,213,219, 66, 4, 69,253,152,124,187,221,185,115,231,206,
- 35,143, 60,146, 23,153, 84,158, 24, 63,185, 96,203, 10, 75,207,
- 202,100, 73,201,212,215,229, 8,230,115,218,244,176, 59,119,239,
- 25,191, 37,165,180, 66, 8, 38, 97, 44,165,245,163,182, 74, 89,
- 149,230,175,116,204,218, 96,233, 8, 0, 56,233, 22, 75,211, 78,
- 110,177,116,250, 73, 33, 69, 90,231, 57,155, 59, 3,184, 50,187,
- 109,221,254, 32,254,200, 71, 74, 11,238,138,116,180,126,178,244,
- 154, 16, 82, 72, 43,140, 21,233, 37, 43,178, 53, 40, 69, 62, 72,
- 150,178,163,145, 68,126,178, 83, 81, 20,214, 99,109,133, 73,211,
- 32,179,180,150,180,177, 90, 25,165,141, 54,201,130,216,233,114,
- 103,197,128,219,188,103, 15,149, 1,112, 58, 34,152, 51, 41, 23,
- 23,115, 87, 8,206, 38, 12, 41, 90, 96,197,188,132,169,217,212,
- 230,195, 48, 8,220,133,213,146,149,144,210,139, 82,202,124,197,
- 34, 43,172,176, 66,138,100, 46,178,124, 18,223,172, 17,150, 30,
- 136,244,147,129,249, 59, 59, 59,181,164,225,101,217, 10, 18, 54,
- 173, 31,109,178,172,172,214,214,232,114,229,232,156,228,200, 40,
- 30, 1, 56, 53, 17,140,137, 69,222, 59, 18,201, 92,227,110, 9,
- 57,128,115, 0, 32,138,186,221,110,189, 94,151,114,112,149,112,
- 45,117,234, 48, 35,165,176, 54, 49,152, 16,130, 57,139, 96,194,
- 105,132, 9,230,236,248, 35,111,111,111, 55,153,172,214, 86, 74,
- 73,194,218, 60,127, 25, 78, 44,150, 45, 52,203,214,157,163, 7,
- 226, 2,224,180, 69,176,172,207,149, 76,202, 75, 34, 85, 75, 50,
- 45,229,192,108,247,238,205, 57,136,186,221,238,242,242,114,186,
- 72,119, 58,208, 94,107,153, 99,146,175, 54, 41, 30,237, 64, 21,
- 41, 68,145,240,152,252, 36, 4,110,111,111, 11,107,153, 12,219,
- 108,135,146, 56,102,138,245,177,173,201, 7,124,237, 54,155, 5,
- 0,224,180,120,204,169, 31,211,238, 23, 21,163, 28,134,247,148,
- 216,152, 94,175,103,180,214, 89,240,210,217,127, 58, 79, 97,158,
- 148, 86, 74,107,172,149,210, 10, 43,109, 54,143,117, 81, 69,230,
- 231,101,250,137, 75,123,221,110, 75, 91, 43,201, 74,182, 36, 4,
- 179,181, 76, 73,224, 74,102,209,201, 87,156,117, 98, 23, 38, 38,
- 4,224, 52,218,139,243,229,139, 6,230, 40,101, 26,218, 79, 74,
- 167,169, 14,163, 32, 8,180, 49, 66,235,188,112,212, 73,234, 50,
- 198, 24, 35,165,244,140,177, 73, 12,179,198, 90, 41,172,149, 66,
- 90, 81,116,193,210,168, 71,130, 4,167,227,239,149, 82,117,163,
- 211, 69, 66,146, 54,156,205,230,255,178, 38, 89,109,155, 77,113,
- 98, 7, 15,238, 27, 0,224,116, 68, 47,166,124,184,106,178,188,
- 119,238, 52,225,142,165, 42, 47,166,155,126, 81, 74, 25,173,147,
- 243,179,141, 54, 58,215,151,244,140, 52, 82, 74, 99,140,148,158,
- 148,214, 74,107,173,149, 86,102, 17, 44, 31, 75,145, 87,145,194,
- 15,131,208, 24, 19,132,161,191,211, 37,207, 99, 41, 89, 72,203,
- 36,172, 37, 99,141,214, 42,138, 84, 24,170, 40, 82,177, 50,198,
- 36, 19, 99,179, 59,103, 54, 97, 81, 71, 0, 78,143,194, 4, 9,
- 182,156, 24,196, 18, 9,178,146,132, 37, 41,211,249,194,152,117,
- 54,223, 97, 50, 45,141,205,230,212, 55,204,183,127,242,214,135,
- 158,125, 86, 74, 45,141,212, 82, 75,147, 4,175,100, 86,124,233,
- 25,207, 24,227,121,198,218, 76, 96,108,165, 77, 86,242,206,102,
- 23, 44,202, 85,146, 16, 15, 0, 96,146,100,190,210,102, 24,214,
- 38,157,246,124,105, 15,107,243, 73, 18, 75, 75,154, 49, 49, 29,
- 98,126,113,232, 14, 0,112,120, 15,232, 76, 84,195,236,149,253,
- 196, 49, 24,103,255, 12, 42,204,159,254,179, 1, 0,204, 15, 71,
- 95,146,192, 24, 99, 60, 79, 26,227, 73, 89,137, 94, 38, 29,234,
- 96,173,177,214, 75, 87, 86,179,108, 37,203,228,107, 62,248, 33,
- 169, 32,177,190, 11, 0, 96,162,228,227,177,202, 17,204,154,252,
- 202, 84, 96,121, 4,115,167,197, 39,119,153,141,195,251, 11,129,
- 11, 0,112, 24,127,229, 20,101,162, 77,150, 4, 49,214, 21, 87,
- 190,184,109, 33, 48,114,231,189, 25, 99,253,184,135,227,138,200,
- 135, 95, 29, 0, 51, 94, 24,102, 83,204,139,177, 74,160,116, 13,
- 115,197, 90, 89,227, 62,187,170,176, 23, 39, 11,170, 89,206,142,
- 64, 82, 62,221,179,115,254,208,120, 35,151,187,126, 47, 51, 91,
- 34,194, 57,146, 0,204,188,188,146, 57, 3,179,213, 58, 74,179,
- 223,140, 57,127, 21, 10, 51,214,122,133,182, 76, 41,146,113, 58,
- 108,190,188,168, 26,165,249, 75,112, 58,127, 14,149,150, 92, 43,
- 205, 49,125, 96,231, 48, 81, 50,208, 67,179, 53,201, 72,144,116,
- 9, 57, 0,192, 76, 43, 44, 89,128,182, 70,194, 23,194, 23,210,
- 203,102,175, 31,115, 89, 86, 10, 96, 92,201, 93,249,144,137,108,
- 101, 5,206,214,180, 45, 41, 44,249,215,207,229,149, 72,199, 79,
- 43,203,253,246,121, 23, 27, 37,139,190,105,203, 49,155,136,109,
- 192, 28, 18, 43, 98,131,119, 7, 0, 51, 47, 48, 65,228,179,168,
- 147,104,145,108, 17, 55, 73,214, 73,202,100,125,142,113,231, 47,
- 78, 7,184, 22, 2,227,106,223, 43, 95,145,187,218,187,207, 91,
- 96, 62,101,211,244,252,248,238,237,165, 70,243,234,218,121, 95,
- 212,188, 67, 41,215, 18, 27,203,138,109, 96, 77,151,109,135,108,
- 143,108,223,218,190,142, 35,165,176, 64, 17, 0,115, 16,193,132,
- 88,240,235,171,245,198,178,231, 47,177,183, 36,185, 65,146,132,
- 28,163,194,210,252,149,228,171,226, 2, 59,253,250,108,212,106,
- 222,253, 42,250,247,228,158,115,233, 39,123,237,121,222,139, 79,
- 61, 29, 71,209,255,247,222, 59, 31,191,244,196, 90,171,125,192,
- 154,145,153,200, 48,199,108, 3,107,182,217,108,145,125,104,212,
- 253,238,206,189,157,109,188, 45, 0,152, 59, 46, 47,175, 60,187,
- 124,150, 69,125,153, 68,147, 88,236, 82, 72, 30, 34,146,228,139,
- 233,101,181, 97, 58,200, 43, 13, 92,153,171, 42,227, 38,184,114,
- 0,146,136,136,100,190, 20,136,244,188,165,197,197,207, 62,115,
- 237,221,205, 7, 94,189,126,208,178,215, 50,107,203,161, 53, 15,
- 217,108,144,189, 27, 7, 63,190,123, 27,242, 2, 96, 78,185,185,
- 243,240,149, 15,222,187, 21,246,250,108,227,221,103,245, 58,100,
- 254,114,200,131, 88,170,178,162,109,239,110, 66, 78,221,152,223,
- 73, 54,254,203, 90,171,162, 72,133,145, 71,226, 76,171,189, 19,
- 71, 94,163, 62,226,193,135,164,147,150,132,175, 46,217,109,178,
- 247,194,254,219,247,238,104, 44,231, 7,192, 60,163,172,253,214,
- 221,155,239,245,119, 20,179, 41, 4,198,123,202,224,128, 6,203,
- 60,229,246,186, 6,114, 87, 46,175,116, 41,202,252,252, 33,153,
- 11, 40,189, 35,226,229,122, 67, 25, 45,253,154,244, 61,177,255,
- 40, 16, 38, 78, 14, 56,218,144,237, 14,217, 45,163,222,185,127,
- 23,191,123, 0, 78, 6,223, 90,191,253, 80, 69, 78, 24, 57,234,
- 1, 73,102,215, 97, 84, 57,186,104,135, 92,202,167,186, 41,214,
- 59, 75,238,196, 47,221,105,186,168, 7,179,177, 66, 10, 33, 37,
- 141, 80,242, 38,119,170,136,251,100, 67, 98, 87, 94, 88,162, 8,
- 128,249, 37,111, 34,253,233,221, 27,127,239,137,107,201, 85, 71,
- 175, 35,243, 6, 86,222,207, 34, 30, 38, 48, 71,113,101,125,229,
- 67, 40,200, 31, 22,167, 92,239,136, 81,130, 34, 51, 25,230,136,
- 248, 65,208, 15,148,202,175,255,111,254,219,223,192,155, 0,128,
- 57,229,255,248,183,255, 38,185,208,209,241, 91,157,135, 47,172,
- 156, 99,107,199, 50, 48,127,160, 29,191, 23,228, 12,188,119, 87,
- 202,102, 30,223,249,219,134,200, 16,109,245,187,248,173, 3,112,
- 242,184, 30,246,252,122,221,243,253,253,234,177,145,228, 85,186,
- 92, 17, 25,185,230,202,100, 71,217, 90,103,217, 63,201,247, 99,
- 243, 87,114,135, 91, 65, 31,191,105, 0, 78, 30, 55,123, 59,245,
- 86, 83,214,252, 97, 53,217,193,207,210, 41,157, 13,148,213,124,
- 89,159,158,202, 35, 85,211,172,149,231,175,172,103, 69, 52,190,
- 252, 37,136, 36,145,194, 49, 71, 0, 78, 34,161,209, 94,173,230,
- 121,222, 56,206, 39,114,231,197,207,207,150,166,114, 49,153,127,
- 239,230,175,234,173,229, 88,246,161,112, 24, 0,224,132, 34,199,
- 116, 42,145,123,252, 49, 43, 10,211,132,149,127,235,172, 35,233,
- 230,175,124,201,141,244, 58,204, 95, 8, 0, 24,177,200, 18, 36,
- 199, 52, 39, 69, 49,141,170,155,191,138,111, 41,147, 85,166,181,
- 114,106,226,163,231, 47, 0,192, 41,134,143,176, 49,151, 47, 23,
- 51,122, 21,249,139,156,252, 85,174, 31,115,225,141,216,191,199,
- 32, 46, 0,192,152,237,150,159,198,232,204,104, 95,228,175,202,
- 189,184,103,110, 31,186,255, 5,145, 1, 0,142,170, 7,174,244,
- 226,121,200, 72,119,103,168,132,187,100,135,243, 32, 99, 61,254,
- 8, 0, 0, 7,151,222, 80,113, 21,134,202,199,122, 13,249, 57,
- 252, 5, 0,152,116,252,218,237,218, 98, 97, 90,230,161, 61,178,
- 129,219,202,169, 60, 1, 0, 0, 98, 87,217, 28,124,136, 25, 78,
- 145,191, 0, 0,199,144, 94, 14, 21,199,170,147,244, 48, 13,255,
- 22,254, 2, 0,204,180, 15,247,200, 99, 24,255, 5, 0, 24,107,
- 226, 26,255, 77,121, 88, 50, 67,254, 2, 0,204,150, 7,249, 80,
- 150,147,163, 63, 0, 0, 0,236,235, 9, 62,228,237,118,253,158,
- 119,223, 82, 30,249,177, 0, 0,167,202, 82, 7, 80,192,168,135,
- 20,249,144, 63, 66,253, 8, 0, 24,123,124, 25,126, 80,113,236,
- 15, 10,127, 1, 0,166, 46,195, 67, 26, 14,254, 2, 0, 76, 51,
- 170, 29, 5,248, 11, 0, 48,175, 28,216, 95,104,223, 3, 0,102,
- 36,162, 73, 40, 10, 0, 48,187, 37, 34,234, 71, 0,192, 73,210,
- 22,252, 5, 0,152,123, 70,247, 23,170, 74, 0,192,108,229, 52,
- 57,243,123, 8, 0, 0,168, 31, 1, 0,240, 23, 0, 0,192, 95,
- 0,128,211,194,113,244,154,228,108,238, 22, 0, 96,222,221, 52,
- 1, 51,200,202,227, 57, 11,128,192, 75, 0,128,185,169, 31, 75,
- 11, 74,138, 81,108,123,244,243,199, 1, 0, 39,168, 24,228,201,
- 22,105,178,188,128, 55, 51,115, 47,142,132,148,194,243,246,118,
- 24, 0, 0,204, 68,254, 98,182,198,178,101,102,162, 7,221,206,
- 165, 71, 31, 21,158, 71,101,129, 33, 97, 1, 0,102,206, 95,204,
- 204,150,147,142,215,223,220,124,255,201,199, 30,175, 53,155,100,
- 45, 91,139, 23, 8, 0, 48,179,248, 68, 68, 36,132, 16,111,222,
- 189, 45,132,120,254,234,213,167,159,120,146,163,216,104,205,214,
- 50,241, 40,211, 93, 35,154, 1, 0,166,227, 47, 33,200,243,188,
- 151,158,251,240,153,179,171,205,102,211, 42,173,131,208, 42,197,
- 204, 48, 19, 0, 96,118,253, 37,136, 4, 9, 33, 37,179, 85, 65,
- 72,177, 18, 74,115, 20,179,214,100, 45, 97, 20, 5, 0, 96,182,
- 235, 71,178,214,170, 32, 12,180, 49,210,247,137,132,177,194, 88,
- 184, 11, 0, 48,235,254,226,180,133,111,173, 54, 70,178, 32,225,
- 113,178,202, 27, 4, 6, 0,152,249,252, 69,217,224, 47,178,123,
- 15, 93,133,209, 0, 0,179,194,168,231, 63,242, 48,125, 65,102,
- 0,128,195, 27,100,236,254,130,146, 0, 0,135,246,211,140,230,
- 47, 0, 0,152,215,250, 17, 0, 0, 78,136,191, 80,102, 2, 0,
- 144,191, 0, 0, 0,254, 2, 0, 28, 59,179, 85,122,201,121,220,
- 105, 0, 0, 64,254, 2, 0,156, 28,127, 49,114, 23, 0, 0,249,
- 11, 0,112, 74,153, 88,238,129,191, 0, 0, 39, 44,127, 29,216,
- 159, 40, 52, 1, 64,210,162, 9,207, 24,136,252, 5, 0,152,215,
- 168, 34,231,253, 9, 0, 0, 80, 63,194, 76, 0,128,185,246, 23,
- 210, 22, 0, 96,126, 74, 76,244,191, 0, 0, 51, 43,168,113,249,
- 11, 49, 12, 0, 48, 99, 82,144, 39,227,105, 0, 0, 78, 33,168,
- 31, 1, 0,167,214, 95,200, 94, 0,128,185,243, 23,196, 5, 0,
- 152,174, 9, 80, 63, 2, 0, 78,109,253,136, 36, 6, 0,152,146,
- 40,144,191, 0, 0,227,150,210,164, 50, 13,252, 5, 0, 56,205,
- 245, 35, 0, 0,169,107, 98, 69, 35,252, 5, 0,152,188,204,224,
- 47, 0,192,188,168,234,216,205, 38,103,107,119, 0, 0, 39,211,
- 122,199, 34, 15,121,200,157, 1, 0,128,105,115, 32,127,193, 92,
- 0,128,153,247, 23,143,228, 45,232, 12, 0, 48, 55,249, 11, 0,
- 0,118, 79, 47, 19,143, 52,242, 24,158, 4, 0,224, 52,137,140,
- 247, 42,218,142,213, 17, 18,110, 2, 0,140, 51,149, 77,208, 28,
- 168, 31, 1, 0,135,169,182,120, 6, 34, 15,252, 5, 0, 56, 70,
- 205, 77,218, 95,140,130, 18, 0, 48, 15, 32,127, 1, 0, 78,142,
- 191, 70, 27,251,133, 84, 6, 0,152, 29,127,241, 81,189, 4,145,
- 1, 0, 80, 63, 2, 0, 0,252, 5, 0, 24, 31, 51, 87, 99,201,
- 185,127, 6, 0,128,169,123,109, 74, 94,144,135, 85, 21, 60, 6,
- 0,152,178, 19, 80, 63, 2, 0,230, 21,248, 11, 0, 0,127, 1,
- 0, 0,252, 5, 0,152, 11,120,191,150,215,113,183,196,224, 47,
- 0,192, 97,220,133,252, 5, 0,128,213,142,201, 95, 60,123,190,
- 5, 0, 32,140, 13,245, 23,214,233, 0, 0,204, 71,233,136,250,
- 17, 0, 48,215, 28,213, 95,200,102, 0,128,121,243, 23,188, 5,
- 0,152,182, 40,228, 12,238, 19, 0,224, 4,120,107, 2,158, 64,
- 255, 11, 0,112,210,234, 71, 68, 44, 0,192,188,250, 11,213, 36,
- 0, 96,214, 63,245,114,196, 61,101,104, 10, 0,112, 88,197, 29,
- 147, 62,208,255, 2, 0,204,107, 36,131,191, 0, 0,243, 10,252,
- 5, 0,128,191, 0, 0, 40, 20, 39, 91, 98, 74,154,157,125, 1,
- 0,128,177,248,107, 20, 59,193, 96, 0,128,249,171, 31, 43,230,
- 98,152, 12, 0, 48, 7,254,130,170, 0, 0,179, 33, 10,121,168,
- 93,129,195, 0, 0,211, 87, 26,142, 63, 2, 0,230, 49,123,193,
- 95, 0,128,121, 70,238,237, 76,158,154, 88, 1, 0,224, 72,249,
- 11,182, 2, 0,204,171,191, 96, 53, 0,192, 17, 57, 70, 97,160,
- 255, 5, 0,152,148,151,198,173, 50,185,207,131, 32,107, 1, 0,
- 102,181, 42, 67,254, 2, 0,204, 43,251,251, 11, 9, 12, 0, 48,
- 175,254,154,233,248, 8, 0,128,191,160, 33, 0,192,220, 37, 21,
- 244,191, 0, 0, 39,188,126, 68, 44, 3, 0,204,156, 12,228, 9,
- 125, 94, 0,128,147,175, 55, 57, 31,187, 9, 0, 64,242, 58,162,
- 191,224, 44, 0,192,236,248, 66,206,218, 14, 1, 0,224,168, 99,
- 175, 31, 1, 0,128,166, 58,203, 22,252, 5, 0,152, 87,142,230,
- 47,148,147, 0,160, 92,156, 45,127,193, 74, 0,128,113,155,237,
- 56,188, 34,199,178,103, 0, 0, 88,139, 39,174, 15,121, 60, 79,
- 4, 0, 0,166, 82, 63, 2, 0,192, 60, 36, 25,248, 11, 0,112,
- 220, 22, 59, 46,167,193, 95, 0, 0,212,143, 0, 0, 84,135,147,
- 237,131,195, 95, 0,128,227,113, 25,252, 5, 0,152,109, 99, 77,
- 211, 98,240, 23, 0, 96, 62,211,215,110,254,226, 3,239, 52, 70,
- 127, 1, 0,102, 58,127,241, 46,170,130,188, 0, 0,168, 31, 1,
- 0, 0,254, 2, 0,204, 10,199, 86,161,201, 81, 31, 9, 53, 34,
- 0, 96, 90,162, 66,254, 2, 0,156, 48,129,201,153,221, 51, 0,
- 0,140, 54,186,191, 32, 40, 0,192, 24,165,116,236, 74,145, 71,
- 120,112,248, 14, 0,176,191, 11,142,207, 20, 18, 90, 2, 0, 28,
- 78, 82, 83,119, 5,250,247, 0,128,227, 83,221,241, 42, 78, 34,
- 123, 1, 0,230,148, 35,230, 47,248, 14, 0,128,250, 17, 0,112,
- 82,138, 70,248, 11, 0, 0,165, 29,206, 95,168, 11, 1, 0, 7,
- 181,210,196,189, 33,247,219, 73,134,208, 0, 0,123,122,106,106,
- 122, 56,106,253,200, 60, 19, 79, 3, 0,112,218,138,199,163,248,
- 139,225, 44, 0,192,116, 65,255, 30, 0, 48,111,185,235, 48,254,
- 66,210, 2, 0,204,146, 12,144,191, 0, 0,243, 42,179, 49,248,
- 139,145,203, 0, 0,211,245, 23, 44, 4, 0,152,175, 74, 82,206,
- 250, 14, 2, 0,192,120,235, 71, 40, 13, 0, 48,117, 63,200,185,
- 216, 75, 0, 0, 12, 54,102,127, 1, 0, 96,168,249,171, 31, 1,
- 0,208,215,212,109, 38, 71,182, 43,138, 69, 0,192,108, 33, 15,
- 161, 40,152, 12, 0, 48,155,245, 35, 38,148, 0, 0,140,189,194,
- 156,108,253, 56,115,123, 10, 0, 0,199,225, 47, 0, 0, 34,213,
- 228, 51,142,220,247, 49,144,173, 0, 0,200, 95, 0, 0, 48, 25,
- 127, 33,119, 1, 0,102,161,246, 28, 87,254,130,211, 0, 0,179,
- 99, 4,121,168,253,133,199, 0, 0,211, 23,158, 68,210, 2, 0,
- 204, 41,232,223, 3, 0, 78,149,191,152,136,145,208, 0, 0, 83,
- 174,217,144,191, 0, 0,135,215, 20, 59, 77,241,201, 27, 76,142,
- 79,168, 8,100, 0,156,218,160, 53,157,143, 63,242, 23, 0, 96,
- 94,139, 75, 57,197,199, 6, 0, 64, 85,199,236, 47,216, 11, 0,
- 48,147,160,126, 4, 0,156, 76,127, 33,122, 1, 0,102,182,124,
- 60, 68,254,130,211, 0, 0,179,225, 9, 57, 75, 59, 3, 0, 0,
- 71,240, 23, 68, 5, 0,152,151, 24, 38, 15,186, 19, 16, 28, 0,
- 96, 70,202, 53, 57, 15, 59, 9, 0, 56, 45,166, 99, 62,128,102,
- 48,126, 2, 0, 48, 99, 33,140, 71, 93,138, 3,254, 2, 0, 76,
- 208, 90,214, 10,107,247,220, 62, 61, 19,156,247,200,104,217, 87,
- 57,206, 61, 3, 0, 64, 85,123,210,221,220,218,185,183,110,226,
- 184, 90, 40, 14,150,142, 67, 31,138, 75, 9, 77, 78,247,201, 0,
- 0, 78, 21, 70,233,173, 15,238, 60,184,123,143, 43,206,170, 76,
- 77,191, 71, 1,201,168, 31, 1, 0, 83, 66,133, 81,208,237,106,
- 165, 6,211, 23, 87, 4,198,187, 6, 48,248, 11, 0, 48,133, 66,
- 147,217, 90, 99,114,127,241,176, 57, 17,147,237,216, 17, 88, 69,
- 97,188,187,191, 80, 11, 2, 0,142,160,168,125,183, 31, 24, 37,
- 193,238,143,216,153,214,149,147, 18,147,243,105,235,157, 76,198,
- 200, 95, 0,128,169,186,142, 51, 41, 49, 15,241,217,158, 51, 84,
- 203,131, 62, 22, 0, 0,238, 57,186, 32,152,136,221, 24,198,204,
- 165, 92,150,100, 45,222,251, 97,228,193,172, 5,157, 1, 0,198,
- 105, 68,174,120,133, 19,136,220,194, 49,181, 27, 85, 15, 83, 30,
- 168,126,100,196, 52, 0,192,120, 62,245,236, 4,175, 36,119,113,
- 169, 13,150,133, 48,206, 47, 19, 23, 87,237,239, 47, 72, 9, 0,
- 112,108,138,168,180,240,139,241, 19,204,133,216,156, 77,185, 52,
- 198,226,176,227, 87,161, 53, 0,192,193,229, 48,112, 86, 99, 86,
- 41,150, 58,243, 89, 31, 44, 43, 30,147,139,149,250, 49,147,153,
- 28,199,126, 1, 0,224,172, 67,222, 44,209, 83,214,247, 26,158,
- 191,168,168, 46,243,240,133,241, 19, 0,128, 25, 83, 96,145,191,
- 56,207, 95,249,113,201, 92,111, 35,244,191, 0, 0,224,184,170,
- 50, 46, 37,174,226, 59, 38,231,248, 99,145,185,242,248,229, 22,
- 155,240, 23, 0, 96,170,146, 99, 87, 81, 89,205,152, 23,149,213,
- 1, 21,165, 83, 34,229,100,247, 20, 0, 0, 40, 23, 22,231,195,
- 86,179, 14,189,147,196,200, 29,209,202,121,242, 98,206, 7, 81,
- 32,127, 1, 0,142, 39,196,240,104,219, 22,199, 22,179, 33,171,
- 78, 81, 73,229,102, 88,105,152,197,208,254, 61, 82, 20, 0,224,
- 232,101, 22,143, 82, 54,114, 81, 45,150, 2, 87,222,183,119, 11,
- 202,242, 16,138, 49,212,143,144, 29, 0, 48,216,225,182,100, 71,
- 97, 92,118,150,107, 43,167,161, 79,149, 30, 62,234, 71, 0,192,
- 180, 11,205,226, 20, 34,119,198, 47,118,126,144,119,249,157, 67,
- 147, 71,245, 23, 35,132, 1,128,216,117,120, 15,184, 67,240,221,
- 163,141, 69,225,200,249, 68, 21,204, 85,235, 29,201, 95,124,196,
- 93, 7, 0,204,169,196,248,232, 38, 99,118,143, 45, 14, 76,105,
- 152, 70,176,242,144,251,242,232,175, 67,143,191,135,174, 0, 0,
- 7,242, 4,239,187,101,249, 68, 34,103,192,106,218, 23,203, 92,
- 135,254, 23, 0, 96,122,133, 39, 87,199, 70, 12,157, 98,149, 43,
- 167, 64,186,163, 87,247,152,255, 30, 89, 12, 0,112,140, 31,122,
- 75,236,249, 62, 13,214,143,206,192, 47,103, 10,252,234, 50, 68,
- 121, 65,233, 31,101,223, 97, 46, 0,192,129,229, 37, 37,147,240,
- 107, 53, 30,168, 31,157, 62, 24,231,229, 36,149,230,211, 57,220,
- 248, 47, 70,246, 2, 0, 28,197, 3, 76, 68, 36,132,105,212,151,
- 207,174,142,120, 23, 3, 43, 63,150, 78,129, 68,255, 11, 0, 48,
- 57,180, 39,253,133,246,218,185,115,153,131,156,163,144, 78, 14,
- 43, 29,105,220,101,137,110, 66,255, 30, 0, 48, 73, 22,151,151,
- 159,188,122, 85,122, 94, 85, 73,110,217, 72, 84,140,100,101, 26,
- 178,138,109,214, 0,147,251, 5,190, 17, 98, 29, 0, 0,149,226,
- 94, 55, 40,110, 86,171,213,242,228,229,108,197,213,107, 10,151,
- 85, 87,246,112, 55,144, 7,218, 79, 72, 11, 0,112,172,122,228,
- 189,162, 84,181, 27, 38, 71,185, 71, 0, 0,152, 65, 23,200,221,
- 247, 18,226, 2, 0,204,180,233,208,191, 7, 0,140, 93, 91, 99,
- 23,152, 32, 65, 68, 98,119,127, 29,117, 25, 36, 0,192,169,118,
- 215,193, 92, 32, 68,245,178, 16,162,170,168,244, 10, 33, 6,212,
- 37,136, 72,200,209,118, 12, 0, 0,142, 43,225, 8,114,178, 85,
- 234, 53,145, 74,203, 53, 87,126, 57,187, 1,234, 71, 0,192,100,
- 41, 5, 47, 33,210,240,149, 5,173, 68, 93,130,138, 44, 38, 92,
- 107,149,130,216,232,254,226, 61, 60,138,132, 6, 0, 2,214,161,
- 74,199, 65,167,149, 5, 55,100,195, 60,169, 33,127, 1, 0,198,
- 171,179,145,125, 54,208,210, 18,165,122, 81, 8,202, 26, 98, 34,
- 41, 39, 7,110,115,120,127, 33,115, 1, 0, 14,233,129,164,104,
- 204, 11, 67,145,235, 73,164,174, 18, 37,117,185,213,165,219, 17,
- 147,199,184,139, 0, 0,176, 91,236, 74, 13,150,246,191, 74, 71,
- 30, 69,185,210, 20, 67, 74,199, 68, 98,168, 31, 1, 0,179,145,
- 204,146,204,149,143,165, 72,123,248,162, 20,208,168,100, 59,121,
- 192, 71, 67, 20, 3, 0, 28, 77, 5, 66, 84,142, 36, 38,122, 18,
- 110, 40, 75, 55, 40,140,230, 30,164,204,111,135,252, 5, 0,152,
- 140,183, 74, 53,100, 81, 61,230,122,114,242,151, 40,231,175, 36,
- 113,137,178,190,170,227,191, 24,241, 10, 0, 48, 9,165,137,234,
- 248,251,114,254, 42,174,205, 75, 73,167,109,150, 15,108, 69,254,
- 2, 0, 76,212,105, 98,160,142, 20,229,252,149,199, 50, 81,202,
- 95,121,215, 94,228,135, 32,229, 65, 45,202,149, 45,121,220,193,
- 18, 0,112,130,107, 72, 81, 58,207, 49, 27, 40, 81,228, 47,225,
- 6,180,180, 49,150,253,143,156,250, 81, 84,253, 5, 0, 0,199,
- 107, 54, 81, 36,169,210,120,137,188,233, 69,194,233,125, 81,254,
- 95,233, 86, 89,252, 58, 72,255, 30,241, 10, 0, 48,220, 11,135,
- 178, 67,169, 80, 44,138, 73,119,252, 68,169,144,204, 15, 74,230,
- 213,166,132,165, 0, 0,147,211,157,210, 30, 17, 49,139, 74, 77,
- 89, 20,147, 84,252, 47,111,119, 21,195,243, 75,179, 85,200,177,
- 101, 45,136, 15, 0, 20,142,251,209,221,218,218,124,255,134,142,
- 162,162,126,116, 38,255, 34,183,137, 79,197, 76, 20,162,226, 49,
- 66,255, 11, 0, 48,113,145,177,181,157, 7,155, 27,119,239,209,
- 192,176,213,226,248, 98, 49, 84,162,116, 38,209, 81,230,207, 1,
- 0,128, 49,160,226, 40, 10, 2, 21, 69,228, 28, 75,172,158, 3,
- 233, 76, 0, 54, 48, 45,107,225,181,113,248, 11,149, 35, 0, 8,
- 93, 7,249, 49, 51, 91,107,135,110,155, 87,137,110, 59, 95,148,
- 206,249, 70,254, 2, 0, 76, 47,183, 48, 15,206, 18, 86,204,178,
- 58,100,122, 67,162,210,184,175,108, 83,248, 11, 0, 48, 5, 42,
- 115,228,208,144,217, 9,135,174,217, 81, 2,254, 2, 0, 76, 54,
- 125,141, 15, 57, 79, 59, 11, 0,128,219,246,244, 23, 79,120, 15,
- 0, 0,115, 37, 38, 30,139,181,156,181,110,139,147,170,121,239,
- 187,100,212,143, 0,128,153,148, 35,103,146,218,101, 5, 16,199,
- 158,217,166,114, 79,193, 29,227,114,224, 0, 0, 48,204, 82,156,
- 184, 44,213, 21,179,235, 54, 46,203, 8,249, 11, 0, 48,253,138,
- 148,139,255,101,166,202,190,101,230,114,130,226,124,166, 85,121,
- 248,199, 4, 0,160,228, 59,194,141,153,185,156,175, 82, 49, 57,
- 105,139, 7,165,229, 62,166,132,166, 0, 0,147,201, 89,123, 89,
- 144,217, 41, 24, 57, 29,224,154,248,141,179,186,145, 29,101,242,
- 81,234, 71,184, 13, 0, 48, 62,187, 49, 57,214, 42, 76, 86,241,
- 86,209,255,226, 61,242, 23,195, 80, 0,128,227,118, 86, 6,229,
- 133,164,155,191,146, 43,243,252,149,111, 64, 89,149,201,232,223,
- 3, 0,166, 82,119,241, 46,249, 43,119, 23,229,233,171,232,228,
- 59,149, 36, 13, 25, 63,177,231,195, 48, 42, 71, 0,192, 24, 5,
- 86, 84,140, 92, 50, 83, 58, 12,172,240, 89,186,101, 81, 26,238,
- 223,255,130,170, 0, 0,199,150,207,152,203,227, 35,156,244,149,
- 151,149,121, 51, 44,203, 95, 78, 5,137,241, 95, 0,128,169,248,
- 141,203, 38,115, 7, 82,176, 51,156,130,139,178, 50,223, 52,171,
- 40,209,255, 2, 0, 28,147,166,246, 15, 99,121,208, 42,242, 87,
- 238,177,188, 7, 86, 12,113,205,227, 87,254, 40,242, 0,187,131,
- 170, 18, 0, 48, 54,201, 49,187, 23,135,228,175,210,129,199,180,
- 251, 94, 26, 27,193, 71,205, 95,144, 25, 0,168, 2,199,104,180,
- 161,249,203, 41, 32,217, 61,211, 72, 30,249, 9, 64,100, 0,128,
- 131, 97,139,161,170, 69,253,200, 67,149, 86, 46, 24,185,184,158,
- 9,253,123, 0,192, 68,146,154,139,176, 68,181, 70,195,233,201,
- 115, 49,192,190, 24, 1,230, 28,108,116, 79,140,116,206,138,148,
- 227,219, 39, 0, 0, 74,200,221,174, 46,190,183,190, 71,158, 39,
- 165,228,161,245, 99, 41, 99,185, 18, 27, 50,254, 84,142,229, 25,
- 0, 0,192, 40,158, 96, 41, 85,221, 95, 89, 59,187,215,102,123,
- 217,209, 45, 34, 15,232, 47, 40, 11, 0,112, 20,140, 39, 87, 46,
- 92, 88, 93, 91,203, 35, 23,187, 85, 97,105,214, 9,114,103, 45,
- 36, 26,109,254, 28, 30, 89, 96, 12,185, 1, 0, 14,194,153,149,
- 149, 11, 23, 46, 12,243,138, 83, 54,230, 62, 43,213,147,206,229,
- 236, 6, 99,232,223,195, 91, 0,128, 17, 77, 32,164, 40,123,202,
- 185, 92,157,104,149,157, 51,187,135,246,211,134,143,255,130,145,
- 0, 0, 7, 22,214,120, 22, 38,218,237, 78,134,205,234, 37,247,
- 221, 65,200, 12, 0, 48,155,213, 25,198,127, 1, 0,102,223, 84,
- 163,248, 11, 89, 11, 0, 48, 61, 67, 9, 34,177,219, 79, 4,149,
- 126, 40,144,191, 0, 0,147, 38,115,144,112,101, 36,170,215, 20,
- 54, 19,201, 79,134,121, 77,200,125, 92,139, 68, 6, 0, 24,191,
- 189, 74,223, 10, 87, 94, 66, 20,129, 75, 36,255, 23,165, 16,150,
- 221, 76, 32,127, 1, 0,198, 91,100,238,159,121,202,201, 75, 8,
- 71, 74, 66,228,215, 21,181,164, 24,144, 93,134, 60,210,158, 2,
- 0,160,172, 35,167, 48,218,181,237, 53,208,241,114, 91,100, 98,
- 52,127, 65, 84, 0,128,221,189,192,135, 51,135, 24,200,101, 34,
- 253,146,212,138,217,191,201,149,194, 41, 42,199,145,191,224, 55,
- 0, 32,177, 67,109, 35,132,219,243, 18, 66,184,215, 84,234,199,
- 244, 39,213, 66, 82, 28,201, 95,144, 22, 0,224, 16,228,210,202,
- 84, 85, 26, 25, 81, 42, 24, 69,233,192,163, 24, 56,120,137,254,
- 61, 0, 96, 54,114, 90,154,187,146,255,220,146, 49,189,222,209,
- 222, 81,199,127,241,200, 59, 5, 0, 56, 45, 54, 26,237, 28,110,
- 33, 74,255,119,234,199,114, 66, 43,108,229, 14, 3, 43, 54, 20,
- 242,160, 59, 10, 99, 1, 0,142, 92, 67,102,101,163, 91, 63, 22,
- 201, 43,203, 95,169,173,132,200, 47,149,238,227, 32,249,139,247,
- 250, 17,180, 6, 0,234,192, 67,230, 28,167,127,239,182,187,132,
- 27,204,242,186, 81,100,199, 38,105,108,253, 47,232, 11, 0, 80,
- 81,194,110,171,119,148,235,200, 82,254,114, 19, 24,149,251, 95,
- 197,224, 9,113,136,254, 23, 20, 5, 0, 56,122,229, 72, 36,220,
- 241, 18,194,137, 90,228, 94,147,187,140,242, 77,168,122, 18,247,
- 40,254, 98,232, 11, 0, 48, 62,129,149, 37, 84, 68, 45,167, 41,
- 70,131, 61, 50,145,107, 46, 63, 50,137,241, 19, 0,128, 3, 22,
- 134, 71,140, 95,142,184,114, 69,229, 22, 19,229,250,209, 57, 70,
- 89,154,140, 34,249, 71, 78,243,169, 0, 0, 78,161,238, 68,121,
- 188,132,147,191,168, 84, 46,186, 99,193,178,252, 85, 30,131, 47,
- 15, 40, 39,134,195, 0, 0, 71,214,153, 24,146,191,178,110,151,
- 91, 46,186, 35,238,171, 7, 40, 49,254, 30, 0,112,244, 68,117,
- 196,233, 2, 69,245,160,164, 27,185, 10,203, 81,249,100,110,248,
- 11, 0, 48,105,245, 13, 52,182, 74,165, 34, 21, 51, 24,150,103,
- 93, 21,206, 20,210,217, 88, 48,248, 11, 0, 48, 89,156, 89,113,
- 132,123, 58,163, 40,231, 47, 42,242,151,211, 35,115, 34,155, 24,
- 115,254, 66, 47, 12, 0, 48,220, 6,251, 77, 6,230, 12,140, 24,
- 200, 95,162, 80, 86,214, 1,195,250, 29, 0,128,137,184,107,152,
- 175, 92,113, 21, 93,124, 39,163, 81, 54,249,189, 16,228,134, 52,
- 167,171, 15,127, 1, 0,166, 84, 69,102, 30, 43,159,149,237, 12,
- 254,162, 34,146,149,234,199,236, 6,163,250,171,124, 54, 19,234,
- 68, 0,144,177, 14, 43, 46,103, 98, 85, 49,112,220,177,216,170,
- 152,243,107,215,217,241,145,191, 0, 0, 99,212,215,126,147,209,
- 8, 55,124,229,151, 7,214,127, 28, 50,235,234,144,197,109,225,
- 47, 0,192,100,211,152, 16,131, 82, 27,108,135,229,162, 19,206,
- 156, 19,229, 1,248,229,241, 19, 40, 11, 1, 0, 19, 70,236,178,
- 168,109,105,252,151,168, 46,164,134,249,239, 1, 0, 83,241,213,
- 174,169, 76, 84,214,241, 16,131,183, 17,168, 31, 1, 0,147, 44,
- 26,121, 87,141,137, 93, 22,215, 22,187,155,111,232,252, 95, 40,
- 30, 1, 0, 19,204, 97, 98,255,107,118,141, 95, 2,227, 87, 1,
- 0, 51, 88, 76,138, 33,139,213, 14,187,149,216,219, 95, 72,100,
- 0,128, 99, 44, 43,119,183,154, 24,205,117,200, 95, 0,128,105,
- 9, 76,236, 91, 86,138, 61,111, 47,199,188, 63, 0,128,211,102,
- 166,233,233, 1,249, 11, 0, 48,175,192, 95, 0,128,201, 85,140,
- 240, 23, 0, 0,236,230, 47, 70,187, 11, 0, 48,135,254,226,209,
- 66, 34, 4, 7, 0,152,122, 77, 41,103,115,183, 0, 0, 51, 40,
- 36,158, 49, 29,200,131,237, 62, 92, 6, 0,152,217,250,241,192,
- 118,130,192, 0, 64, 97,184,123, 62, 59, 86, 69,224,248, 35, 0,
- 224,232,101,228, 76,228, 47,164, 41, 0,192,161,172, 54, 13,121,
- 72,148,133, 0,128,113,149,144,227,191,209,184,235, 71, 44, 67,
- 4, 0,152,146,177, 14,234, 47, 72, 10, 0, 48,155, 72,200, 11,
- 0, 48, 71,153,235,136,245, 35, 28, 7, 0,152,135,252, 5, 0,
- 0,115,225, 47, 30, 53, 83, 49, 2, 24, 0,224, 0,182,224,227,
- 17, 5,242, 23, 0,224,224,166,226,153, 8, 47,114, 20,153, 34,
- 96, 1, 0,142,150,195, 38,228,175,253,246, 2, 50, 3, 0,204,
- 134, 17,228, 33,119, 10, 22, 3, 0,240,148,155,225,242, 32,187,
- 10,113, 1, 0,102, 8,121,104,115, 66,100, 0,128,153,241, 23,
- 68, 5, 0,152,111,127, 29,214, 86,176, 28, 0, 39,155, 25,252,
- 140,203,121,221,113, 0,192,169,151, 29,198,175, 2, 0,230, 53,
- 144, 73,100, 46, 0,192,156, 34, 15,166, 87, 72, 13, 0, 48, 31,
- 254, 2, 0,128, 25,174, 36,225, 47, 0,192, 49,232,107, 34, 74,
- 147, 99,217,105,148,149, 0, 0,228, 47, 0, 0,152,128,191, 16,
- 186, 0, 64,173,136,252, 5, 0, 56,201,174, 59, 54,231,201, 17,
- 13,203,152, 52, 26, 0, 48,170,178,120,119, 87,140, 83, 29,114,
- 140,251, 13,165, 1, 0, 38, 89,114,202,163, 61, 52,148, 5, 0,
- 152, 26, 7,205, 95, 12,139, 1, 0,230,200, 95,208, 19, 0, 96,
- 22,189,128,227,143, 0,128,121,116, 23,252, 5, 0, 56,201,245,
- 35,106, 71, 0,192,188,250, 11, 0, 0,224, 47, 0,192, 9, 99,
- 234,229,153, 60, 41, 79, 4, 0, 48,123, 94, 59,102, 49,200,227,
- 216,103, 0,192,169,119,215, 36,132, 32,199,183,187, 0,128,211,
- 84, 50,242, 97,111, 56, 17,127, 49, 15, 60,250,177,159, 78, 14,
- 0, 0,211,168, 31, 1, 0,200,101, 19,173,207,224, 47, 0,192,
- 49, 75, 12,254, 2, 0, 64, 95, 99,240, 23,163, 1, 6, 0,152,
- 1,144,191, 0, 0,227, 13, 95,147,139, 55,240, 23, 0,224,120,
- 140,118,252, 30,131,191, 0, 0, 71,203, 91,243, 81, 63,162,233,
- 5, 0,152, 37,228, 80, 65,141,106, 42,172,217, 1, 0,152, 94,
- 214,145,179,181, 59, 0,128,121,119,215, 4,109,129,254, 23, 0,
- 96, 54,211,213, 56,252,133,232, 5, 0,152, 77, 14,148,191,120,
- 215,239, 25,170, 3,224, 20, 37,175, 25,249,172, 75,100, 45, 0,
- 192,152,170,199, 73, 27, 68,162,120, 4, 0,204,125,253, 8, 85,
- 1, 0,142, 24,200,120,228, 31, 29, 75,254,226,221,247, 15,130,
- 3, 0,204,104,254, 26, 67,241, 11, 0, 0,179,236, 47, 24, 13,
- 0, 48,191,254,130,175, 0, 0, 39, 37,127, 1, 0, 78, 45,211,
- 141, 51, 18, 81, 11, 0,112,234,242, 23,220, 6, 0, 72, 93, 48,
- 37, 29,160,126, 4, 0,204,107,177, 41, 17,175, 0, 0, 99,183,
- 19, 79, 68, 39,200, 95, 0,128, 99, 76, 81,199,154,132,224, 47,
- 0,192,204, 21,134,135,247, 23, 42, 71, 0,192, 92,128,252, 5,
- 0,152,215, 12, 38,103, 44, 15, 2, 0,160, 45,228, 47, 0,192,
- 201,182,215,232,254, 66, 30, 3, 0,204,154, 27,144,191, 0, 0,
- 243,106, 57,248, 11, 0, 48,175,192, 95, 0, 0,248, 11, 0,112,
- 226, 75,192, 25,107,132,203,113, 60, 39, 0,192,105,178,216,124,
- 251,139, 33, 49, 0,224,176,131,223, 98,220,166, 64,253, 8, 0,
- 152, 87, 14,238, 47,100, 45, 0,192, 76,250, 11,114, 2, 0,140,
- 152,100,120,234,222,144, 72, 88, 0,128, 83, 83, 63,162,172, 4,
- 224,212, 70,174, 25,179,129, 60,194,174, 67, 89, 0,128,105, 26,
- 76, 30,112,167, 24,238, 2, 0,204,136, 6,228,193,118, 9,218,
- 2, 0,186, 58,144, 10,248, 24, 13, 34, 71,122,120,222,115,167,
- 32, 53, 0, 96,180,105,152, 0,227, 87, 1, 0,243, 10,252, 5,
- 0,152, 72, 60,155,156,191,184,252,101,194, 59, 5, 0, 56, 65,
- 174, 58, 62, 99,200,163,237, 24, 0, 0, 76, 45,147,201,163,237,
- 3,212, 6, 0,152, 26, 18, 57, 11, 0, 48,163,249,234,152,242,
- 23, 0, 0,236,165,175,137,120, 12,254, 2, 0,204,107, 0,147,
- 227,216, 17, 20,158, 0,192, 81, 83,240,130,132,148, 0, 0,115,
- 10,234, 71, 0,192,188,214,145,114,223, 7,102,100, 51, 0,192,
- 12,216,106,172,249,139, 97, 50, 0,192,190, 26, 59,198, 67,146,
- 242,104,123, 6, 0, 0, 83, 83, 5,250, 95, 0,128,121,168, 21,
- 15,225, 47,222,115,119, 81, 65, 2, 0,133, 77, 81,238,183,167,
- 75, 0, 0, 32, 0, 73, 68, 65, 84, 1,242,160,126,133,174, 0,
- 0,179,159,191, 14,100, 42,104, 13, 0, 48, 99,245, 35, 0, 0,
- 192, 95, 0, 0,112,220,254,226,161,223, 50,138, 68, 0,192, 62,
- 76,124,182,102,121,132, 61, 3, 0,156,118, 65,237,189, 2,209,
- 113,107, 3,245, 35, 0,224, 72, 17,107,150,234,199, 35, 61, 33,
- 132, 52, 0, 32,178, 41,249, 11, 35, 38, 0, 0,199, 80, 87,162,
- 126, 4, 0, 0,248, 11, 0,112,250,252,133,138, 17, 0, 48, 75,
- 66,144,187,237, 13,100, 5, 0,152,179,252, 53,130,182, 96, 54,
- 0,192, 92,213,143,144, 22, 0, 96, 84, 89, 76,106, 21, 72,244,
- 239, 1, 0, 39, 61,127, 1, 0, 0,252, 5, 0, 56,169,117,227,
- 28,251, 11, 45, 50, 0,192, 48, 37, 28,155, 27, 36,244, 3, 0,
- 152,211, 84, 38,103,119,215, 0, 0,224,160,254,194,124, 18, 0,
- 128,121,245, 23, 0, 0,192, 95, 0, 0,144, 21,115,199, 80,206,
- 193, 95, 0,128,211,145,191,208, 15, 3, 0,204,142, 40,228,252,
- 237, 50, 0,224, 20,184, 9,245, 35, 0, 96,114, 86,155,188,218,
- 228,248,118, 30, 0,112,138, 18, 24,207,192,167, 95,142,255,105,
- 1, 0, 80, 77,162,126, 4, 0,204,129,178,248,144,183,131,191,
- 0, 0, 51, 33,174,169, 36, 49,121, 92,207, 12, 0,128, 82,114,
- 6,253, 5, 89, 1, 0,102, 1, 9, 71, 1, 0, 78,152,191, 0,
- 0, 96,214,235, 72, 57,251,187, 8, 0,128,178, 14,236,175, 97,
- 11,218, 66, 92, 0, 0,212,143, 0, 0, 36, 50,248, 11, 0,112,
- 250,106, 71,248, 11, 0, 48, 86,117, 77,216,102,240, 23, 0, 96,
- 94, 67,154, 60,194, 46,160,151, 15, 0,152,102,101,233, 31,118,
- 39, 74, 87, 11, 65,130,132,192,111, 12, 0, 48,119,245,163, 32,
- 18, 68,146, 96, 48, 0, 78,174, 44,228,225,117,113, 76, 89, 76,
- 30,102, 71,120, 80, 94,194, 39, 81, 39,225, 11, 52,212, 0, 56,
- 129, 52,253,154,231,251, 98,255, 42,107,162,109,165,145,116,179,
- 239, 44, 25, 66, 80, 77,136, 22,137, 71, 90,109,252,166, 1, 56,
- 121, 60,125,238,188,244, 61,158,186,177,142,167,126, 20, 53, 18,
- 109, 33, 47,183, 22,241,155, 6,224,228,241,161,181, 11,196,196,
- 198, 28,229, 78,198,110, 58,191,122,247, 98,191,114,113,184,191,
- 200,147,178, 97,237,179,237,229,215,182, 55,186, 90, 37,215,175,
- 175,223,195, 47, 30,128,121,231,236,194,226,103,158,185,214,121,
- 176,161,149,158,170,175,246,246,215,190,143,207,187,215,149,204,
- 190,148, 45,182, 95, 90,123,244, 63,220,187,145, 92,249,231,223,
- 252, 51,252,238, 1,152,119,190,241,209,143,235, 56,142,250,125,
- 163, 20, 51, 19, 51,137,153, 24,111, 48,230,118,187,239,249, 79,
- 180,151,126,246,194, 37,252,202, 1, 56, 25,252,202, 39, 62,117,
- 237,209,199,251,219, 59,113, 16,176,181,135,136, 86,199, 23,195,
- 252,163,221,188,180, 99,204, 44,152,165,231,125,100,245,188, 95,
- 175,255,249,157, 27,145,209,248,245, 3, 48,167,180, 27,141,255,
- 226, 35, 47,126,250,234, 51,157, 7, 27,253,237, 29, 29,103,225,
- 107,102,240,199,123,119,214, 90, 18, 66, 18,191,176,118,225,202,
- 202,217,239,109,220,253,225,157, 91,120, 31, 0, 48,119,124,234,
- 234, 51, 63,243,236,243,231, 22,150, 58, 15, 54, 58, 27,155,113,
- 24, 88,107,118,151,215,144,222,249,204,248,235, 32, 43, 38, 89,
- 99,116, 76, 66,136, 51,173,214,215,159,126,254,231,174, 94,123,
- 235,225,131,157, 56,222,137,194,135, 97,128,183,197,145,254, 60,
- 48,199,108,243,195, 35, 68,116,161,181,192,108,217, 50, 94,135,
- 83,248, 58,140, 23, 65,180,210, 94, 88,105,181, 86, 90,237, 23,
- 46, 93, 89,108, 52,195,110,111,235,206,221, 96,103, 39, 14, 35,
- 107, 44,113,106, 47, 49,145,218,240,248,242,215,222,109,125, 98,
- 99, 84, 24, 89,109,140, 82,181, 86,235,163,107,143,212, 27, 77,
- 175,230, 75,207, 19, 82, 10,156,104,116, 88,250, 70,223,143,195,
- 87,119, 54,242,107,126,253,153, 23, 84, 28,233, 40,198,235,112,
- 10, 95,135, 99,249,219, 96,140, 53, 70,245,194,141,251,155, 81,
- 175,167,194, 72, 43,197,108,201,142, 94, 55, 78,110,174, 83,127,
- 255, 44,120,240,221, 96, 34,182,150,149, 50,198,196, 65, 24,214,
- 106, 94,205,247,124, 63,145,151,144,240,215, 33,233,106,125, 47,
- 234,223,120,120, 63,191,102,107,241,156, 10, 35, 21,133,120, 29,
- 78,225,235, 48, 70, 82, 57, 49, 39,254,210, 74, 89,173,173, 54,
- 156,113,208, 10,109,150,243,215,136,175, 8,179, 49,108,173, 49,
- 70,132, 68, 34, 9, 94,144,215,225,233,104,181, 21,246,214,183,
- 214,139, 79,242,197, 45, 21,134,113, 16,226,117, 56,133,175,195,
- 113,125,110,211,175, 76, 76,204, 51, 93,146, 31,222, 95, 60,154,
- 120,147, 3, 22, 76, 36, 4, 49,228, 53,142,108,175,181, 46, 93,
- 163,141, 61,218,168,104,188, 14, 96,152,195,142,226,133, 9, 37,
- 50,127,176,242, 59,166,136,148, 88, 29,111,141,163, 70,218, 74,
- 152, 79,255, 62, 48, 94,135, 83,248, 58,204,192,111, 98,202, 5,
- 21,166,139,152,187,247,203,192,247,140,215,129,240,199,241,116,
- 34, 15,249,126, 1, 0,128, 81,254,174,204, 76,254,130,196, 0,
- 0,115,152,191, 0, 0, 96, 78,253,197,136,100, 0,128, 3,124,
- 244, 39,162, 6,228, 47, 0,192, 73,202, 95,140, 96, 5, 0, 56,
- 57,245, 35,152,155,216,142,215, 1,156, 30,124,188, 53, 0, 17,
- 173, 92,185,244,137,223,248, 85, 34,122,229,159,255, 11,213, 15,
- 136,232,133,111,124,253,194,115,207,110,189,127,235, 7,255,230,
- 15,146,109,190,242,143,126, 55,223,254,250, 95,126,231,250, 43,
- 223, 38,162,143,255,250,175,174, 62,113,233,214,171,127,243,147,
- 63,249,102,242, 45, 17,185, 55,201,239, 33,217,242,155,255,244,
- 127,199,171, 13,142,213, 95,176,216,169,163,222,110, 95,120,254,
- 26, 17, 93,122,233,197, 68, 76, 79,125,254, 51, 11,231,207,185,
- 219, 92,120,254, 90,220,235, 63,188,113,211,189,114,245,137, 75,
- 23,158,191,182,114,229,242,245, 87,190,173,250,193,234, 19,151,
- 42, 55,169,108,137,151, 26, 28,191,191, 38, 55, 1, 6,152, 33,
- 226, 94,255,252,115,207, 94,127,229,219, 43, 87, 46, 45,156, 63,
- 183,245,254,205,202, 91, 96,235,198,205, 63, 47, 7, 40, 38,234,
- 221,127,176,112,254,220,181,175,189,252,218, 31,254,209, 30, 51,
- 197,225,221,132, 82,127,146,249,107,191, 29,153,244, 80, 91,176,
- 199,171, 60,158, 23,255,214,171, 63,188,244,137, 23,191, 71,191,
- 127,233,165, 23,183,222,191, 25,247,251,149, 59, 95,189,114,249,
- 103,254,209,239, 18,209, 15,254,245, 31,228, 65,172,251, 96,227,
- 222,143,127,242,161,175,126,229,205, 63,249,179, 93,246,135,199,
- 190,171, 60,241,143, 10,200, 16, 99,249, 85,141, 5,121,228,119,
- 14,222, 49, 39,135,251, 63,126,171,190,208, 94,185,114,249,241,
- 79,124,236,250, 95,126,123,244, 27,254,232, 15,255, 67,125,161,
- 125,237,107, 47,227, 53, 60,213,127, 92,121,210,127, 81,124,188,
- 232, 32,167,119,127, 99,235,253,155, 31,250,218, 87, 86,159,184,
- 252,221,223,251,253,199, 63,241, 49, 26, 82, 63,254,179, 33, 55,
- 124,240,224,221, 87,190,245,161,175,126,165,247, 96, 35, 75,109,
- 0, 85,194,177,227,143, 92, 30,130, 83,241, 94, 89,127,227, 39,
- 215,126,254,229,238,253, 7,149, 62,125,194,194,185,181, 23,190,
- 241, 75,201,102,235, 63,126,179, 18,193,174,126,225,115,245,133,
- 246,189, 55,138,235,111,125,255,135,151, 94,122,241,227,191,254,
- 107, 68,244,200,243,215,110,125,255,135, 39,224, 51, 3,102, 7,
- 127,212, 55, 1,227,237,115, 42, 28,118,251,213,191,185,246,243,
- 47,223,254,254,223, 12,109,188, 47,158, 63,247,194, 55,190, 78,
- 68,175,209, 31,173, 59,158, 34,166,222,253, 7,239,190,242,173,
- 171, 95,248,156,123,147,239,254,222,239, 19,209,181,159,127, 57,
- 113,217,119,127,239,247,143,247,125,130, 55,225, 4, 16,123,188,
- 250,147,158, 12, 76,252,237,223,190,166,141,249,230, 55,255,172,
- 241,253,215,106, 82,214,164,172,145,144, 76,194, 90, 50,214,104,
- 165,194, 40, 10,130,160,215,239,119, 59, 97, 24, 25,182,134, 57,
- 249,215, 18, 91,102, 78,103, 95,194,123,231,216,233, 24,117, 43,
- 232,255,197,214,221,252,154,255,229, 99,159,137,131, 80, 5, 1,
- 94,135, 83,248, 58, 76,201, 95, 66, 16, 9, 34, 41,132, 36, 33,
- 133,240,132,240,132,240,133, 16, 36,136,200, 18,107,102,109,173,
- 98, 27, 89, 19, 25, 19, 88, 19, 26, 19, 90, 19, 90,211,191,112,
- 246, 67, 47,126,204,247,125,223,247, 61,207,175,213,124,223,247,
- 107,181, 90,173,158,210,104, 52,234,141, 70,179,209, 72, 46, 52,
- 234,141, 90,189, 94,175,215,106,181,122,173,230,167, 55,240,124,
- 207,247, 60,233, 73,252,241, 2,243,249, 33,194,107,112,146,251,
- 24, 35,130,243,135,230, 43,185,139, 90,121,245, 38, 41,229, 41,
- 252, 36, 75, 18, 53, 33,241, 58,128,253,252, 53,254,129, 59,224,
- 240,212,165, 60,227,215,243,111,155,190,239,215,235,167,112, 73,
- 167,154,148,203,126,205, 85,216,233,124, 29,166,155,180,248, 64,
- 91, 79,204, 95,208,212,236,126,110,133, 60, 91,111,188,124,225,
- 82,195,243,155,126,237, 23,174,189, 64, 66, 48,219,211,249, 58,
- 124,241,252, 99,201,235,240,141,143,188, 40, 78,229,235, 0, 48,
- 254,107,174,234, 71, 33,106,158,255,209,165, 71, 62,245,212, 51,
- 181,102,211, 26, 29,236,116,140,210,120, 29,130,157,174,209, 26,
- 239,144,233, 36,177,249,242, 23,207,226, 19, 57, 53,239, 24,107,
- 85, 24, 89, 99,165,215, 73,215, 73, 62,149,139, 30, 14,121, 29,
- 52, 22,127, 60,117, 82, 67,254,154,175,183, 6, 51,179,177,214,
- 40,133,215, 1,175,195,212,252, 36,102, 69, 96, 56,254, 8, 0,
- 152, 87, 14,153,191, 6,231,158, 64, 1, 9,192,105, 96,164,163,
- 188,147,210, 1,242, 23, 0, 96,156,197,229, 36,145,179,180, 51,
- 0, 0,112, 60,249, 11, 50, 3, 0,204,148, 17, 36,132, 5, 0,
- 152, 83,124,216, 10,127, 26,231, 2,156, 28, 52, 83,239,174, 25,
- 249,117, 96,252,215, 73,240, 20,151,103, 48, 74,191, 61,113,242,
- 18,217,167, 38, 57, 85, 59,249, 22, 94, 59,205, 54,131,191,230,
- 216, 89,204,196,196, 76,148, 92,216,209, 74, 89,203, 68,129,213,
- 193, 9, 26,148,223,146, 94,211,243, 4, 81, 77,202, 37,191, 46,
- 136, 4,147, 32, 33, 4, 11, 74, 46,192,101,167,190,126, 28,177,
- 18, 65,153, 57, 69,109,185,206,138,173,221,136,195, 29,173, 54,
- 85, 20, 90, 19, 26,115,102,237,172,223,168, 17, 81,123,233, 76,
- 107, 97,129,153,231,127, 78, 73,182,214,110,117,123, 97,191, 79,
- 68, 42,142,187,247,239, 55, 61,175, 41,189,149, 90,125,201,175,
- 173,213, 26, 53,233, 73, 38,153, 78,170,151,186, 12, 34, 59, 37,
- 165, 36,242,215,156,164, 45,102, 75,100,153,183,117,124, 59,236,
- 109,170, 56,242,196,133,199, 30, 91, 57,183,246,177,139, 23,155,
- 237,118,115,161,173,148, 82, 74, 89,107,173,181, 74, 41,173,181,
- 181,115, 63, 37, 3, 51, 75, 41,107,181,154,231,121,201, 53, 97,
- 191,223,239,118, 31,222,127,112,123,123,231,245,141, 7, 77,166,
- 85,191,241,104,179,117,198,175, 75, 33, 36, 11, 41, 72,166,179,
- 132, 34,145, 77,255,173, 59,125,127, 49,226,215, 84, 3,151, 37,
- 238,104,117, 35,232,174,199, 97,115,117,229,234, 39, 95,124,238,
- 226,197,133, 51,203, 81, 20,245,251,253, 94,175,119,239,214, 70,
- 175,215, 11,130, 32,142, 99, 99,140, 49, 70,107,109,172, 97, 59,
- 223,191, 47, 33,132, 16,194,243, 60,223,247,189,140, 70,163,209,
- 108, 54,151, 46,156, 63,127,229,178,239,251,253,157,206,246,198,
- 198,107,183, 63,176, 59, 91,231,234,141,203,173,133, 69,175,230,
- 37, 83, 27, 35,142, 77,215, 83,199,191,156, 26,242,215,172,155,
- 235,118,216,191, 25,116,227, 86,227,185,159,254,248,199,158,120,
- 194,107,212,187,157,206,131,173,173,159,188,251,206,246,246,118,
- 183,219,237,247,251,169,185,230, 95, 88,251, 34,165, 76, 20,214,
- 202,104,183,219, 11,103,150,159,185,248,136, 81,234,225,250,253,
- 239,223,188,213, 54,252,120,179,253,104,163,237, 9,225,145,144,
- 68,176,216, 73,197, 63,200,103, 10, 76,212, 92,111,247,118,110,
- 134,189, 51,143, 94,252,228,207,125,105,229,252,185,157,157,157,
- 219,119,239,220,187,119,111, 99, 99, 99,123,123,187, 31, 4, 42,
- 142, 43, 45, 46,113,210, 63,164,204,172,181,214, 90,247,122, 61,
- 18, 66, 10, 81,175,215,219,237,246,226,210,226,210,210,242,226,
- 242,210,213, 79,188, 24,116, 58,239,221,184,245,206,230,189,199,
- 155,237,167,218,139,158,144,176,216,108,100,179,241, 59,196, 31,
- 242,120,248, 13, 79, 81, 94,204,134,248,131,176,127, 35,232,158,
- 125,246,233,159,255,244, 79, 75,223,223,216,216,248,193, 15,126,
- 112,231,206,157,205,205,205,126,191,175,181,182,156, 29,132, 20,
- 167,239,143,139,243,254,180,204, 97, 20, 69, 81,244,240,225,195,
- 68,100,203,203,203,203,203,203,143, 94,123,214, 42,189,126,227,
- 230,131,237, 7,143, 55, 22, 30,107,166, 89,204, 59, 13,142,159,
- 206, 59, 87, 76, 37,238,248, 71,221,109, 48,190,216,101,153, 54,
- 85,244,126,208,181,231, 86, 63,249,213, 47, 45,173,174,222,189,
- 123,247,198,141, 27,119,239,222,125,248,240, 97, 24,134,121, 63,
- 94,208,240,255,159,222, 23,144, 57,138,162, 56,142,119, 58,157,
- 214,198,198,210,210,210,210,210,210,226,197, 11,102,229,204,187,
- 247,214, 55, 58,155,151,154, 11,103,107, 13, 22, 66,146,148, 8,
- 98, 99, 23,214,148,114,143, 15, 65,205, 78,236,250,113,119,251,
- 150,137, 62,245,229, 47, 61,126,245,169,245,245,245, 87, 95,125,
- 245,198,141, 27, 91, 91, 91, 74,169,164, 78,116,163, 3,187,255,
- 63,109,191, 39,225,252, 87,198, 26,147, 28,202,216,222,222, 94,
- 90, 90, 58,115,230,204,234, 19,151,131,135,219, 63,184,123,239,
- 241,122,235,217,246,114, 77, 18,130,216,113, 36,174,169,224,143,
- 229,153,204, 26,159,254,237,223, 92,255,241, 79,174,191,242,237,
- 121,120, 31,164,177,235,189,160,235, 95,186,248,141,159,125,185,
- 219,235,189,246,218,107,215,175, 95,127,240,224, 65, 24,134,150,
- 237,208,151,184, 20,189,240, 65, 44,191, 52,150, 57, 12, 67,165,
- 84,191,223, 95, 90, 94, 94, 92, 88, 56,123,245,201,245, 59,247,
- 162,238,214,229, 52,136, 73,143, 72,138, 98, 76,255, 76, 81,111,
- 183, 63,255, 15,255,254,234,149,203,255,215,223,255,221,185,177,
- 215, 52,148,230, 31,241, 89,204, 32,159,254,237,223,188,250,197,
- 207, 93,253,226,231,136,104,150, 21,150,213,140,252, 94,208,125,
- 43,238,127,234,203, 95,122,244,169, 39,111,221,190,253,214, 91,
- 111,221,190,125,187,215,235, 25, 99, 40, 57, 75, 70,236,246,226,
- 159,226,121, 35,119,143, 96, 57,198,152,126,191, 31,199,113,208,
- 239, 47, 45, 45,181, 46,156,235,118,186,175,110,108, 62,211, 90,
- 186,210, 90,168,145,244, 72,204, 96, 45, 89,111,183,191,242,191,
- 254,207,171, 79, 92,158,219,100, 54, 87,249,107, 6,229, 21,247,
- 250,245,133,246,103,126,231,183,102, 86, 97,156, 14, 73,229, 55,
- 186,219,235, 62,125,245, 87,126, 89,248,254,235, 63,250,209,219,
- 111,191,189,177,177, 17,171,152, 56,173,111,118,243,148,115, 10,
- 224,124,255,189, 25, 22, 42,143,120, 47, 37, 31,105,173,187,221,
- 110, 28,199, 11,139,139,173,102,179,113,126,237,237, 7,155,161,
- 209,207, 46,156,169, 73,233, 39,115,176,204, 82, 45,249,233,223,
- 249,205, 89,150,215,144,152,197,196, 83,122,249, 78,148,191,114,
- 121,125,243,159,254,179,149, 43,151, 62,243, 59,191, 53,155, 10,
- 203, 27, 94,127,215,217,234, 45,182,126,241,151,255,171,173,135,
- 15,223,252,209,143,222,123,239,189, 78,167, 83, 25, 52, 63,232,
- 169, 67, 39,175,147, 89,101,238,171, 30, 33,146,238,190, 49, 70,
- 43,213,106,181,234,231,215,110,111,108,169,238,195,231, 23,207,
- 176,240,124, 73, 30,207,138,194, 62,253,219,191,121,233,165, 23,
- 183,222,191, 73, 68,115, 17,193,166,251, 71, 81,142, 99,175,102,
- 226,239,186, 43,175,173,247,111, 94,127,229,219,223,249,151,255,
- 138,136, 62,243, 59,191,245,212, 23, 62, 59,155,242,106, 60,117,
- 229,107,191,246, 43,247,214,215,127,248,195, 31,190,253,246,219,
- 59,157,157, 68, 94, 34, 29,121, 46,132, 24, 82,220,136,242, 6,
- 46, 36, 78,226,129, 53,177,219,211, 77,158,243, 48,163, 13,219,
- 32, 41, 39,123,189,158, 97,246,215, 86,239, 9,243, 70,119, 59,
- 102,163,173, 53, 52, 19,103,139, 38,239,225,173,247,111,126,243,
- 127,251,103,113,191, 79,224,216,242,215,108,213, 34, 21,121, 37,
- 87, 38,177,107,166, 82,152, 43,175,250, 83,151, 63,241,197,207,
- 95,191,126,253,141, 55,222,184,123,247,110, 28,151,107,198,236,
- 211, 36,136,168,114,216,113,247, 15, 90,105,126,153,211,195, 30,
- 209,169,220, 62, 52,198, 4, 97, 96,173,109, 52,155,220,106,222,
- 233,246,185,251,240,185,133, 21, 34, 34, 41,167,155,194,146,247,
- 112,247,254, 3, 87, 94, 47,252,242, 47,173,191,241,166,234, 7,
- 249,187,122,198, 75,201, 57,170, 31,121, 70, 84, 54, 84, 94, 51,
- 168,176,170,188,190,240,249,247,222,123,239, 71,175,191,190,126,
- 239,158, 78,214,142, 22, 34,113,147,235,172,234, 8,251, 97,122,
- 58, 1, 19, 77,140,179, 96,220,101,155,244,111,131,229, 40,138,
- 152,185, 94,175,115,187,121,167, 31, 80,111,250, 10,203,223,195,
- 127,249,207,255,133,155,188, 62,250,141,175,211, 55,190,158, 92,
- 190,245,253, 31, 94,127,229,219,183,190,255,195,185,248, 45,241,
- 76,249,107,102, 63, 31,123,200,107,166, 20,150, 30,109, 76,228,
- 245,228,229, 79,124,225,243,239,223,184,241,250,235,175,223, 95,
- 95,215,217, 92, 93,185,155, 74,249,107,132,240,133,145, 76,123,
- 188, 8,213,235,133, 32, 34,165, 20, 17, 53, 26, 13,221,108,220,
- 238, 5,212,123,248,252,226, 10, 89, 18, 82,202,137, 39,216,161,
- 239,225, 31,252,235, 63, 88, 56,183,182,242,196,101, 34,186,240,
- 220,179,171, 87, 46, 95,122,233,197,164, 53,246,221,223,251,253,
- 153,140, 99,115,149,191,120, 6,236,182,175,188,102, 73, 97,108,
- 153,223,232,110,119, 23,154, 63,251,197,207,223,188,121,243,141,
- 215, 95,191,127,255,190,214,122, 80, 91, 67, 69, 54, 52,124,141,
- 148,188,230,103, 38, 25,206,158,213,209, 83,216,224,207, 75,127,
- 9,152,181,214, 66, 8,207,247, 2, 79,220,137, 67,191,183,243,
- 161,133,101,193,194,159,236,184,176,221,222,195, 91,239,223,220,
- 122,255,166,155,182,158,250,194,103,175,125,237,229,213, 39, 46,
- 255,252, 63,249,199,223,249,151,255,106, 46,134, 55, 30, 55,242,
- 128,166,154,167,228, 85, 81,216, 20,219,249,201, 32,213,247,130,
- 238,186, 71, 95,254, 47,191,126,247,238,221, 55,223,124,115,125,
- 125, 61,249, 8,229,159, 43,145,181,158, 93, 97,237,209,200, 39,
- 218,171,175,237, 54,176,211, 65, 78, 98,166,201,159,252,136, 79,
- 106,239, 23, 99,240,234,202,183,204,172,148, 54,218,212,235,245,
- 190,239,221,138,250, 55,130,158,178,214,112, 58, 73,228,100,222,
- 27,235, 63,254, 9, 17,213, 23,218, 43, 87, 46,237,251, 30,254,
- 227,127,252, 79,254,238, 15,255, 40,121, 27, 95,120,254, 67,240,
- 151,247, 15,254,193,255, 96,153,175, 95,191,238,221, 89,247,132,
- 244,132,144, 66, 72, 34,145,142, 80,178,214,104,163,181, 86, 74,
- 197,177, 49,218,230,115, 36, 20, 19, 25, 79,129, 79,252,198,175,
- 62,251,242,151, 18,121, 45,156, 91, 91,126,236,226,206,157,187,
- 123,108,127,237,107, 47,111,188,115,253,193,219,239, 38, 33,188,
- 247, 96,227,225,141, 91, 19,203, 20,150,233,255,103,239, 93, 99,
- 44,203,174,251,190,181,214, 62,231, 62,235,253,234,119,247, 76,
- 15,103,122,154, 28,146,195,225,155,163, 33,101, 82, 50, 73, 88,
- 68, 98,138,162, 13,136,177,101, 32,118,190,216,128, 19,125, 72,
- 32, 27, 72, 62,200,130,191, 40,118,144, 0, 70,164, 4,145, 0,
- 41,128, 5,135, 66, 64, 57,162, 2, 83,136, 69, 81, 36, 45,241,
- 77,113,166,103, 56,211,211,211,239,238,170,234,122,221,215, 57,
- 103,175,149, 15,251,236,115,246, 62,231,220,170,234, 71,245,220,
- 234, 62,187,171,171,110,221,186, 85,117,235,220,123,126,247,255,
- 255,239,181,215,222, 74,162, 11,189,173,143,125,238,179,163, 56,
- 126,229,149, 87,174, 93,187,150, 36, 73,134,164, 34,182,170, 78,
- 210,253,158,216,229, 65, 68,120,104, 6, 56,255,247,196,242, 46,
- 72, 43, 95,237,125,234, 92, 84, 74, 9, 72,130,176, 19,141, 22,
- 194,102,131,136,178, 25,222,131,127,122,108,188,117,165,183,186,
- 86,126, 90,190,240,203,191,116,254,115,159,233, 46, 47,173,156,
- 63,215, 93, 90, 68,196,225,230, 22, 0,220,122,249, 85,115,251,
- 149,103,159,121,243,235,223,212,113,242, 54, 88,117,115,252,236,
- 33, 37, 64, 66, 36,123,192,108, 84, 2, 44,162, 69, 18,251, 22,
- 11,107,150,120,170,179,120,244, 40,217,161,148,121,159,143, 32,
- 8, 84,144, 14,243,137,243, 69,251, 13,102, 32, 5,227, 78, 57,
- 156,108,241,181,114,254, 92,166,188, 62,243,235,255, 60,234,245,
- 119,207, 53, 95,248,210, 23,111,190,124,225, 79,127,227,127, 76,
- 95,187,158,125,230,225,200,239,172, 78,245, 98,127,231, 29, 31,
- 254, 64,208,106,189,242,242,203,215,174, 93, 51,249, 75,238, 19,
- 253,229,141,178,255,240,107,247,115,236, 16, 6, 99, 89, 93,189,
- 236,186, 9,137,136,236,106, 16,199, 95,237,191, 80,136,136,214,
- 58, 8,130, 88, 36, 82,112,121,208,235,170,128, 8, 17, 5, 31,
- 86,150, 95,153,111,204,157, 57,117,228,252,185, 35,231,207,101,
- 55, 51, 79,242, 87,255,223, 63,189,248,245,111, 26,222, 61,243,
- 153, 79,253,248,203,127, 52, 49,214,255,109,120,174, 29,214,250,
- 213,175,254,243, 95,119, 63,109,116, 59,230,194, 39,127,237,191,
- 113, 31,242, 31,253,225, 87, 10, 15,240,197,175,127,243,225, 6,
- 7,194, 32,175,236,108,242,177,165, 51,231,158,185,120,241,226,
- 149, 43, 87,134,195, 81,118, 30,185,228, 42, 99,203, 61,135,177,
- 58, 86,222,223, 73,123, 8, 7,142,167,216,126,206,149,221,243,
- 47,247, 19, 17, 17,145, 48, 12, 99,136,175,199,163,160,191,253,
- 76,119,134, 4, 17, 65,193, 67, 74, 14,199, 69,180, 95,251,141,
- 223,236, 46, 45,118,151, 23, 87,158,125,230,200,249,115,102, 97,
- 220,149,239,124,255,199,127,248, 71, 39,223,255,252,147, 63,243,
- 209,137,225, 87,101,226, 36, 53,191, 14,241, 48,206,113, 59,137,
- 175, 36,163, 79,191,244, 51,183,110,221, 50, 21,246, 0, 98,242,
- 151, 74,138,249, 32,219,243,252, 41,157,167,143,214,100,164,165,
- 88,177,136, 68, 42, 20, 25,220,131,254, 50,151,153, 57, 8, 2,
- 34, 26, 5,112,109,212, 63,210,104,205,135, 77, 34,194,116,129,
- 36, 60,124,132,165,233,216,203,175,230, 47,210,157,246,147, 47,
- 125,236,185,191,253, 11,198, 60, 70,189,254,212,242,210,252,153,
- 83,135,100, 46, 82, 38,135, 95,147, 94,109,244,181,223,248,205,
- 149,243,207,188,251,111,127,238,237,126,196, 82,231,248,236, 11,
- 207, 15, 71,163, 75,111,189,181,182,182,198,204,230, 4,172,210,
- 95,233,177,245,103,202,220, 3,190, 7,173, 42,216,117, 8,113,
- 38,206,255,236,143,144,189,247,180,148,221,255,232,113,250,203,
- 92,212, 90, 43,165, 18,145, 72,209,213, 97,127, 42, 8,149,228,
- 91,180,193, 67, 71, 88,212, 43,214,223, 71,253,193,133, 63,249,
- 218, 27, 95,255,139, 23,126,249,139,166, 61, 1, 0,156,120,255,
- 123,223,102,126,189,173, 69,172,193, 35,197,173,201, 58, 9, 69,
- 4,174, 13,251,219,221,230,243,231,158,121,235,173,183,178, 58,
- 85, 87, 83,248, 20,203,213,214, 56, 9,182, 15, 49,113, 15,216,
- 194,135, 15,168,253, 68, 96, 62,211, 65, 0,157, 4,208, 19, 97,
- 34,178, 79, 35, 93,125,196,204, 81, 70, 36,162, 36,128,155,209,
- 104,118, 52, 56,217,234,144, 32, 1, 10,202,195, 71, 88, 22,137,
- 20, 70,220, 31,124,251,183,127, 23, 0, 12,194,230, 79,159,154,
- 236,179,224, 96,185, 17,220,223,115, 79,106,162,141, 59, 72, 34,
- 192, 34,111, 13,118,158,123,241,111,108,109,109, 93,189,122,117,
- 48, 24,164, 82, 2, 0, 68,112,223,201,253,216, 19,178,234,226,
- 158,130,108, 18, 76,225,254, 36,152, 20, 89, 15, 32,217, 18, 5,
- 188,187, 39,223,126,184,111, 92,100,146, 36,163,128,110,140,250,
- 71, 26, 45,133,164, 64, 16, 30,106,159,176, 12, 97,187,220,230,
- 219,191,253,187,243,103, 78,205,159, 57, 21,118,218,135,194, 48,
- 202,164,240,107, 82,135, 41,135,105,116,188, 87,173,238,226,226,
- 219, 84, 38, 35, 2,112,117,212,167,197,249,233,133,249,139, 23,
- 47,174,175,175,107,173, 77,236,101, 94,235, 43,201, 85,118,142,
- 165, 83,199,171,100,242, 47,140,129, 24, 28,142, 18, 86,113,208,
- 85,168,224,205,161,159,246,252,151,241, 57, 88,245,193,220, 93,
- 164,186,143, 2, 17,105,165, 54,147,248,198,104,112,178,213, 85,
- 10,201,136,191,135,120,252, 12,194,230,119,173, 8,251,238,239,
- 255,193,167,126,237, 87,187, 75,139, 19,229, 57, 30,178,113, 11,
- 238,230,119, 76,202,130,199,202,241,169, 95,251,213,242,149, 89,
- 35,195,135, 79, 47, 35,190,206,127,244, 19,219,219,219,183,110,
- 221, 26, 69, 81, 10,175,130,254,202,133, 6, 58,207, 2,207, 78,
- 142,145, 84,233, 5,255,195, 46, 12,115,180, 15, 78, 34,183,208,
- 119,143,230,192, 32, 8, 32, 58, 23, 50, 5, 54, 86,130,149,130,
- 252,221,167, 34,139, 7,140,136, 68, 36, 14,212,205,104,112,164,
- 217, 14, 4, 85, 90,251,251, 80,143,202,197,175,127,243,226,174,
- 55,184,245,242,171,111,252,217, 95,196,143,119,155,138,224,158,
- 158,106,147, 53,126,244,135, 95, 41, 92,211,187,189,118, 11, 94,
- 253, 17,124,165,112,229,195, 75,190, 0,110, 69, 3,181, 56, 63,
- 179,184,240,230,155,111,110,110,109,101,138, 32,211, 95,105,106,
- 3,238, 82,109, 48,242,162,100, 86, 42,206, 55,239,195, 24,148,
- 77,104,119,228,106, 55, 89,110,138,103,170, 39, 48,191, 32,146,
- 191, 6,236,230, 30,171,181,210, 46,115, 31,133,227, 75, 68,137,
- 162,205, 36, 94,141,134,199,154, 29,165,132, 0, 5,100,210, 14,
- 167, 9,194,106,126, 29, 22, 82, 85,143,202, 18,152,222,234,154,
- 59,247,252,118,136,175,222,153,247,125,168,215,235,173,174,174,
- 70,163, 81,230, 25,119,137,189,118, 49,121,101, 85,229,128, 43,
- 189, 8,152,214, 50, 49,155,178,217, 67, 31, 78,102,127, 99, 86,
- 143, 15, 25,188,140,250, 42,105,176,177, 85, 20, 57, 45, 61, 10,
- 149, 25,102, 44,164, 82, 42, 86,250,102, 52, 88,106,180, 2, 73,
- 83,176,122,153,252,164,233,156,186,254,235,193, 63,114, 2,208,
- 211,201, 78, 67, 45, 29, 59,122,229,202,149,205,205, 45, 95, 56,
- 64, 86, 60, 81,157,212, 8, 8, 72,105,241, 80,122,214,185, 18,
- 43,255, 33, 0,172, 53,107,157,232, 68,107,205,204,194, 98, 55,
- 254, 56,172, 59,122, 34, 66,186,242,201, 89, 95,146, 47,133,178,
- 127,152,236, 42,190, 50,167,185,191, 32, 44, 63,186, 68, 20, 7,
- 234,206, 48,234,233,164, 65,196,136,100,148, 96,253, 20, 63,196,
- 254,177, 30,251,146, 95,114,101,216, 59,254,212, 19,195,225,112,
- 109,109, 61,138, 70, 89,193,151, 93,245,130, 48, 62,176,207, 88,
- 85, 25,123,121,126, 17, 80, 64, 88,235, 40,138,162, 40, 66,196,
- 169,110,119,170,219, 13,195, 16, 4, 26,237,150, 9,215, 36,171,
- 65,240, 47, 76,196,235,179,184,169,125,118,127, 69, 0,132, 89,
- 68,226,225,136,133,147, 36, 25, 70, 81, 20, 69, 74,169, 48, 12,
- 149, 82,184,143,229,137, 34, 96,194,198,177, 49,152,163,197,202,
- 194,214,184,200,155,163,193,116, 16, 6, 34, 10,165,210,231,214,
- 99, 55,211, 94,243,235,208,209,139, 69,174,141,250,239, 63,125,
- 122,123,123,123,123,123,155, 89,178, 34, 0,183, 78,181, 98,170,
- 177,232, 31, 43, 52, 66,246, 94, 4,152,117, 20, 69,195,225,176,
- 213,106,157, 62,121,170,213,237,184,132, 18,145, 2, 29, 38, 10,
- 97, 30,203,220,187,237, 30, 17, 17,213, 8,145, 25,149, 82, 97,
- 200,204, 58,142, 71,163,136, 20,101, 20, 27,107, 30,109,116,182,
- 87, 10, 86, 93,144, 98, 22, 23, 39,138,214,226,209, 19,204, 26,
- 137, 69,168,182,144,135, 83,127,213,101, 94,251, 60, 76, 34, 0,
- 155, 73, 28, 76, 79,169, 70,184,121,235,230,112, 56, 44,193, 75,
- 252, 58,213, 74,114,141, 21, 8,217, 15, 73,146,100, 56, 24, 32,
- 209,153, 83,167,219,221, 14, 0,204,119,167,206, 46,173,156, 93,
- 90,158,111,182, 69,235, 51,115, 11,200, 44, 6,168,249,212,246,
- 4, 78, 34, 75, 81,138, 73,202, 49, 22,254,233,218,109, 0, 92,
- 237,239, 92,184,117,227,213, 91, 55,110,111,109,134,141,144,147,
- 36, 26,141,194, 70, 35, 8, 2,159, 40, 57,176,118,143,219,199,
- 87,165,184, 22, 18,129,104, 4,122, 43,137,155,164,178,206, 43,
- 88, 75,176,137, 9,196,106,253,245,224, 17,182, 22, 13,231,143,
- 175,196,113,178,179,179,163,117,226,152,199, 66,242,181, 27,185,
- 198,158, 88, 0, 34, 18, 71,113,127,208,159,157,153, 57,114,244,
- 40, 0, 28,153,153,125,207,201,211,159,124,234, 89,142, 34, 29,
- 69, 58,142,133,113,120,103, 67,180, 78, 85,152,100,219,116,139,
- 147,178,165,191,216, 45,105,127,248,142, 35,223, 64,188,200, 47,
- 17,129,147, 24, 2,192,201,169,249,247, 77, 47,200,211,207,253,
- 63,175,191,252,157,171,111, 93,189,179,206,146,182,129, 14,195,
- 176,236, 37,247, 76,241, 43, 41,230, 30,106,147,226, 19, 81, 66,
- 184, 30,143, 22,194, 38,139, 72,157,128, 29, 74,253, 85,203,175,
- 187, 48,143,112, 43, 26, 62,121,252, 88, 20,141,134,195,161, 61,
- 145, 10,201, 87, 21,185, 82,141,180,139,191, 49,243,111, 18,199,
- 113,191,223, 59,114,228,200,204,236, 44, 0,188,244,204,249, 95,
- 56,255,110, 61, 24,142,238,108,232, 40,210, 73,194,137, 22,214,
- 194, 34,194,192,226, 58, 71,215,179, 77,226,225,203, 8,109, 61,
- 112,122, 89,196, 28,154,159, 95, 57,249,243,199,159,248,119,175,
- 254,248,107, 63,125, 69,107,205,137,198, 46, 5,129, 74,219, 62,
- 143,115,142, 99,143,237, 30, 41,152, 82, 42, 65,220, 78,226, 4,
- 152,133, 88,128, 30,191,221, 81, 38, 67,105,213,250,235,224, 31,
- 56,227, 47, 54,226,104,122, 97,254,214,173, 91,195,225,104, 76,
- 242, 85, 69,174,252, 52,218,109,201, 94,146, 36,131,193, 96,101,
- 101,101,122,102, 38, 84,234, 75, 31,121,233,217,185,197,209,198,
- 102, 60, 24,234, 56, 22, 59,249,232,229, 95,238,251,137,229,151,
- 248,255, 37,237,146, 41, 44,194, 44,194,233, 5, 0, 68,252,207,
- 79, 62,117,118,106,230,127,251,238,183,134,113,196,219, 60, 61,
- 59,227, 54, 43, 44, 88, 60, 83, 58,134,121,153, 89,181,255, 43,
- 167, 96, 70,127,177,162, 94, 28,107, 17,157,234,216, 90,131, 29,
- 190,252,171, 30,251, 37,216, 90, 52,154, 91, 94, 50,123, 62,199,
- 113,140, 56, 54,249,170, 34,215, 30,214, 38, 73,146,225,112, 56,
- 53, 53, 53, 53, 51, 19, 42,245, 95,127,234,179,243,168, 6, 27,
- 155,201,112,196, 73, 98, 38,236, 64,114,120, 21, 17, 54,129,228,
- 170, 92, 36,231,136, 47,251,102,103, 70,152, 89, 24,162,232,157,
- 173,233,255,246,131, 31,255,245,111,254,233, 40,142,130,126,191,
- 59, 53,101,187, 66,123,250,200, 78, 65,238,171,111,154,115,204,
- 243, 20, 12, 17, 53,225,102, 28,181, 72,113,138, 47,168, 9, 54,
- 33, 10, 44, 56, 4,247,241, 80, 61,114,235,241,104,230,216,177,
- 56,142, 77, 58, 3, 78,239,151, 93, 74, 37,246,145,206,160, 8,
- 199,113,204,154,151,150,150, 64,228,151, 63,252, 51,115, 64,195,
- 173,237,100, 56,148, 68, 75, 42, 88,192, 65, 24, 27,231, 85,133,
- 176,137,124, 32,197,227,186,135, 48,102, 96, 6, 97, 16, 6,102,
- 102, 22,145, 37,162, 95,121,215, 11,191,253,195,191,236,245,251,
- 205, 86,171,209,104, 64,177,135,199, 56,120, 57, 20, 43,177,168,
- 92,139,175, 9,183,146,120,185,209,146,250,137,239,153,244, 67,
- 161,191,164,102,215,126,211, 27, 17,216, 74,226,197,169, 41, 91,
- 144, 85, 76,190,236, 52,160,236,115, 61,181,139,176, 36,209,209,
- 104,180,178,188,196, 34, 31,126,242,169,103,103, 23, 70,155, 91,
- 201, 96,200, 73,146, 85, 27,216,240,200,120, 46, 25, 27,222, 79,
- 208,163, 88, 85,133, 42,249, 1, 21, 71, 75,166,115,169, 44,192,
- 44,204, 73,162,207,119,103,127,230,228, 19,127,126,229,205,157,
- 173,173,197,229,229,194, 26,210,253, 47, 90, 31, 23,228, 27, 11,
- 169, 1,250, 58, 97, 16, 78,183,246,168, 35,176, 73, 1, 88,112,
- 79,247,187, 30,227, 14,141, 36,194, 42, 8,146, 36,201,187, 77,
- 32,250, 86,177,234,164,218,205,148, 32, 34, 48,115, 18,199,164,
- 84,216,108, 30,153,153,253,252,115,239,139,182,123,241, 96,200,
- 113, 92,168,249,202,135, 99, 39, 11,252,154,156,149, 69, 8, 0,
- 192, 69,132,185, 19,145,204, 96, 18, 61, 22, 72,103, 36, 88, 88,
- 18,150, 68, 88,115,242,217, 19, 79,190,186,190,122,171,191, 19,
- 69, 81,179,217,130,116,186,183,170,202, 97,111,231, 87,177,206,
- 148,136, 52, 66, 98, 66, 69,111,218,182,126,182,191,253,116,168,
- 243,175, 7,154,126, 1,108,196,209,185,133,249,245,245,117,219,
- 170,208,150,218,143,179,138,105,175, 9, 25,103,103,172,121,148,
- 56, 73,102,166,166,153,249,189, 39, 78,225, 48,138,251,125,142,
- 99, 97,206, 3,163, 76, 4, 50,155,201,199, 84, 48, 88, 59, 86,
- 244,104,147,115, 14, 56, 34,172,184,189, 37,179,137,189,204,155,
- 185,108,166, 87, 53,115, 34,146, 48,159,159, 95,186,213,223,233,
- 109,111,119, 58, 29,131,238,226,161, 46, 31,228,241, 32,115, 31,
- 168, 84,127, 33,166,250,203,217,118,171, 30, 80, 33,155, 31, 54,
- 217,131,123,189,175,245,168,118, 60, 0,192,204,163, 81,100,246,
- 118, 44, 39, 95, 0,126,201, 83,133, 34,171, 56,193,152,153,153,
- 195,102,163, 25, 4, 47,157,121, 42,222,233,235, 81,196, 6,145,
- 78,160, 38, 41,181,204,217,110,150, 64,166,225,183, 56,246,117,
- 50, 7, 22, 67,176,244,104,102,134, 81,152, 57,101, 86,186, 49,
- 87,204, 58, 17,121, 97, 97,229, 91, 55,174, 12,163,168,209,104,
- 48,179,217,219,169, 64,174, 42,217,187, 27,200,242, 5,167,144,
- 238,188,201,217,202, 38,172, 53,216,164,140,224, 0,206,100, 17,
- 1, 51,223,204, 34,242,216,160, 79,139,172, 70,195,238,252, 92,
- 146,232, 36,142,157,149,195,232,157, 75,166, 1,223,190, 26,113,
- 165,223, 45, 44, 90,235, 64, 5,204,252,212,210,145,134,150,225,
- 112,164,227,216,246,243,179, 39,187,131, 47, 73, 67,110,150,108,
- 242, 46,151, 52, 19, 79, 46,183,139,182,145,147, 58,229, 87, 34,
- 108,156, 99,204,156, 88,253, 21, 0,156,156,154,121,125,115, 61,
- 138,162, 86,171,149,196,201,174, 47, 15, 99,239, 66,133,248,181,
- 160,138, 17, 86,163, 17, 54, 80,139,132, 66,234, 81, 15,192, 12,
- 179, 3, 36,101,122,127, 76, 42,174,131,123,133,212,216,193, 2,
- 3,157,108, 37, 81, 79, 39, 49,243,227,163,218, 24,100, 43,137,
- 135, 24,198,113,172, 89, 99,169,131,251,190,207,165,138,151, 4,
- 102, 14,149,210, 90,159,156,157, 75,134, 67, 29, 69,146,232,130,
- 211, 18, 48,188,178,240, 98,102,230,108,253, 54, 64,113, 47,144,
- 201,129,151,140, 33, 90,206, 47,102,102,209, 41,191, 56,227, 87,
- 156,126, 42, 75,173,246,235,155, 48,236,247,167,167,167,205,204,
- 239,125,244,105,244, 94,116,204,131, 54, 98,189, 26, 13, 35,214,
- 1, 81,128, 72,240,200,243, 11, 66,162,174, 10,103,130,176,165,
- 148,154, 84,132, 5, 15,220, 47,198,172, 87,163,225,213, 81,127,
- 53, 26,198, 34,143,143,204, 22,128,132, 57, 12,167,205, 22,244,
- 213,103,195,189,255,116, 33,165,180,214, 79,206, 47,154, 21, 66,
- 172, 53,218,179,223, 13,239,141,236, 98, 35, 88,220,249,187, 98,
- 224, 52,113, 10, 12, 61,243,102, 67, 61, 22, 96,214,194, 9,139,
- 150, 92,127, 37,204,177,131,179,149, 86, 27, 0,122,189,254,153,
- 78,199, 76,254, 62, 56, 33, 2,134, 95,215, 71,131,213,120, 68,
- 153,159,124,212, 7, 33,206, 4,225, 59,187,115, 10,145,198, 41,
- 206,183,219, 72, 7,247,123,143, 74, 39, 66, 34,210,211,201, 27,
- 131,157,190, 78,224, 49, 27, 2, 50,111,211,174, 61, 58, 21,200,
- 126,206,104, 55,139, 65,102, 22,173, 37, 73, 52, 19,199,137,104,
- 237,224,200, 52,156, 73,165,151,136, 88,126,177,228,107,113, 96,
- 66, 59,128, 99,229,197, 92,127, 89,114, 89,253, 37,146,100,228,
- 202,174,209,108, 94, 42,218,237,118,175,215, 43, 68, 96,251,191,
- 3,227, 70, 34, 50,210, 9,242,227,149,122,221,138,134, 91, 73,
- 252,159,173,156, 38,162,201,220,171, 39,184,111,209, 85,220,107,
- 151, 16, 59, 42,120, 12,225,229,158, 11,105,104,176,203,241,196,
- 187,251,161,136,200,137, 22, 17,157, 36, 76,196, 73, 34, 70,127,
- 101,224,116,235, 38,172,225, 18,225,172,151,131, 76, 98,241,215,
- 238, 79, 38, 83, 53, 33,137,112, 34,172,173,236,178,239, 83,138,
- 105,243, 37,102,115,156,130, 32, 80,164,118,133,226,221, 65, 21,
- 1, 31,231,134, 19,183,162,225,212,220,108, 52, 24, 38,209,232,
- 238, 14,168, 60, 56, 79,247,192,243, 10,121, 31,104, 0, 0, 32,
- 0, 73, 68, 65, 84,175, 93,238, 89,131,104,185,209, 90, 8,155,
- 235,241,232, 49, 69,152, 25,100,170, 87,203,143,156,220,213, 73,
- 132, 0,130, 68,136, 17,107,102,224, 68, 51, 37,150, 95, 54,248,
- 246,249, 37, 25,190,196,246, 96,157,232, 24,210,187,119,146, 9,
- 47, 0, 22, 51,207,232, 73, 45, 39, 5, 19, 3, 47,227, 43,205,
- 1, 11,130, 0, 41,107, 71, 33,119,139, 44, 44, 1,236,225,109,
- 192, 61,145,227,137,185,133,102,183, 27, 71,209, 61, 55, 41, 57,
- 208,167, 94, 80,254, 77,114,127,247, 38, 64,154,110,168, 47,156,
- 121,230,175, 7, 91,170,216,158,233, 81, 30, 44,178, 57, 28,220,
- 1, 38,164,188,163,139, 61,143,156, 70, 49,120,183,103, 20, 41,
- 82, 65,192,131,129, 22, 97,173, 89,136, 19,109,252, 35, 58,221,
- 178,178,185, 71,157,190, 29,142, 54,248,121,113,173, 83, 86, 98,
- 58,150,153, 63,196,211, 92,182,236,203,188,103,225,236, 54,230,
- 149,163,217,108, 18, 17,185,125, 87,239,150, 95, 88,241,106, 52,
- 213,104, 30,233, 76,205,180, 90, 13, 21, 4, 68,244, 56, 60,171,
- 17, 17,241,195, 39,206,112,127, 96,158,108,111, 51,171,238, 86,
- 127,201,125,252,229, 13,162,143, 44, 29, 11,155, 77,116, 27,155,
- 60,202,201, 23,104,214, 87,182,183,190,183,189,102,186,215, 35,
- 82,126, 8,241,222,142,102,122,150, 16, 82, 16, 4, 0,144, 36,
- 201,197,181,219,167, 22,143, 49,107, 73,146, 60,249,178,213, 73,
- 12,162, 37, 69, 24,231, 11, 32,139,143, 41,190,205,207,186,234,
- 95, 47, 96,215,107,218,106,144,212, 60, 90,231,232,164, 96,162,
- 133,179,191, 81, 64, 54,162, 17, 0, 44, 46, 46, 41, 82, 32,247,
- 214, 38,181,162, 28,204,236, 26, 2, 0,221, 48,124,106,118,254,
- 196,244,108, 39,108,180,148, 82,164, 30,125,128, 33,128, 72,188,
- 211, 27,245,251, 58,153,208, 56, 40, 40, 61,149,240, 62,159,207,
- 2, 2,154,147,209,136,227,100,168,122,143,137,254, 18, 0,205,
- 50, 24,246,178,149, 67, 68,232,148,103,221, 35,196,236,206,207,
- 24, 4, 1, 41,165,135,195,215, 87,111,189,180,120, 76, 51,107,
- 173,109,139,153,244,189, 89,160,103,245, 23,179, 5,129, 83,120,
- 54,225,177, 87, 90,172,102,144,148,133, 95, 58,115,139,105,224,
- 101,213,165,243, 71,109, 68, 67, 0, 56,122,236,104,156,196,137,
- 78,238,157, 95, 85,171, 32, 69, 68, 39,122,184,211,235,107, 16,
- 21,196,164,212, 99, 33,192,192, 76, 4,177,214,247, 17, 64,200,
- 195,228, 87,245,239,151,187, 71,152,137, 96,224,113, 10,241,181,
- 72,155,101,176,189,109,214, 60,102,219,125,229,235, 98,228,174,
- 33,150,109,229, 17,168,160,213,110,111,109,111,191,124,227, 90,
- 252,236,123, 18,128, 88,242,130,112,247,132, 55, 20,211, 86,152,
- 136,215,111,117,130,225, 37,158,254,202,254, 16,167,108, 34, 39,
- 151,159,153,137, 0,172,141, 6, 0,112,250,204,153,181,181, 53,
- 179,242,225,238,213,198,152,125,213, 0,152,153, 52, 55, 89,146,
- 81, 20, 43,141, 68,252,120, 47,224,158,156,229, 7,245,250,199,
- 7, 57, 66, 36, 78, 91,217,100,237,234,161,160,194,246,120,149,
- 194,234,147, 74, 5,170,211,233, 52,130,112,117,103,251, 27, 87,
- 47,189,119,106, 62, 78, 51,122,123,182,139, 48, 0, 91, 75,101,
- 206,127, 55,252, 42, 76, 36,200, 4,182, 47,116,244, 87,166, 37,
- 179,153, 71, 87,115, 21, 14,219, 91,189,237,126,146, 44,206, 47,
- 116, 58,221, 43, 87,174,228,107,230,247,119,144,203,226, 43,123,
- 217,128,180,158, 78, 76, 49, 58,214,173,239, 39, 34,245,170,249,
- 117, 48,113, 1, 2,116,131, 96,184,211, 35, 34, 69,202, 84,142,
- 230, 91,172, 34, 96,165, 10, 18,144,180,214,162,100, 97,242,109,
- 31, 41, 12, 27,211, 51,211,107,235,235,127,254,214,197,119,191,
- 103, 41, 65,212,206, 36,163, 43,190, 28,126, 57,251,118, 72, 85,
- 226, 52, 73, 39, 64, 33,249,202,140,112, 82, 69, 46,112,130,255,
- 183,122,219, 0,240,222,231,223,219,239,247,134,131,161, 51,249,
- 136,222, 77, 81,118, 89, 33,143, 37,120, 33,166,149,255,196,210,
- 164, 28, 94, 53,194, 38,135,111, 53,191, 30, 40,193, 16, 91,164,
- 162,225,176, 57, 61, 21,132, 65,146, 36, 40,233,190,243,226,189,
- 250, 75, 73,139, 75, 94, 58,230,157, 34, 89, 35, 80, 8,195, 96,
- 97,113,113,107,107,235,226,218,237, 63,185,244,211,151,150,142,
- 199,144,106,176, 2,182,236,101,167,239,132, 84,164,248,147, 20,
- 179,100, 73,133,184,138,210, 53,140,133,166, 91, 25,188, 94,222,
- 188,179, 54, 26,180, 91,173,119,190,235, 93, 23, 46,188,106,246,
- 193, 28,243, 26, 81,121,132, 11,230,209,219, 32, 24,128, 89, 51,
- 1,132, 68, 4,104,227,252,154, 96,247,196, 45,121, 27,249, 85,
- 119,159,216,159,254,154, 86,225, 86,175,215,153,155, 13,195,144,
- 211, 14, 92, 6, 95,152, 46, 39, 46, 73, 48, 41, 79,217,231, 39,
- 88,126, 58,153,237, 14,143, 30, 59,118,249,242,229,175,189,241,
- 234,217,153,185, 5, 84,166,158,192,203,191, 28,132,101, 68, 40,
- 71, 96, 19, 37,189,178,254,176,118, 46, 66, 24, 64, 11,251,162,
- 75, 4,176,112,247, 55,226,232,194,214, 58, 0,124,254, 23,127,
- 113,115, 99,115,107,107,147,133,203,221, 62, 10,237,192,198,111,
- 158,230,110, 82,135,136,144, 36,162,181, 38,145,182, 10,208, 86,
- 178, 98,205,165,137, 57, 6,193,110,119, 76,118, 69, 88, 77,180,
- 42,132,205,135,141,155, 91,219,116,138, 2, 21, 68, 24,217,189,
- 184, 32,119,145,101, 9, 86, 37,228,202,219, 62,138, 72, 16, 4,
- 179,179,115, 59, 91,219,119, 54, 55,254,240,181,159,252,210, 59,
- 222,217, 64,176,179,141, 69, 9,230,216, 49,207, 62, 74, 21, 60,
- 222,246,215,231, 66,254,229,116, 44,243,247, 11,112,198, 64,235,
- 239,172,221, 4,128,231,223,243,222,249,249,249, 87, 94,185, 48,
- 24, 12,210, 93,154,188,109, 32,139,237,192,138, 81,189,215, 42,
- 199,254, 67, 52,109,215, 18,157, 4, 2,109,165, 8,144,234,198,
- 171, 19, 54,106,255,248,128, 13,228, 76,208, 24,109,109, 34, 34,
- 41, 34, 36, 73, 59,176,166, 77,245,196,169,100,173,120,221,144,
- 114,132,236,157, 78, 0,208,108, 54,158, 56,251,228,232,149, 87,
- 86,123, 59,255,247, 27, 23,254,198,137, 51, 51,168, 18, 22,102,
- 91, 15,149,137, 47, 17,182,109, 95, 29,120,249,221,239, 39, 50,
- 197,223, 15,230,183,226,248,251,119,110,109,199,209,177,163, 71,
- 63,253,217,207,188,246,218,107, 27, 27,119,152,185, 96, 14,199,
- 72,133,138, 62,171,174,246,178, 91,129, 72,146, 36, 58, 73, 90,
- 2, 51, 65, 72,147,221, 73,166,230,215,132, 70,116,135,201, 63,
- 34, 52,136,218,130,253,237, 29, 10, 3, 36,194,116, 97, 15, 32,
- 216, 40, 12,100, 79,245,229, 57, 71,159, 95, 34,210,108, 54,223,
- 253,158,247,254,240, 7,223,191,182,189,249,111, 95,253,241, 7,
- 143,156, 56, 63,179,160, 33, 85, 97,110, 85,167, 28,170,135, 69,
- 246,109, 87,126,186,189,249,147,205, 53, 22, 89,152,159,255, 47,
- 254,222,223,187,122,245,234,205,155, 55,205,110, 79,222, 55,101,
- 27, 65,250, 66,206,147,183,249, 12, 73, 74, 47,107, 30,145, 57,
- 137,163, 8,180,110, 17, 53, 80, 17, 34, 1,214, 83,144, 19,117,
- 254, 7, 53,150, 30,116, 4,134,115, 97,163,183,177, 57,179,178,
- 28, 4, 1,107, 45,152, 53,177, 73,189,100, 6,179,170, 3, 46,
- 5,229,149, 42, 2,219,181, 69, 68,180,214,173, 86,251,227,159,
- 248,196, 15,127,240,131,235, 55,110,124,243,250,229, 43, 59, 91,
- 231,102, 23,150, 27, 45, 45, 98,226,176, 67,251,236,151, 93,110,
- 128, 0,183, 71,131,215,183, 55,111, 12,122, 0,240,238,231,158,
- 251,197, 47,124,225,205, 55,223,188,124,249, 74,191, 63,200,203,
- 238,109, 21,118,234, 28,211,233, 93,192, 10,126, 21, 95, 36,242,
- 15,136, 81,164, 71,163,136, 88,186, 65,160, 16,149,201,239,235,
- 103,249,225,209, 95, 82, 3,237,238,220,163, 32,161, 28,111,118,
- 126,176,182, 54,119,244, 72, 16, 4,177,112,170,185,208, 10,177,
- 52, 15,131, 44,209, 47, 11,178, 49,137, 76,122,182, 49,115, 20,
- 141,130, 64,189,255, 3, 31, 88,189,189,250,151,127,249,151,151,
- 183, 55, 47,111,111, 46,183,187,199, 58,221,217,176,185,216,104,
- 226,164,175,217,190,139,231,149, 0,172,141,134,155,241,232,122,
- 191,103,234, 84,195, 32,248,187,127,247,239,158, 62,115,230,181,
- 215, 94,187,122,245,106,175,183, 99,143, 44, 88, 94,229,251,166,
- 101, 74, 12,199,120,243,204, 51,250,230, 17,146, 36,137,162,168,
- 5,184, 16, 54, 21, 34,161, 89,202, 93, 11,176, 58,255,122,180,
- 35,176, 48,196,237, 81, 18,141, 40, 8,136, 40,219,253, 43,163,
- 152, 51, 31,185,219,207, 1,172, 8,101, 50,132, 13, 6, 67, 17,
- 88, 57,178,242,139,191,244,133, 11, 63,121,249,194,133, 87,110,
- 15,122,183, 7,189, 71,251,240,118, 90,237, 15,127,228,195, 31,
- 255,196, 39, 54,183,182, 94,126,249,149,219,183,111, 13, 6, 67,
- 27,123, 65,190,211,182,117,142,206, 22,144,133,156,203, 59,182,
- 133, 35,140,136, 73,146,140,134, 35, 78,226, 38,224, 84, 16,170,
- 12, 94,245, 24, 99,234, 15, 31,191,106, 49, 86, 25,129,145,224,
- 82,163,181,179,126,103,230,200, 10,145, 50,203,168,237,155, 41,
- 200,247,138, 42,198,129,172, 60, 29,102,127,131, 65,152, 30,141,
- 134,155,155,156, 36,201, 59,159,123,238,163, 47,190,120,253,250,
- 181,159,190,250,234,141, 27, 55,214,238,220,121,196, 14,236,242,
- 226,226,233,211,167,159,127,225,133,119,188,227,233,245, 59,235,
- 111,188,113,241,246,237, 91,219, 91,219,113, 18, 23, 55, 6, 6,
- 65,243,175,176,243,166,111, 21,161, 84, 42,225,194, 11, 0,147,
- 68, 15, 6, 3,197, 50, 29, 52, 20,162,170,195,175,177, 16, 40,
- 161, 76, 14, 9,191,106,138, 85, 66,135, 16, 79,182,186,223,185,
- 117,123,246,200, 17,165,148,237, 65,159, 55,115,206,130,176,180,
- 168,162, 12, 49,129,162,127,132, 52,125,113,202, 39, 81, 68,162,
- 40,214,122,123, 56, 26,237,236,108, 79, 77, 77,191,248,210, 75,
- 83,211,211,221, 78,167,209,108,154,174,229, 88,238,104, 85,245,
- 217,196,120, 71,167,191,181,216, 99, 35,146, 36,122, 48,232,111,
- 110,110,254,240,135, 63,216,220,220,220,217,233,197,113,204,172,
- 237, 95,146,215, 6, 99,230, 31,205, 42, 34,255, 72, 22, 95, 21,
- 178,216,203, 31,204, 60, 26, 13,135,195, 97, 27,112, 33,108,154,
- 109, 44,168,198,215,225,240,143, 82,177,104,187,134,212,254, 37,
- 24, 1, 78, 5, 65, 71,203,112,103,167, 53, 61, 69, 64,206,214,
- 26,217,192, 10, 47,233,128, 76,178, 62,212,254,252,163,123,162,
- 166, 15,141,112, 52, 26, 37,113,188,179,179,179,190,222,108,183,
- 91,205,102,171,209, 8,145, 8,139,154, 99, 2,233, 85,194,150,
- 67, 47,115,216,180,214,113, 28, 15,134,131,225, 96, 16, 69,145,
- 214, 90,156,149,157,152, 30,180,108,122,214, 44,155,151,116,243,
- 58, 27,185,151,253,184, 39,187, 32,109, 57,105, 70, 28,199,253,
- 94, 95,226,120,138,130,233, 32, 12, 76,248, 85,135,247,135, 47,
- 255,218,127,193,246, 4, 19,174,187,188, 56,181,180,100, 46,223,
- 121,235,114,212,235, 31,180,133, 84,130,199,154,157,107,171,107,
- 237,233, 41, 36, 18, 17, 17,146,226,216,219, 75, 22,245,151,173,
- 0,119, 75, 58,179, 51, 86,107, 30,142,134, 81, 52, 66,220,178,
- 137,116,206, 64,184,255,158,202, 15,135, 95,206, 94,188,146,247,
- 149,229,236,127,245, 65, 79,191, 49, 19,182,169,121,244,177, 85,
- 229, 25,193, 97, 23,165,101, 95,195,225,176,215,219,105, 8,204,
- 5,141, 16, 73, 33, 41,215, 60, 62,222, 47,230,178, 63, 21, 42,
- 19,193,175,195, 60,142,156, 63,247,228, 75, 31, 93,126,231, 51,
- 211, 22, 94, 0, 48,234,247,191,247,123,127,240,198,159,253,197,
- 65, 91,200, 19,173,206,155,235, 55,227,227,199,194,102,211,246,
- 210,225, 18,194, 42,189,164, 39,196, 92,132,165, 5, 26,165,167,
- 138,164, 69, 23, 94,169, 42, 22, 94,125, 38, 87, 60,248, 47,146,
- 213,252,202, 86, 18,216,203, 85,155,174,217,169, 93, 44,170,215,
- 113,158,209,113,143,100,197,215,104, 20,109,111,111, 71,131,225,
- 34,170,229, 70, 43, 32, 12,106,243,184,219, 99,135,111,163,156,
- 121, 4,249,213,232,118, 78,190,255,249,119,125,254, 23, 12,182,
- 182,227,254,215,175,255,240,167,155, 87, 1, 96, 42,108,127,230,
- 244,135, 62,242,143,126,165,119,123,237,230,203, 23, 14,212, 66,
- 42,196,227,173,206,234,181,235,203, 79, 62, 65,100,188,141,170,
- 66, 88,217, 75, 58,142, 50, 95,214, 13,110,253,101,254, 12,201,
- 151,201,236,178,172, 82, 38,173,229,234, 88,140,185,251, 41, 65,
- 190,247,155, 71,177,234,150,116, 25,255,179,248,190,202, 45, 22,
- 235,188, 10,240, 34, 17, 30,244,251, 91,155, 91, 45,192,249,176,
- 25, 18,165,225, 87,109, 30,239, 61,211,172,249,181,239,113,238,
- 51, 63,247,220,231,127,161,217,233, 0,192,215,175,255,240,171,
- 151,255,211,159, 95,255,161,123,131, 63,191,241,163,255,233,197,
- 127,242,161,255,234,239,127,229,159,254,218,129, 90, 72, 2,124,
- 162, 61,125,109,253,102,124,252,104,163,213,166,212,155,224, 88,
- 132, 21,188,100,169,111, 5,238,150, 24, 85, 61,119, 76,253, 64,
- 42, 68,196,180,143,129,251,216,214,245,225, 69, 95, 30,193,242,
- 234, 19,219,162,162,130, 96,185, 96, 53, 69,117,228,112,203, 9,
- 16,113, 87,120, 33,194, 96, 16,111,108,220,137, 71,195, 25, 84,
- 199,154,237, 16, 41,176, 57, 98,205,175,253,169,176,135,250,210,
- 24,220, 51, 49, 39,237, 21,252,228, 7,158,127,223,151,190,104,
- 52,215, 31,191,245,237,223,185,240,199, 55,250,235,229,155,125,
- 127,245,181,239,173,190,246,190,165,167,207,125,230,231, 46,124,
- 245, 63, 28,160,133, 4, 8, 16,143,183, 58,215, 47, 94, 58,254,
- 236, 51, 0, 1, 17, 2, 32, 51,102,129, 78, 17, 97, 34,206,122,
- 201, 92, 81,164, 89, 53,186,114, 43, 91, 20,147, 63, 30,197, 94,
- 13,232, 5,100, 89, 19,172, 73, 13,112, 10,125,202, 60, 9, 6,
- 69, 43, 89,106,236,111, 15,187,128, 16, 82,217, 45, 86,194, 43,
- 243,140,198, 32,106,157,236,108,111,111,108,108,118, 4,231, 27,
- 205,144, 40,180,187,109, 63, 52,124, 29, 57,127, 14, 0, 86,206,
- 63, 83,249,213,222,234, 90,239,246,218, 65,103,184,135,104, 60,
- 10,250,171,209,237,124,248, 31,254,253, 83, 31,120, 95, 70,174,
- 169,176,253,133,179, 63,251,142,217, 19,239, 91,122,250,235,215,
- 127,248, 47,191,247,251, 59,241, 32,187,253,191,252,222,239,255,
- 219,159,255, 31,158,251,252, 47, 28, 36,191,128,172, 4,219,220,
- 90,235,221,217,152, 94, 92,180,243, 91,102,143, 70,220, 21, 97,
- 48, 86,134, 21,156, 97,102,186, 42, 58,243,228,228, 50,251,160,
- 227,196,178, 11,160, 18, 94,249,230, 74, 5, 29, 6,144,107,177,
- 2,192,128,138,110,209, 89, 18, 84,158,106, 76,131,123, 66, 17,
- 25, 12, 6,107,107,171,144, 36, 51, 42, 56,214,108, 55,172,248,
- 58,232, 29,212,230,207,156,122,242,165,143, 30, 61,127,110,238,
- 204,169,125,126, 75,127,117,237,198, 79, 46, 92,249,238,247,175,
- 252,213,247,107,126,221,175,230,122, 27,207,137,147, 31,120,254,
- 195,255,232, 87,154,157,206,107,155, 87,254,151, 31,255, 33, 0,
- 252,119,239,251,229,247, 45, 61,157,221,224,165, 99,239,249,233,
- 230,213,223,185,240,199,217, 53,207, 47, 61,189, 29,247,167, 59,
- 157,249, 51,167,238, 92,186,124,112, 18, 76, 1, 4,136, 39, 90,
- 221,151, 47, 95,105,207, 76, 19,181, 84, 64,132, 36,194,136, 50,
- 70,136,101, 8,179,117,152,217,191, 98,255,174,188,184, 60, 61,
- 219,171, 58, 91,184,226,203, 80, 12, 74,121,218,219,171,186, 42,
- 10,117, 36,111,167, 51, 70,136, 85,244,254,201, 68, 86, 33,234,
- 42,151,167,122,222, 49, 45, 50,193,209,104,184,190,182,190,189,
- 185, 53, 45,176, 24, 54,155,164,140,248, 82, 7, 41,190,230,207,
- 156,122,225, 75, 95, 52,154, 11, 0,228,198, 53,184,113, 29, 54,
- 54,224,230,117, 24, 14, 42,190,225,204, 89,104,181,224,232,177,
- 206, 19,103,207,126,252, 99,103, 63,254,177,222,237,213,111,253,
- 214,239, 30, 92,152, 59,225, 89,216,225,214, 95, 47,124,233,139,
- 207,126,230,231, 0,224,255,120,229,143,255,221, 27,255,223,175,
- 156,251,236, 47, 61,245,179, 0,112,253,149, 11,151,254,236,155,
- 87,190,243,125, 0,248,220,191,250,141, 47, 60,245,137,175, 94,
- 254,246,141,254,250, 59,102, 79,252,227,231, 62,111,232,246,202,
- 87,255,195,193,193, 43, 75,193, 20,224, 74,163,117, 39, 30,173,
- 95,189,182,116,250, 20, 17, 82, 16, 16, 40,102, 65,100, 43,196,
- 74, 50, 44,239, 90, 81, 4, 89, 94,239,108,150,200,152,204,204,
- 118,217,119, 82,127, 79,124, 89, 90, 21,102,250,112, 2,159,221,
- 226,238,231, 81,156,140,116,246,186,204,154,203, 26,245, 73,119,
- 11, 47,114, 98, 47, 76,146,100,115, 99,227,246,237, 91, 45,128,
- 165,176,185,220,104, 53,108,114,127,112,244,154, 63,115,234,231,
- 254,217,175,134,157,142,188,249, 6,252,224,187,240,202, 79, 96,
- 56, 4, 0,104,181,224,217,119,194,153, 39,225,232,177,252,214,
- 27,119,224,230, 13,248,193,119, 97,227, 78,122,212,158,125, 39,
- 156, 59,223,125,254,253,159,250,103,191,250,173,223,250,157, 3,
- 157, 82,159,216, 76,233,176,242,171,209,237,188,240,203, 95, 60,
- 251,241,143,109,199,253,127,254,159,254,247,159,110, 94,249,215,
- 47,254,147,167,103, 79,110,175,174,126,239,247,254,192, 21,213,
- 175,126,245,107,239,254,252,231,254,241,115,159,223,137, 7,159,
- 61,253, 97, 67,183,191,254,191,254,232,214,193,191,100, 33, 32,
- 33, 40,196,179,157,233, 31,173,223,217,238, 78,205, 46, 47, 42,
- 165, 80, 41,133, 34,130, 25,197,236,182,217, 54,175,134,188,101,
- 133,181,147, 46,200, 76, 99, 66,143,106,126,127,196,130,211, 52,
- 63,160,172,185, 38,201, 75,138,255,206,177,198,190, 10, 3,167,
- 223,180, 65, 23, 82,198, 41, 40, 78, 49, 86,154,198,156, 92,132,
- 132,200, 44, 59, 59,219, 55,111,222,192, 56, 89,160,240,120,171,
- 211,176,226,235, 64,203, 38, 94,248,210, 23,195, 78, 71,254,228,
- 223,195,183,190,145, 95,251,145, 23,225, 19,159,196, 86,187,250,
- 123, 62,253,183,228, 91,223,128, 63,249,247, 0, 0,175,252, 4,
- 94,249,137, 92,120, 25,255,206,151,222,255,165, 47, 62, 60,126,
- 77, 82, 45, 78, 48,161,207,230,189,198,167,126,237, 87,231,207,
- 156,122,109,243,202, 63,253,198,255, 12, 0, 6, 94,151,255,234,
- 123,223,254,237,223, 45, 68,155, 63,250,242, 87,158,248,248, 71,
- 95, 58,246, 30, 0,216, 94, 93,253,235, 47,255,209, 67,123,164,
- 109, 33, 5, 53, 8, 78,180,186, 63,185,244, 86,179,219, 86, 74,
- 53, 72, 17, 41, 17, 3, 47, 76, 55,225,192, 42, 37,102,201,229,
- 131, 44,203,244, 37, 95,239, 7, 82,202,192,138,179, 66,226,132,
- 254, 56, 65,212,170,250, 76, 10,251,114,139,247,207,252, 49, 37,
- 100, 21,139, 36,118, 73,235,211, 77,210, 73, 64,250,253,222,141,
- 235,215,123, 59, 59, 51,130,139,141,102,139,148, 21, 95,116,160,
- 101, 19, 71,206,159,147, 27,215, 60,120, 1,224,167,255, 86,220,
- 239,191,254,213,255,112,229, 59, 63,112, 95, 98, 87,206,159,155,
- 63,115,242,217, 79,127,170,251,145, 23,229,194, 79,224,205,139,
- 233, 23, 94,249,137,124,255, 59,225,243,239, 95, 57,127,238,214,
- 36,187,200, 90,127,229, 47, 81,255,232, 87, 50,120,237,196,131,
- 95, 57,247, 89, 3,175,175,255,235,127, 83,121,251, 63,255, 87,
- 255,230,220,167, 63,117,231,173,203, 23,191,254,205,135, 63,113,
- 67, 8, 1,224, 74,163,181,157,196,215, 95,191,120,252,252, 57,
- 0,108, 54,155,164, 8, 82, 9,102, 82, 48, 11, 50,191,222, 73,
- 160, 2,100,222,123, 91,215, 89,216,105, 18,242, 46, 12, 21,128,
- 144, 73,129,152,236,173,197, 28,102,101,253,209, 10,236, 2,172,
- 238,225, 85,240,140,174,248, 34, 66, 17, 24,244,251, 55,174, 95,
- 91, 93, 93,155, 22, 92, 12,155,105,242,133, 70,124, 29,252, 95,
- 111, 12,163, 63,214, 47, 93,254,238,239,253, 65,225,202, 91, 47,
- 95,184,245,242,133, 70,167,243,238,207,127,174,248, 13, 27, 27,
- 143,107,124,127, 8,249,181,114,254,220,217,143,127,236,122,127,
- 205,192, 11, 0,222, 49,123, 2, 0,174,126,247, 7,227,190,229,
- 206,165,203,223,250,173,223,121, 91,238, 45,218,112, 38, 64, 58,
- 219,153, 26,238,108,220,190,120,105,233,137,211, 68,212, 82, 77,
- 36,229,194,203, 94,150,170, 50,125, 17,175, 38,170, 40, 70,188,
- 168, 8, 74, 36,155,148,188,226, 30,189,100, 58,119, 74,128, 64,
- 99,203,234, 11,105,215, 94,202, 11, 0,134,195,193,141, 27, 55,
- 174, 95,191,222, 17, 88, 80,225,169,118, 55, 19, 95,198, 57,214,
- 53, 95, 19,238, 33,233,208, 5,119,231, 62,253, 73, 0,248,151,
- 223,251, 63,179,146,136,127,247,198,127, 4,128,119,125,254, 23,
- 38,243,161,206,202,241, 3,164,103,187,115,221,222, 96,237,242,
- 213,225,112, 24,199, 49, 0, 40, 69,170,106, 16, 41,162,236,139,
- 68,138,136,148, 34, 51,148,249, 52,125,239, 12, 69,206, 53,120,
- 104,207, 65, 76, 83, 45,239,239, 82,222, 5, 42,254,217,233, 1,
- 82,148, 30, 58,242, 15,166,243,137, 82, 74, 33, 97, 20,141,110,
- 221,186,121,245,242,149, 22,195,146, 10, 79,183,167, 90, 68, 13,
- 82,117,193,253,253,159,245, 15,141, 7,193,189,210,245,109,123,
- 233, 94,121,231,185,235,253,181,239,175,190,150, 93,243,253,213,
- 215,254,248,173,111,127,246,244,135,223,253,249,207,253,232,203,
- 95,153,204,199,218,184, 72, 33,122,166, 51,251,202,230,198,198,
- 205,155,178,178,220,237, 66,171,213, 34, 82,146, 55,104, 69, 17,
- 177, 90,172, 32,192,178,182, 11,142, 16, 43,196, 67,126,114, 84,
- 245,113, 2,149, 23,238,126,169, 98, 55,185, 49,166,209, 79,235,
- 177, 58,179, 71, 4,144,225, 96,120,227,250,141, 75,111,190, 25,
- 48, 47,169,240, 84,171,219, 34,213,204, 99,251,135,245,151, 63,
- 113, 22,254,251,223,184,235,239,250,251,255,176,134,231,131,241,
- 143, 15,255, 60,136,250,253,169,217,206, 84,216,118, 75, 82,127,
- 231,194, 31,255,204,177,119, 63,243,153, 79, 77, 38,191,114, 23,
- 9,208, 84,116,178,213,189,124,115,117, 93,235,100,121, 25, 68,
- 218,157,142, 82,100,139, 38, 80, 68,144, 42,124,100, 69, 13,148,
- 255,222,179,142,224,150, 86, 29,198,134, 9, 89,147,212, 2,197,
- 42,182, 53,113,186, 63,151, 99, 47, 42,173,112,148, 94,175,127,
- 237,234,213, 75,111,190, 25,138,172, 80,176,220,104,117, 84,208,
- 82,222,156,227, 67, 32,216,183,126,235,119,158,124,233,163,229,
- 235,127,244,229, 63, 26,247, 45,111,124,253, 47, 42, 75,243,239,
- 92,186,252,182,135,247,111,139,165, 12, 14, 21,187, 0, 0,174,
- 254,213,247,159,253,204,207,125,225,236,207,102, 37,169, 71, 59,
- 11,255,248,185,207, 79,135,157, 81, 60,185,139, 42, 28,132,209,
- 98,216, 20,128, 43,171,119,214,163, 72,152, 89,164, 59,213, 13,
- 84, 0, 0, 41,191, 76,187, 29,174,230, 87,198,176, 42, 9,230,
- 130,172,234, 49,154,100,148, 97,197,231,101,241, 85,170,243, 42,
- 240,171,162,196,222,100, 94,128,200,204, 59, 59,219,151,223,186,
- 124,245,202,149,166,200, 18, 5,203,141,246, 66,216,104,146,202,
- 170,237, 31,154,229,126,227,207,254,226,110,167,194,123,183,215,
- 190,246, 47,126,243,145,176,152,147,161,191, 30,254,248,241, 31,
- 254,209,147, 31,255,216, 63,120,246,179, 95,189,252,237,157,120,
- 240,133,179, 63,251, 15,158,253, 44, 0,108,175,174,126,251,127,
- 253,221, 9, 79,117,204,194, 60, 32, 90, 12,155, 45,162, 55,182,
- 118, 86,227,183,244,137, 19, 73,146,204,204, 76, 55, 26, 77, 36,
- 5, 25,187,200,214,231,131,219,132, 97, 44,191,252,202,207,125,
- 185, 70,153, 28, 88,221, 27,191, 42,244, 87,101,177, 42, 34, 64,
- 156, 36, 27,119, 54,222,186,244,230,237, 91,183, 91, 44, 75, 42,
- 60,222,234, 76,169,176, 69,212, 32, 10,168,142,189,238, 67,114,
- 21,186,161, 76,146,254,146,251,190,193, 3,245,143,189,254,143,
- 191,252,149,247,127,233,239,252,250,135,254,203,163,157,133,233,
- 176, 51,234,247,127,252,229,175, 92,248,234,215, 14,129, 41, 50,
- 8, 3, 0,162, 41, 8,207,117,103, 95,237,109,174, 94,124,115,
- 116,236,104, 20,141,230,231,231,219,237, 14,145, 2,112,186, 29,
- 82,169,160, 2,202, 65,216, 56,253, 5, 19, 61, 3,137,123,127,
- 205,181,145, 88,236, 68,232,237,217,232,252, 47,218, 71, 16, 25,
- 12,134,183,111,223,186,244,230,155,189,237,157, 14,203, 98, 26,
- 216,171, 38,169,166,129, 87,189,189,246,225,179,143,135,179,254,
- 235,194, 87,191,246,196,199, 63,246,244,233, 83, 70,132,127,231,
- 247,255, 32, 62, 84,203,241,201,244,101, 39, 2,128,115, 83,179,
- 175,247,182,174,191,249, 86,124,100, 57,142,226,185,249,249,169,
- 233,169, 70, 24, 34, 81, 65,115, 21, 83, 48,247, 2,184, 77,103,
- 202, 8, 59, 92, 17, 24, 86,102, 96, 99, 54, 13, 42, 34,172, 64,
- 48, 0,208, 73,178,189,189,125,245,234,213,183, 46, 93, 34,150,
- 46,203, 82,208, 56,213,234, 54,149, 74,109,163,129, 87,205,174,
- 67, 56,130,201,124, 97,222,115,252,233,191,248,205,249,211,167,
- 122,171,171,189,219,107,135,235,136, 99,134, 48, 0, 36, 66,129,
- 167,187, 51,221,209,224,250,237,181,213,193, 96, 48,232,207,204,
- 204,206, 47, 44,116,187, 29,149, 38, 98, 57,196,242,126, 88,246,
- 114, 97, 73, 13,120,123,110, 23, 58,210, 28,166, 99, 84,104,117,
- 61,110,199,179, 18,194, 60, 33,198,204,131,193,224,246,237, 91,
- 151,223,186,188,185,185,209,100,153, 5,181,216,108,174, 52, 90,
- 70,118,133,182,212,171, 86, 94,135, 50,253, 58,188,235, 31,227,
- 94,255, 80,175,150, 48, 70,210, 20,101, 34,225,137, 86,103, 46,
- 104,188,217,223, 89,235, 95,237,207,110,247,251,189,249,133,133,
- 217,217,217, 86,171, 77, 68,214, 28,238, 14,175, 92,133,237, 41,
- 190,100,242,142,198,216,235,156,222,253,229,142,208, 30,194,156,
- 6, 95,194, 50, 26,141, 54, 54,238, 92,189,114,245,218,181,171,
- 129, 64,151,101, 65,133,199, 90,157,174, 10,154,164, 26, 68, 33,
- 146,217, 24,173,174, 83,125,176,196,122,152,207,174, 96, 47,114,
- 202, 94, 87,214,227,126, 78, 90, 84,102, 67, 14, 32, 10,194,103,
- 187,179,215, 71,253, 27,235,155,235,189,254,206,246,206,157,153,
- 233,133,133,133,153,153,217, 86,187,165, 72, 33,161,167,194,188,
- 10,124,103, 73,115,177,145,233, 97, 61, 58, 94,183,236,194,230,
- 103, 99,151,107, 3,179,140,134,195,205,205,205, 27,215,111, 92,
- 187,118, 53,137,147, 54,203, 52,170,197,102,218, 85,162,129,166,
- 194, 30, 21, 98, 93,100,255,200,250,199, 9,209,135,143, 3,194,
- 40, 61, 3,133, 16, 78,180,186, 43,205,214, 27,253,157, 27, 55,
- 110, 14, 55, 55, 55,239,108, 76,207,204,204,205,207,205,206,206,
- 118, 58,157, 48,108, 16,102,114,204,239,242,231,144,171,132, 45,
- 57, 44, 15, 23,238,170,191,220,173,152, 10,123, 9,129, 72,156,
- 36,131,254, 96, 99, 99,227,246,173, 91, 55,110, 92,215,113, 18,
- 178, 76,177, 44,134,141, 19,173,110,131,168, 73, 20,162, 10, 9,
- 157,253,132,106,120, 61, 32,213,133,135,145, 95,245,120, 64, 8,
- 51,109, 8, 17, 8, 73,148,224,211,221,153, 19,186,115,101,216,
- 187,121,123,117,117,107,107,237,246,237,238,244,244,236,220,236,
- 236,236,220,212, 84,183,213,110,135, 65,136, 10, 1,160,106, 17,
- 164,159,122,201, 33, 63, 52, 30,200,138,213,247, 34,146, 36,201,
- 112, 56,236,237,236,172,223, 89,191,125,235,214,250,250, 58, 9,
- 4, 44, 45,150,197,176,177,210,105,119, 72,153,126, 56,153, 97,
- 36,179,250,177,134,215,161,140,188,238,155, 95,181,234, 58, 16,
- 21,102,119,253, 32, 20, 18, 84,136, 79,119,102, 78,104,125,109,
- 212, 95,219,218,217,233,245,183, 86, 87,175,181, 91,221,110,119,
- 118,110,110,122,122,166,211,105, 55,155,173, 70,163, 17, 4, 1,
- 169,180,197,113,105,237,208,161,218,133, 24,171,240,229,171, 48,
- 179,163,109,146, 36,113, 28,141, 70,163,126,127,176,185,177,177,
- 182,182,182,190,190,198,204, 1, 75, 91,164, 37, 56, 27, 54,150,
- 27,173,142,197, 86, 96,155, 17,214,178,235,225,162,236,192,159,
- 112, 65,141,173, 73, 19, 98,102,239, 15, 5,164, 20, 6, 72, 29,
- 53,125, 70,166, 86,163,225,237,104,184, 57,220,220,218,218,185,
- 115,243, 54, 52,194,102,179,217,237,118,167,166,166, 58,221, 78,
- 179,217, 10,195, 48, 8, 2, 21, 40,183, 14,224,145,200,191,192,
- 52,147,213, 90, 39, 73, 18,199,241,112, 56,232,247,122,219,219,
- 59,219,219, 91,189, 94, 15, 0, 2,150,134, 64,192, 50,165,130,
- 249, 70, 99,193,238,123, 22, 34, 6, 72,138, 48, 0, 36,187,244,
- 177,150, 93, 15, 95,143, 29,220,115,176,246,143,147,103,152, 0,
- 76, 34, 70, 32,154, 36, 0, 12, 68,142,183, 58, 43,141,214,136,
- 121, 53, 30,110,196,209,230, 78, 47,233, 15,214, 55, 54,110, 3,
- 50, 2, 40, 10,131,176,209,108,132, 97,104,230, 43, 31,177,193,
- 204, 81, 20,141,134,163, 56,137, 1,128, 4, 72,128, 64,218, 44,
- 74,100, 90,133, 51, 97, 56, 23, 54,155, 68, 1, 82,128,104,138,
- 233,205,214, 65, 42,171,167,168,201,245,246, 57,202, 3, 42,226,
- 169,249, 53,177, 66, 44,111,168,170, 0, 24, 69, 35, 53, 72, 58,
- 74,157,104,118, 18,145,141, 36,218, 74,162,190,214, 67, 78,162,
- 36,214, 81,146,244, 7, 35,194, 71,248,176, 4, 44, 1,128, 18,
- 9,145, 90, 74,181, 72, 77, 55,194,153, 48, 84,144,210, 74, 33,
- 170, 44,228,202, 39, 70,108,234, 95, 63,183, 38, 0,100, 19,197,
- 175,218, 83, 30,104, 16,148, 26, 30, 66, 96, 65,133,194, 34, 12,
- 200, 2, 90,164, 69,106,185,209, 98, 49, 87,202,102, 18,139,200,
- 182,142, 69, 30,205, 7, 6, 1,166,154, 1, 2, 78, 7, 33, 1,
- 80, 74, 40, 36, 68, 83, 61,175, 16, 41, 13, 16, 17, 33,219,244,
- 172, 38,215,193,160, 8, 39,130, 14,181,254, 58, 4, 20, 3, 0,
- 101, 86, 28,153, 0, 27,129, 69, 24, 64, 68, 24,132, 5, 4,164,
- 69,129,128,172, 64, 91,108, 5,190, 60,114,135, 34, 93,162,109,
- 55, 70, 49,239, 9,210,110,170,100,191, 84, 11,174, 73,101,222,
- 131,127, 74, 22,249, 37, 50,182,114,187,126, 54, 76,134, 28, 67,
- 1, 81,136,166, 21,190, 0,176,221, 14,209, 33,151, 60,162,199,
- 1,125,138,121,204, 2, 39,244,175,159,171,147,233, 29, 31,248,
- 51, 51, 40,192,107, 63, 17,103,253,228,120, 91, 41,102, 66,177,
- 244,129, 18, 0,195, 50,128, 20,103,143,170,177,119,254,124,183,
- 138,181, 54,137, 19, 77, 44,187, 73,231, 65, 61, 33, 3, 31, 94,
- 102,171, 64,244,183, 63, 78,191, 92, 63, 36,147,168,200,204,131,
- 147,203,142, 67, 92, 50,113, 87,134,186, 6,214,225, 1,153, 28,
- 92, 21, 69,224, 3,211,228,114,226,236, 73, 47,187,194, 11,235,
- 8,127,162,180, 73,173, 68,234, 49, 9,186,171,156,192,102, 42,
- 232,193,242, 34,112, 49,201,108,186,229,121, 78,181, 62, 25,234,
- 81,143,122,220,181,115,180, 32,203,152,117, 16, 22, 46,175,117,
- 20,246,154, 20,131,179,119,106, 22, 59, 32,212, 76,171, 71, 61,
- 234,177, 47,136, 9,216,153, 37,176, 93, 56, 15,206, 63, 10, 51,
- 3, 8,160, 32,152, 85,102,192, 89,111, 22,169,246, 44,133,253,
- 234,235, 81,143,122,212,220, 74, 53, 87,222,174,206, 82,236, 32,
- 231, 31,153, 89, 16,205,123, 1,180,173,138, 57,235,204,143,158,
- 244, 50,248,170, 83,253,122,212,163, 30, 46,188, 50,255,230,188,
- 25,156,129,136, 45,121, 57, 16,126, 49,128,144, 48, 18, 1, 10,
- 164,149, 69, 34,130,144,206, 75,154,173, 16,176, 54,144,245,168,
- 71, 61, 60, 47,230,233, 47,112,153,101,183,157, 49, 31,130,217,
- 233, 7, 24, 68, 57,252,210, 90,139,104, 1, 66, 96, 83, 98,196,
- 146,237,204,181, 11,179,208, 78, 89,214,163, 30,245,120, 60,217,
- 133, 89, 57, 34,128, 0, 48, 56,204, 2, 96, 1, 6, 97, 16, 1,
- 8,130, 7,185,230, 39,255, 89, 90,107,101, 82, 47, 20, 54,101,
- 205, 44, 34, 12,204,238,125, 69,216, 27,157, 53,203,234, 81,143,
- 71, 87, 99,237,246, 37,199, 48,166,204, 50,235,115,249, 0,138,
- 39,114,126, 5, 65,192, 73,162, 17, 53, 49, 41, 69, 72, 8, 72,
- 34,162, 89, 68,128, 5,236,186, 13,211,172, 55, 11,239,235, 2,
- 176,122,212,227,113, 24,222,146,109,244,187, 75,230,251,214, 74,
- 182, 73, 60,219,205,151, 83,132,137, 48,136,136,184,253,157,112,
- 95,120,220, 7,191,186,221,238,109, 69, 20, 37, 9, 9,177,144,
- 217, 71, 93, 0,152,133,217, 20,120, 91,120,165,157,123,177,230,
- 86, 61,234,241, 56, 43, 50, 44, 80, 71, 0,128,157,169, 70, 6,
- 48,189, 82, 44,194,128, 27, 97, 24,132, 15, 80,251,165,252,154,
- 158,158,214, 0, 73, 18, 19, 42,173, 56,221, 74, 29, 32,181,177,
- 105, 33, 5, 80,186, 83,149,160,160, 93,181, 98, 35,253, 26,103,
- 245,168,199, 99, 9, 49,244,205, 99, 70, 43, 45,162, 93,241, 5,
- 2, 68,141, 70,227,222,221,105,233, 75, 41,191,230,102,231,226,
- 70,160, 54, 98, 34, 77, 28, 16,165, 18, 12, 69,140,254, 2, 16,
- 115, 79,209,218, 70,187,134,214,172,155,172, 35,252,122,212,227,
- 241, 32,214, 24,164, 8,100,211,141,194, 14,185,180,136,150,212,
- 78, 74, 24, 84,240,171, 84, 80,129, 99, 63,197,106,253, 53, 53,
- 61,165, 91,205, 36,142, 21, 41, 98, 33, 98, 84, 10,140, 6,147,
- 180,144, 21,237,102,121,229, 55, 41,253,190,154,101,245,168,199,
- 35,134,173, 2,114,202, 32, 51,158, 81, 11, 24,120,105,145, 68,
- 88,131, 65, 24, 8, 0, 4, 65, 24,134,251,150, 89,123,135, 98,
- 105,150,214, 8, 27,225,194, 92, 18,199,113, 20,197, 81,148,196,
- 145,142, 99,157, 36, 58,209,172, 89,132, 17, 4,115,132,165, 73,
- 24,250,197,172,117, 81, 88, 61,234,241,184, 81, 45,143,238,197,
- 153,109, 76,201,197,218,234, 47,227,207,168,219, 81, 74,193,190,
- 227,122,172,248, 77, 37,126, 33, 0, 18,174, 60,117, 54, 22,142,
- 227, 40,137,226, 56,138,147, 40,214,113,194, 58,225, 36, 17,205,
- 194,105, 9, 24, 98,190, 77,123,250,134, 21,248,170, 89, 86,143,
- 122, 60,210,204,242, 58,157,100,105, 61, 67,238, 25, 19, 54, 18,
- 44,173,252, 2,162,246,252, 44,238,183,254,126,215, 30,186,152,
- 241,203, 94, 58,117,250,180,158,234, 70,163, 40,138, 70,142, 10,
- 75, 88,107, 97, 78, 75, 40,208,238,137,144,153, 71,116,100,100,
- 45,193,234, 81,143, 71,218, 60, 98, 94,176, 90, 60,221,179,228,
- 62, 17, 78,172,121, 76,132,181,112,154,139, 53, 27,211, 83,211,
- 123,253,112,191, 52,191, 80,161, 81,226, 75, 94,191,186,178,178,
- 194,179,211,124,245, 58,105, 69,138, 73, 49,114, 0,138, 21,145,
- 217,232, 24, 68, 80,196, 52, 29,103, 49, 93,198, 37,205,242,209,
- 244, 0,245, 86,115,215, 41, 88, 61,234,241, 72,210, 12, 29,220,
- 152, 79, 24,192, 77,235, 13,185, 18, 35,190,196, 54,162,104, 53,
- 58,157,182,255, 51, 92, 58,225,238,198,173,242, 43,121, 45, 89,
- 171,213,234,156, 61, 99,126,101,172,117,156, 36,113, 20, 37, 81,
- 164,227,152,181,137,225,172,133,180,155,187,228, 22,178,150, 96,
- 245,168,199, 99, 32,190,188, 62, 14,102,201,144,164,123, 47,112,
- 78, 46, 73, 68, 98, 54, 8,227,172,255, 4,205, 76, 43, 21,148,
- 225,229,168, 47,251,179, 17, 11,147, 3,227,150,253, 80, 14, 62,
- 196,167,223,251, 30,152,158, 74,216,220, 3, 78, 68, 18,102,157,
- 104, 29, 39,156,104, 96, 6,145,172,120,130,192,108,250,146, 89,
- 72,196,146,103,173, 89, 86,143,122, 60,122, 44, 67,159, 47, 38,
- 185,215, 32,134, 92,137,112,194, 28,139,196,146, 47,219,134, 70,
- 56,187,184, 88, 1,174,114,241, 4, 66,105, 94, 16,171,191,238,
- 234, 47, 4,124,234,169,167,240,137,147, 73, 46,255,216, 58, 88,
- 97, 97,102, 6,177,155,190,228,209,125,118, 49, 79,196,246, 84,
- 125,245,168, 71, 61, 14,159,248,242,120,147,159,217,102, 19,172,
- 204, 54,198,204,177,112, 34,204, 22, 95, 12,160,167,186,115,179,
- 179,222, 26, 36,180, 90, 7, 51, 27,234,125, 25,178,127,232,252,
- 106,244,238, 26,185,182,175,213,108, 45,189,235,188, 14, 40, 17,
- 142,141, 2,100, 73, 68,180, 48,103,205, 19, 17, 16,128, 82,253,
- 229, 75, 48,103, 23, 43,172, 17, 86,143,122, 60, 98, 44,195,138,
- 24,157,157, 82,175,132, 83,120,197,204, 49,179,105, 4,198, 0,
- 64,212, 88,152, 83,165,206, 19, 25,194, 48,199,147,155,170,185,
- 248,116,172,157,131,177,192,197, 12, 34,190,247,131, 31,184,241,
- 31,191, 17, 95,189, 73,192, 68, 64,166,153, 33, 16, 0,187,141,
- 199,156,153, 71, 68, 1, 2,144, 52,228, 79,247,189, 23,216,101,
- 77, 81, 29,235,215,163, 30,147, 47,185, 42,196,151,167,155,108,
- 147,249,212, 57, 26,114, 9, 71,204,177,176,216, 80, 95, 68,184,
- 211, 58,178,178,226, 57,208,202, 95,107, 9,134, 69, 90, 90,187,
- 138,197,219,146,239,107, 97,121,105,169,243,238,243,137,152,187,
- 34, 6,165,214, 66, 10, 11,128,157,112,204, 37, 24, 98,254,169,
- 239, 34,235, 32,172, 30,245, 56,108,163,122,227, 30,183, 82, 42,
- 133,151, 0,167,240, 28,110,250, 69, 0, 0, 32, 0, 73, 68, 65,
- 84,226, 68, 56, 18,142, 56,133,151,206,186, 80,152, 31,183, 48,
- 215,110,183,209,227, 31,230, 18, 12,243,192, 62,219,143, 56,155,
- 221,116,234,228,157,249,131,188,254,171,144,135, 17,125,240,227,
- 47,209,241, 35,153, 8,244, 16,102,155,144,101, 8, 36, 4, 50,
- 63, 5, 60, 23,233,108,137, 92, 35,172, 30,245, 56,220,122, 12,
- 243,170, 79,187,229,104, 90,179,154,214,169, 26, 86, 24,132, 37,
- 204, 98, 59,127,137, 8,119,219, 43,199,143,123, 85,171, 41,193,
- 208,243,143, 22, 84, 46,187,114,114,184,113, 24,228,121, 24,101,
- 19, 9,104,239,228,177, 99,199,186,239,121,103,194, 98,212, 96,
- 108,167, 18, 44,194, 50,251,151,146,147,208,190,153,203, 37,132,
- 65,149, 10,173, 71, 61,234, 49,177,254, 17,199,157,179,232,194,
- 11, 76,181,106,156,139, 47, 29,177,182,133,248,144, 54, 62, 93,
- 152,235,118,187, 0,133, 94, 21,224, 83, 36,157, 14,116, 6,128,
- 183,218,199,185, 91,206,207, 32, 71,197,217,108,158,232, 99,159,
- 252, 27,116,246, 84, 33,141, 51, 8, 99,225,116, 59, 34,204,193,
- 156, 27,201,244, 55,102,156, 70,172,206,242,107,132,213,163, 30,
- 147, 30,128, 97,201, 57,230, 38, 83,192,100,246, 49,167,228, 26,
- 177,142,152, 51, 93,102, 42,194,146,153,169, 99,167, 78,186, 66,
- 38,229,131,131, 41,207,174,121,235, 18, 29,118,229, 30, 19,115,
- 177,229,215, 79,228, 42,110, 97,113,241,232, 7, 95,208,173,134,
- 129, 87, 36,218, 32,204,148,134,153, 44,204,248,200,108, 45,183,
- 73,190, 8,211,169, 73,196, 61, 17, 86,143,122,212, 99,226,216,
- 133, 21,159,123,147,129,105,181, 4,136,182,202, 38, 98, 61, 98,
- 142,152,117,218,121,213, 68, 99, 2,129,106,172, 44,181,154, 45,
- 112,122,213, 20,126,137,195,168,140,104, 14,220,208, 7,104,138,
- 149,252,115,207,237,101,132, 35,196, 15,191,248, 98,112,238,169,
- 76,127,165, 8, 75,203,106,197, 24,201, 84,194, 25,102,229, 22,
- 50,189, 6,205,123, 79,222,185, 8,171, 57, 86,143,122, 76, 46,
- 188,156,249, 64,171,185,108,157, 61, 91,120, 69,194, 35,214,230,
- 45,157,115,148, 84,127, 49, 64, 50, 55,115,244,248,113,116, 3,
- 123, 39,167, 47,193,202, 14, 42, 94,145,219,200, 66,253,127,154,
- 127,185,211,133,246,150,173, 86,235,249,159,251, 36, 44, 45, 68,
- 204,145, 69, 88,196, 58,118,139, 90,157,169,138,180, 40,204,153,
- 136,204, 16, 70, 99,227,252, 26, 97,245,168,199,196,217, 70, 24,
- 51,237, 38, 86,124,153,229, 65,145,240,136,205, 91,234, 28,221,
- 110,247,210,110, 46,158, 62, 25, 40, 5,158,214, 2,112,121,180,
- 207,145,137, 46,155,226,103,171,199,201,129,153,123, 35, 68,196,
- 39,159,124,114,233, 99, 31,212,205, 70, 54,179, 16,231,197,181,
- 162,109, 81, 69,150,134,165,130,203,254,202, 12, 97, 8, 99,103,
- 36,235,229,146,245,168,199,100,192,171, 88,246, 85,168,118, 55,
- 193,150, 89,158,157,195, 75,235, 33,235,145,137,189,236,182, 29,
- 90, 68, 2, 69,199,142,204,206,206,129, 95, 30, 1, 78, 56,239,
- 165, 96,169,240,162, 42,249,149,171, 47,116,219, 94, 32, 64, 90,
- 63,225,174, 4,114,176, 72,164, 94,252,196, 39,154,239,125,103,
- 134,173,136,109,137,135,173,242,208,226, 86, 84, 24,132,129,231,
- 37,193, 79,225,176, 76,250, 26, 97,245,168,199,164,195,203,246,
- 150, 72, 69,204,136,181,133,151, 22,200,154, 23,166,251,119, 36,
- 203, 11, 39, 78,157,242, 23,126, 99,217, 60,186,236, 34, 7, 95,
- 84, 69, 49, 23, 34,217, 79,162,188, 2,195, 73,253,179, 31, 25,
- 134,225,139,127,243,231,233,201,211, 57,188,204, 5,209,134, 98,
- 153,145, 20, 71, 82, 17, 88, 33,102, 17,230, 23, 85, 96, 21,194,
- 106,138,213,163, 30,147, 3,175,140, 92,249, 6, 28, 90, 36, 22,
- 137, 82,120,113, 21,188,132, 69,146,185,233, 19, 79, 60,161,136,
- 60,217, 85, 40, 85,117,194, 46,151, 88, 68, 6,101,132, 68,213,
- 34,204, 89, 12,105,212,146, 87,129,225, 40, 48, 66, 68, 34,154,
- 155,159,127,238,111,126, 74,150, 23,173,139,212, 17,167,240,138,
- 36,243,146, 98,215,106,218,138, 10, 27,234, 99,246,222, 44,252,
- 118,155,184,214, 94,178, 30,245,152, 48,120,185,121,151, 41,162,
- 79,201,197, 98,167, 26,245,144, 51,229, 37, 34,121,231, 85, 45,
- 194,157,246,194,147, 79, 52, 91, 45,112, 48,227, 34,204, 82, 10,
- 115, 66, 17, 17,146, 25,233,101,123, 53,209,152, 48,223, 82,140,
- 48,239,101,239,231,255,206, 15,127,242,201,179, 39, 62,241, 34,
- 119, 90,110,149,173, 41,250,200,234, 42,180,216,245,154,146,247,
- 8, 35, 64,133,102, 70,210, 80, 12, 76,129, 43,213, 94,178, 30,
- 245,152, 84,120,217,166, 55, 32, 0,102,247, 13, 83,164, 58, 98,
- 30, 90,120, 13, 89, 51,164,116,203, 98,123, 9,131,214,153,147,
- 115,115,115,249, 58, 33, 39,246, 2,207,219, 17,165,174,145,178,
- 208, 43, 3, 24,122,228, 34,215, 76,102,245,247,230, 7, 6,224,
- 236, 37, 82, 18,117,118, 40,122,239,123,222,187,125,103, 99,253,
- 27,223,150,193,144, 25, 4,133, 73,152, 73, 16,152, 64, 0, 25,
- 72, 1, 40,244,148, 20, 34,128, 0,129, 89,219,141,128, 32, 2,
- 156,173,158,242,247, 93,203, 66, 52,169, 23,120,215,163, 30, 15,
- 11, 94, 99, 55, 67,179,150, 80,219,181,217,182, 78,149, 71,162,
- 83,204, 57,182,145,195,128, 78, 29, 63,122,228,136, 83, 40, 95,
- 168, 85, 45, 70, 94,228, 48,134, 28, 5,150,125, 76,111, 84, 57,
- 27, 9,128, 0,193,152, 64,141, 28,145, 71, 68, 20, 4,234,195,
- 31,251,232, 55,146,120,227, 91,223,145,225, 72, 0,153, 65, 16,
- 152,132, 89, 4, 41, 32, 16, 64, 17,195, 62,191, 72, 67,132, 0,
- 25,133, 4, 5, 5, 4, 5, 68, 16, 57,157,185, 68, 0,179,137,
- 36, 56, 29,122,160,166, 88, 61,234,113, 48,228,130, 93,226,102,
- 177, 93, 37,108, 51,123,187, 66,136,217, 36, 95,177,176, 57, 57,
- 61,120, 41, 5, 39,142,158, 60,125, 58, 83, 93,110, 97,189, 23,
- 120, 89,174,144, 21, 92, 62,195,148,197, 87,102, 49,115,129,230,
- 152, 71, 39,191,183, 68,243, 44,164, 5, 33,102, 63, 63, 8,195,
- 15,126,244,163,205,103,223,145, 32,102,117,183,246,175, 74, 47,
- 251,113, 88,102,129, 49,171, 14,203,214, 75, 90, 47,233, 76, 41,
- 64, 33, 17,195,218, 76,214,163, 30, 7, 32,187, 42,108, 99,190,
- 117,118,222,207, 75, 76, 82, 52, 98, 30,106, 61,212,122,200, 58,
- 102,150, 18,188,132,144, 87, 22, 79,157, 57, 67, 78,145,106,121,
- 97, 99,166,166,200, 85, 94, 42, 3,151,242, 62,181, 34, 44,151,
- 82,133, 90, 10, 4, 68,171,191, 42,204, 35,250,226, 78, 41, 69,
- 212, 8,195,143,124,234,147,223, 84, 52,248,241, 43, 60,140, 24,
- 144, 25, 24,133, 81, 24,136, 81, 24, 41, 64, 96, 68,149,229, 92,
- 89,120,103,182, 80, 50, 91,122, 3, 18,130, 8, 8,138, 0,178,
- 8,154, 13,190,125, 33,102, 13,104, 45,196,234, 81,143, 7, 28,
- 120,129,179, 30,200,216, 29,179, 71,163,215,143, 80, 36, 74,157,
- 163, 54,203,131,202,183,228, 48,224,229,133,211, 79, 61, 69, 68,
- 246,148,205, 49, 89,172,145,168, 48,140,164,204, 40, 73, 48, 7,
- 96, 78, 2,150,247,168, 71, 0, 8,198,205,105, 82, 46,193,188,
- 95,212,106,182, 62,242,137, 79,252,101,163,177,253,157, 31,202,
- 112,100,152,101, 92, 36, 35,105, 4, 38, 9,128, 24, 80, 1, 42,
- 48,202, 43,131, 81,106, 24, 9, 68, 4, 5,205,174,146, 66,102,
- 247, 34,144,130,119,172,237,100, 61,234,113, 64,240,114,201, 5,
- 217,186, 31,103, 3, 33,179, 88, 48, 22, 30, 25,217,149,222, 94,
- 76, 45, 88, 90,109, 31, 6,120,242,216,153,211,167,137,168,184,
- 180,198,197,138, 21, 80,101,116, 21, 57, 70,202,151, 96, 89, 97,
- 24, 21,166, 31,141, 46, 10, 10, 75,145, 8,137,137,125,237,229,
- 252, 92,165,148,162, 70, 24,190,255, 67, 31,250, 43,129,237,239,
- 254,128,135, 35, 1, 96, 70, 70,208, 86,136,105,148, 0, 41, 64,
- 100, 68, 5,233,190,221, 8,130,222,159, 39,104, 18,125,200,133,
- 152,164, 91, 45,213, 20,171, 71, 61, 14, 60,240, 42,144,139, 1,
- 116,186,123, 16,199,156,246, 46, 53, 75, 6,115,143,153, 46,111,
- 4,177,129,253,201,211,167, 41,239,137,143,110,145,189, 27,164,
- 23,243,121,165, 12,188, 84, 62,204,149,164,200,190,243, 44,100,
- 54, 13,153,215,175, 34, 66, 96,141, 93,177,144, 63,207,213, 20,
- 145, 38, 82,100,127,133, 82, 74, 5, 65,248,190, 15,188,255, 39,
- 157,246,173,191,250, 30,223,217, 10, 16, 83, 33,134,162, 33,189,
- 192, 72, 10, 49, 64, 82, 89,143, 67,244,118,142, 19, 4, 18, 17,
- 192, 28, 94,233, 5, 91,134, 81, 53, 59, 89, 83,172, 30,245,184,
- 31,217,229,122, 64,119,146,209,172, 8,204, 91,254,177,142,132,
- 217, 58, 35,200,225, 37, 44,160, 59,173,246,153, 83, 71,143, 28,
- 193, 50,188,192, 53,143, 69,207,168,236,123,229,193, 43, 35,152,
- 50, 20, 51,183, 67,155,192,251,141,193,242,245,224,129, 69,151,
- 228,232,226, 84,130, 57,248, 74, 37,152,202, 62, 6, 42,228,240,
- 217,103,159,237,116, 58,111,124,251, 47,229,198,109, 6,100,128,
- 44, 17,211, 72, 26, 37, 32, 98, 16, 5,100,188,164,161,152,223,
- 65,209, 4, 92,230, 14,165,118, 50,149,134,134, 98,104, 55,153,
- 171, 41, 86,143,122,220,151,236, 18, 7, 67,185,230,242,247,109,
- 116, 90,254, 9,139,243,157, 22,121,194, 0,201,236,244,194,217,
- 39,230,230,102,157,173,206, 16, 43,245, 87, 94,199,224,103,233,
- 46,181,220, 79, 45,189, 84,209, 64,146,151,129, 89, 33,100,242,
- 123,241,188, 37, 33,113,209,165,234, 76,130, 25,253,165, 20, 43,
- 21, 4,193,201,147, 39, 59,157,206,143,191,245,109,190,116,149,
- 153, 25, 81, 91,120,105, 36, 13,162,145, 2,148, 0,145,145,200,
- 82, 12, 11,221,250, 77, 89, 5, 32,185, 46,178, 76, 49, 7, 89,
- 146,191,176, 72,141,177,122,212,163, 10, 94,233, 43,126, 25, 67,
- 46,185, 50,207,152,216,192, 43,102,214,246,155,140,252,202, 58,
- 79, 48, 97,178, 52,127,252,236, 89,211,207,222,135,151, 95,170,
- 154,151,111,149, 51, 46, 85, 64,152,131, 47,195,153, 98, 77, 24,
- 146, 87, 31,145,201,152,192, 82,194,199,166, 65, 88,174,192,216,
- 252,116,118,224,149,129,108,110,110,238,133,151,126,230, 7,237,
- 239,196, 63,189,200, 81,204,146,122, 73,141,162,193,224, 12, 53,
- 146,114, 40, 70, 32,100, 52,159, 13,197, 76,221,106, 58,225, 56,
- 142, 98,102, 26,211,206, 81,218, 7,198, 87,104,245,168, 71, 61,
- 252, 61,190, 36,205,145,109,110,229,147,203,120, 70, 55,243,114,
- 103,253, 51,217, 37, 0, 58, 12,224,232,242, 19, 79, 60,161,130,
- 192,219,168, 49,195, 73,161,133,151,165,151,202,216,229, 36, 94,
- 129,115, 33, 40,249,200,220, 64, 22,234,239,243, 89,205,188,126,
- 85, 10, 11,136, 8,133, 51, 13,166, 72, 49, 49, 27,126, 25,118,
- 217,183,128,153, 57, 96,110,181,219,239,251,208, 7, 95, 95, 90,
- 184,253,227,151,131,181, 13, 6, 52,182,145, 57,151, 99, 10, 73,
- 35, 42, 20,133,168, 16,149,100,229, 96,198, 59,166, 47, 26,146,
- 115,220,163, 24,218, 87, 15,176, 20,115,181,152,179,230,180, 6,
- 89, 61,234,145, 75,175, 98,185,131,237,129,227,206, 51,218, 29,
- 179,153,197,227, 29, 88,217, 37, 0,201,116,183,123,250,196,202,
- 242, 10, 22,186, 65,103, 20, 43,212,214,151, 4,151, 59, 2,165,
- 84, 16,168, 32,112, 8,230,114, 44, 47,162, 64,127,254,177,176,
- 29, 81,144, 22, 83, 72,158,130, 17,161, 8,146,144, 16, 19, 41,
- 69,204, 86,130,113,192, 14,187, 20,155,207,130, 32, 96,150, 48,
- 124,234,236, 83,243,115,243,175,126,239,251,250,202,117,197,172,
- 80, 52, 98,144,122, 73, 84,233,123, 10, 12,191, 44,194, 8, 16,
- 65, 40,165, 82, 30,240,167, 91, 73, 26,123, 41, 32, 32,230,243,
- 244, 50,160, 85,110,149, 32,171, 41, 86,143,199, 28, 91, 0,142,
- 224, 18, 17,237,151, 71,228,202, 43,237,168,204, 5,225,150,201,
- 46,227, 25,143, 61,249,100,167,211,129,242, 14,218, 80,220,124,
- 35,223,208,199, 15,188,200, 85, 91, 65,144, 94, 14,130, 2,190,
- 40,207,191,148, 93,208,157, 21, 96,248, 27,172, 1, 6,238,214,
- 106, 88,114,144, 68, 66,164,148, 98,102, 98, 86,204,172,148, 10,
- 84,192, 86,121, 49,179,176,112,192,166,201,198,252,252,252,123,
- 62,246,209, 87,254,250,175, 71,175, 95,226, 94,159, 17,217, 81,
- 94,206,123, 84, 72, 25,194, 20, 34,129,160,141,198,156, 61,222,
- 82, 24,101, 20,203,221,101,201, 84,186,138, 89,106, 57, 86,143,
- 199,144, 92,146,151,104, 57,130, 11, 28,217,149, 98, 43, 77,235,
- 57, 77,190,202, 4,204, 61, 99,171,169,142,173, 60,113,234,148,
- 82,170, 2, 94,165,192, 62, 95,149,173,138,105,125,174,185, 2,
- 243, 63,200, 63,122, 14, 50,173,172,200,218, 81, 84,245, 99, 77,
- 239, 73,224,134,125,174,250, 19, 17, 50,255,172,246, 50, 35, 8,
- 2,102,163,195, 2, 78, 57,198,129, 4,233,126, 35, 34,173,102,
- 243, 93,239,126,247,141,229,229, 43, 47,191,162,111,220, 54, 66,
- 204, 0,203, 85, 97,233,149,144,106, 49, 66,164, 92,142,229, 1,
- 191,183, 97, 82, 26,122,165,246,220, 53,149, 70,142,165,182,189,
- 6, 89, 61, 30, 75,181,149,113,135,157, 86,206,185, 91, 4,209,
- 194, 9,123,179,141,229,200,204,228,245,169,236,154,159, 93, 60,
- 125,106,110,118,214,219, 10, 49,171, 94, 24, 3,175, 66, 93,189,
- 107, 24, 29,108,217,207,172, 18, 11,130,192,203,191, 92,255,232,
- 172, 31,242,118, 2, 49,235,135,210,240, 9, 12, 18,220,121,207,
- 148, 97,164,136, 36, 35, 88,134, 48, 97, 97, 49, 18,204,192, 43,
- 72, 59, 95,139,200,209,163, 71,103,103,103, 95,187,112, 97,116,
- 233, 74,176,211,211,130, 10,197, 72,173, 4, 41,200,225, 69, 42,
- 179,147, 57,194,192,163, 88,161,211,142,185, 44,104,230,128, 83,
- 147, 89,131,172, 30,143,153,212, 2,168,192,150,228,216,242,170,
- 186,204,122, 70, 87,127, 73, 53, 10,211,159,166, 59, 45,117,100,
- 249,137,147, 39, 85, 16, 20,100, 23,248,219,104, 87,194,203,173,
- 21,117,224,165, 44,184,220,161, 84,250,193,175,160,200,151,113,
- 123,240,202, 86, 62,154,187, 18,216,213,134, 89,138,238,210, 11,
- 81,144,132, 20, 41, 33,118, 8,198, 65, 16, 8, 51, 75, 32, 22,
- 95,146, 9, 48, 73,149,103,171,213, 62,255,174,119,173, 29, 61,
- 250,214, 43, 23,240,214,154,138, 99, 37,152, 75, 48,112, 84, 88,
- 198, 47,176, 90, 12,170, 65,150, 7,245, 70, 67, 10, 74, 26,150,
- 217,116,204,250,202,253,128,172, 48, 77, 83,143,122, 76, 62,179,
- 202,216,114,235, 33,210, 38,130,190,230, 42,240, 11,118, 37,151,
- 40, 74, 22,231, 86, 78,159,158,158,154, 42,182,145,246,225,133,
- 133,158,129,222, 82,233,188,210,189, 96, 24,131,208,251, 16,248,
- 240,114,179,251,180,236,190, 80,187,234,136, 47, 0, 8,210,164,
- 60,149, 96, 14,192,172,139, 20, 17, 81, 66,162, 72, 68,177,100,
- 176, 98,230,192,124,200,201, 37, 89,105, 92,218, 0, 13,100,113,
- 113,113,230, 67, 31,188,124,229,202,198,235, 23,245,157, 77,197,
- 172,173, 97, 84,226,193, 75,153, 2,177,220, 78, 66, 14, 50, 1,
- 52, 25, 25,102, 51,149,182,120, 76, 28, 81,107,126, 53, 26,105,
- 182, 55,200, 32,223, 78,184, 6, 89, 61, 14,143,218,114, 23,241,
- 56,125, 32,116,105,122, 49,213, 95,246, 74, 25,243,163, 83,114,
- 33, 38, 51, 83,221,227, 71, 79,173,172,152,197,216, 21,158, 49,
- 211, 92,174,246,202,219, 74, 80, 94, 35,145, 37,244, 70, 96,133,
- 65, 16,132, 65, 24,250, 20,203,209,166,130, 64,169,128,108,210,
- 159,215,126,149, 26,175,186,187,186, 5,206,159,226,192, 53,237,
- 171, 35, 25,194, 20, 41, 33, 17, 37, 98, 61, 99, 16, 4, 30,184,
- 36, 39,152,109, 37,157, 99,251,204,233,211, 43,203,203,151, 46,
- 94, 28, 92,187, 17,108,237,104,102, 66, 84, 8, 36,168,144, 40,
- 229,151,184,113,152,178,157,118,148, 32, 33,160,177,150,198,226,
- 102, 91, 90,138,215,134, 45,175,189, 40,130,172,194, 90,186, 93,
- 46,100, 76,189, 95, 61,234, 49, 25,130,107, 55,108,217,221,100,
- 11,178, 43,189, 38,177,107,128,170,101,151, 33, 23,161,238,118,
- 194,229,197,211,199,143,135, 97,232,166,205, 99, 60,163,173,245,
- 42,244,195,113,224,101,125,161, 51, 50,201, 21, 26,140,133,110,
- 118, 31, 84,184, 71,242, 26,226, 64,161,195,150,229, 23,162, 73,
- 190,220,134, 93, 64,132, 0, 36, 2, 41,193,148, 40, 33, 17, 35,
- 194,198, 13,200, 62,184, 7,200,252,241,157, 78,231,233,115,231,
- 122, 39, 79, 94,122,253,245,232,198,109,181,211,215,166,175,180,
- 72, 6,172, 28, 94,246,211, 92,130, 33, 42,163,194, 28,156, 33,
- 0, 66, 74, 52, 41,246,195, 77, 11, 67,140, 57,206, 50, 50,176,
- 235,195, 51,227,233,227,170,102, 89, 61, 38, 72,112,185,229,163,
- 92,165,182, 50,102,185,202,203, 37, 26,148,150,110,139,127, 65,
- 119, 90,184, 56,127,226,228,201,102,179, 9,165,189,117,220, 10,
- 175,138,181, 65, 88,174,174,183,153, 87,102, 25,195, 48,116, 25,
- 150,193,203,185,214, 22,130,145, 87,249,133,101, 5,230, 78, 28,
- 128, 89, 63, 4, 5, 9,230, 6, 97,150, 98, 6, 97, 74, 21,146,
- 174, 10,205, 85, 65, 46,119, 76, 77, 77, 61,251,220,115,155,167,
- 54,175, 94,186, 20,221, 90, 85, 59,125, 66,212, 54,182,119,225,
- 69,227, 66, 49,107, 45,209,128, 12, 28, 81,230, 77, 89,122,123,
- 169,184, 25, 25,166, 12,243,220, 37,212, 44,171,199,164, 96,171,
- 156,109, 85,152,196,242,101,183,194,171, 18, 88, 80, 34, 23, 44,
- 204,173, 28, 63,222,237,116,188,170,208,113,178,203,201,188,104,
- 156,109,116,224,149,139,172, 48, 27,198, 71,250,240, 82,121, 0,
- 150, 59,199,194,172, 99,149,248, 2,183,254,190, 32,193, 32, 95,
- 62, 46, 78, 16,230, 32, 12,202,242, 11,100,252, 73,238,238,165,
- 52, 55, 55, 55, 61, 61,189,181,181,117,237,210, 91,209,234,186,
- 234,245,137,153, 16, 82,144, 57,252, 34, 79,136, 65, 33,221, 71,
- 123,125,198, 50, 91,220,230,177, 12,220,248,223,110,146, 4, 54,
- 58,203, 86,120,213, 44,171,199, 65, 15,172,164,137,236,109, 18,
- 199,161,138,237,101, 22,209,105, 10, 63,158,143,230, 61,161,238,
- 180,113,126,118,229,216,177, 49,228,242,211,174, 66,230,149,245,
- 115, 46,182, 55, 37,107, 28, 85,230, 19, 51,118, 5,238, 91,224,
- 41,175,140, 94, 94,236, 85,220,202,182, 66,124,249,249,151,157,
- 136,116,251, 97, 16,129,233, 25,145, 39,243, 74, 84,154,206,167,
- 4, 43, 62, 32, 82,129,174,108,227, 54, 68,208, 90,167, 20,155,
- 157,157,126,238, 93,189, 94,239,218,149, 43,163,155,183,105,167,
- 79, 90, 27,123,104,202,193, 84,129,101,217,110, 70,185, 16,203,
- 182,200,205, 68, 89,186,245,145,207, 50,243,203,165,114, 87,116,
- 183,238,127, 23,150,185,121, 89,197,236, 77,125,106,214,163,138,
- 86, 48,238,228, 16, 40,119, 4, 76, 75,183, 82, 30,121,241,214,
- 56,132,177,128,185,176,159, 95, 42,138,116,167, 29, 44, 45, 28,
- 63,122,180,101,221, 98,217, 48,150,101, 87,117,157, 68, 33,243,
- 202,164,151, 27,121, 25,120,101,232,242,117,152,101, 87,154,220,
- 231,225,151,227, 28,193,111,155, 83,248,243,178,250, 85,201, 38,
- 34, 69,160, 92,225, 65, 68,230, 60, 86,160,188,249,197,172,165,
- 108,182,227,146, 20,101, 87,174,252,156,163,160,181, 70, 68,208,
- 122,106,106,234, 29,207, 60, 51, 58,115,230,198,205, 27, 59, 87,
- 111,192,206,142, 26, 70, 70,100, 37,136,132,144, 7,249, 14,200,
- 82,198,101,101, 22,246,178,105,171,143,150,101,148,109, 59, 46,
- 128,254,110,154,224,239, 62, 57,142,101, 96,203,255, 37,127,241,
- 220, 27,103, 53,209, 30,123, 90,217, 72,214,127, 62,236, 71,106,
- 165,151, 93, 90,101, 32,203,175, 44, 98,107, 23,253, 0, 0,186,
- 25,114,167,211, 57,178,188,180,180, 20, 6,193,158,228, 2,187,
- 78, 58, 87, 94, 68,165,201,198,162,109,244, 74, 84,173,248,114,
- 254, 59,174, 49,180,177, 87,154,223,147, 82, 94,205,106,185,216,
- 222,157,118,204,238,120, 80,117,204,109,163,231,244,219,210,198,
- 214, 41,182, 76,150, 15, 42,223, 37,174,178, 36, 52,207,159,208,
- 149, 96,238, 65,201,132, 24, 34,182, 90,173,211,167, 78, 39,199,
- 142,175,175,175,175, 93,187,158,220,217,164,193,144, 88, 19, 98,
- 82,150, 93, 96,251,235, 23,138,197,108, 58,134, 62,203,208,122,
- 76,203, 50, 65,191,203,218, 56,150,185,182, 81,242, 70,110,123,
- 227, 76,188,103, 70, 77,180, 71,155, 86,187,236,229, 35,149,204,
- 202, 42,182,178,114, 83,183, 98, 62,223, 11,214, 65, 88,134, 45,
- 115, 97,191,129, 26,162,110, 55, 97,118,122,110,101,101,110,118,
- 150,148,170,190,211,238, 41, 80, 50,140,224,247,147, 40, 7,246,
- 148,205, 30,250,202,171,196,175, 84,129, 57,213, 19, 42, 40, 57,
- 199, 76,219,121, 11,182,177,186,137,108,224,162, 43, 91, 53, 45,
- 158,139,204,162,176, 84,131,121, 15, 78,126,102,138,247,128,250,
- 252, 42, 21,113,160,246,133, 88, 54, 86, 86, 86, 22, 23, 23,123,
- 189,222,173,155, 55,135,171,107,180,181, 67,113,162, 33,163, 82,
- 78, 49, 85, 84, 97,222,167, 70,130,185, 44, 67,251, 41, 34,144,
- 100, 96,207,113, 6, 14,206,178, 99,229,224,204,101, 25, 56,171,
- 196,115,156, 85,153,205,154,104,143,158,176,218, 51,130,207,236,
- 97,133,206,178, 43, 19,129,211,205,171,203, 83,138, 69,231,152,
- 239,244, 83, 84, 90, 99,239, 12,135,129,158,234, 52,230,231,150,
- 151,151,219,237,118,113,253,207,238,228,170, 90,146, 93,222,125,
- 99, 23,120, 21,249, 21,230, 73, 88, 81,124,121,173,191,138,229,
- 170, 57, 69,161, 66,124,149,244,151, 83, 75, 33,146,183,225, 7,
- 48, 26,140,211, 44,204, 60, 56,169,143,180,150, 81,198, 88,232,
- 221,118,176, 76, 7, 51,103, 20, 99,102, 68,156,158,158,158,154,
- 154,138, 79,159,222,216,216, 88,191,117, 43, 89,223,160,193,144,
- 18,109,154, 85,160, 64,133,236, 74,185, 6, 25,206,208, 94, 46,
- 216,201, 20, 94, 98, 5,154, 43,205, 0, 48, 93, 88,153,215,249,
- 150, 15, 91,182,172,220,193, 89,246,188,245,112,230, 18, 13,198,
- 90,206, 7, 10, 53,169, 73,115, 32,156, 66, 40, 60,172, 69,102,
- 185,203,167,211, 60,203,210,170,176,154, 90,198,184,197, 92,136,
- 57,159,234,187, 89,240, 38,138,116,187,133,115, 51,179,139,139,
- 179,179, 51, 74, 41,128,187, 35, 23,140,221,106, 22,203,105,253,
- 184,216, 43,197,151,143, 45, 91, 71, 17,102,101,171,233,226, 34,
- 82,222,198,143, 78,175, 9,215, 32, 85,110,167, 24, 84,204,141,
- 160,123,106,162, 83,214,154, 27, 73,115, 90, 42, 80,165, 71,220,
- 57, 14, 80,220,215,168,140,243, 84,130, 49,187, 20, 19,251,105,
- 163,209, 88, 94, 94, 94, 92, 92, 28, 13,135,171,107,107, 59, 55,
- 111, 37,189,190, 26, 12,137,133, 77,229,151, 83, 17, 86, 86, 97,
- 104,233,230,238, 53,153,251,202,140,101,230, 30, 10,148,112,102,
- 136, 38,224,108, 70, 89, 38,154, 20,158, 9,197,236, 44,111,151,
- 237,105, 52,128,253, 65,173,144,249,222,223, 57, 44, 53,164,202,
- 223,141,119,245,179,197,153,177, 25, 23,102,153,141, 20,157, 5,
- 137, 41,158,138, 61, 33,138, 87,122,202, 75,246,245,136,217,215,
- 60, 36,221,110, 74,167,221, 93, 94, 90,152,159,111, 52, 26, 48,
- 78,112,237, 77, 46,175, 54, 53, 43, 79,117,235, 36,188, 22,208,
- 222,140, 99,161, 64, 53, 12,131, 48, 47,249,114,107,190,108,197,
- 170,221,174, 67,149,108, 99,190,207, 99,121,114,116,156,254,202,
- 93,100,222,153,198,126, 15, 17, 48,151,109,100,193, 53, 66,190,
- 67, 27, 22, 68,104,105, 10,195,182,218, 64,173,217, 26, 73,179,
- 190, 18,153, 13,200, 88, 4, 17,219,237,246,201, 19, 39,244,177,
- 99,253,126,127,253,206,122,255,214, 42,244, 7, 6,100, 8,192,
- 6,100, 86,112,161,151,232, 67,214, 37,145,192,185, 96,111,105,
- 54,214,205,246, 36,183, 56, 75,213, 89,122, 4,197,217, 70,216,
- 30,162, 2,209, 92,117,235, 9, 80,231, 53,218,211,104, 0,224,
- 30, 92, 7,122,165, 87,248,187, 0,146, 60,168, 51, 95, 14, 25,
- 149,118,253, 49,120, 63,191, 74, 74, 10,203,166, 90,134, 83, 46,
- 176,210,166,242,165,120,203,107, 54,239,139,175,236,154,244,242,
- 190, 31, 4,113,177,213, 94, 92, 88,158,155,107,183, 90, 72,180,
- 43,155,139, 9,125, 41,223, 1,111,175,198,170,253, 26,221,126,
- 132, 65, 5,191, 50, 88,165,162, 43,229,150,191, 96,200,237,151,
- 227,146,171, 80,173, 10,232, 85,113, 86,214,127, 85, 61,224,198,
- 69,250, 65, 24, 0, 24, 23,201,224, 31,164, 49, 7,203, 69,121,
- 118, 76,204,125, 77,136, 48, 73, 50,138,145,137,195,136, 88,107,
- 205,140,214, 75, 26, 35,203,204, 98, 12, 45,226,244,212,212, 84,
- 183,171,143,159, 24,244,251,235,119,238,244,111,167, 32, 67, 22,
- 11, 26, 73,213,147,128, 59, 35, 73,182,168, 34, 47, 28, 75,223,
- 251, 42,204,197,153, 11, 50, 68, 18,103, 58,213, 33,154, 57, 90,
- 89,209,172,255,106, 81,140, 17, 11, 7,202,217,219, 37,219,182,
- 36,127,226, 98, 33,105,188, 59,180,237,113, 22,200, 67,161,201,
- 193,195, 13,239,246,190,163, 39,132,171, 15,203, 46,185,123,145,
- 86, 78,149,105,118, 61, 59, 20,147, 42,241,229,198, 94, 50,166,
- 100, 75,118,137,216,144,116,187,181, 95,108, 85, 10, 46, 39,161,
- 135, 42,114, 21,100,151,103, 26,169, 74,121, 41,127, 69,118, 9,
- 91,110,181,106, 9, 94, 10, 75, 21,171, 94,236, 53,254, 17, 13,
- 198, 60,190, 94, 16,230, 43, 11, 34, 98, 0,103, 95,218,194, 97,
- 171, 84, 91,136,229,100,142,144,144,146,188, 79, 99, 38,192,172,
- 10,203,133,152, 67, 49, 17, 65,162,169,233,233,238,212, 20, 31,
- 63,222, 31, 12,238, 24,144, 13,134, 52, 24,145,214, 8, 98, 56,
- 194,144,110, 49,105,147,175,146,157,116,244, 90, 94, 53,230, 70,
- 99, 2,142,187, 68, 74,165,169,103, 57,115,105,102, 55, 17,207,
- 178,198,130,247,244,184,230,100,139,222,151,164, 98, 62, 68,156,
- 202, 23, 41, 61, 65,221,109, 50,177,226, 4,192, 93, 78,227,201,
- 144, 97,248, 64, 88,122,247,170,170,172,173,138,151,197, 22, 62,
- 102,192,170,242,137,238,123,225,116,107,159, 92,115, 73,149, 22,
- 219,253,224, 86,126,137, 21,113,187, 37,173,230, 56,108, 85, 38,
- 92, 37,209,181, 71,212, 85, 53,205,152,243, 75,149,150, 8, 21,
- 27,226,132, 89,127,137,226, 10,161,172,237,106, 65,121,217,212,
- 190, 4,175, 98,236,133,251,225, 87, 33, 8,179, 89,190,157, 79,
- 36, 2,102, 27,132,249,235, 13,253,250,216, 10,138, 21,142, 74,
- 66, 9, 38, 72, 68,148, 36,121,205,154,214,154,136,181,102,127,
- 152,251, 33,110,183, 30, 17, 68,156, 74, 21,217,241,209,104,184,
- 185,185,181,189,182,198,189, 62, 13, 70,106, 20,165, 0, 23, 64,
- 0,134,180,127, 43, 58,243,152,232,106, 49,119,154, 18, 60,195,
- 152, 87,195,186,251, 7, 72, 73,163,217,202, 19,175,103,153,228,
- 152,242,184,102, 27, 96,227,152,249,120,116,152,133,206, 51, 90,
- 74, 79,111, 41,213,245, 73,213,163, 93,104,179, 13,187, 87, 87,
- 190,125, 50, 12,239,255, 70,197, 63, 52,191,162, 16, 90,249,168,
- 2, 17,143, 89, 25,173,220, 60,158, 11,215, 88, 96,121, 20,203,
- 57,149,111,176, 40,251,240,134, 99, 75,183, 90, 45,234,182,187,
- 243,243, 51, 51, 51,205, 70, 99, 47,108,249,217, 5, 86, 87,210,
- 195,248, 84,218,221,107, 86,249,240,242, 58,169, 58,174, 81, 21,
- 123,226,184, 5,170,249, 59,149,214,122,145,242, 11, 38,208,209,
- 94,224,192, 11,112,143,135, 60,216, 69,101,103,255, 49,109,224,
- 128, 37,132, 49,216, 8, 63, 37, 92,161,232, 13,252,109,120,137,
- 144, 40,241,187, 99, 39, 73, 98, 62, 32,145, 46, 33, 44,181,147,
- 68,100, 26, 37,162,213, 96, 14,200,140, 80, 84,157,110,187,221,
- 57,114,228, 72, 28,199, 59, 59, 59,155,119,238, 68, 91,219, 48,
- 24,170, 76,148,229,189,119,128,197, 54, 15,131,220,102, 22,112,
- 150,170,179, 28, 91, 46,200, 42, 84, 88, 6, 71, 23,106,144,221,
- 88, 50, 87,157,114, 13,138,117, 45,153,247,148, 92,161,137,191,
- 84,160,218,235,151, 31,188,202,178,198,113, 25,194,216,197,170,
- 15, 96, 50,225,190,106, 17, 96,247,186,170, 49,156,146,114,165,
- 104, 73, 94,101,107,221, 28, 84,185,215,123,179,135,187,130, 44,
- 5,150, 87, 27,225,210,109,159,144,146,170,105, 68,105, 53,195,
- 153,169,249,217,185,169,110, 55,112,138, 78,247,233, 19, 97, 92,
- 25,125, 85,235, 46, 55,237,170, 10,235,199,194,203, 47,250, 42,
- 119, 38,204,192,149,175, 18,202,160,152,109, 80,155,195, 43, 63,
- 41,156,109, 98,199, 63, 79,130,221,131, 2,183, 48,223,236, 91,
- 102,142,161,131, 48,193,146, 88,200,238, 5, 22, 85, 97,134, 46,
- 52, 9,152,135, 48,173,117,146, 20, 16, 70,204,154,136, 53, 51,
- 49, 89, 71, 41, 34,156,129,172, 52,154,141, 70, 99, 97, 97,126,
- 126,158,153, 71,163,209,214,246,214,206,157, 13,189,211,195,225,
- 136, 70,113,198, 50, 43,148, 32,157,202,132,220, 27, 86, 9, 49,
- 231,122,135,104,249, 52,101, 9, 94,224, 41,181,156, 86,249,151,
- 32, 45, 42,203, 35, 51,119, 97,128,100, 83,159,158,118,243, 30,
- 79,172,148,111, 99,108,253,125, 72, 30,169,186,237,253,104, 51,
- 217,189,126, 74,170,111, 44,254,109,220, 13,190,192,223,169, 16,
- 28, 54,249,151,253, 48,171, 82,115,249, 85,166,174, 16,203,108,
- 99, 81,118,229,215, 20,235,192,246,143, 45, 81,164,155, 13,105,
- 54,212, 84,183, 59, 59, 59, 61, 61, 93, 41,181,238, 17, 91,176,
- 91, 21,147,107, 24, 83,162,100, 2,169,104, 27,109,187,155,192,
- 237, 0,237, 55,179,175,144, 93,206,182,143,182, 57,180, 19,176,
- 21,218,171,162,255,220,222,237,137, 22,236,231, 5, 51, 91,222,
- 13,144,199, 97, 22, 97, 44, 64,174,101,202,151, 90, 22,242, 47,
- 180,201,125,102, 21, 41,195,149, 97, 87, 74,177,236,141,137, 52,
- 51,105,157,162,203, 25, 70,144, 73,149, 22,203,158, 97,132,168,
- 58,157,118,187,125,100,121, 69,107, 61, 28, 13,183,119,118,122,
- 27,155, 62,203,114,143,153, 97, 69, 91,156,129, 31,231,147,135,
- 173,146, 16, 3, 40, 66,205, 89,244,144,177, 12,160,160,215, 28,
- 33, 38,121,255, 50,112,103,114,115,199,151,191, 40, 33, 56,171,
- 1, 60,223,224, 61,240,184,235, 60, 28, 30,140, 67,148, 10,155,
- 91,165, 50,220,169,180,162,203,205,247,239,130,106, 60,229,242,
- 198,153, 19, 44,244, 38, 5, 40,114, 10, 96, 12,170, 74,162,204,
- 208,170, 58,182,207,110, 80, 42,100,216, 27, 91,227,153, 53,211,
- 237, 78,181,154, 77, 34,218,135,212, 42,154,196,202,140,107, 79,
- 205, 53, 54,237,170,174,242,242, 82,123, 85, 6, 88, 1, 91,165,
- 180, 43, 23, 95,233,174,142,227,224,133,251,124, 94, 6,251,152,
- 171,129,172,162,162,140, 48, 17, 98, 16,242,154, 21,102, 39,121,
- 33,193, 79,239, 43, 89,144, 17, 17, 37, 58, 73, 63,106,143, 98,
- 68,202,216, 73,102, 67,177,114, 34,150, 35,108,140, 22,179, 75,
- 204, 17, 68,144,168, 27, 4,221, 78, 87, 86,142,104,173,135,195,
- 225,206,206, 78,111,115, 83,239,244, 32,138,213, 40,162, 56, 49,
- 249,184, 43,205,210,214,135,153, 35,147, 10,108,145,215,161,191,
- 240, 85, 39, 26,203, 29,118,222, 57, 54,163, 21,166,175, 18, 78,
- 243, 31,219, 90,214,179,150, 37,198, 57, 2, 13, 43, 83,252, 76,
- 26, 99,249,249, 47, 37,154, 61, 24,120,237,102, 51,165,240,191,
- 202, 0, 58,218,170, 60, 27,232, 56, 68,103, 81,151,107, 12,221,
- 73,195,242, 4, 98,149,127,172, 6, 25, 87,125,117, 76, 33,131,
- 236,143,212, 0, 0, 28, 6,220,108, 72, 24,170,169,206,238,204,
- 26, 39,181,118, 81, 91, 62,182,160, 80, 0, 80, 25,117,141,139,
- 234,171, 23, 55,170, 34,187,242, 13,132, 2, 15, 93,206, 94,142,
- 123, 4, 94, 69,120,249,149, 72,247,195,175,226,116,100,142, 48,
- 231,119, 56, 94, 18,179,141,217,192, 93, 34,100, 9,102,143, 85,
- 26,219,155,220,139, 52,105,107, 24, 51,138,153,145,169, 48, 67,
- 49, 19,135,101, 35,219, 58,132,153,169,152,236,143, 5,153, 0,
- 16, 98, 48, 53, 53,213,237,202,202,138,102,142,162,104, 48,232,
- 247,122,253,225,198, 38, 12, 6, 24, 37, 20, 39, 70,154,185, 56,
- 131,172,248, 43,133,136, 91,211,144, 71, 99, 96,101, 26, 20, 68,
- 153,175,197,192, 93,214,158,151, 98, 56, 97,191, 56, 55,206,226,
- 87,241,204, 96, 70, 45,148,210,228,102,225, 9, 47,176,159, 56,
- 180,170,148, 19,171,214,169,148, 42, 16,100,207,243,214, 59,197,
- 165, 52, 35, 33,254,151,188, 50,209,236, 39, 72,113,222,176, 50,
- 228, 2,135, 77, 80,149,115,193,190,253,227, 94,101,163,178, 31,
- 102,137, 34, 14, 67, 14, 3,108,183,154,115,179,211,157, 78,187,
- 221,110,132,225,190,153, 85,144, 90, 80,209,220, 6,138,205, 81,
- 247,227, 22,211,247, 46,184,118, 85, 94,121,148, 21,120,197, 19,
- 170,224, 21, 11,171,130, 20, 17,209,252,252,194, 65, 40,253, 96,
- 31,183,113, 16, 6,214, 72,250, 79,105, 35,196,192, 32,206, 81,
- 95,160,243, 3,105,145,159, 30, 49,163,179, 18, 75, 46,247,189,
- 46, 13,165,181, 86,202,196, 97, 69, 33, 38, 66,101, 71,105,125,
- 101,230, 37, 29,144,129,136,160, 85,109, 72, 20, 40,213,110,183,
- 23,230, 23,228,196,137, 56, 73,134,195, 97,191,223,239,111,109,
- 233,254, 0,162,136,140, 52, 99,169,194, 89,246,108, 18,118,202,
- 83,193,115,133, 78, 51,178, 60,249, 66,175,204,194, 41,203, 0,
- 159,110,224, 86,252,123, 24,205,251,100, 87, 71, 99,251,155, 1,
- 192, 93,242,116,217,175, 30,147, 10, 67, 56,246,196,118, 97, 52,
- 54,125,175,116,145,110,237,104, 81,109,185,193,150,231, 25,193,
- 223,205,112,156,127,220,207,164, 68, 73, 53,142, 7, 22, 34, 55,
- 2,110, 52,160,217, 80,237,118,103,102,186,211,105, 55,155,173,
- 32, 8,198, 25, 35, 28, 63, 49, 83,237, 16,199, 4,243, 80,170,
- 65, 40,212, 45,121,216, 42, 40, 47,139,173, 74,118, 21,172,163,
- 242, 46, 6,110, 52, 86, 41,187, 14,104,182, 58,216,223,205, 28,
- 35,153,182,152,113,235,194,204, 87,217, 82,204,129, 63,160, 70,
- 141,140,136,230, 93, 22,222,231,177,189, 54, 22, 50,231,151,210,
- 58, 41, 35,140,180,102,165,204,251,178,151, 76,101,152,253,152,
- 226,202,180, 93, 76, 41,230,117, 92,180, 79,109,139, 51,251,190,
- 73,212,104, 52,102,166,167,229,200, 17, 97,142,227,120, 48, 28,
- 14,134,131, 81,127, 16,245,122, 48, 24, 98,148,144,214, 20, 39,
- 110, 74, 85,144, 69, 94,123, 68, 17, 44, 86, 45,160,183, 74,161,
- 112,217,121,121, 69, 55,219,170,138,240,177,212, 5, 5, 75,175,
- 215, 56,158, 86, 21, 98, 76, 42,151,215,200,158,181, 22, 50,206,
- 61,150,112, 38, 69, 61, 38,126, 53, 86,110, 32,139, 22,210,111,
- 152, 5,165,110,165,224, 1, 75, 74, 45,152, 1,224,238, 42, 69,
- 203, 34,107, 28,176, 56, 12, 68, 41, 14, 3,104,183,194,110,167,
- 213,105,183, 91,173, 86,171, 29, 26, 96,221, 63,179, 74, 14,209,
- 243,137,197,108,190,184, 0,104,111,114, 57,216, 26, 11, 47,101,
- 203,230, 51,127, 24,184,166,210,219,126, 54,133, 23,229,187,104,
- 191,189,252, 42, 32, 44,175, 11,195,172,183, 2, 18,176, 0, 8,
- 17, 8, 10,176, 19, 17, 99,198, 47, 55,188,207, 2,252,132, 52,
- 233,140, 95, 74,235,164, 66,130,105,173, 89,107,173,148, 30,135,
- 48,159, 98, 57,200,178,230,177,213,190,210,129,152,248, 21,187,
- 136,164, 84,179,217,156,155,157, 21, 0, 97,142,147, 36, 26,141,
- 70, 81,212, 31,244,163,141, 45,142, 99,140, 19,138, 34, 76,152,
- 76, 47, 32,223,178, 21,160,102,143, 94,102, 60,203, 5, 89, 88,
- 76,238, 43,167, 38, 43, 2,178,146, 4,195,170,116,191, 26, 94,
- 78, 75,218,251,159, 82,172, 58,219,165,138,101, 34,197,200,172,
- 100, 33,139,104,115, 90, 24,185, 78,208,201,245,247,242,125,123,
- 3, 75,246, 84,142, 32,138, 56, 80,220,104, 64,160,176,209,104,
- 206,206, 76,181,219,141, 70,163,217,108,238,162,176, 96,236, 90,
- 129,253, 49,171, 50,150,135, 61,123, 35,228, 57,211, 88,114,237,
- 11, 94,185, 43,116, 86,255,228, 23,201, 65,151,211, 12, 71,101,
- 167,251,219,206,175,221, 17, 6, 8, 32,100, 26,130, 17,179, 80,
- 186,188,144,253, 37,144,140,108, 86, 11,229, 32,211,218, 82, 44,
- 139,190,198, 72, 48,173,181, 98,214, 90,179,102,173, 52, 87,133,
- 250,149, 66,108,175,104, 44,155,180, 4, 79,154,217,191, 15,204,
- 86,108, 74, 53, 21, 53, 27,141, 41,128, 69, 88,148, 19,194,172,
- 147, 56, 25,142, 70, 81, 52, 26, 14, 71,209,214, 22, 39, 9,142,
- 98,140, 19, 20, 86,163,216, 43, 95,200, 48, 83, 44, 31,205,159,
- 175,130,174, 3,173, 40, 34, 64,255,249,238, 87,141,129, 23,143,
- 8,140, 41,142,245, 85, 88,190, 1,221, 61, 87,137, 86, 82,108,
- 183, 32,223, 45, 50, 40, 92, 41, 62, 70,164,202, 66, 2,236,127,
- 145,224, 93,208,106,172,182,106,134,130,196, 97, 96,104,213,152,
- 153,110,181, 90,141, 70,163,213,108,170, 32, 48,116,184,187, 74,
- 219,221, 58,205,131,219,167,175,210, 36,230,200,218, 71, 73,196,
- 126,101,151,227,245,118, 17, 95, 99, 63,117, 42,196,168,208,200,
- 203,206, 51, 78, 2,191, 60,132, 65,182,192,200,188,130, 59,203,
- 140,213,100, 61, 27, 0, 0, 17, 42, 73, 68, 65, 84,140,145, 76,
- 27,185, 22,123,229, 32, 35, 34, 49,105, 36,180, 5,171,105,213,
- 132, 19,119, 37, 74,107,237, 83,140, 53,107,118, 46,229, 20,243,
- 64,150,239, 10,206,214, 60,122, 91,236,150, 88,230, 33, 44, 83,
- 100,142,193,204, 89,150,170, 30, 35, 87,144, 16, 3, 21, 52, 91,
- 173, 44, 84, 97, 22,157, 36, 81, 28, 69, 81, 60, 28, 14, 71,189,
- 158, 30,142, 32,138, 68, 51,197, 9, 10,211, 40,198,138,148,170,
- 136,182, 2,221,192,109, 92,129, 21,168,192, 93, 79,217,177,177,
- 125, 53,188, 16,238,105,133,115,169,136,107, 87,241, 53,222,108,
- 142, 99,206, 1,169,170,106, 84, 17, 65,179,161,154,205,102,183,
- 99,104, 21,134,161, 57,189,239,154, 86,187, 3,107, 63,193, 86,
- 101,188, 85, 5, 47,119, 74,207, 78,246, 59,145,179, 27,214,103,
- 213, 93,238, 63, 7, 68,187,194,203,243,137,150, 92, 84,213,131,
- 208,105,134, 51, 25,252, 2,119,226, 41, 91,230, 93,152,242,202,
- 50, 83, 34,176, 39,123,169,227,151,193,151, 70,237,191, 28, 16,
- 105,149,209,140, 85,209, 63,154, 11, 70,133,217,247,198, 87,114,
- 105,106, 50, 19, 99, 25,182, 76,216, 47,187,142, 2,194, 10,239,
- 114, 80,167,210, 76,108,133, 5,162, 8, 41, 80, 74, 53,154,205,
- 124, 91, 80, 17,214, 58,209, 58,137, 99,195,181, 40,138,226,237,
- 109,102,198,225, 72, 4, 84, 20, 1,128,153, 34, 40, 63,203, 93,
- 21,134,227,107, 73,101,215, 22, 11,178, 71,167,235,187, 5,197,
- 62, 26, 35,220,211,247, 11,220,251,111,222,127, 17,131, 16, 74,
- 24, 8, 0, 55, 26, 8, 32,173, 38, 41, 10,166,167, 26,141, 70,
- 35,108, 52, 26,141, 48, 72,251, 25, 23,155,138,220,179, 37, 28,
- 11,172,241,106,171, 44,183,246, 97, 21, 51, 90, 56,236, 40,112,
- 203,153,103,244, 61,163,219,143,208, 71, 84,225,162,231, 20,199,
- 147, 43,215,127,147,198,175,202, 73, 73, 47,209, 55,137,138,241,
- 146,217,169,239,250,200,180,225, 4, 35,103,201,125, 58,255,145,
- 86, 77, 80, 26,116,149,224,101,104,229, 92, 74,241,149,161, 75,
- 103, 85, 22,169, 12,147,130,169,204, 18,253, 42, 57, 6, 99,230,
- 43, 11,121, 63,120,210, 12, 16,196,238,206, 38,229,122, 19, 34,
- 10,194, 0,154, 77, 55, 36, 98, 17,102,157, 36, 58,142,227, 56,
- 142,147, 36,137,227, 56, 30, 12,244,104, 36,137,198, 40, 22, 3,
- 53, 97, 96,177,181,105,149, 26, 10,177,116,170,226, 94,132, 56,
- 232,101,141,242,160,111,191, 31, 60, 21, 2,117, 32, 52, 98, 10,
- 1,164, 17, 98,160,168,209,108,116,218, 78, 43,189, 48, 8, 2,
- 115,182,237, 39,253, 27, 31,194, 99, 69,205, 73,101,113, 41,184,
- 221,202,113,108,221,214,248,249, 68, 24, 47,184, 60,120,149, 10,
- 234, 51,177, 53,166,157,132,175,165, 84,197, 52,162,173, 65,173,
- 16, 92,202,229, 99,169, 48,117, 50,249, 53, 38, 14,203,218, 79,
- 59,183, 33, 18, 17, 19,234,163,109,140, 67, 72, 22, 55,166,111,
- 142, 49,145,236,112, 76,147,210, 74,171,162,123,100,135, 98, 69,
- 33,102,249,165,115, 9, 54,206, 81, 90,148,249, 56,219,167,175,
- 172,164, 25,218,171, 28,117,150,154,205,212,170, 73, 78,125, 5,
- 162,136,194, 32,108,183, 90,133, 60, 72,152, 53,179, 41,229,205,
- 135, 78,146,193, 80,143, 34, 17,129, 56,198, 68, 11, 0,106,109,
- 230, 13, 0, 32,115,166,251,203,176, 14,172,244,254, 46, 51,254,
- 253,131,204,117,121,233, 5,165, 68, 41, 4,144, 64, 65, 24, 32,
- 18, 53, 26, 97,187, 85,108,216, 66, 68, 74, 33,226,126,244,212,
- 30,124,175,108,134, 80, 85,159, 85,182,132,123, 82,107,255, 62,
- 177, 68, 47, 79,119,149,221,162, 93,134,157,243,171, 32,187, 10,
- 2,140, 28,177,229,250, 74,175,192,194,153, 91, 76,169, 85, 37,
- 187,252, 38,132,147,197,175,170, 56, 44,109,160,239,204,147, 57,
- 66, 12, 81,152, 1, 17, 25, 77,151, 46, 27,241,155,142, 57,100,
- 150, 11,165,213,170,100, 10,190,116, 10,179, 20, 82, 90,235, 44,
- 194,231,156,101, 5,132,105,167,208, 85,118,161, 88,233,194,158,
- 32, 43,196,252,197,212, 63, 95,210, 82, 52,155,105,127, 29,143,
- 104, 21,103, 50, 2,128, 82, 74, 41,177,219,184,187, 22, 80,108,
- 204,102,254,160, 36,209, 90, 39,204,194,172,163, 56,102,205, 34,
- 146, 68,145,238,255,255,237,157,235,118, 27, 57, 14,132, 1,182,
- 146,153,221,247,127,215, 61, 51,137,200,253,209, 55, 92, 10, 0,
- 91,182, 99,249, 34, 29,123,168, 30,197,246, 81,172, 47,133, 98,
- 1,252,223,249,253,255,249, 71,126,147,246,239,191,230, 87,169,
- 253,250, 77,190,116,125,107, 69,214,184,255,184,153, 39,244,159,
- 63,213,166,232, 95,127, 29,239,223,229,191,255,185,253,252,201,
- 204,109,105, 63,110, 63,150,101, 97,230, 53, 58,121, 28,181, 69,
- 87, 8, 85,113,138,242,177,203, 70, 91, 89, 72, 81,148,140,151,
- 212, 74,247, 18,243,106,209,152,243, 1,185,116, 48,213,194, 75,
- 210,107, 3,214,142, 48,169,203, 20,185,188, 61,175,125, 46, 48,
- 192,139,101,150,241,233,248,229,236,176,163,150,180,191, 71,188,
- 59, 98, 60, 70,223,103, 68,111,145,138,179,189,241,104, 23,218,
- 40,182,194,107, 89,150,131, 95,242,174, 4,152,208, 94, 93, 94,
- 16, 20,115, 21,165,248,124, 30, 43,158,128, 44, 46, 45,141,221,
- 79,190,204, 20,186,108, 39, 26, 29, 26,237,124, 5,161, 60, 25,
- 71,152,139, 7, 19,181,182, 14,253,216, 74,210, 1, 74,173, 67,
- 233,172, 82,116, 19, 44,189,255,250,253,235,126, 63,251,246,122,
- 239,191,127,255,186,223,187,159,148, 96, 80,120,249,215, 66, 64,
- 7,252,175,165,221,110, 63,228,182,186,185,114,188, 49,200, 15,
- 183,189,254,219, 57, 3,169,136, 83, 24, 85,211, 30,124,104,199,
- 7, 69, 98, 6, 46,239,207, 55,215, 4, 20,198, 82,245,210, 9,
- 48,229,226,139,103,156, 66, 11,109, 44, 6,154,235,196, 22,243,
- 133,102,198,119,225,215,140, 16,219,118,239,134,213, 98,107, 45,
- 185,105,177, 19,100, 39,197, 86,134,245, 53, 56,177, 44,203,253,
- 222,151,142,252,251, 29, 90,119,101,129, 73, 83,204,148,148,189,
- 175,236,218,239,178,176,220, 64,134, 88, 38, 17,150, 81, 44,228,
- 89,184,128, 80, 19, 92, 27,226,112, 2,169,203, 88, 29, 11,174,
- 195, 98, 68,212,150, 38,255,192,223,244,247,181,194,237, 49,122,
- 189, 12, 58, 47,162, 82,181,143,202,181,215,238, 5, 88,129,170,
- 201, 13,196,156, 92, 24, 94,102,178,223,217, 67,204, 7, 65,108,
- 7, 35,203, 86, 32,167,192, 54, 44, 1,255,222,225,173, 53,117,
- 178,134,194, 86,228,115, 5,211, 7,249,201,249,149, 11,177, 67,
- 142,169, 78,107,230, 49, 58,119,238, 60,152,185,141,182,166,195,
- 36,197,118,152, 45,189,111, 8,235,189, 47,247,123, 95,182,252,
- 215, 94, 42,138,133,208, 96, 14,100,128, 95, 39,200,156, 55, 86,
- 236, 84,122,168, 17,138,146, 69,114,140,236, 85,146,173,203,199,
- 53, 83,126, 42,189,118,152, 88, 99, 4,182,189, 2, 92,130, 42,
- 118,123,149,122,127,224, 57,110, 92,213,124,243, 10,107, 78, 94,
- 57, 48,249, 93,195, 76,112, 37,187,136, 51,219,137, 65,181,232,
- 176,133,199, 71, 52,233,217, 47,106,109, 23, 74,163, 5, 69,162,
- 23, 92, 59,194, 28,182, 20,187,222,214,105,189,189,193,175, 88,
- 234,136,137,232, 17,143, 49,120,112,231, 62, 6,175,159,152, 71,
- 27,146, 98,167,123,213, 78,164,173, 20, 91, 65,181,116,100,123,
- 9,114,221,141, 10,219,120,101, 19,175,160,168,148, 44, 11,228,
- 152,151,100,228, 45,255, 74,145, 57,136,129,133, 50,191,197, 73,
- 148, 82,178, 9,216,145, 5,156, 11, 81,132, 27,148,252,154, 27,
- 139,175, 47,172,174, 52, 60, 63,198,172, 89,157,117, 85,109,249,
- 131, 80, 33,194, 76, 49, 38, 39, 11,234, 82,209,170, 46, 54, 77,
- 216,106,179, 81, 92,148,120, 90,150, 5, 33, 79, 24,255,154, 92,
- 98,167, 96,255, 17, 15, 32, 67,217,245,214,255,250,221,222,236,
- 151,208, 10, 49,115, 20,236, 56,182,227,218,104, 99,109,169,238,
- 123,226,189,141,214,219, 62,177,176,157,198,123,211,228, 57, 65,
- 6,157,123,141,173,172,223, 72,218,251, 39,190,124,224, 66,211,
- 236, 2,203,140, 46, 43,253,178,124, 33,101, 26,153,254,227,177,
- 143,122, 85,128,147,242, 77,138, 56, 11, 38, 14,135, 78, 95, 8,
- 144,189, 34,176,102,106, 64,247, 99,207, 2, 43,252,152,220, 61,
- 156,138,154, 78, 49, 75,159, 9,113,140,107, 57, 74, 52, 5,174,
- 67,127, 37,253, 64,190,238, 3,240,130, 26,107,166, 78,180, 62,
- 23, 46, 24,153,248,202, 63, 76,207,195, 47, 36,196,116, 57, 41,
- 236,232,213, 17, 91,171,202,253,120, 14,238, 99,108,190,216,230,
- 227,247,214,155,243,224,205, 6, 99,239,125, 57, 96,134,203, 70,
- 253,108, 68,177, 49,122, 71, 20, 83,139,138, 98,175, 10,178,144,
- 107, 33,209,156,105, 5,103,154,234,190,114,198,204, 98, 60,139,
- 186,172, 58, 95, 86, 9,206,168, 42,232, 88, 65, 84, 25, 51, 14,
- 210,170, 84, 88,111,140, 45, 77, 46,161,185,172, 59,207, 25,185,
- 56, 67,211,146,240,202,126, 81, 41,184,206, 34,209, 24, 93,100,
- 68, 87, 92, 48,242,199,210, 95, 72,136,157,229, 36, 29,199, 83,
- 31, 97, 40,222,167,216,239, 51, 34,184,143,157, 96, 99,172,181,
- 100, 27,237,208, 98, 67, 81,204, 19,109, 21,101,227,188, 56, 74,
- 150,137,116,133, 79,237, 43,156,217,252,107, 78, 49, 61,245,194,
- 98,108, 6,103, 22,100, 88,144,129, 21, 4,153,223,101,196, 50,
- 106, 76,207,185, 31,227,241,209,135,243,189, 56,209, 60, 82,175,
- 188, 2,108, 17,202,189,195, 82,103, 30, 91,114,224, 48,235,133,
- 81, 38,137,183, 37,231,227,113, 11,183, 22,163,116, 4,167, 82,
- 138, 17,217, 0, 2,245,134,128,199, 86, 83,135,185,198,228,138,
- 165,240, 71,228, 23, 40, 39,137, 78, 83, 44,162, 24,211,174,196,
- 6,143, 49,250, 1,178, 85,139,141,118, 18, 76,237, 33,122, 18,
- 105,113,229,130, 20,138, 98, 67,242, 78, 55,129,203,187,140,236,
- 251, 94, 74, 37,205,232, 64, 23,225, 8,198, 5,138,205,179, 12,
- 235,179,151,176,204,122,106,127,196,255, 74,124,174,107,204, 2,
- 235,151, 48, 43, 34, 23,134,151,120,179, 75,145,197,201, 28,103,
- 143, 18, 37,140, 68,123,142,101,146,213, 99,108, 48,167, 63,212,
- 38,128, 70,167,207,246, 43, 62, 3,114,121,171,235, 15,237,250,
- 220,232, 15,221,144, 41,230, 40,182,111, 79,186,109,202, 29,104,
- 141, 91, 31,125, 28,254,152,215, 72,214,200, 50, 8, 83, 56,139,
- 117,156,253, 34, 88,139, 25,130,117, 80, 88,210, 69, 69,118,158,
- 236, 76,149, 46,139,161,166,230, 58, 76,226, 44,138, 74, 84, 39,
- 21,226,192,218,107,137, 47, 40,187,114,126, 65, 96, 57,193,101,
- 80, 85, 49, 75,127,154, 83, 91, 51, 7,161,130, 41, 17, 78,115,
- 177,211, 74, 86, 55, 65, 96,105,238,153, 71,199,103, 41,181,252,
- 126, 34,156,239,236,201,245,103,172,174,247,229,151,162,152, 50,
- 197,172,189,191,185,251, 58,108, 65,135, 32, 91,181,216,104, 99,
- 19, 98, 27,197,128, 72, 58, 52, 26,196,153,128,151, 95,184,103,
- 129, 78,240, 97,146,252,197,164,158, 1,180,152, 57,112,132, 0,
- 193,106, 81,118,244, 6, 62, 34,202, 60,181, 2,138,213,136,154,
- 167,216, 76, 83,244, 12,185,226,135,165,212, 18,179,214, 43,193,
- 101,220,105,127, 28,134,215, 92,161,197, 37,225, 37, 39, 68, 0,
- 106, 1,226, 56, 91,221,199, 26, 52,176, 84, 51,164,185, 35, 96,
- 133,198,188,202,161, 62, 7,185,222,133, 95,128, 98,251,193,178,
- 167, 47, 38, 40,118, 32, 76,190,215,133, 54,107, 99,195, 87,219,
- 234,202,131, 39, 43,198, 70,164,157,188,182, 50,251,143, 49,185,
- 108,108,223,231,197,142,239, 62, 5,178,173,204,164, 25,171,127,
- 14, 97,136,104, 50,128,241, 50,150, 77, 3,237,138, 20,227, 73,
- 144,205, 48, 11, 84, 53,230,173,151,195,203,232, 46,184,144,181,
- 212, 76,132, 75,146,194,229,185, 18,237,197, 46,190,224,210, 12,
- 64, 85, 65,133,165, 44, 54,177,205,233,180, 22, 19,206, 67,176,
- 60, 39,241, 93,170,197, 39,225, 87,224,139,109, 50,108,168,225,
- 87,103, 85,185, 78, 25,211, 39,114,172, 97,254,181,160, 28, 99,
- 180,190,141, 91, 85,161, 7,211,235,232,244,147,188, 26,222,193,
- 179, 20,191, 92, 63,101, 92, 83,134, 8,219,175,208,121, 33,160,
- 152,199, 88,205, 50,105, 99,169,225,205, 49,206, 2, 85,245,186,
- 240,202, 16,230,174,170, 11, 25,177, 10,102,225, 18, 49, 35,151,
- 47, 14, 47,204, 62,197, 93,139, 62, 76,207, 14, 91, 64, 55, 1,
- 74,233,144,131, 14, 94, 88,223, 77, 7,204, 72,185,242, 81, 6,
- 53, 72, 69,188, 39,185,222,157, 95,193, 30,165, 43, 40,247,243,
- 115,181, 28,147,198, 18,239, 71,114,172, 73,178,209, 71, 19,115,
- 163, 97,127, 35, 88, 36,132, 83,208, 82, 20, 3,124, 4, 31, 3,
- 216,252,208, 30,155,152,123, 1, 53,152,133,150,188,160, 63, 41,
- 138,145, 56,149, 98, 68,216,242,231, 86,228,215,175,253,237,227,
- 173, 75,119, 61,212, 93,136, 97,165,202, 2,218,162, 12, 65, 4,
- 180, 34, 84,123, 97,225,229,234, 54, 35,142, 32,138,124,117,233,
- 57, 5,228, 21,216, 43,128, 1,136,160, 72, 44, 75,197,247, 39,
- 215,147,240, 43,165, 24,185,243, 87,135,247,248,201,181, 36,182,
- 131, 12,221,176, 44,200,163,186,105, 58,129,164, 58,153, 5, 22,
- 82,241,193, 14,202, 50, 62, 38,116, 87,156,230,143, 71,146,129,
- 22,165, 97,201, 21, 38,251, 35, 69, 70,193,240,210,241,200, 12,
- 194,124, 46, 13,231,226, 43,240,183, 8,246, 30, 6,197, 33, 37,
- 135, 95, 32,108, 17, 56, 25,131, 38,203, 68,219,189,232,212, 80,
- 139, 23,225,136, 9,196,196, 24, 88,219, 37,154, 96,150, 73, 66,
- 168,198,132,167, 36,215, 83,241,203,188, 46,135, 53,230,229,152,
- 44, 41, 15,167, 31,131,140, 86,151,159, 52, 63, 26, 10,110, 25,
- 177, 20,104,168, 30,172,149,225,213, 61,180, 76, 73,105, 52, 88,
- 21,126,213, 92, 19, 68,219,141,179,253, 68,176, 65, 80,157,157,
- 103, 92, 20, 8,203,214,122, 25, 32,108, 92,249, 59,246,118,190,
- 30,203,111,119, 33, 47, 79,125, 56, 36,131,243,183,228, 89,241,
- 18, 73, 39,173, 28,167,168,112,186,148,157,212, 92, 90,162,217,
- 135,141, 91, 54,246, 57,229,148, 69,149,181,178,212,232, 45,241,
- 41,147, 90,198,225,122, 94,193,245,204,252, 10,229,152,240,248,
- 135,252,237, 21,231, 5, 69, 32, 19,198,191, 58,135, 40, 56,149,
- 168, 7,140,193,125,144, 50, 60,225, 60,251,158, 38, 92, 67,138,
- 145,254,148, 38,199, 52,188, 30,138,245,203, 78,164, 17,145,107,
- 148, 89,176,107,133,100,176,107,101,219,125, 2,138, 57, 51,230,
- 114,122,203, 32, 12,108, 39,186, 24, 4, 21,161, 8,164,125, 0,
- 91,162, 93, 63,115,212, 25,250,170,177,227,206,133, 13, 95, 97,
- 43,138,154, 60, 53,185,158,153, 95, 86,142, 73,143,159,252,104,
- 177, 26,100, 64,154, 69,246, 83,102, 87,141, 62,137,187,137, 47,
- 149,103, 43,204, 35, 83, 89,198, 6, 63,196,214,113, 22,153, 2,
- 153,214,101,132,167, 96,212,245,100,164,206, 10,241, 5,255,113,
- 103,125,108, 9, 16, 3,168, 45, 81, 83, 76,138,175, 60, 15,225,
- 236,121,184,175, 72,145,225, 21,235,176,153, 28, 69,140,163,118,
- 229, 75, 77,137,172, 73,108,125, 8,193,245,129,248,149,200,177,
- 75, 32, 3, 20, 3, 60,168,112, 54,201,186, 7,110,161,226,194,
- 63,157,170, 38, 61,200, 8, 4, 96, 47, 25, 98,117,204,194,116,
- 91,214, 27,150,241, 91, 36,172, 85, 46,133,185,210, 77, 69, 16,
- 224,114,216,170, 49, 6,115, 81,111,115,163, 41, 96, 17,116,229,
- 242,242,112, 14, 91, 31,131, 92, 31,136, 95, 72,142, 77,130,108,
- 237, 25, 39,142,219,117,108, 40,158, 48, 74, 40,194, 24,165,185,
- 136, 20,124, 38,140, 95,106, 45,109,222,203,159,212, 56,250,208,
- 11,195, 27,147, 38,114, 97, 19, 23,117, 53, 73,143,231,239, 83,
- 195, 62, 37, 24,206, 70, 88,112,133, 33, 84,181,144, 9, 84,149,
- 144,136, 24, 17,213,104,136,114, 25,151,226, 63,230,190, 23,217,
- 168,131,137,104,165, 17,249, 79,136,173,143,200,175, 7, 64,118,
- 28,240, 38, 96,134,222,211,129, 52,203,184,230, 69, 19, 21,138,
- 138, 52, 8,131,194, 54, 36, 23,153,108, 24,218,145,212,216, 58,
- 46, 88,150,229,177, 49,151,172,176,187,147,100, 79,165,125, 36,
- 69,129,236, 97, 38,148, 70, 21,181,163, 89,104,108, 57,183, 94,
- 20,145,206,188,135, 32, 35,182,142,190,193,150,181,198, 40,234,
- 116, 12,255, 67,185,148,139, 57, 21,136,172,184, 54, 4, 61,213,
- 159, 7, 91, 31,154, 95,240,117, 31,114, 95,106,159,247,170,118,
- 45, 19, 81,166, 93,240,204, 62, 11,138, 55, 39,136,230,235,190,
- 202,155,199,237,145,104,243,209,237, 69, 6,119,155,180,192,228,
- 42,118, 36, 35,116,129, 7, 28, 24, 96,214, 8, 75,119, 27, 51,
- 138, 89,219, 43,186, 71,254,189,230,156,179,243, 51,143, 31, 20,
- 155,232,127,133,193,215,128,149,161, 83, 23,248,122,105,208,244,
- 131, 89,242, 95,135, 95,133,217,191,237, 86, 14, 63,138,229, 28,
- 129,113,204,251,195,177,208, 64,166,121, 53, 20, 74, 36,183,206,
- 47, 82, 49,105, 39,115,185, 10,120, 61,232,223,151, 97,176, 23,
- 12,200, 7, 27,145,248,109,247,160,127, 31, 35, 44, 48,200,180,
- 174,201,131,248,112,244, 68, 60,143,130, 98, 25,133, 0,138, 75,
- 66, 36,177, 96, 91,207, 39,148, 90,159,155, 95, 69,117, 41, 56,
- 54,246,243, 48,118,152,145,103, 89, 8,180, 68,239,224, 5, 10,
- 157, 22,166, 21, 46, 3,211,198,238,172, 45, 50,182,237,135, 56,
- 151,141, 46, 12,121,173, 44,252, 57,197, 60, 87, 73,170, 53,192,
- 153,130, 23, 52,242,243,161, 18, 19, 62,127,186,155,151, 44, 60,
- 179,220, 2,234,193, 9,235, 29,190, 42,148,245, 51,124,210,219,
- 141, 62,237,141,205,187,234,140,146,173,110,153,110,178, 36,127,
- 236,200, 86, 99, 38, 56,192,133, 39,190,168,188, 40,163,141, 2,
- 175, 42, 52,176,242,125,197, 25,143, 62,238,136, 76,234, 69, 56,
- 198,181,134, 86,108,224,211, 99,161,251,164,219, 17,166,239, 97,
- 173, 85,226, 34,182,207, 92, 61,167,168, 4,159, 97, 36, 85, 18,
- 239,160,216,201,138,152,245, 53,164,214, 87,227,215,156, 83,134,
- 89,198, 18, 99,242,196,159, 41,156,165,152, 35, 71,165,217, 2,
- 48, 42, 10, 19,213, 85,128,235,138,217,229,227,247, 52,153,250,
- 154,175, 32,169, 26, 57,113,173, 99,219,230, 91,125, 28,191,114,
- 204,242,242,211, 64,141, 42, 48,205, 2,171,142,149,126,105,102,
- 125, 65,126, 77,177,140, 8, 28,147, 68, 99,247,254, 69, 39, 83,
- 133,179,163,190,138, 88, 70,186,187,231,130,215, 30,195,203,244,
- 9, 5,252, 10,125,250,224, 3,130, 42,113,237,231,234, 71, 70,
- 69, 36, 37, 45, 68,174,166,140,125,125,192, 47,229,244,187,237,
- 75,119,191,176, 39, 80, 73, 59,188, 87,154, 5,178,130,210, 57,
- 0,214, 87,100,214, 23,231,215, 76,141, 9,188,255, 3,101, 37,
- 206, 16,194,242,135,225, 69,131,171, 8, 85,214,198, 74,189,249,
- 2, 94, 51,252, 74, 46, 92,124,209,201, 82, 42,227, 87,240, 80,
- 113,170,240,248,245, 2, 66,205, 48, 43, 39, 17,100, 97,244,240,
- 10,176,190,153,245,205,175,199, 89, 22, 72,179, 24,103,123,104,
- 99,156,224,203,130, 9, 97,141,231,205,245,218,116,159, 89, 80,
- 48,244,235,129,209, 57,145, 6, 43, 73,198,149, 32,171,211, 21,
- 248, 33,132, 23,101,153,139,116,145, 86,161,213,152,158,178,250,
- 75,236,246,111, 96,125,243,235,157,112, 38,144, 6, 38, 99,231,
- 68,171, 48,231,158, 95,112, 42,189, 72,190,189,209, 62,156, 13,
- 73,140, 64,137, 93,120,101, 57, 40, 38, 9, 71, 43,114, 61,150,
- 174,243,139,190,248,156, 91,212,180, 74,107,192,111, 96,125,243,
- 235,121,112,230,254,192,224,108,214,127, 57,183,166, 30,108,163,
- 114, 15, 84, 78,193,177,161, 7,247,144, 8,228, 36, 8,158,239,
- 104,190,204, 35, 47,104, 54, 57,157, 17,218,176, 73, 22, 62,228,
- 234, 88, 15,136,173, 18, 79,217,122,134, 86,133, 18,253,190, 93,
- 185,253, 31,230,204,154,229,115, 62,144, 15, 0, 0, 0, 0, 73,
- 69, 78, 68,174, 66, 96,130
-};
-
-static const unsigned char _data_keyboard_png[11032] = {
- 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 1,112, 0, 0, 0,178, 8, 2, 0, 0, 0,212, 44, 3,
- 99, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11,
- 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,216,
- 1, 30, 13, 6, 32,218,243, 41,227, 0, 0, 32, 0, 73, 68, 65,
- 84,120,218,237,125,207,111, 35,199,181,110,217, 20,203,160, 89,
- 6,221,101,112,186, 7, 84, 51,144,154,198,168, 21,152,116, 48,
- 212, 98, 56,139,153, 0, 17, 3,220,120, 17,103,241,222, 91, 36,
- 249,227,238,189,139, 36, 11,123, 51, 94,152, 50,144, 81,128,105,
- 45,166, 7, 30,210,184, 67, 14,204,166, 16,182,136,116, 13,145,
- 238, 33, 82, 52,145,226, 37,240, 22, 53,106,211, 36,245,139,234,
- 106, 73,156,250,160,133,212, 18,120, 84,213,117,190,250,206,169,
- 211,125,222,217,223,255, 27,136, 5,185,117, 29, 0,208, 59,114,
- 165, 57,105, 78,154, 91, 85,115,239, 2, 9, 9, 9, 9, 73, 40,
- 18, 18, 18,146, 80, 36, 36, 36, 36,161, 72,196,136, 68, 34,145,
- 74,165,228, 60,220, 68, 32,132, 52, 77,147,132,114, 89,164, 82,
- 169, 66,161, 16,155, 27,108,108,108, 64, 8, 33,132, 27, 27, 27,
- 49,152,203,231,243,124,104, 24,227, 24,150, 75, 42,149,202,229,
- 114, 66, 77, 96,140, 63, 41,126,242,233, 47, 62,205,102,179,225,
- 69, 8, 97,161, 80, 72, 36, 18,162,233,178, 80, 40, 64, 8, 69,
- 79, 99, 38,147,217,222,222,254,244, 23,159,110,111,111, 99,140,
- 227, 89,153,169, 84, 42,123, 43, 27,167, 15,167, 82,169,141,141,
- 13,209,119,141,223,184,141,141,141,211,125,252,221, 8,141,161,
- 15, 80, 12,163,226,206,144, 74,165, 24, 99,154,166, 77, 38,147,
- 56, 44,126,132,185, 33,132,144,232,123,150,207,231, 55, 54, 55,
- 208, 7,232,211, 95,124, 90, 40, 20, 4, 89,204,173,231, 14, 59,
- 135, 47,254,231,133,118, 91, 11,151,136,166,105,140, 49,209, 83,
- 154,205,102, 83,239,167, 68,243, 50,132,112, 99,115,131, 82,218,
- 254,190, 77, 41,205,255, 44, 47,148,194, 66, 81, 57, 26,141, 70,
- 63,140,226,148,153, 27, 27, 27,163,209, 40, 6, 71,152, 76, 38,
- 163,209,232,244, 45,252, 70,134, 60,217,108,150, 82,154, 72, 36,
- 240, 71,152, 82, 26,131,136,157, 76, 38,140, 49,190, 27, 8,181,
- 200,119,128,254,171,254,232,135, 81,251,251,246,104, 52,226,118,
- 35, 31, 81, 34,145,160,148, 50,198, 70, 63,140, 56,103, 33,132,
- 50, 31,102,122,189,158,104,198,204,222,202,182,191,111,227,143,
- 176, 80, 15,231, 31,238,251, 62,165,212,247,253,240,138, 56,153,
- 112,103,235,206,246,246,182,166,105, 92,232,125, 82,252, 36,159,
- 207,199,176,185,194,247, 96,191,223,143,199,245,250,253, 62,124,
- 15,158, 34,247,214,162,178, 20,131, 99,135, 11, 37,245,126,170,
- 223,239,103, 50, 25,209,118,249, 46,154, 74,165, 38,255, 59,121,
- 243,253,251,169, 76, 38,131, 16,242, 60, 79, 8,121,125,128,186,
- 127,239, 50,198, 16, 66,148,210,120,102,149,235, 74, 77,211,250,
- 175,250, 49,200,147,193,235,193,104, 52,242,255,233,107,154,214,
- 237,118, 5, 25, 26,141, 70,225, 6,192,183, 4,126, 69, 16,184,
- 20, 2, 0,228,114, 57,238,225,158,231,137,216, 12,230,195,186,
- 193,235, 65, 60, 58,157,139,148,193,235, 65, 38,147,225, 28,189,
- 10, 10,133, 49,246,252,219,231,190,239,251,190,255,252,219,231,
- 49,220, 51, 30, 94,113, 46, 99,255, 22, 27, 17,208,127,209,108,
- 54, 43, 58,191, 48, 63,132, 76, 38, 3, 33,244, 60, 15, 33, 36,
- 78,168, 67, 8,179,183,178,156,139, 61,207, 19, 42, 82, 38,147,
- 73,255, 85, 95,187,173,109,108,108,100,111,101,187,127,239,138,
- 246, 58, 74,105, 42,149, 74, 36, 18,189,163, 94, 54,155, 21,164,
- 46,103,111,220,135, 25,161, 68,185,144,169, 51, 31,102, 98, 10,
- 121, 98,211, 41,241,192,243, 60,207,243, 38,147, 9,223,112, 70,
- 163,209,104, 52,226, 23, 5, 89,236,245,122,147,201,132, 7,252,
- 24, 99, 65, 57, 41, 30,114, 35,132,184,220, 27, 12, 6,185, 92,
- 174,215,235,221,185,115, 39,151,203, 21, 62, 46, 76,103,106,163,
- 85,124,131,215, 3,238,102,140, 49, 46, 82,132,238, 61,137, 68,
- 34,243, 97,166,251,247,238, 96, 48,136, 65, 59,231,214,115,124,
- 171, 75,172, 37, 68,167,213,249, 86, 23,191,211,113,115, 39,237,
- 58,242,216,248, 28,183,237,253, 84,168,159, 69,239, 6,163,209,
- 168,221,110,119,255,222, 77,172, 37, 52, 77,187,115,231,142, 32,
- 189,112,216, 57,220,216,220,216,254,249,182,255, 79, 63,147,201,
- 112, 39, 79, 36, 18, 47, 95,190,124,217,122,153, 91,207,137,240,
- 55,252, 17,158,230, 98,161, 34, 37,151,203,105,183,181,222, 81,
- 111,244,195, 40,255,179, 55,135,116,252, 44, 82,144, 69,198, 88,
- 251,251,118,191,223,159, 76, 38,135,157, 67,209,217,168, 48, 86,
- 189, 18,156,100,122, 77,242,197, 73,192, 24,135, 26,129,103,215,
- 82,239,167, 38,255, 59, 65, 8,241, 93, 72,232,214, 58,250, 97,
- 116,120,120, 88, 40, 20, 52, 77, 59, 60, 60, 20,177,207,124,215,
- 248,142,175,140,237,159,111, 31,118, 14, 17, 66,161,118, 0, 0,
- 240, 36, 78,180, 70, 95,182, 94, 78, 71, 1,140,177,151,173,151,
- 226, 98,171,222, 81,175,223,239,251,190, 95, 40, 20,242,249,124,
- 187,221,230,225,164,184, 72, 36,156,177, 21,147,234,231, 71,148,
- 132,194,147, 82, 43, 3,126, 8,194, 19,218,124, 95, 45,124, 92,
- 224,161,120, 12,177, 49,207, 2,112,209, 46,212, 74, 46,151, 27,
- 188, 30,240,204,165, 80, 67, 11, 39, 77,144,226,227, 26,132,127,
- 248,100, 50,105,183,219,133, 66,225,206,157, 59,240, 61,184, 98,
- 171,244,186, 33,210, 58, 20,132,174, 80,131,137,112, 0,190,207,
- 12, 6, 3,254,205,100, 50,225,223,139, 35,148,237,237,237,124,
- 62,143, 49,230, 71,143,153, 15, 51, 66, 79, 4, 83,169, 84,230,
- 195, 12,167,203,153, 65,197,118,112, 32,142,188,194,104,113, 50,
- 153,248,190, 15,223,131,236,223, 44,230, 20,230, 21,166, 51,174,
- 36,113,179,118,190,219, 51,110, 54,155,105,132, 10,198,230, 73,
- 127,147,205,102,181,219, 90,184,153, 47, 59, 65,195,102,171,229,
- 251, 1, 0, 0, 99,197,220,218, 66, 40, 45,108,205,141,187,174,
- 75, 8,161,116, 8, 0,208,212, 91,134, 97,204,155, 75,165, 82,
- 60,159,151, 74,165,120,193, 82, 52,106,206,233, 12, 41,157,183,
- 216,239,247,121,174, 52,177,150, 24, 13, 70,221,110,119, 57,242,
- 162,116,232, 56,206,204,197,249, 59,152,203,229,250,175,250,220,
- 4,165, 52,183,158,227,135,226, 75, 59, 94,219,233, 76, 79,105,
- 169, 84,140,252,198,121,132, 16,143, 44,252, 85, 56, 64,198,216,
- 224,245, 32,183,158,131, 16,242,244, 51,250, 0,245,142,122, 24,
- 227, 66,161,208,110,183, 47, 74,151,140,141,219,142,227,186, 71,
- 0, 0,132,210,134,177,169,169,170, 72, 66,252,209,220,233,142,
- 48,250, 97, 20, 9,161,180,157,142,227,116,206,227,119,167, 59,
- 194,217,132,226, 7,193,227,199,251,148, 82, 85,213, 78, 33,148,
- 193, 96,128, 16,186, 76, 46,189, 94,111,212, 27, 13, 0,128,170,
- 106,227, 49,107, 54,155,142,227, 84,171,187, 88, 81, 34,191, 97,
- 126, 16,212,106,123,188,220, 35,157, 70,227, 49,171, 55, 26,205,
- 86,107,222,220, 96, 48,224,174,197,143,120, 34,177,222,117, 93,
- 203,178, 0, 0,170,166,206, 19, 10,231, 20, 77,211, 46,147,213,
- 163, 67,202, 39,115, 26, 51,119,144,215,182,133, 10,136, 49,214,
- 253,123, 55,155,205, 78, 38,147, 37,178, 54,140,141,107,123,123,
- 190,239, 67, 8, 21, 5,243, 73, 22,225,108,196, 35,243, 67,155,
- 31,224,225,225, 97, 54,155,229,197, 74,163,209, 27,106,246,125,
- 63,155,205, 94,116,161, 50, 54,126,244,213, 87,148, 82,140,113,
- 50, 9, 93,215,117, 28,167, 92, 46,111,155, 91, 98,116,199,240,
- 209, 87, 95,241,112, 59,153,132,167, 59,130,239,251,218,109, 13,
- 92,174,154,231,235,218, 55,132,120,220, 23,206,244,187,204,135,
- 25,239, 31,222,146,132,242,162,217,178,109,251, 60,207, 65,240,
- 227,137, 75, 78,165,174,235,247, 43, 21, 8,147,156, 50, 45,203,
- 170,215, 27,191,124,248, 32,242,123,134,210, 72,215,245,233,125,
- 134,155,123,250,244,217,175,171,191,250,201,126,120, 44,184,162,
- 74,179, 49, 54,182,172,131,211, 83,131,124,233, 95,114, 81, 2,
- 0,170,213,221, 83, 54,210,201,100, 50, 35, 39, 7,131,193,210,
- 91, 2,103, 19,113,110, 22,162, 84, 42,206, 11, 31,143,144, 90,
- 109, 79, 83,111,205,179,243,233, 67, 62, 15,158,218, 54,165,180,
- 82,169, 28,203,159,113,109,111,207,182,237,188,174,139, 80,208,
- 79,172, 3,198, 88,120,239,248,230,247,248,241,254,239, 62,255,
- 237, 73,132,130, 49, 94,122,193,180,157, 14, 33,158, 97, 24,247,
- 43,247, 66,115,150,117,240,217,111,254, 99,254,143, 57, 21,156,
- 98,235,221,211,181,165,109,219,134, 97, 84,119,119, 99,136,205,
- 74,165,226, 47, 31, 62,224,108, 2, 0, 40, 24,155, 24, 99,215,
- 21,242,166, 41, 8,147,247, 43,247,166,157,141,155, 35,196, 19,
- 61,204, 39,150, 5, 0, 48, 12,227,244, 20,192, 37, 9,101, 24,
- 239, 41, 67,219,233,248,190, 95, 42, 22, 69,179,201, 73,224,114,
- 221, 52, 77, 65,146,129,175,144,112,241,232,235,235, 92, 6,138,
- 8,118,184,123,135,139, 19, 43, 74,185, 92,166,148,182,157,206,
- 194, 93,161,119,212,211, 52,109,233,244,101,171,213, 2, 0,236,
- 148,203,161, 57,195, 48,124,223,159, 23,152,137, 68, 66,211,180,
- 222, 81,239,148,128,241, 52, 66,209, 84,181, 90,221,189, 95,185,
- 23, 58,121,204, 72, 38, 97,156,230, 24, 99,162, 75, 84,219, 78,
- 199,117,221, 74,229, 30, 76,198, 49,165, 66,227,252,216,252,249,
- 156, 9, 35,195, 48, 4, 45, 84, 46, 67, 56,173, 28, 71,148, 67,
- 174,115, 5, 4,227, 62, 0, 0,165,127, 34,124,242,186, 14, 0,
- 8, 78, 8, 33,125,223,127,241,226,197,210, 73,116,223,247, 85,
- 85,155,158, 58, 93, 95, 7, 0,184, 93,119,158,188, 94,188,120,
- 113,250, 86,247,238, 53, 89,145, 39, 81,181,170,198,244,106,137,
- 182,211,161,148,154, 91, 91, 66,215, 61, 87,124,124,125,136,245,
- 177,225, 48,206,155,197,239, 20,132, 73,198,198, 30, 33,130,178,
- 39, 39,161,217,106, 1, 0, 76, 97,226,136,127,242,227,253,125,
- 206, 41, 47,154, 45,199,113, 76,211, 20,119, 98, 48, 47,168, 1,
- 0,252,176, 34,106,254, 10, 66,198,156, 78, 8, 44,157, 2,187,
- 190,133,109,205,102, 19, 0, 96,156,156, 6,142,106,103, 3, 0,
- 120,228, 85, 16,248,165, 98, 81,196,169,196,116,108, 12, 33, 12,
- 181,165,232, 77, 27, 0,240,167, 63,255,133,103,106, 48,198,250,
- 250,186,105,154, 34,246,240,112, 81, 62,181,159,241,187, 6, 0,
- 64, 8,149,203,119, 99,160, 78,198,198,142,227,168,170, 38, 34,
- 121, 31, 70, 1, 15, 31, 62,176,172,131, 47,190,252,146,151,255,
- 137, 91, 42, 88,193,124, 65,150,126,186,219,137, 83,229,243,130,
- 136,243, 11, 99,227,213, 33, 20,143,144,122,163,113,250,185, 82,
- 20,219,248,143, 71, 33,170,170, 37, 69,198, 59,245,122,131, 16,
- 175, 90,221,141, 39,126, 52,205, 59, 0, 0,158,164,100,227,177,
- 235,186,245, 70,195, 61, 58,170,238, 70,255, 15,240, 69, 73, 8,
- 129, 16, 62,124,248,128,231,155,109,251,153,101, 29,224,223, 96,
- 209,219,120,219,113, 24, 99, 66, 55,158, 99,153, 0,249, 96, 25,
- 99,108, 60,102,108, 44,226, 86, 66,152, 52, 77,179,217,108, 62,
- 177, 14,248,160,136, 71,220,163, 35,112, 67,112, 29, 9,133, 31,
- 84, 99,140, 69,156,239,204, 4,116,127,252,195,239, 67,169, 98,
- 219,118,167,211, 89,152,220,190,252,136,234,141, 70,169, 88,140,
- 45,132,204,235,250,180, 58,216, 41,223,125, 98, 29, 56,142,211,
- 118, 28,113,121,211,105,182,130, 16,214,106,123,205, 86,107,167,
- 124, 87,232, 72, 91,173, 22, 58,181, 66, 42,146,112,216,178, 44,
- 195, 48,184,186,108, 54,155,245, 70,131, 16, 34, 98,169, 0, 0,
- 74,197, 34, 99,204,113, 28, 46,159, 17, 66,149,202,189, 90,109,
- 47,182, 8,107,165, 8,133,210, 97,173,182, 7, 0,120,248,224,
- 65,108,201, 96,132,210, 92,193,214, 27,141,182,211,137,124,117,
- 242,115, 98, 85, 83, 61, 66,166,115, 28,111, 74,248, 20, 28,195,
- 72, 75,197,162,227, 56,174,123, 36,136, 80,140,205,205,233, 81,
- 188, 57,242,244,197, 38, 83,120,230,171, 84, 44, 10,181, 98,219,
- 182,170,106,252, 84, 21, 0, 80, 42, 21,147, 16,218,182,253,162,
- 217, 18, 49,153,252, 8,114,167, 92,246, 3, 31, 66,136, 21,133,
- 47,155,153,192, 36,154,149,159, 70, 96, 46,227,198,227,229,229,
- 214,228,245, 34, 20,198,198,143,247,247, 1, 0,213,234,110,252,
- 124,172,106, 42,104, 8, 57,112,229,137,113, 78,148, 51, 43, 21,
- 156, 85, 45, 18, 33,105, 10, 75, 49, 96, 16,123, 26,152,195,113,
- 58, 16, 66,161,167, 75, 30, 33,140,177,153, 10,151,109,115,203,
- 182,109,113,236,204,253, 57, 92, 21,188,100, 86,207,235,130, 86,
- 197,244, 1, 22, 56, 62, 14, 95, 46, 39,181,118,173,216,164,182,
- 183, 71, 41, 21, 84, 29,123, 14,183, 15, 0, 0, 34, 50, 41,213,
- 234,238,188, 39,240,106, 75,140, 21,238,144, 49,164,165, 0, 0,
- 24, 43, 34,150, 62,198,152, 16, 50,191,203,137, 48, 55, 61, 34,
- 94,178, 17,127, 89, 3, 79, 88,198, 99, 87,116,214, 89,215,117,
- 215,117,167, 83, 66,156,191,148,165,238,221,187,215,138, 77,120,
- 129, 96, 12,108, 50,127,180,233, 17,210,104, 52, 32,132,133, 83,
- 75,206,150, 78,214,204,124,113,249,138,177,162,169,170,136,117,
- 217,118, 58,211, 89,122, 74,135,182,253, 12, 28,151, 24, 68,142,
- 173,173, 45, 74,233, 19,235, 32,188,155, 79,109, 91,156,185,144,
- 148,121, 40, 39,116,169,104,170, 10, 33,108,182, 90,211, 11,230,
- 120,116,122, 12, 11,181,182,183, 7, 0,216,217, 17,149,138,226,
- 169, 95, 62, 34, 0,128, 31, 4,142,227, 32,132,150, 59,161,187,
- 46, 10,197, 15,222,188, 97,228,209,163,175,230,131,255,200,143,
- 232,248,243, 32,225, 83, 39,195, 33,165,148, 66, 8,203,229,242,
- 85, 85,241, 69,157,181,177, 44, 0,248,195, 32,227,241,155,186,
- 219, 74,165, 34, 40,182, 42, 24,155,132, 16,199,113, 8, 33,233,
- 52, 10, 2,159, 49,102,154,166,184, 80,142,231,209, 85, 85,139,
- 33, 52,174, 84,238, 61,126,188,255,232,209, 87,188, 42,138,143,
- 206, 48, 12, 65,153, 96,254, 24,193, 84, 84,130,132,238,178,121,
- 93, 55, 12, 35,188,119,132,120,252,180,110,185, 79, 59, 47,161,
- 148,138,197,180,200,247,101,160, 52, 58,105,171, 81,181,232, 23,
- 165,105,154,105,132,194,231, 98, 21, 69,217,218,218, 18,244,104,
- 198, 73,131, 42,129,162,136, 82, 75,142,207, 62,251,141,219,117,
- 61,242, 10, 0,144, 76,194, 82,177,184,240, 89,234, 8,113,191,
- 114, 79, 85, 85, 46,158,103,158,147, 18, 66, 40, 67, 90, 42, 22,
- 69,164, 21, 22,186,220,239, 62,255,220,113, 28, 62,159,162, 71,
- 135, 21, 28,250,130,170,169, 49,228,215,166,239,157,105,154,151,
- 121,202,255,157,253,253,191,197,227, 66,178,199,189, 52, 39,205,
- 173,188, 57,249, 78, 89, 9, 9, 9, 73, 40, 18, 18, 18,146, 80,
- 36, 36, 36, 86, 24,239,180,157, 67, 57, 11, 18, 18, 18, 82,161,
- 72, 72, 72, 92, 47,172,201,228,182, 52, 39,205, 73,115, 82,161,
- 72, 72, 72,200,144, 71, 66, 66, 66, 18,138,132,132,132, 68,124,
- 132, 2, 33,212, 52, 77, 78,232,229,193,223, 45, 46,186, 49,168,
- 132,196,181, 39,148,219, 43, 75, 40, 27, 27, 27, 16, 66, 8,225,
- 198,198,134,104, 91,147,201, 4, 66,152,207,231, 99,238,235,154,
- 205,102, 11,133,130,104, 43,185, 92, 46,151,203,173, 82,203, 90,
- 9, 25,242, 92, 12, 24,227, 84, 42,197, 24,211, 52, 45,158,142,
- 191,221,110,151, 82, 26,167,226,211, 52, 77,187,173, 81,241,221,
- 124, 70,163, 17, 66, 40, 6, 94,150,144,132,114, 77,145,205,102,
- 41,165,137, 68, 2,127,132,105, 92, 13,180,186,221,238,101, 90,
- 145, 94, 20, 8,161,209, 15,163,203,244,165, 62, 39,124,223, 31,
- 12, 6,232, 3, 25,208, 69,131, 84, 42, 21,131,174, 60, 63,214,
- 228, 45, 57, 51,148, 75,189,159,234,247,251,188, 75, 46,141,183,
- 35,159,132,196,233, 72, 36, 18, 49,176,115, 34,145, 88,216,146,
- 125,222, 29, 36,161,156, 1,198,216,243,111,159,135,187,171,156,
- 16,137,183, 84, 7,125,188, 64, 7,133,174,113, 83, 9, 37,145,
- 72,108,108,108,160, 15,208,100, 50, 25,188, 30,112, 15,207,102,
- 179,135,135,242,137,164,203, 78,236,104, 52,138,141,163,185,197,
- 120, 18, 82,171,234,225,185, 92,142, 79, 35, 0, 32,140,122,218,
- 237,182, 8,115,148,210,121,238, 88,133,144, 39,149, 74, 81, 74,
- 61,207, 75, 36, 18, 24, 99,206,154,253, 87,125,185,194,150, 6,
- 198, 24, 99,156, 72, 36,250,253,152,166,113, 48, 24,208,127,209,
- 59,119,238,248,190, 31, 67,214, 38,102, 94, 14, 67, 3,222, 17,
- 76,144,161,201,100,194,195, 13, 30,146, 95,159, 72,252,134, 17,
- 10,165, 52,156,187,193, 96, 32,233, 32, 18,142,230,242, 68,220,
- 234,159,119,134,209,104,148, 72, 36, 86,175,214,102, 58, 52,240,
- 254,225,137,163, 75,198, 24,255,112,132, 16,254, 8,139,230,101,
- 132,208,106,134, 60, 18,145,131,159, 37,109,111,111,107,154, 22,
- 207,185, 82, 38,147,201,222,202,190,248,159, 23,177, 81, 88,156,
- 27,222, 57, 67,131,155,133,209,104,212,254,254, 92,193,148, 36,
- 20,137, 55, 59,222,194, 52,190,160,109, 28, 28,103, 82, 36, 98,
- 115,245, 72, 34,172,203, 18,138, 71,136,235, 30,241, 14, 88, 8,
- 165, 85, 85,141,176,117, 0,239,132,160, 96,101,166, 3, 72,219,
- 233, 12, 41,157,121, 75, 59,255,227,116,164, 93,108,235,245,198,
- 252, 69, 65,111,135,231,131, 10,127, 84,176,162,169,154,160,150,
- 29, 51,182,102, 16,121, 79, 18, 62,141,243, 31,187,240, 62, 70,
- 53,186,147,204, 69, 62,186,208, 17,136,247, 99, 39,179,180,224,
- 110,202,231,247,187,243,187,250,249,135,166,169,234,210,183,108,
- 237,228, 45,107,252,196,178, 92,215,229, 17, 20,132,208,113, 60,
- 199,113, 90,173,214,195, 7, 15, 34, 89, 34, 16,194,122,163,129,
- 49,158, 33, 20,219,182,249,246, 53,189, 56,252,192,175, 55, 26,
- 209, 54,157,172, 55, 22, 16,138,170,169, 34, 8,197,113, 58,132,
- 204, 6,186, 34, 90, 14,157,100, 75, 28,161,208,225, 2,174,167,
- 116,104, 89, 22, 66, 40,114,115,124,116,243, 31,123,210,245,168,
- 224, 7, 1, 33,132, 49,166,170,154, 33, 44,251, 19,131,223,205,
- 128,247,168,138,106,101,158, 72, 40,124, 84,186,174,239,148,203,
- 124, 24,140,141,121,223,249,199,251,251,213,221,221,203,239,174,
- 188,133,165,239,251,211,109, 16,121, 43, 89, 0,128, 71, 94,149,
- 166,135, 77, 94, 1, 0,212,159,182,152,189, 60, 84, 85,251,117,
- 245, 87,177, 9,212, 63,254,225,247,124, 38, 61,226, 89,214, 65,
- 189,209,152, 23,104,151,199,244,136,190,174,125, 67,136,199,237,
- 158, 30,242, 32,132, 16, 66, 75,108,119,188, 13,123,171,213,154,
- 38, 20,199,113, 0, 0,197,185, 94, 75,169, 84, 42,149, 74,177,
- 127,223,176,120,135,247,123,228,147, 41,116,193,196,224,119, 11,
- 193, 27,108, 95,126,101,190,123,178,226,114, 49,198,191,124,248,
- 35, 41, 66,152, 44,149,138,165, 98,209,247,253,102,179, 25,201,
- 48,244,245,117, 0,128, 55,181,157,114,245, 85, 42, 22, 9,241,
- 166,155,105,114,249,167,169,171,240,252, 33,132,201,188,174, 87,
- 42,247,192,113, 63,205, 43, 71,175,215, 27,141, 70, 11, 51,249,
- 103, 2,161,180, 97, 24,190,239,123,199,237,141, 25, 27, 55, 91,
- 45,180, 40, 46,200,229,114, 16,194,120,234,134, 10,133,194,167,
- 191,248,116,250,235, 90, 85,169, 95,161,223,157,190, 50,203,229,
- 242,210, 43,115,237, 36, 85, 9, 0,216,218, 90,208, 89,222, 52,
- 205,122,163,225,116, 58,145,104, 75, 85, 83, 65, 3, 16,242, 42,
- 228, 66,143,188,194, 24,243, 70,205, 30,241,194,235,132,120, 24,
- 227,213,232, 19, 26, 70,124,224,184,237,246,149, 99, 50,153, 92,
- 198,201,185, 72,169,215,191,211,170, 42, 0,160,237, 56,140, 49,
- 190, 46,103, 51, 29,237,118,108,131,138,211, 86, 84,209, 92, 60,
- 126,119,230, 14,177,244,202, 92,172, 80,130, 32, 0, 0, 44, 20,
- 60, 60, 78,161,148,206,216, 91, 46,219,204,219, 44,242,136,145,
- 143,129, 16, 79, 85, 85,174, 68,120,152,195,153, 27, 0,160,138,
- 239,201, 24, 39,120,100, 23, 91,243, 83,209, 75,208, 48, 12, 66,
- 60,222, 81,188,117,130, 60,145, 56, 29, 75,248,157, 80,181, 18,
- 25,161,240,146,246,147, 62, 49,153,132, 0, 0, 63,240,103,182,
- 184,229,178,205,170,170, 81, 74,121,143, 97, 30,251,168,234, 45,
- 8,147,170,170,133, 68,195,227,160,200, 19, 40, 0,128,225,144,
- 214,235,141,233,175,120,238, 22,165,195, 70,227, 59, 0,128,177,
- 42, 94,199,219,241, 54,155,173,182,211,161,148, 22,139, 69, 73,
- 16, 23,197, 18,126, 39, 2,205,102, 11, 0,160, 47,149,218,187,
- 250, 58, 20, 93, 95, 39,196,243, 8, 41,160, 77, 46, 73,184, 60,
- 209,245,117,219,182, 41, 29, 34,148,230,251,158,136, 4, 10,165,
- 116, 38,197, 45, 84, 82,126, 93,251, 6, 0, 48, 30, 51,223,247,
- 33,132,149, 74, 69, 91, 21,217,197, 69,138,227, 56,132, 16, 41,
- 79,110, 28, 28,167, 67, 60,194,198, 99,215,117, 41,165, 24,227,
- 229,238,224,213, 19,138,166,169, 0, 0, 66, 72,193,216, 36,132,
- 132,137, 18,126,253,152,104,136,160, 4, 74,204,167, 60, 33,139,
- 1, 0,170,213, 93,172, 40,171,180, 40,121, 38,133, 82, 90,169,
- 84,164,139,222, 52, 66,113,248, 55, 24,227,114,185,188,109,110,
- 45,247, 57,139, 9,101,254, 52,119, 26,227, 49, 3, 0, 96, 5,
- 71, 50, 18,172, 40, 16,194, 32, 8, 24, 27,251,190, 95, 58,150,
- 202,252,186,235,186,154,170, 50,198, 86, 35,129,194,201,203, 35,
- 164, 86,219,123,250,244, 89,252, 92, 38, 90,164,168,170, 70,136,
- 39,229,201,146,190, 16,163,223,205,128, 31, 27, 95,254,115, 22,
- 231, 80, 20, 69, 1, 0,116,221, 5,205,129,184,219, 35,132, 34,
- 212, 11,170,170,250,190,207,131, 67, 85, 83,167,162, 33,157, 16,
- 242,230,186,128, 4,202,149,137, 50, 85,213,117,157, 16,111,225,
- 12, 75,156, 7,243,185,201,225,240,198,191,251, 42,102,191, 19,
- 129,197,132,194, 51,133,173, 86,107,254, 87, 60,227, 96,108, 70,
- 185, 5,241,244, 79,189,254, 29, 56, 62,247, 9,137,134, 49,198,
- 207,210, 86,163, 2, 37,196, 78,185, 12, 33,180,237,103,215,228,
- 216,248, 6, 65,215,215,231,189,142,210, 33,165, 84,143,186, 68,
- 48,102,196,236,119,241, 17, 10,223, 66,125,223,255,235,227,125,
- 126,254,194, 57,178, 94,111, 52,155, 77,140,113,180, 37,240,156,
- 68,134, 67,170,254,148, 53,248,249, 89, 16, 4, 43, 86,129,194,
- 163, 3,115,107,107, 62, 37, 44,113, 38,242,186, 14, 33,180,109,
- 59,172,163,163,116,248,120,127, 31,220,252, 35,179,152,253, 78,
- 4, 78, 76,202,222,175, 84,120, 21,176,235,186,252,153, 2,126,
- 166,133, 49,142,188,254, 23,161, 52, 47,250,158, 41,233, 9,107,
- 243,197,205, 35, 33,222,127,254,215,127,139, 8, 38,207, 68,169,
- 84,116, 58,157,102,179,105, 24,155, 43,150,157, 21,205,197,229,
- 114,217,178,172, 90,109,111,122,101,154,166,153, 23,166, 80, 60,
- 66,154,205, 86, 16,248, 0,128,175,107,223, 24,198,166,160, 60,
- 81,156,126, 23, 43,161, 64,152,252,229,195, 7,211, 79, 61,242,
- 81,125,246,155,255, 16,241,127, 20,139,197, 33,165,243, 11,162,
- 88,252, 36,240, 3, 61, 47,100,161,148, 22,213, 74,160,180,144,
- 231,190, 12, 99, 83,155, 75, 3, 85, 42,247,136, 71, 40,165,226,
- 8,101,161, 93,161,162, 61, 6,115, 5, 99, 83, 83,213,102,171,
- 197, 87,166, 97, 24,134,177, 41,122, 27,192,138, 18, 3,239,207,
- 251,157, 97, 24,209, 62,229, 63, 3, 85, 83, 75,160, 24,213,178,
- 95, 59, 83,131,133,247,137, 63, 25,213,118, 58, 34,198,118,210,
- 103,230,117, 93,220,182, 19, 67, 21,243,233, 3,156,158,222, 56,
- 237,174,128, 57,132,210, 59,229,187,113, 6, 35,113, 86, 12,197,
- 105, 46, 90, 91, 23,232,203,179,179,115, 23, 66,104, 89, 86,251,
- 122, 60,207, 38, 33, 33,113,221,112, 1, 66,193,138, 82,173,238,
- 66, 8, 91,173,150, 60,155,144,144,144,184,112,200,179,152, 83,
- 146,112,197,206, 92, 36, 36, 36, 34,193, 59,109, 71,118,180,145,
- 144,144,136, 61,228,145,144,144,144, 56, 35,228,233, 29,197, 84,
- 253,157, 91,215, 1, 0,210,156, 52, 39,205,173,176, 57,169, 80,
- 36, 36, 36, 36,161, 72, 72, 72, 72, 66,145,144,144,144,132, 34,
- 33, 33, 33,113, 54,110, 94, 43, 82, 8, 97, 62,159,239,118,187,
- 49,247,178,212, 52,109, 52, 26,197,211,161, 61,151,203,241,126,
- 157,188,187,133, 80, 91, 24, 99,140, 49, 0,192,247,125,254, 28,
- 154,132,196, 91,164, 80, 24, 99, 16,194,108, 54, 27,167,209, 68,
- 34,161,221,214, 38,147, 73, 60,230, 82,169, 20,132,144, 82, 26,
- 131, 69,198, 24,165, 20,125,128,120, 91, 15, 9,137,183, 75,161,
- 0, 0,250,253,190,118, 91,235,245,122,177, 89,204,100, 50,224,
- 248, 93,176,177,241,166,231,121, 49, 24,162,148, 82, 74,181,219,
- 87,240,254, 42,132,144,166,105,130,186,231, 32,132, 48,198,158,
- 231,197,223,149,125,185, 6,140, 87,104, 46,108,134, 61,221, 45,
- 112,186, 67,118,169, 84,228,111,159, 57,243, 49,194, 27,153, 67,
- 241,125, 63,145, 72,112, 39,143,141, 80, 70, 63,140,128, 68,116,
- 62, 80, 40, 20, 54, 54, 55,196, 57, 30, 15, 21,183,127,190,157,
- 207,231,227, 20, 95,217,108,182,240,113, 33, 54, 5, 29,137, 57,
- 199,233, 36, 33, 84,176,226, 56,157, 39,214,193,244, 69, 85, 83,
- 249, 91, 89,137,247,147,158,234, 43,165, 80, 38,147,137,255, 79,
- 31, 99, 28, 79, 70, 3, 0, 16, 79,235,204,183,132, 74, 52, 77,
- 131, 16,122,158, 55, 56, 28,136,139,233, 38,147, 73,183,219,245,
- 60, 15, 99,124,103,235,206,224,245, 32, 30,181,194, 77,196, 38,
- 139,162, 50,135,177,162,169,106, 94,215,191,174,125,227, 7, 1,
- 127,243, 11,191,184,250, 33, 15, 0, 96, 48, 24,108,108,110, 64,
- 8,227, 23,180, 18,203,129,103,211, 57,149,196,150,253,229,145,
- 99,191,223,207,102,179,156, 86,186,221,174,232,149,249,252,219,
- 231,113, 58, 66,180,230, 52,245,150,219,117, 57,161,240,102, 61,
- 233,139,116, 89,122,247,230, 18, 10,251, 55,227,199, 19, 18, 55,
- 11,137, 68, 34,145, 72,172,182,197,213,128,162, 40,170,166, 98,
- 124,129,247,212,173,221,220,209,250,190,207,179,110,242,198,223,
- 8, 48,198,218,237, 54, 66, 40,155,205,106,183,181,120, 98, 16,
- 110, 14,125,128, 6,175, 7, 47, 91, 47,165,158, 61,219,173,130,
- 32,124,215,247, 91, 20,242,112, 66,209,110,107, 49,103,212, 37,
- 46, 9,126,168, 4, 33,212, 52,109,251,231,219,131,215, 3, 65,
- 249, 41, 8,225,198,198, 6,124, 15,246, 95,245,187,221,110,108,
- 71,254, 55,153,241,199,109,199, 25, 14,135,151,121,233,234,218,
- 77, 30, 63, 27,188, 30,240,150,244,114, 53,220,184,123,215,237,
- 118,123,189,158,184,211,144, 68, 34,209,239,247,227, 47,213,131,
- 16, 66, 8, 71,163, 81, 60, 20,150, 72, 36,178,217,108,191,223,
- 191,140, 57,140,149,227,174, 88,183,170,187,187,211, 23,235,224,
- 59, 0,192,175,171,191, 74, 35,228, 56, 29,175,246, 13, 0, 96,
- 103,231,238, 73,239,235, 62, 23,161,116, 93, 55,240, 3,211, 52,
- 69,191,168,141,115,164,235, 30, 1, 0, 32, 76,170,170,154,215,
- 117,132,210,167,100, 82,242, 63,203,247,122,189,139,206,166, 71,
- 126,114, 6,150,132, 80,211, 84,209,239, 52,159, 62,216, 15,161,
- 106, 2, 95, 71,236, 7,129,219,117, 61,242, 42, 92, 34,170,122,
- 43,242,151,126,243,113,205,191,241,251,164,235, 33, 38,147,201,
- 37, 35,214, 83, 76,140, 70,163,168,138,140,249,106, 49, 12, 99,
- 122, 41, 50, 54,110, 54,155, 73, 8,103,218, 0, 99,140,181,219,
- 218,119,141,239, 4,141,107, 6, 60,126, 4, 0, 92,102, 38, 23,
- 190,238,123,230, 98,225,124,157, 67,206, 69, 40,150,117,192, 24,
- 155,159,187,200,217,164,182,183,231,251, 62,132, 80, 81, 48,111,
- 77, 50, 28, 14, 79,121,185, 57,255,227, 68, 34,113, 81, 66, 33,
- 30,153,239,176,133, 16,122,248,240,129, 56, 90,113,156, 14, 33,
- 179,119,189, 4,138, 34, 8,133,177,241, 95, 31,239,115,115, 8,
- 161,116, 26, 17,226, 17,226, 53,155,205, 74,165, 18,237,187,233,
- 249,184,230, 87,255, 73,215, 99, 48, 29, 45,248,106, 81, 53,117,
- 154, 80,248, 90,253,236,179,223,204,175,162,193,235,203, 30,135,
- 159,127, 92,131,193, 0, 33, 20, 73,253, 4, 99, 99,222,246,247,
- 108, 69,163,156,216,120,239,108, 66,233,186, 46, 99, 12, 33,212,
- 233,116,132, 18, 74,179,217,244,125,223, 48,140,251,149,123,225,
- 206,112,102,187,144,203, 16,115,216,211,139,239,228,205, 86,235,
- 209,163,175, 68, 55,250,250,227, 31,126,127, 78, 41,139, 16, 90,
- 78, 57,135,212,172,235,250, 78,185, 28,186, 1,165,195,174,235,
- 206,176, 9,151,232, 50, 10,187, 16,158, 88, 7,190,239, 87, 42,
- 149,249,237, 7,125,128,218,223,183, 99,251, 79, 70,163, 81, 36,
- 165,198,225,154,185,144,227, 44, 67, 40,142,211,129, 16,110,109,
- 109,217,182, 29, 86,188,136, 0, 87,230, 59,229,114,120, 37,182,
- 214, 36,188,135,147,170,169,181,218,158,101, 29,252,238,243,223,
- 94,249,146, 77,189,159, 42,124, 92,104,127,223, 94, 34, 67,244,
- 212,182,103,168,249,120,243, 76,207,111, 9, 92,162, 75,142, 56,
- 63, 94, 52, 91,142,227,148,138,197,121,161, 7, 33,236, 29,245,
- 110, 92, 82,143,179, 9,165,244,179,207,126, 19, 58, 56,165, 67,
- 190, 21,133,223,240, 61,190, 86,219, 59,229,163,222, 61,211,146,
- 235,186,250,113,183, 45, 71,124, 71,158, 43, 60,216,211, 84,213,
- 48, 12, 74,233,149, 55, 30,106,183,219,207,191,125,254,252,219,
- 231, 75, 44, 77,198,198,142,227, 64, 8,167,169,249,116,137,199,
- 109,201, 3,248,115,102, 55,108,219, 54, 12, 99, 97, 60,194, 24,
- 235,247,251, 55,148, 77,170,213,221,144, 77,234,245,198,163,175,
- 190,242,131,160,237,116,190,248,242,203,176,141,244,153,120,247,
- 172,233,115, 0, 0,134,177,137, 80, 90,215,117,199,113,196, 13,
- 76,215,215,193,113,151,249,171, 2,255, 31,130, 32,184,185, 43,
- 222, 35, 30, 0, 64,215,117,217,234, 36,114,248, 65, 96,219, 54,
- 198,120, 70,250,221, 92, 44,100, 19, 0,128,105,154, 8,161, 90,
- 109,207,178, 44,195, 48,206, 31, 43,156, 17,242,116, 58, 29,132,
- 16,255, 56, 93,215, 93,215,237,186,174,160,222,160, 5,195,232,
- 116, 58,142,227, 16, 66,138,139,244,100, 12,224,217,132,176,151,
- 243, 77, 68,224, 7, 0, 0,148, 78,199,108,183, 94,159,221, 9,
- 134,195,149, 58,206,103,140, 89,214, 1, 0, 32, 60, 88, 93, 1,
- 120,196,227,185,182,153, 84, 6,132,201,205,205, 77,219,182, 1,
- 0,230, 69, 50,167,107,167,243,177,239,251,166,105,242, 31,243,
- 186,110, 1,224, 56, 29, 65,132, 2, 97,178,186,187,251,212,182,
- 29,199,177, 44,171,209,104,148,203,119,197, 53, 54,190, 42,252,
- 231,127,253,247,244,143,162,115,192,243, 70, 85, 85,251,117,245,
- 87,209, 19,202,149, 74,203, 24, 96,219,207, 24, 99,140,177,182,
- 227, 8, 61,157,136, 19,121, 93,175, 84, 42,150,101, 61,177, 14,
- 166,101, 87, 24,217, 5, 65, 80,171,237,205,232,151, 37, 9,133,
- 103, 76, 24, 99,225,230,131, 16,114, 93,151,177,177, 32, 57, 13,
- 97,242,126,229, 94,169, 88,172, 55, 26,142,227, 60,126,188,255,
- 240,225,131, 21,227,148, 82,241, 39,177,119, 84, 93,239,207,105,
- 84,156,219,207,159, 94,125, 93,251,102,254,152,252,230, 34,157,
- 70,213,221,123,181,189,189, 70,163,113,122,121,212,205, 2, 15,
- 5, 44,203, 2, 0,132,156,130,177, 98,154,230, 78,249, 46, 99,
- 227, 39,150, 21,141, 66,225, 25,147,249,188,137,104,134, 70, 40,
- 125,191,114, 79,215,215, 31, 63,222,111, 52,190,139,147, 80, 40,
- 29, 2, 0, 52,245,150, 64,223, 22, 92, 52,161, 96, 5, 0, 64,
- 135,195,133, 70, 87, 94, 71,136,188,113,159, 32,148,174, 84,238,
- 213,106,123, 79,172, 3, 17, 42,239,202, 57,133, 49, 22, 42, 17,
- 152, 76,114, 37,129, 21,197,237,186,110,215,157, 95, 87, 23, 32,
- 20, 94,126, 82, 46,151,103,184,227, 79,127,254,139,232,130,148,
- 80,140, 97,140, 99, 46,157,230,162, 76,193,202,205, 93, 28,154,
- 170, 1, 0,200,185,211,242, 18, 23,156, 94,213, 52,205,102,179,
- 249,162,217, 90,153,192, 39,228, 20,199,233,132,117,213, 39, 65,
- 85,181, 83, 10,151,214, 78,119,173,130, 97,204, 92, 55, 12,163,
- 217,108, 10, 45, 72,185, 42,180,157, 14, 33, 30, 66,232, 70, 7,
- 89, 16, 38, 13,195,112, 28,167, 94,111,136, 86, 67,111,169, 84,
- 41, 22, 93,215, 93,177,192, 7,156,187,184,254,116, 44, 62, 54,
- 14,203, 79,230,115, 37,198, 49,147, 69, 62,158, 23,205, 22, 99,
- 227,105,247,230,213, 89, 49, 76,165, 71,200, 19,235,192,178, 44,
- 8,225,195,135, 15, 86, 96,197, 67, 8,235,141,198, 83,251, 25,
- 15,226, 36,162,165,236, 74,229, 30, 99, 44,124, 91,162,196, 25,
- 10,133,151,159,232,139, 54,106,172, 40, 8, 33,199,113, 78,121,
- 196,102, 57,216,182,109,219, 54,127,240,100, 56,164,148, 82,140,
- 241, 57,171,179,150,195, 76,205,159,170,106,167, 60, 70,121,131,
- 128, 80,186, 90,221,125,252,120,191,217,108, 54,155,205,233, 41,
- 149, 43, 62,170,192,135,203, 64,161,129,207,204,129, 96,169, 88,
- 188,254,146,115,237, 4, 14,134,165, 98,241, 36,229, 95, 46,223,
- 13,252, 96,186, 32, 55, 18, 84,171,187,174,123,196,107, 64, 20,
- 69,217,218,218, 42, 24,134,160,227, 36, 85, 83, 75,224,199,123,
- 147, 70, 72, 83, 85,209,242,213, 48, 54,133,166,123,103,120,255,
- 119,159,255,182,237,116, 8, 33, 92,164,164,211,200,216,220, 76,
- 31, 87, 21,197, 48,174, 56,199, 43, 20,124,181,204,156,199,237,
- 148,203,226,138,125, 22, 78, 29,127, 89,244,141, 36,148,211, 67,
- 169,252,113, 37,126,228,172, 31,219,195, 59,113,218, 58,231,172,
- 94,219,168,120,233,113,197, 96,122, 56,164, 49, 60,217,184,112,
- 181, 64,152, 20,167, 23,174,164,170, 83, 32,161, 72, 72, 92, 91,
- 80, 58,244, 8,129, 48,233, 56, 29, 74,105, 88,120, 41, 33, 9,
- 69, 66,226,226,132, 50,164,214,113,169,149,174,235, 51,133,130,
- 18,146, 80, 36, 36, 46, 22,128, 84,171,187, 0, 0,148, 70,171,
- 116,106,187, 26,120,167,237,200, 22, 86, 18, 18, 18,209,224, 93,
- 57, 5, 18, 18, 18,145,133, 60,189, 35, 55, 30, 75,185,117, 29,
- 0, 32,205, 73,115,210,220, 10,155,147, 10, 69, 66, 66, 66, 18,
- 138,132,132,132, 36, 20, 9, 9, 9, 73, 40, 18, 18, 18, 18,146,
- 80, 36, 36, 36, 36,161, 72, 72, 72, 72, 66,145,144,144,144,132,
- 34, 33, 33, 33,113, 37,132,194,216,120,190, 3,139,132,132,132,
- 4,184,232,195,129, 97, 71,101, 58, 28,174, 76,243, 52, 9, 9,
- 137, 43, 80, 40, 97,215,194, 82,177,232, 56,142,124,161,166,132,
- 132,196,146, 10,101,166, 7,106, 26,161,153,206, 64, 18, 18, 18,
- 18,231, 34,148,249,142,202, 11,187,141, 73, 72, 72, 72, 66,185,
- 48,155,112, 72, 78,145,144,120,171,208,118, 58,173, 86, 43,157,
- 78,223,175, 84, 78,122,123,252,218,114,108, 18, 57,167, 80, 58,
- 156,239,121,202, 97, 24, 70,228, 47,230,122,209,108,141, 25,155,
- 127,201,112,215,117, 3, 63, 48, 77, 83,208,219,246,193,155,118,
- 98,111,222, 68,143, 80, 90, 81,148,104, 95,238,239, 17, 66, 60,
- 162,106, 11,222,171,204, 39, 57,141, 80,228,239, 64,158, 57,248,
- 19,218, 69,128,219,210,243,250,204,130,228,163, 91, 56,240,203,
- 204,228, 66, 91,211,255,137,136,249,188,158,112,156,142,239,251,
- 190,239,159,210,140,248, 12, 66,225,103, 58, 8,161,167, 79,159,
- 241, 43,188,115,141, 31, 4,225, 21, 8,161,227, 56, 16,194,203,
- 116,234,161, 67,122, 82,219, 93, 85, 19,178, 52,185,185,105, 78,
- 161,116,248,248,241,254,194,246,102,145,192, 15, 2,203, 58,224,
- 205, 85, 49,198, 0, 0,199,241, 0, 0, 11,169,109,105,240, 22,
- 95,198,208,152,247,171,174,235,214, 27,141,178,128, 86, 71, 11,
- 239, 29,239,182, 45,200,150, 71, 94,205,116, 23,230, 75,168, 4,
- 138, 81, 17, 10,241, 8,183,181,240, 76,147, 79, 38, 0, 64, 85,
- 181,149, 33,148,115,118, 4, 29, 51,182,100,200,163, 40, 74, 50,
- 249,166, 77,193,120,204,124,223,103,140, 1, 0, 24, 99,132,120,
- 170,170, 1, 0, 20, 5, 3, 0, 96,242, 82, 78,168,169,234, 31,
- 255,240,251, 25,113,244,197,151, 95, 66, 8, 69,244,187,216, 54,
- 183, 58,157, 78,179,213,154,150, 63, 79,172, 3, 8,161,160,214,
- 98,140,141,107,181, 61,198,152,105,154,165, 98, 49,228,172,182,
- 211,137,182, 39, 9,239,196,230,186, 46, 0,179, 62,224,186, 71,
- 0, 0, 65,141, 86, 85, 85, 11, 61,188,235,186,150,117,208,108,
- 54, 13, 99, 83, 80,227, 52, 66,188,174,235,198,208, 52,246,148,
- 201,132, 16,178,147, 93,235, 38,178, 73,173,182,247,255,254,239,
- 255, 17,152, 67,153, 38,102,143,144, 90,109,207,113, 58,196, 35,
- 188, 9,187,208, 6,244, 79,109,155, 49, 38,174, 49,104,165,114,
- 239,209,163,175,158, 88, 7,124, 20,188,177,113,185, 92, 22, 36,
- 212,249,112,230, 55,109, 17,155,155,174,235,205,102,115,198,223,
- 24, 27, 19,226, 97,140, 99,120,177,115, 94,215, 89,121,108, 89,
- 150,219,117, 69, 16,138,170,106, 65,224,219,246,179, 24, 8, 69,
- 85, 87,231,206,243, 0, 0, 10,171, 73, 68, 65, 84, 85,199,113,
- 230,201,139,247,234, 61, 41, 78,191,161,108,114,121,126,188,112,
- 165,172,227, 56,245, 70, 67,244, 60,122,132, 56,142,163,235,186,
- 184,118, 92, 88, 81, 76,211,228, 27, 29, 99, 99,219,182, 49,198,
- 130,218, 74, 50, 54,230, 81, 97, 60, 61, 31,120,255,105,174, 71,
- 166, 37, 58, 0, 96,115, 51, 38,113, 46,154,182,138,197, 34,165,
- 52,134,162,109, 93, 95, 95, 56,153,140, 49, 83, 88, 19,210, 27,
- 202, 38,224, 66,149,178, 40,141, 98,235,129, 98,219,207, 32,132,
- 247, 43, 21,161, 86, 74,197,162,235,186,150,117,160,235, 58, 99,
- 172, 34,236,172,202, 35, 30, 23, 14,226,114,189,103, 70, 61,174,
- 235,138,139,119, 22,109, 60, 29, 0,128,158, 23,101,110,219,220,
- 106,181, 90,205, 86, 75,104, 6,157,231,164,116, 93,159,155,204,
- 35,132,208, 10,180,193, 62, 63,155,248, 65, 64,136, 23, 37,161,
- 204,231, 77, 5,181, 98,172,215, 27,190,239,151,203,101,209,238,
- 7, 97,178, 82,185, 87,171,237, 57,142, 99,154,166,184,245, 17,
- 248, 1, 0, 64, 92, 43,220, 51,163, 30,198,198,174,235, 10,141,
- 119,134,195, 31,245,130, 71, 94, 5,129, 95,169, 84,132,186, 28,
- 191,119, 79,109, 91,116,213, 2, 39,148,233,168,199,117, 93,195,
- 48, 86,146, 77,102, 58,180, 47,158,144,147,247,137, 11, 55,250,
- 170, 86,119, 53, 85,229,249, 20, 17, 35,164,116,216,108,181,196,
- 69, 31,243,178,139,127,163,172,196,110, 51, 29,245, 52,155, 77,
- 215, 61,226, 62, 16, 67,188, 67,233, 79,246, 27,211, 52, 69, 71,
- 61,154,170,170,170,230, 56,142, 97,108, 10,237, 84,157,215,117,
- 11,128,112, 50,219, 78,135, 49,102,220,252,147, 29, 74,135, 75,
- 68, 58,170,170,157,178, 79, 92,152, 80,108,251, 89, 50, 9,199,
- 99, 81,201,109,158,188, 44, 11, 56,110, 60,201, 28,132, 16, 33,
- 100,219,118, 62,174,144, 36,158,168, 7, 99, 28, 10,117, 30,239,
- 20, 68,110,170,211,167, 60,126, 16,212,235,141, 90,109,175, 82,
- 169, 8, 61, 82,189, 95,185,247,197,151, 95,214,235,223,105, 85,
- 129,132, 2, 97,114, 58,234,113, 93,119, 53,226, 29,132,210, 23,
- 205, 43,235,186,126,122, 34, 98,237, 34,107, 20, 79,231, 80, 68,
- 108,119, 30, 33,174,235,154,166, 41,116,195,153, 49, 87, 42, 22,
- 85, 77,173,213,246,234,141,198,142, 24, 34, 83,176, 2, 0, 96,
- 227,113,156,203,101,115,115,211,182,237,174,235,106,170,198,143,
- 36, 98,163, 75,172, 40,247, 43,149, 63,253,249,207,141, 70, 67,
- 40,161, 32,148, 46, 21,139,245, 70,163,237,116,132, 10,162, 48,
- 234,225,147, 89, 22, 83, 91, 16, 63,120,180, 56,205, 41,188,205,
- 235, 73,114,254,204, 73,190, 0,161, 64,152, 20,148, 52,225, 96,
- 108,108, 89, 7,177, 29,133, 0, 0, 44,235, 0, 33,196, 7,165,
- 170,154,184,186, 9,172, 96,190,179,237,196,165,188,184, 80,183,
- 109,219,117,143, 24, 27,115,151,136,115,165,114,242,162,148,138,
- 54,100,154,102,179,213,106, 52, 26, 66, 85,109, 24,245,240,201,
- 204,199, 59,153,113,114,202, 37,247,242,107,244,198,182,102,179,
- 73, 41,141, 33, 23,203, 81,175, 55, 40,165,225,201, 14,159,214,
- 176,252, 55,242,141, 84, 85, 53, 74,233,139,102, 43, 78, 65,139,
- 49, 38,132, 16, 66,226,247, 1,238,120, 8,161, 24,152,171, 92,
- 46, 83, 74,155,205,151, 49, 68, 61,162,115,219, 87,197, 41, 81,
- 229,152,175, 11,161, 80, 58,172, 55, 26,177, 85, 49,243,212,239,
- 116,157, 11, 66,105,195, 48, 8,241,218, 78, 71,132,197,157,157,
- 187, 0, 0,219,182,235,245, 6,119,182, 48,221, 48,253, 99,228,
- 81, 15,165,148, 16,162,199,155, 30,242,131,160,182,183, 7, 0,
- 48, 98, 41,123, 41, 24,155, 24,227,243, 28,106, 94, 50,234, 97,
- 140,185,174, 27, 91, 45,207, 95, 31,239,255,233,207,127,241, 8,
- 185, 65,156,178,118, 77, 8,133, 43, 46, 66,188,249, 83,171, 82,
- 177, 24,121,168,197,223, 14, 53, 83,101,191, 83, 46,187,174, 43,
- 40, 59,139, 21,229,225,195, 7,150,117, 80,111, 52,234,141, 6,
- 198, 56,153,132,220, 7,248,193,153,184,168,135, 82, 90, 20, 31,
- 69,206,223, 59, 93,215,133,198,200,211, 40,151,239, 10, 58,118,
- 156,137,122,226,212,122, 60,149, 78, 60, 18, 79, 74,241,126,229,
- 30,132,112, 69, 8, 69,213,212, 18, 40,158,244,171,200,213,184,
- 166,222, 50,205, 59, 51,194,149,151,165, 4,126, 64,135, 20, 67,
- 69,196,138,212, 62,215,218,142, 67, 8,225,170,196, 48, 12, 69,
- 81,120,134, 69, 80,212, 83, 46,151,199,140,137,246,129,153,180,
- 87, 18, 66, 77, 83, 5,157,131,148,138,197,244, 92, 36,165,169,
- 42, 31,105,132,171,133,175,201,176,176, 0,194,100,165, 82, 97,
- 140, 77, 47,155,133,255, 76,116, 44, 89, 38,132,196, 89,240,114,
- 249, 28,223, 59,251,251,127,139,231,127,149, 61,238,165, 57,105,
- 110,229,205,201, 54, 26, 18, 18, 18,146, 80, 36, 36, 36, 36,161,
- 72, 72, 72,172, 48,222,105, 59,135,114, 22, 36, 36, 36,164, 66,
- 145,144,144,184, 94, 88,147,201,237,155,104, 78, 66, 46,149,235,
- 105, 78, 42, 20, 9, 9, 9, 73, 40, 18, 18, 18,146, 80, 36, 36,
- 36, 36,161, 72, 72, 72, 72,156,141, 53, 57, 5, 18, 18,145, 32,
- 147,201, 96,140, 51, 31,102, 0, 0,244, 95,180,215,235,141, 70,
- 35,169, 80, 36, 36, 36,150, 4, 99,172,253,125,187,253,125,123,
- 50,153, 20, 62, 46,200,144, 71, 66, 98, 53,161,105, 90,161, 32,
- 214,195, 7,131, 65,175,215,163,148, 82, 74,123,189, 94, 34,145,
- 136,225,253, 82,146, 80, 36, 36, 36, 36,161, 72, 72,220, 64,228,
- 114,185,171, 18, 68,236,223, 44,134, 87,234, 74, 66,145,144,136,
- 15,217, 91,217,124, 62, 31,179,209,124, 62,159,249, 48,115,120,
- 248, 54, 62, 37, 39, 79,121, 36,110, 62,107,100,179,137, 68,226,
- 164,223,226,143, 48, 0, 32,146,198,189,231,212, 38,248, 35,252,
- 178,245,242, 45, 60,226,145,132, 34,177, 18,113,205,250, 25,113,
- 77,230,195,204,224,245, 32,158,127, 6, 33,228,255,211,127, 59,
- 217, 68, 18,138,196, 42,224,101,235,229, 73, 10,165,240,113, 97,
- 50,153,180,191,111,103, 50,153,203,191,129,249, 60,232,245,122,
- 147,201,228,173,189, 23,146, 80, 36,110, 60, 78,145, 3,156, 77,
- 70,163, 81, 38,147,137,231,159,225,180, 21, 91,132, 37, 9,229,
- 122,193, 15, 2,207, 35, 99,198, 0, 0, 10, 86, 52, 85, 91,153,
- 246,198, 18, 0, 0,206, 38,209,126, 38,165, 67,199,113, 84, 77,
- 93,216,221, 98, 99,115, 3, 0,240,252,219,231,146, 80,222, 46,
- 116, 93,215,182,159, 81, 74, 33,132,138,130,199, 99, 86,111, 52,
- 0, 0,166,105,150,138, 69, 73, 43, 43, 47, 94, 46,179,114,234,
- 141, 70, 85, 91,220, 3,184,255,170,255, 54, 79,248, 91, 74, 40,
- 79,172, 3,199,113, 12,195,168,238,238, 78,183, 89,105, 59, 29,
- 219,182, 9, 33,213,221, 93,201, 41,171, 4,198, 88, 84,228,210,
- 106,181, 16, 66, 39, 53,223,234,245,122,111,243, 60,191,141,117,
- 40,245,122,195,117,221,106,117,247,126,229,222, 76,175,175,130,
- 177, 89,173,238, 82, 74,159, 88,150,116,194,149,138,109,125, 63,
- 18, 87,247,131,128, 82,106,196,213,141,116, 5, 21, 10,132, 16,
- 99, 12, 0,240,188, 55,189, 99, 49,198, 16, 66,254, 99,248,219,
- 169, 8,147, 46, 81, 32,232, 17, 66, 60,146,132,176, 96, 24,116,
- 72,221,174,171,231,117,222,122,142, 55, 24,223, 54,183,234,245,
- 6, 0,192, 48, 12,206, 2,126, 16,184, 93, 23, 0,112,161,126,
- 151,188,137,114,185, 92,230, 59,140, 31, 4,205,102,139,210, 33,
- 0, 0, 99, 69, 85,111,229,117,189, 92, 46, 91,150,229, 7,129,
- 160,222,119, 18, 55, 23,205,102,139, 47,194, 21, 27, 87, 84,110,
- 126, 54,161,100, 50,153,236,173,108, 34,145, 24, 12, 6, 92, 52,
- 98,140,209, 7, 40,180,164,221,214,126, 66, 13,255,240, 46, 74,
- 40, 30, 33, 97, 99,218,225,112, 88, 42, 22,155,173,150, 71, 94,
- 253,186,250, 43, 63, 8,108,219,230,157, 46,121,142,131,141,199,
- 188, 97,162,227,116,154,205,230, 69, 9,165,222,104, 32,132,182,
- 205, 45, 30,224, 88,150,165,170,154,166,222, 2, 0, 52, 91, 45,
- 223, 15,242,186, 94, 48, 54,109,219,118,187,174, 36, 20,137, 25,
- 184,174,171,170,218,140,176, 93, 1, 68,229,230,103, 19, 74, 54,
- 155, 29,188, 30, 32,132, 48,198,243,162,145, 82,250,252,219,231,
- 8,161,194,199, 5,239, 31, 94, 72,111, 23, 2,241, 8, 0,160,
- 90,221,229, 93,126, 33, 76,154, 91, 91,245, 70,195, 35,196,113,
- 58, 16, 66,211, 52,127,252,227,227,102,244,174,235, 34,132, 46,
- 74, 94,174,235,154, 91, 91, 0, 0,198,198,182,109,235,186,254,
- 203,135, 15,222,252,234,232, 40,204,155, 40, 10,246,200,171,146,
- 116, 32,137, 41,180,157, 14, 99,204, 48, 86, 48,222,137,202,205,
- 207,200,161,164, 82, 41,248, 30,164,148, 14, 6, 3, 94,194, 44,
- 2,188,221, 52, 23,147,220,165, 77,211,132, 16,218,246, 51,199,
- 113,204,173,173,208,207,117, 93,247,125,159,210, 33, 15,101,213,
- 11,118,165,247,131,128, 29,247,211,238,186, 46, 99,108, 90,221,
- 248,190, 47, 78,146, 60,181,159,125, 93,251,230,204, 63,251,186,
- 246,205,121,254, 76,226,170,228, 9,132, 80,116,231,249,248, 17,
- 161,155,159, 65, 40, 60,112, 26, 12, 6,148,210, 68, 34, 33,168,
- 58,168, 96,108,154,166,233,186,238, 23, 95,126,233, 7, 1,167,
- 149,114,185,236,251,254,140, 60,193,138, 2, 33,244, 8,241, 60,
- 130, 49, 70,233,139, 41,207,233,114,163, 33,165,252, 3,227,185,
- 103,190, 31, 16,114,182,124, 35,196, 59,207,159, 73,196, 15, 74,
- 135,174,235,234,186,190,122,199,127, 17,186,249,218,153,145, 21,
- 0,224,147,226, 39,225,143,131,129,144,103, 34,118,202,119, 13,
- 99,243,209,163,175,234,245, 6,143, 65, 10,198,166,101, 89,138,
- 130,103,238,159,174,235,174,235, 14,135, 67,125,125,253,242,118,
- 25, 27,243,207,231,121,217, 31,233,102, 40, 36,147, 47,213,199,
- 205, 69,215,117, 1, 0,186,190,190,122, 67,139,208,205,215,206,
- 20, 66,254, 63,125,190,177, 35,132, 50, 31,102, 64,247,205,111,
- 249,219,168, 38,147,201,229,143,247,249,173, 58,231,163, 22,170,
- 170,218,182,205, 24,171, 84,238,241, 83,158,243, 99,186, 44, 90,
- 207,235,245, 70,163,237, 56, 60, 65, 91,111, 52, 32,132,116, 56,
- 4, 0,120,132, 80, 74, 69,100,242,165,250,184,185,232,116, 58,
- 8,161, 85,141,119,162,114,243,181, 51,133,144,231,121,220, 18,
- 198, 56,255, 65, 62,148, 67,252,149,153,244, 95,180,221,110, 95,
- 114, 72,129, 31,240, 19, 28, 8,161,105,110,157,254,199,121, 93,
- 183, 44, 11, 33,132, 21,229,162,132,194, 35, 38, 66, 94,229,117,
- 29, 43,138, 97, 24,182,109,119, 58, 29,254, 91,126, 90, 76,233,
- 48, 8,124,211, 52,163,205,228,239,236,220,125,107,159,239, 88,
- 1,248, 65,224,251,254,116,244,189, 98,241, 78, 84,110,190,118,
- 106,216,239, 15, 6,131,208, 13, 6,131, 65,251,251, 54, 99,140,
- 191, 47,147, 95,228, 15, 86,142, 70, 35,254,171,229,134, 84, 42,
- 21,245,188,206, 24,195, 63, 13,112,170,213,221,105,217, 82,173,
- 238,162, 52,130, 48, 25, 94, 55, 12,131,103, 88,207, 15, 93,215,
- 29,199,225,197,245,247, 43,247,116,125, 61,240,131, 52, 66, 5,
- 99, 19, 0,128, 80,154,120,164, 84,250, 68,187, 96,186,247, 60,
- 92, 38,221,242,230,194,113, 58, 0, 0,126, 62, 24, 27,158, 88,
- 7,148, 14,119,118,238, 10, 93, 60,209,186,249,105,132, 50, 35,
- 114, 38,147,201, 73,103,180,167,252,234, 50,254, 54,227,213,225,
- 143,225, 55, 8,165, 47,170, 35,118,202,101,215,117,107,123,123,
- 188,184, 62,175,235,211, 34, 86, 83,213,200,169, 68, 98, 37, 8,
- 197,193, 24,199, 92,126,226, 56, 14,132, 80,244, 86, 20,173,155,
- 191,117,165,247, 92,224, 80, 74,191,248,242,203,122,189,225, 29,
- 87,181,120,132,180,157,206, 19,235,128, 31, 51, 73, 72,132,160,
- 116,104,110,109,149,203,119,227, 52,202, 87,166,126,211, 82, 54,
- 111,227,195,129, 88, 81,126,247,249,231,245, 70,163,217,106,241,
- 220,205,116, 64, 4,147, 80,186,144,196, 52, 16, 74, 95,168, 26,
- 59,162, 72, 36, 0, 0,156,153, 82,148,132,114, 93,116,202, 78,
- 249,238, 78,249, 46,165, 67, 58,164,128, 63,173, 32,211, 28, 18,
- 215, 6, 65, 16, 96,140,111,220,154,124,219, 95,176,180, 68, 22,
- 70, 66, 34, 6,220,175,220,187,137,255,182,108,163, 33, 33, 33,
- 17, 25,254, 63,181, 34,148,206,219,178, 22,153, 0, 0, 0, 0,
- 73, 69, 78, 68,174, 66, 96,130
-};
-
-
-static const FileEntry _file_entries[] =
-{
-
- { "arrow_down.png", _data_arrow_down_png, 3438 },
- { "arrow_left.png", _data_arrow_left_png, 4122 },
- { "arrow_right.png", _data_arrow_right_png, 4147 },
- { "arrow_up.png", _data_arrow_up_png, 3493 },
- { "back.png", _data_back_png, 3564 },
- { "end.png", _data_end_png, 3562 },
- { "home.png", _data_home_png, 3578 },
- { "key.png", _data_key_png, 2857 },
- { "layout", _data_layout, 7714 },
- { "menu.png", _data_menu_png, 3079 },
- { "power.png", _data_power_png, 3782 },
- { "select.png", _data_select_png, 3374 },
- { "send.png", _data_send_png, 3561 },
- { "spacebar.png", _data_spacebar_png, 2916 },
- { "volume_down.png", _data_volume_down_png, 3586 },
- { "volume_up.png", _data_volume_up_png, 3856 },
- { "device.png", _data_device_png, 45511 },
- { "keyboard.png", _data_keyboard_png, 11032 },
- { NULL, NULL, 0 }
-};
-
diff --git a/android/skin/file.c b/android/skin/file.c
deleted file mode 100644
index b0cb9cf..0000000
--- a/android/skin/file.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/file.h"
-#include "android/utils/path.h"
-#include "android/charmap.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/system.h"
-#include "android/utils/debug.h"
-
-//#include "qemu-common.h"
-
-/** UTILITY ROUTINES
- **/
-static SkinImage*
-skin_image_find_in( const char* dirname, const char* filename )
-{
- char buffer[1024];
- char* p = buffer;
- char* end = p + sizeof(buffer);
-
- p = bufprint( p, end, "%s" PATH_SEP "%s", dirname, filename );
- if (p >= end)
- return SKIN_IMAGE_NONE;
-
- return skin_image_find_simple(buffer);
-}
-
-/** SKIN BACKGROUND
- **/
-
-static void
-skin_background_done( SkinBackground* background )
-{
- if (background->image)
- skin_image_unref(&background->image);
-}
-
-static int
-skin_background_init_from( SkinBackground* background,
- AConfig* node,
- const char* basepath )
-{
- const char* img = aconfig_str(node, "image", NULL);
- int x = aconfig_int(node, "x", 0);
- int y = aconfig_int(node, "y", 0);
-
- background->valid = 0;
-
- if (img == NULL) /* no background */
- return -1;
-
- background->image = skin_image_find_in( basepath, img );
- if (background->image == SKIN_IMAGE_NONE) {
- background->image = NULL;
- return -1;
- }
-
- background->rect.pos.x = x;
- background->rect.pos.y = y;
- background->rect.size.w = skin_image_w( background->image );
- background->rect.size.h = skin_image_h( background->image );
-
- background->valid = 1;
-
- return 0;
-}
-
-/** SKIN DISPLAY
- **/
-
-static void
-skin_display_done( SkinDisplay* display )
-{
- qframebuffer_done( display->qfbuff );
-}
-
-static int
-skin_display_init_from( SkinDisplay* display, AConfig* node )
-{
- display->rect.pos.x = aconfig_int(node, "x", 0);
- display->rect.pos.y = aconfig_int(node, "y", 0);
- display->rect.size.w = aconfig_int(node, "width", 0);
- display->rect.size.h = aconfig_int(node, "height", 0);
- display->rotation = aconfig_unsigned(node, "rotation", SKIN_ROTATION_0);
-
- display->valid = ( display->rect.size.w > 0 && display->rect.size.h > 0 );
-
- if (display->valid) {
- SkinRect r;
- skin_rect_rotate( &r, &display->rect, -display->rotation );
- qframebuffer_init( display->qfbuff,
- r.size.w,
- r.size.h,
- 0,
- QFRAME_BUFFER_RGB565 );
-
- qframebuffer_fifo_add( display->qfbuff );
- }
- return display->valid ? 0 : -1;
-}
-
-/** SKIN BUTTON
- **/
-
-typedef struct
-{
- const char* name;
- AndroidKeyCode code;
-} KeyInfo;
-
-static KeyInfo _keyinfo_table[] = {
- { "dpad-up", kKeyCodeDpadUp },
- { "dpad-down", kKeyCodeDpadDown },
- { "dpad-left", kKeyCodeDpadLeft },
- { "dpad-right", kKeyCodeDpadRight },
- { "dpad-center", kKeyCodeDpadCenter },
- { "soft-left", kKeyCodeSoftLeft },
- { "soft-right", kKeyCodeSoftRight },
- { "volume-up", kKeyCodeVolumeUp },
- { "volume-down", kKeyCodeVolumeDown },
- { "power", kKeyCodePower },
- { "home", kKeyCodeHome },
- { "back", kKeyCodeBack },
- { "del", kKeyCodeDel },
- { "0", kKeyCode0 },
- { "1", kKeyCode1 },
- { "2", kKeyCode2 },
- { "3", kKeyCode3 },
- { "4", kKeyCode4 },
- { "5", kKeyCode5 },
- { "6", kKeyCode6 },
- { "7", kKeyCode7 },
- { "8", kKeyCode8 },
- { "9", kKeyCode9 },
- { "star", kKeyCodeStar },
- { "pound", kKeyCodePound },
- { "phone-dial", kKeyCodeCall },
- { "phone-hangup", kKeyCodeEndCall },
- { "q", kKeyCodeQ },
- { "w", kKeyCodeW },
- { "e", kKeyCodeE },
- { "r", kKeyCodeR },
- { "t", kKeyCodeT },
- { "y", kKeyCodeY },
- { "u", kKeyCodeU },
- { "i", kKeyCodeI },
- { "o", kKeyCodeO },
- { "p", kKeyCodeP },
- { "a", kKeyCodeA },
- { "s", kKeyCodeS },
- { "d", kKeyCodeD },
- { "f", kKeyCodeF },
- { "g", kKeyCodeG },
- { "h", kKeyCodeH },
- { "j", kKeyCodeJ },
- { "k", kKeyCodeK },
- { "l", kKeyCodeL },
- { "DEL", kKeyCodeDel },
- { "z", kKeyCodeZ },
- { "x", kKeyCodeX },
- { "c", kKeyCodeC },
- { "v", kKeyCodeV },
- { "b", kKeyCodeB },
- { "n", kKeyCodeN },
- { "m", kKeyCodeM },
- { "COMMA", kKeyCodeComma },
- { "PERIOD", kKeyCodePeriod },
- { "ENTER", kKeyCodeNewline },
- { "AT", kKeyCodeAt },
- { "SPACE", kKeyCodeSpace },
- { "SLASH", kKeyCodeSlash },
- { "CAP", kKeyCodeCapLeft },
- { "SYM", kKeyCodeSym },
- { "ALT", kKeyCodeAltLeft },
- { "ALT2", kKeyCodeAltRight },
- { "CAP2", kKeyCodeCapRight },
- { 0, 0 },
-};
-
-static unsigned
-keyinfo_lookup_code(const char *name)
-{
- KeyInfo *ki = _keyinfo_table;
- while(ki->name) {
- if(!strcmp(name, ki->name))
- return ki->code;
- ki++;
- }
- return 0;
-}
-
-
-static void
-skin_button_free( SkinButton* button )
-{
- if (button) {
- skin_image_unref( &button->image );
- AFREE(button);
- }
-}
-
-static SkinButton*
-skin_button_create_from( AConfig* node, const char* basepath )
-{
- SkinButton* button;
- ANEW0(button);
- if (button) {
- const char* img = aconfig_str(node, "image", NULL);
- int x = aconfig_int(node, "x", 0);
- int y = aconfig_int(node, "y", 0);
-
- button->name = node->name;
- button->rect.pos.x = x;
- button->rect.pos.y = y;
-
- if (img != NULL)
- button->image = skin_image_find_in( basepath, img );
-
- if (button->image == SKIN_IMAGE_NONE) {
- skin_button_free(button);
- return NULL;
- }
-
- button->rect.size.w = skin_image_w( button->image );
- button->rect.size.h = skin_image_h( button->image );
-
- button->keycode = keyinfo_lookup_code( button->name );
- if (button->keycode == 0) {
- dprint( "Warning: skin file button uses unknown key name '%s'", button->name );
- }
- }
- return button;
-}
-
-/** SKIN PART
- **/
-
-static void
-skin_part_free( SkinPart* part )
-{
- if (part) {
- skin_background_done( part->background );
- skin_display_done( part->display );
-
- SKIN_PART_LOOP_BUTTONS(part,button)
- skin_button_free(button);
- SKIN_PART_LOOP_END
- part->buttons = NULL;
- AFREE(part);
- }
-}
-
-static SkinLocation*
-skin_location_create_from_v2( AConfig* node, SkinPart* parts )
-{
- const char* partname = aconfig_str(node, "name", NULL);
- int x = aconfig_int(node, "x", 0);
- int y = aconfig_int(node, "y", 0);
- SkinRotation rot = aconfig_int(node, "rotation", SKIN_ROTATION_0);
- SkinPart* part;
- SkinLocation* location;
-
- if (partname == NULL) {
- dprint( "### WARNING: ignoring part location without 'name' element" );
- return NULL;
- }
-
- for (part = parts; part; part = part->next)
- if (!strcmp(part->name, partname))
- break;
-
- if (part == NULL) {
- dprint( "### WARNING: ignoring part location with unknown name '%s'", partname );
- return NULL;
- }
-
- ANEW0(location);
- location->part = part;
- location->anchor.x = x;
- location->anchor.y = y;
- location->rotation = rot;
-
- return location;
-}
-
-static SkinPart*
-skin_part_create_from_v1( AConfig* root, const char* basepath )
-{
- SkinPart* part;
- AConfig* node;
- SkinBox box;
-
- ANEW0(part);
- part->name = root->name;
-
- node = aconfig_find(root, "background");
- if (node)
- skin_background_init_from(part->background, node, basepath);
-
- node = aconfig_find(root, "display");
- if (node)
- skin_display_init_from(part->display, node);
-
- node = aconfig_find(root, "button");
- if (node) {
- for (node = node->first_child; node != NULL; node = node->next)
- {
- SkinButton* button = skin_button_create_from(node, basepath);
-
- if (button != NULL) {
- button->next = part->buttons;
- part->buttons = button;
- }
- }
- }
-
- skin_box_minmax_init( &box );
-
- if (part->background->valid)
- skin_box_minmax_update( &box, &part->background->rect );
-
- if (part->display->valid)
- skin_box_minmax_update( &box, &part->display->rect );
-
- SKIN_PART_LOOP_BUTTONS(part, button)
- skin_box_minmax_update( &box, &button->rect );
- SKIN_PART_LOOP_END
-
- if ( !skin_box_minmax_to_rect( &box, &part->rect ) ) {
- skin_part_free(part);
- part = NULL;
- }
-
- return part;
-}
-
-static SkinPart*
-skin_part_create_from_v2( AConfig* root, const char* basepath )
-{
- SkinPart* part;
- AConfig* node;
- SkinBox box;
-
- ANEW0(part);
- part->name = root->name;
-
- node = aconfig_find(root, "background");
- if (node)
- skin_background_init_from(part->background, node, basepath);
-
- node = aconfig_find(root, "display");
- if (node)
- skin_display_init_from(part->display, node);
-
- node = aconfig_find(root, "buttons");
- if (node) {
- for (node = node->first_child; node != NULL; node = node->next)
- {
- SkinButton* button = skin_button_create_from(node, basepath);
-
- if (button != NULL) {
- button->next = part->buttons;
- part->buttons = button;
- }
- }
- }
-
- skin_box_minmax_init( &box );
-
- if (part->background->valid)
- skin_box_minmax_update( &box, &part->background->rect );
-
- if (part->display->valid)
- skin_box_minmax_update( &box, &part->display->rect );
-
- SKIN_PART_LOOP_BUTTONS(part, button)
- skin_box_minmax_update( &box, &button->rect );
- SKIN_PART_LOOP_END
-
- if ( !skin_box_minmax_to_rect( &box, &part->rect ) ) {
- skin_part_free(part);
- part = NULL;
- }
- return part;
-}
-
-/** SKIN LAYOUT
- **/
-
-static void
-skin_layout_free( SkinLayout* layout )
-{
- if (layout) {
- SKIN_LAYOUT_LOOP_LOCS(layout,loc)
- AFREE(loc);
- SKIN_LAYOUT_LOOP_END
- layout->locations = NULL;
- AFREE(layout);
- }
-}
-
-SkinDisplay*
-skin_layout_get_display( SkinLayout* layout )
-{
- SKIN_LAYOUT_LOOP_LOCS(layout,loc)
- SkinPart* part = loc->part;
- if (part->display->valid) {
- return part->display;
- }
- SKIN_LAYOUT_LOOP_END
- return NULL;
-}
-
-SkinRotation
-skin_layout_get_dpad_rotation( SkinLayout* layout )
-{
- SKIN_LAYOUT_LOOP_LOCS(layout, loc)
- SkinPart* part = loc->part;
- SKIN_PART_LOOP_BUTTONS(part,button)
- if (button->keycode == kKeyCodeDpadUp)
- return loc->rotation;
- SKIN_PART_LOOP_END
- SKIN_LAYOUT_LOOP_END
-
- return SKIN_ROTATION_0;
-}
-
-
-static int
-skin_layout_event_decode( const char* event, int *ptype, int *pcode, int *pvalue )
-{
- typedef struct {
- const char* name;
- int value;
- } EventName;
-
- static const EventName _event_names[] = {
- { "EV_SW", 0x05 },
- { NULL, 0 },
- };
-
- const char* x = strchr(event, ':');
- const char* y = NULL;
- const EventName* ev = _event_names;
-
- if (x != NULL)
- y = strchr(x+1, ':');
-
- if (x == NULL || y == NULL) {
- dprint( "### WARNING: invalid skin layout event format: '%s', should be '<TYPE>:<CODE>:<VALUE>'", event );
- return -1;
- }
-
- for ( ; ev->name != NULL; ev++ )
- if (!memcmp( event, ev->name, x - event ) && ev->name[x-event] == 0)
- break;
-
- if (!ev->name) {
- dprint( "### WARNING: unrecognized skin layout event name: %.*s", x-event, event );
- return -1;
- }
-
- *ptype = ev->value;
- *pcode = strtol(x+1, NULL, 0);
- *pvalue = strtol(y+1, NULL, 0);
- return 0;
-}
-
-static SkinLayout*
-skin_layout_create_from_v2( AConfig* root, SkinPart* parts )
-{
- SkinLayout* layout;
- int width, height;
- SkinLocation** ptail;
- AConfig* node;
-
- ANEW0(layout);
-
- width = aconfig_int( root, "width", 400 );
- height = aconfig_int( root, "height", 400 );
-
- node = aconfig_find( root, "event" );
- if (node != NULL) {
- skin_layout_event_decode( node->value,
- &layout->event_type,
- &layout->event_code,
- &layout->event_value );
- } else {
- layout->event_type = 0x05; /* close keyboard by default */
- layout->event_code = 0;
- layout->event_value = 1;
- }
-
- layout->name = root->name;
- layout->color = aconfig_unsigned( root, "color", 0x808080 ) | 0xff000000;
- ptail = &layout->locations;
-
- for (node = root->first_child; node; node = node->next)
- {
- if (!memcmp(node->name, "part", 4)) {
- SkinLocation* location = skin_location_create_from_v2( node, parts );
- if (location == NULL) {
- continue;
- }
- *ptail = location;
- ptail = &location->next;
- }
- }
-
- if (layout->locations == NULL)
- goto Fail;
-
- layout->size.w = width;
- layout->size.h = height;
-
- return layout;
-
-Fail:
- skin_layout_free(layout);
- return NULL;
-}
-
-/** SKIN FILE
- **/
-
-static int
-skin_file_load_from_v1( SkinFile* file, AConfig* aconfig, const char* basepath )
-{
- SkinPart* part;
- SkinLayout* layout;
- SkinLayout** ptail = &file->layouts;
- SkinLocation* location;
- int nn;
-
- file->parts = part = skin_part_create_from_v1( aconfig, basepath );
- if (part == NULL)
- return -1;
-
- for (nn = 0; nn < 2; nn++)
- {
- ANEW0(layout);
-
- layout->color = 0xff808080;
-
- ANEW0(location);
-
- layout->event_type = 0x05; /* close keyboard by default */
- layout->event_code = 0;
- layout->event_value = 1;
-
- location->part = part;
- switch (nn) {
- case 0:
- location->anchor.x = 0;
- location->anchor.y = 0;
- location->rotation = SKIN_ROTATION_0;
- layout->size = part->rect.size;
- break;
-
-#if 0
- case 1:
- location->anchor.x = part->rect.size.h;
- location->anchor.y = 0;
- location->rotation = SKIN_ROTATION_90;
- layout->size.w = part->rect.size.h;
- layout->size.h = part->rect.size.w;
- layout->event_value = 0;
- break;
-
- case 2:
- location->anchor.x = part->rect.size.w;
- location->anchor.y = part->rect.size.h;
- location->rotation = SKIN_ROTATION_180;
- layout->size = part->rect.size;
- break;
-#endif
- default:
- location->anchor.x = 0;
- location->anchor.y = part->rect.size.w;
- location->rotation = SKIN_ROTATION_270;
- layout->size.w = part->rect.size.h;
- layout->size.h = part->rect.size.w;
- layout->event_value = 0;
- break;
- }
- layout->locations = location;
-
- *ptail = layout;
- ptail = &layout->next;
- }
- return 0;
-}
-
-static int
-skin_file_load_from_v2( SkinFile* file, AConfig* aconfig, const char* basepath )
-{
- AConfig* node;
-
- /* first, load all parts */
- node = aconfig_find(aconfig, "parts");
- if (node == NULL)
- return -1;
- else
- {
- SkinPart** ptail = &file->parts;
- for (node = node->first_child; node != NULL; node = node->next)
- {
- SkinPart* part = skin_part_create_from_v2( node, basepath );
- if (part == NULL) {
- dprint( "## WARNING: can't load part '%s' from skin\n", node->name ? "<NULL>" : node->name );
- continue;
- }
- part->next = NULL;
- *ptail = part;
- ptail = &part->next;
- }
- }
-
- if (file->parts == NULL)
- return -1;
-
- /* then load all layouts */
- node = aconfig_find(aconfig, "layouts");
- if (node == NULL)
- return -1;
- else
- {
- SkinLayout** ptail = &file->layouts;
- for (node = node->first_child; node != NULL; node = node->next)
- {
- SkinLayout* layout = skin_layout_create_from_v2( node, file->parts );
- if (layout == NULL) {
- dprint( "## WARNING: ignoring layout in skin file" );
- continue;
- }
- *ptail = layout;
- layout->next = NULL;
- ptail = &layout->next;
- }
- }
- if (file->layouts == NULL)
- return -1;
-
- return 0;
-}
-
-SkinFile*
-skin_file_create_from_aconfig( AConfig* aconfig, const char* basepath )
-{
- SkinFile* file;
-
- ANEW0(file);
- if ( aconfig_find(aconfig, "parts") != NULL) {
- if (skin_file_load_from_v2( file, aconfig, basepath ) < 0) {
- skin_file_free( file );
- file = NULL;
- }
- }
- else {
- if (skin_file_load_from_v1( file, aconfig, basepath ) < 0) {
- skin_file_free( file );
- file = NULL;
- }
- }
- return file;
-}
-
-void
-skin_file_free( SkinFile* file )
-{
- if (file) {
- SKIN_FILE_LOOP_LAYOUTS(file,layout)
- skin_layout_free(layout);
- SKIN_FILE_LOOP_END_LAYOUTS
- file->layouts = NULL;
-
- SKIN_FILE_LOOP_PARTS(file,part)
- skin_part_free(part);
- SKIN_FILE_LOOP_END_PARTS
- file->parts = NULL;
-
- AFREE(file);
- }
-}
diff --git a/android/skin/file.h b/android/skin/file.h
deleted file mode 100644
index 8f95368..0000000
--- a/android/skin/file.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_FILE_H
-#define _ANDROID_SKIN_FILE_H
-
-#include "android/skin/image.h"
-#include "android/config.h"
-#include "framebuffer.h"
-
-/** Layout
- **/
-
-typedef struct SkinBackground {
- SkinImage* image;
- SkinRect rect;
- char valid;
-} SkinBackground;
-
-typedef struct SkinDisplay {
- SkinRect rect; /* display rectangle */
- SkinRotation rotation; /* framebuffer rotation */
- char valid;
- QFrameBuffer qfbuff[1];
-} SkinDisplay;
-
-typedef struct SkinButton {
- struct SkinButton* next;
- const char* name;
- SkinImage* image;
- SkinRect rect;
- unsigned keycode;
-} SkinButton;
-
-typedef struct SkinPart {
- struct SkinPart* next;
- const char* name;
- SkinBackground background[1];
- SkinDisplay display[1];
- SkinButton* buttons;
- SkinRect rect; /* bounding box of all parts */
-} SkinPart;
-
-#define SKIN_PART_LOOP_BUTTONS(part,button) \
- do { \
- SkinButton* __button = (part)->buttons; \
- while (__button != NULL) { \
- SkinButton* __button_next = __button->next; \
- SkinButton* button = __button;
-
-#define SKIN_PART_LOOP_END \
- __button = __button_next; \
- } \
- } while (0);
-
-typedef struct SkinLocation {
- SkinPart* part;
- SkinPos anchor;
- SkinRotation rotation;
- struct SkinLocation* next;
-} SkinLocation;
-
-typedef struct SkinLayout {
- struct SkinLayout* next;
- const char* name;
- unsigned color;
- int event_type;
- int event_code;
- int event_value;
- SkinSize size;
- SkinLocation* locations;
-} SkinLayout;
-
-#define SKIN_LAYOUT_LOOP_LOCS(layout,loc) \
- do { \
- SkinLocation* __loc = (layout)->locations; \
- while (__loc != NULL) { \
- SkinLocation* __loc_next = (__loc)->next; \
- SkinLocation* loc = __loc;
-
-#define SKIN_LAYOUT_LOOP_END \
- __loc = __loc_next; \
- } \
- } while (0);
-
-extern SkinDisplay* skin_layout_get_display( SkinLayout* layout );
-
-extern SkinRotation skin_layout_get_dpad_rotation( SkinLayout* layout );
-
-typedef struct SkinFile {
- SkinPart* parts;
- SkinLayout* layouts;
- int num_parts;
- int num_layouts;
-} SkinFile;
-
-#define SKIN_FILE_LOOP_LAYOUTS(file,layout) \
- do { \
- SkinLayout* __layout = (file)->layouts; \
- while (__layout != NULL) { \
- SkinLayout* __layout_next = __layout->next; \
- SkinLayout* layout = __layout;
-
-#define SKIN_FILE_LOOP_END_LAYOUTS \
- __layout = __layout_next; \
- } \
- } while (0);
-
-#define SKIN_FILE_LOOP_PARTS(file,part) \
- do { \
- SkinPart* __part = (file)->parts; \
- while (__part != NULL) { \
- SkinPart* __part_next = __part->next; \
- SkinPart* part = __part;
-
-#define SKIN_FILE_LOOP_END_PARTS \
- __part = __part_next; \
- } \
- } while (0);
-
-extern SkinFile* skin_file_create_from_aconfig( AConfig* aconfig, const char* basepath );
-extern void skin_file_free( SkinFile* file );
-
-#endif /* _ANDROID_SKIN_FILE_H */
diff --git a/android/skin/image.c b/android/skin/image.c
deleted file mode 100644
index 051fc6d..0000000
--- a/android/skin/image.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/image.h"
-#include "android/resource.h"
-#include <assert.h>
-#include <limits.h>
-
-#define DEBUG 0
-
-#if DEBUG
-static void D(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
-}
-#else
-#define D(...) do{}while(0)
-#endif
-
-/********************************************************************************/
-/********************************************************************************/
-/***** *****/
-/***** U T I L I T Y F U N C T I O N S *****/
-/***** *****/
-/********************************************************************************/
-/********************************************************************************/
-
-SDL_Surface*
-sdl_surface_from_argb32( void* base, int w, int h )
-{
- return SDL_CreateRGBSurfaceFrom(
- base, w, h, 32, w*4,
-#if WORDS_BIGENDIAN
- 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
-#else
- 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
-#endif
- );
-}
-
-static void*
-rotate_image( void* data, unsigned width, unsigned height, SkinRotation rotation )
-{
- void* result;
-
- result = malloc( width*height*4 );
- if (result == NULL)
- return NULL;
-
- switch (rotation & 3)
- {
- case SKIN_ROTATION_0:
- memcpy( (char*)result, (const char*)data, width*height*4 );
- break;
-
- case SKIN_ROTATION_270:
- {
- unsigned* start = (unsigned*)data;
- unsigned* src_line = start + (width-1);
- unsigned* dst_line = (unsigned*)result;
- unsigned hh;
-
- for (hh = width; hh > 0; hh--)
- {
- unsigned* src = src_line;
- unsigned* dst = dst_line;
- unsigned count = height;
-
- for ( ; count > 0; count-- ) {
- dst[0] = src[0];
- dst += 1;
- src += width;
- }
-
- src_line -= 1;
- dst_line += height;
- }
- }
- break;
-
- case SKIN_ROTATION_180:
- {
- unsigned* start = (unsigned*)data;
- unsigned* src_line = start + width*(height-1);
- unsigned* dst_line = (unsigned*)result;
- unsigned hh;
-
- for (hh = height; hh > 0; hh--)
- {
- unsigned* src = src_line + (width-1);
- unsigned* dst = dst_line;
-
- while (src >= src_line)
- *dst++ = *src--;
-
- dst_line += width;
- src_line -= width;
- }
- }
- break;
-
- case SKIN_ROTATION_90:
- {
- unsigned* start = (unsigned*)data;
- unsigned* src_line = start + width*(height-1);
- unsigned* dst_line = (unsigned*)result ;
- unsigned hh;
-
- for (hh = width; hh > 0; hh--)
- {
- unsigned* src = src_line;
- unsigned* dst = dst_line;
- unsigned count;
-
- for (count = height; count > 0; count--) {
- dst[0] = src[0];
- dst += 1;
- src -= width;
- }
-
- dst_line += height;
- src_line += 1;
- }
- }
- break;
-
- default:
- ;
- }
-
- return result;
-}
-
-
-static void
-blend_image( unsigned* dst_pixels,
- unsigned* src_pixels,
- unsigned w,
- unsigned h,
- int alpha )
-{
- unsigned* dst = dst_pixels;
- unsigned* dst_end = dst + w*h;
- unsigned* src = src_pixels;
-
- for ( ; dst < dst_end; dst++, src++ )
- {
- {
- unsigned ag = (src[0] >> 8) & 0xff00ff;
- unsigned rb = src[0] & 0xff00ff;
-
- ag = (ag*alpha) & 0xff00ff00;
- rb = ((rb*alpha) >> 8) & 0x00ff00ff;
-
- dst[0] = ag | rb;
- }
- }
-}
-
-
-static unsigned
-skin_image_desc_hash( SkinImageDesc* desc )
-{
- unsigned h = 0;
- int n;
-
- for (n = 0; desc->path[n] != 0; n++) {
- int c = desc->path[n];
- h = h*33 + c;
- }
- h += desc->rotation*1573;
- h += desc->blend * 7;
-
- return h;
-}
-
-
-static int
-skin_image_desc_equal( SkinImageDesc* a,
- SkinImageDesc* b )
-{
- return (a->rotation == b->rotation &&
- a->blend == b->blend &&
- !strcmp(a->path, b->path));
-}
-
-/********************************************************************************/
-/********************************************************************************/
-/***** *****/
-/***** S K I N I M A G E S *****/
-/***** *****/
-/********************************************************************************/
-/********************************************************************************/
-
-enum {
- SKIN_IMAGE_CLONE = (1 << 0) /* this image is a clone */
-};
-
-struct SkinImage {
- unsigned hash;
- SkinImage* link;
- int ref_count;
- SkinImage* next;
- SkinImage* prev;
- SDL_Surface* surface;
- unsigned flags;
- unsigned w, h;
- void* pixels; /* 32-bit ARGB */
- SkinImageDesc desc;
-};
-
-
-
-
-static const SkinImage _no_image[1] = {
- { 0, NULL, 0, NULL, NULL, NULL, 0, 0, 0, NULL, { "<none>", SKIN_ROTATION_0, 0 } }
-};
-
-SkinImage* SKIN_IMAGE_NONE = (SkinImage*)&_no_image;
-
-static void
-skin_image_free( SkinImage* image )
-{
- if (image && image != _no_image)
- {
- if (image->surface) {
- SDL_FreeSurface(image->surface);
- image->surface = NULL;
- }
-
- if (image->pixels) {
- free( image->pixels );
- image->pixels = NULL;
- }
-
- free(image);
- }
-}
-
-
-static SkinImage*
-skin_image_alloc( SkinImageDesc* desc, unsigned hash )
-{
- int len = strlen(desc->path);
- SkinImage* image = calloc(1, sizeof(*image) + len + 1);
-
- if (image) {
- image->desc = desc[0];
- image->desc.path = (const char*)(image + 1);
- memcpy( (char*)image->desc.path, desc->path, len );
- ((char*)image->desc.path)[len] = 0;
-
- image->hash = hash;
- image->next = image->prev = image;
- image->ref_count = 1;
- }
- return image;
-}
-
-
-extern void *loadpng(const char *fn, unsigned *_width, unsigned *_height);
-extern void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
-
-static int
-skin_image_load( SkinImage* image )
-{
- void* data;
- unsigned w, h;
- const char* path = image->desc.path;
-
- if (path[0] == ':') {
- size_t size;
- const unsigned char* base;
-
- if (path[1] == '/' || path[1] == '\\')
- path += 1;
-
- base = android_resource_find( path+1, &size );
- if (base == NULL) {
- fprintf(stderr, "failed to locate built-in image file '%s'\n", path );
- return -1;
- }
-
- data = readpng(base, size, &w, &h);
- if (data == NULL) {
- fprintf(stderr, "failed to load built-in image file '%s'\n", path );
- return -1;
- }
- } else {
- data = loadpng(path, &w, &h);
- if (data == NULL) {
- fprintf(stderr, "failed to load image file '%s'\n", path );
- return -1;
- }
- }
-
- /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
- * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
- * on our CPU endianess
- */
- {
- unsigned* d = data;
- unsigned* d_end = d + w*h;
-
- for ( ; d < d_end; d++ ) {
- unsigned pix = d[0];
-#if WORDS_BIGENDIAN
- /* R,G,B,A read as RGBA => ARGB */
- pix = ((pix >> 8) & 0xffffff) | (pix << 24);
-#else
- /* R,G,B,A read as ABGR => ARGB */
- pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
-#endif
- d[0] = pix;
- }
- }
-
- image->pixels = data;
- image->w = w;
- image->h = h;
-
- image->surface = sdl_surface_from_argb32( image->pixels, w, h );
- if (image->surface == NULL) {
- fprintf(stderr, "failed to create SDL surface for '%s' image\n", path);
- return -1;
- }
- return 0;
-}
-
-
-/* simple hash table for images */
-
-#define NUM_BUCKETS 64
-
-typedef struct {
- SkinImage* buckets[ NUM_BUCKETS ];
- SkinImage mru_head;
- int num_images;
- unsigned long total_pixels;
- unsigned long max_pixels;
- unsigned long total_images;
-} SkinImageCache;
-
-
-static void
-skin_image_cache_init( SkinImageCache* cache )
-{
- memset(cache, 0, sizeof(*cache));
-#if DEBUG
- cache->max_pixels = 1;
-#else
- cache->max_pixels = 4*1024*1024; /* limit image cache to 4 MB */
-#endif
- cache->mru_head.next = cache->mru_head.prev = &cache->mru_head;
-}
-
-
-static void
-skin_image_cache_remove( SkinImageCache* cache,
- SkinImage* image )
-{
- /* remove from hash table */
- SkinImage** pnode = cache->buckets + (image->hash & (NUM_BUCKETS-1));
- SkinImage* node;
-
- for (;;) {
- node = *pnode;
- assert(node != NULL);
- if (node == NULL) /* should not happen */
- break;
- if (node == image) {
- *pnode = node->link;
- break;
- }
- pnode = &node->link;
- }
-
- D( "skin_image_cache: remove '%s' (rot=%d), %d pixels\n",
- node->desc.path, node->desc.rotation, node->w*node->h );
-
- /* remove from mru list */
- image->prev->next = image->next;
- image->next->prev = image->prev;
-
- cache->total_pixels -= image->w*image->h;
- cache->total_images -= 1;
-}
-
-
-static SkinImage*
-skin_image_cache_raise( SkinImageCache* cache,
- SkinImage* image )
-{
- if (image != cache->mru_head.next) {
- SkinImage* prev = image->prev;
- SkinImage* next = image->next;
-
- /* remove from mru list */
- prev->next = next;
- next->prev = prev;
-
- /* add to top */
- image->prev = &cache->mru_head;
- image->next = image->prev->next;
- image->prev->next = image;
- image->next->prev = image;
- }
- return image;
-}
-
-
-static void
-skin_image_cache_flush( SkinImageCache* cache )
-{
- SkinImage* image = cache->mru_head.prev;
- int count = 0;
-
- D("skin_image_cache_flush: starting\n");
- while (cache->total_pixels > cache->max_pixels &&
- image != &cache->mru_head)
- {
- SkinImage* prev = image->prev;
-
- if (image->ref_count == 0) {
- skin_image_cache_remove(cache, image);
- count += 1;
- }
- image = prev;
- }
- D("skin_image_cache_flush: finished, %d images flushed\n", count);
-}
-
-
-static SkinImage**
-skin_image_lookup_p( SkinImageCache* cache,
- SkinImageDesc* desc,
- unsigned *phash )
-{
- unsigned h = skin_image_desc_hash(desc);
- unsigned index = h & (NUM_BUCKETS-1);
- SkinImage** pnode = &cache->buckets[index];
- for (;;) {
- SkinImage* node = *pnode;
- if (node == NULL)
- break;
- if (node->hash == h && skin_image_desc_equal(desc, &node->desc))
- break;
- pnode = &node->link;
- }
- *phash = h;
- return pnode;
-}
-
-
-static SkinImage*
-skin_image_create( SkinImageDesc* desc, unsigned hash )
-{
- SkinImage* node;
-
- node = skin_image_alloc( desc, hash );
- if (node == NULL)
- return SKIN_IMAGE_NONE;
-
- if (desc->rotation == SKIN_ROTATION_0 &&
- desc->blend == SKIN_BLEND_FULL)
- {
- if (skin_image_load(node) < 0) {
- skin_image_free(node);
- return SKIN_IMAGE_NONE;
- }
- }
- else
- {
- SkinImageDesc desc0 = desc[0];
- SkinImage* parent;
-
- desc0.rotation = SKIN_ROTATION_0;
- desc0.blend = SKIN_BLEND_FULL;
-
- parent = skin_image_find( &desc0 );
- if (parent == SKIN_IMAGE_NONE)
- return SKIN_IMAGE_NONE;
-
- SDL_LockSurface(parent->surface);
-
- if (desc->rotation == SKIN_ROTATION_90 ||
- desc->rotation == SKIN_ROTATION_270)
- {
- node->w = parent->h;
- node->h = parent->w;
- } else {
- node->w = parent->w;
- node->h = parent->h;
- }
-
- node->pixels = rotate_image( parent->pixels, parent->w, parent->h,
- desc->rotation );
-
- SDL_UnlockSurface(parent->surface);
- skin_image_unref(&parent);
-
- if (node->pixels == NULL) {
- skin_image_free(node);
- return SKIN_IMAGE_NONE;
- }
-
- if (desc->blend != SKIN_BLEND_FULL)
- blend_image( node->pixels, node->pixels, node->w, node->h, desc->blend );
-
- node->surface = sdl_surface_from_argb32( node->pixels, node->w, node->h );
- if (node->surface == NULL) {
- skin_image_free(node);
- return SKIN_IMAGE_NONE;
- }
- }
- return node;
-}
-
-
-static SkinImageCache _image_cache[1];
-static int _image_cache_init;
-
-SkinImage*
-skin_image_find( SkinImageDesc* desc )
-{
- SkinImageCache* cache = _image_cache;
- unsigned hash;
- SkinImage** pnode = skin_image_lookup_p( cache, desc, &hash );
- SkinImage* node = *pnode;
-
- if (!_image_cache_init) {
- _image_cache_init = 1;
- skin_image_cache_init(cache);
- }
-
- if (node) {
- node->ref_count += 1;
- return skin_image_cache_raise( cache, node );
- }
- node = skin_image_create( desc, hash );
- if (node == SKIN_IMAGE_NONE)
- return node;
-
- /* add to hash table */
- node->link = *pnode;
- *pnode = node;
-
- /* add to mru list */
- skin_image_cache_raise( cache, node );
-
- D( "skin_image_cache: add '%s' (rot=%d), %d pixels\n",
- node->desc.path, node->desc.rotation, node->w*node->h );
-
- cache->total_pixels += node->w*node->h;
- if (cache->total_pixels > cache->max_pixels)
- skin_image_cache_flush( cache );
-
- return node;
-}
-
-
-SkinImage*
-skin_image_find_simple( const char* path )
-{
- SkinImageDesc desc;
-
- desc.path = path;
- desc.rotation = SKIN_ROTATION_0;
- desc.blend = SKIN_BLEND_FULL;
-
- return skin_image_find( &desc );
-}
-
-
-SkinImage*
-skin_image_ref( SkinImage* image )
-{
- if (image && image != _no_image)
- image->ref_count += 1;
-
- return image;
-}
-
-
-void
-skin_image_unref( SkinImage** pimage )
-{
- SkinImage* image = *pimage;
-
- if (image) {
- if (image != _no_image && --image->ref_count == 0) {
- if ((image->flags & SKIN_IMAGE_CLONE) != 0) {
- skin_image_free(image);
- }
- }
- *pimage = NULL;
- }
-}
-
-
-SkinImage*
-skin_image_rotate( SkinImage* source, SkinRotation rotation )
-{
- SkinImageDesc desc;
- SkinImage* image;
-
- if (source == _no_image || source->desc.rotation == rotation)
- return source;
-
- desc = source->desc;
- desc.rotation = rotation;
- image = skin_image_find( &desc );
- skin_image_unref( &source );
- return image;
-}
-
-
-SkinImage*
-skin_image_clone( SkinImage* source )
-{
- SkinImage* image;
-
- if (source == NULL || source == _no_image)
- return SKIN_IMAGE_NONE;
-
- image = calloc(1,sizeof(*image));
- if (image == NULL)
- goto Fail;
-
- image->desc = source->desc;
- image->hash = source->hash;
- image->flags = SKIN_IMAGE_CLONE;
- image->w = source->w;
- image->h = source->h;
- image->pixels = rotate_image( source->pixels, source->w, source->h,
- SKIN_ROTATION_0 );
- if (image->pixels == NULL)
- goto Fail;
-
- image->surface = sdl_surface_from_argb32( image->pixels, image->w, image->h );
- if (image->surface == NULL)
- goto Fail;
-
- return image;
-Fail:
- if (image != NULL)
- skin_image_free(image);
- return SKIN_IMAGE_NONE;
-}
-
-SkinImage*
-skin_image_clone_full( SkinImage* source,
- SkinRotation rotation,
- int blend )
-{
- SkinImageDesc desc;
- SkinImage* clone;
-
- if (source == NULL || source == SKIN_IMAGE_NONE)
- return SKIN_IMAGE_NONE;
-
- if (rotation == SKIN_ROTATION_0 &&
- blend == SKIN_BLEND_FULL)
- {
- return skin_image_clone(source);
- }
-
- desc.path = source->desc.path;
- desc.rotation = rotation;
- desc.blend = blend;
-
- clone = skin_image_create( &desc, 0 );
- if (clone != SKIN_IMAGE_NONE)
- clone->flags |= SKIN_IMAGE_CLONE;
-
- return clone;
-}
-
-/* apply blending to a source skin image and copy the result to a target clone image */
-extern void
-skin_image_blend_clone( SkinImage* clone, SkinImage* source, int blend )
-{
- SDL_LockSurface( clone->surface );
- blend_image( clone->pixels, source->pixels, source->w, source->h, blend );
- SDL_UnlockSurface( clone->surface );
- SDL_SetAlpha( clone->surface, SDL_SRCALPHA, 255 );
-}
-
-int
-skin_image_w( SkinImage* image )
-{
- return image ? image->w : 0;
-}
-
-int
-skin_image_h( SkinImage* image )
-{
- return image ? image->h : 0;
-}
-
-int
-skin_image_org_w( SkinImage* image )
-{
- if (image) {
- if (image->desc.rotation == SKIN_ROTATION_90 ||
- image->desc.rotation == SKIN_ROTATION_270)
- return image->h;
- else
- return image->w;
- }
- return 0;
-}
-
-int
-skin_image_org_h( SkinImage* image )
-{
- if (image) {
- if (image->desc.rotation == SKIN_ROTATION_90 ||
- image->desc.rotation == SKIN_ROTATION_270)
- return image->w;
- else
- return image->h;
- }
- return 0;
-}
-
-SDL_Surface*
-skin_image_surface( SkinImage* image )
-{
- return image ? image->surface : NULL;
-}
diff --git a/android/skin/image.h b/android/skin/image.h
deleted file mode 100644
index a94a372..0000000
--- a/android/skin/image.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_IMAGE_H
-#define _ANDROID_SKIN_IMAGE_H
-
-#include "android/android.h"
-#include <SDL.h>
-#include "android/skin/rect.h"
-
-/* helper functions */
-
-extern SDL_Surface* sdl_surface_from_argb32( void* base, int w, int h );
-
-/* skin image file objects */
-
-/* opaque skin image type. all skin images are placed in a simple MRU cache
- * to limit the emulator's memory usage, with the exception of 'clones' created
- * with skin_image_clone() or skin_image_clone_blend()
- */
-typedef struct SkinImage SkinImage;
-
-/* a descriptor for a given skin image */
-typedef struct SkinImageDesc {
- const char* path; /* image file path (must be .png) */
- AndroidRotation rotation; /* rotation */
- int blend; /* blending, 0..256 value */
-} SkinImageDesc;
-
-#define SKIN_BLEND_NONE 0
-#define SKIN_BLEND_HALF 128
-#define SKIN_BLEND_FULL 256
-
-/* a special value returned when an image cannot be properly loaded */
-extern SkinImage* SKIN_IMAGE_NONE;
-
-/* return the SDL_Surface* pointer of a given skin image */
-extern SDL_Surface* skin_image_surface( SkinImage* image );
-extern int skin_image_w ( SkinImage* image );
-extern int skin_image_h ( SkinImage* image );
-extern int skin_image_org_w ( SkinImage* image );
-extern int skin_image_org_h ( SkinImage* image );
-
-/* get an image from the cache (load it from the file if necessary).
- * returns SKIN_IMAGE_NONE in case of error. cannot return NULL
- * this function also increments the reference count of the skin image,
- * use "skin_image_unref()" when you don't need it anymore
- */
-extern SkinImage* skin_image_find( SkinImageDesc* desc );
-
-extern SkinImage* skin_image_find_simple( const char* path );
-
-/* increment the reference count of a given skin image,
- * don't do anything if 'image' is NULL */
-extern SkinImage* skin_image_ref( SkinImage* image );
-
-/* decrement the reference count of a given skin image. if
- * the count reaches 0, the image becomes eligible for cache flushing.
- * unless it was created through a skin_image_clone... function, where
- * it is immediately discarded...
- */
-extern void skin_image_unref( SkinImage** pimage );
-
-/* get the rotation of a given image. this decrements the reference count
- * of the source after returning the target, whose reference count is incremented
- */
-extern SkinImage* skin_image_rotate( SkinImage* source, SkinRotation rotation );
-
-/* create a skin image clone. the clone is not part of the cache and will
- * be destroyed immediately when its reference count reaches 0. this is useful
- * if you need to modify the content of the clone (e.g. blending)
- */
-extern SkinImage* skin_image_clone( SkinImage* source );
-
-/* create a skin image clone, the clone is a rotated version of a source image
- */
-extern SkinImage* skin_image_clone_full( SkinImage* source,
- SkinRotation rotation,
- int blend );
-
-/* apply blending to a source skin image and copy the result to a target clone image */
-extern void skin_image_blend_clone( SkinImage* clone, SkinImage* source, int blend );
-
-#endif /* _ANDROID_SKIN_IMAGE_H */
diff --git a/android/skin/keyboard.c b/android/skin/keyboard.c
deleted file mode 100644
index 6a9c79b..0000000
--- a/android/skin/keyboard.c
+++ /dev/null
@@ -1,783 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/keyboard.h"
-#include "android/utils/debug.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/system.h"
-#include "android/android.h"
-
-#define DEBUG 1
-
-#if DEBUG
-# define D(...) VERBOSE_PRINT(keys,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-
-#define USE_KEYSET 1
-
-/** LAST PRESSED KEYS
- ** a small buffer of last pressed keys, this is used to properly
- ** implement the Unicode keyboard mode (SDL key up event always have
- ** their .unicode field set to 0
- **/
-typedef struct {
- int unicode; /* Unicode of last pressed key */
- int sym; /* SDL key symbol value (e.g. SDLK_a) */
- int mod; /* SDL key modifier value */
-} LastKey;
-
-#define MAX_LAST_KEYS 16
-#define MAX_KEYCODES 256*2
-
-struct SkinKeyboard {
- const AKeyCharmap* charmap;
- SkinKeyset* kset;
- char enabled;
- char raw_keys;
- char last_count;
- int keycode_count;
-
- SkinRotation rotation;
-
- SkinKeyCommandFunc command_func;
- void* command_opaque;
- SkinKeyEventFunc press_func;
- void* press_opaque;
-
- LastKey last_keys[ MAX_LAST_KEYS ];
- int keycodes[ MAX_KEYCODES ];
-};
-
-
-void
-skin_keyboard_set_keyset( SkinKeyboard* keyboard, SkinKeyset* kset )
-{
- if (kset == NULL)
- return;
- if (keyboard->kset && keyboard->kset != android_keyset) {
- skin_keyset_free(keyboard->kset);
- }
- keyboard->kset = kset;
-}
-
-
-const char*
-skin_keyboard_charmap_name( SkinKeyboard* keyboard )
-{
- if (keyboard && keyboard->charmap)
- return keyboard->charmap->name;
-
- return "qwerty";
-}
-
-void
-skin_keyboard_set_rotation( SkinKeyboard* keyboard,
- SkinRotation rotation )
-{
- keyboard->rotation = (rotation & 3);
-}
-
-void
-skin_keyboard_on_command( SkinKeyboard* keyboard, SkinKeyCommandFunc cmd_func, void* cmd_opaque )
-{
- keyboard->command_func = cmd_func;
- keyboard->command_opaque = cmd_opaque;
-}
-
-void
-skin_keyboard_on_key_press( SkinKeyboard* keyboard, SkinKeyEventFunc press_func, void* press_opaque )
-{
- keyboard->press_func = press_func;
- keyboard->press_opaque = press_opaque;
-}
-
-void
-skin_keyboard_add_key_event( SkinKeyboard* kb,
- unsigned code,
- unsigned down )
-{
- if (code != 0 && kb->keycode_count < MAX_KEYCODES) {
- //dprint("add keycode %d, down %d\n", code % 0x1ff, down );
- kb->keycodes[(int)kb->keycode_count++] = ( (code & 0x1ff) | (down ? 0x200 : 0) );
- }
-}
-
-
-void
-skin_keyboard_flush( SkinKeyboard* kb )
-{
- if (kb->keycode_count > 0) {
- if (VERBOSE_CHECK(keys)) {
- int nn;
- printf(">> KEY" );
- for (nn = 0; nn < kb->keycode_count; nn++) {
- int code = kb->keycodes[nn];
- printf(" [0x%03x,%s]", (code & 0x1ff), (code & 0x200) ? "down" : " up " );
- }
- printf( "\n" );
- }
- kbd_put_keycodes(kb->keycodes, kb->keycode_count);
- kb->keycode_count = 0;
- }
-}
-
-
-static void
-skin_keyboard_cmd( SkinKeyboard* keyboard,
- SkinKeyCommand command,
- int param )
-{
- if (keyboard->command_func) {
- keyboard->command_func( keyboard->command_opaque, command, param );
- }
-}
-
-
-static LastKey*
-skin_keyboard_find_last( SkinKeyboard* keyboard,
- int sym )
-{
- LastKey* k = keyboard->last_keys;
- LastKey* end = k + keyboard->last_count;
-
- for ( ; k < end; k++ ) {
- if (k->sym == sym)
- return k;
- }
- return NULL;
-}
-
-static void
-skin_keyboard_add_last( SkinKeyboard* keyboard,
- int sym,
- int mod,
- int unicode )
-{
- LastKey* k = keyboard->last_keys + keyboard->last_count;
-
- if (keyboard->last_count < MAX_LAST_KEYS) {
- k->sym = sym;
- k->mod = mod;
- k->unicode = unicode;
-
- keyboard->last_count += 1;
- }
-}
-
-static void
-skin_keyboard_remove_last( SkinKeyboard* keyboard,
- int sym )
-{
- LastKey* k = keyboard->last_keys;
- LastKey* end = k + keyboard->last_count;
-
- for ( ; k < end; k++ ) {
- if (k->sym == sym) {
- /* we don't need a sorted array, so place the last
- * element in place at the position of the removed
- * one... */
- k[0] = end[-1];
- keyboard->last_count -= 1;
- break;
- }
- }
-}
-
-static void
-skin_keyboard_clear_last( SkinKeyboard* keyboard )
-{
- keyboard->last_count = 0;
-}
-
-static int
-skin_keyboard_rotate_sym( SkinKeyboard* keyboard,
- int sym )
-{
- switch (keyboard->rotation) {
- case SKIN_ROTATION_90:
- switch (sym) {
- case SDLK_LEFT: sym = SDLK_DOWN; break;
- case SDLK_RIGHT: sym = SDLK_UP; break;
- case SDLK_UP: sym = SDLK_LEFT; break;
- case SDLK_DOWN: sym = SDLK_RIGHT; break;
- }
- break;
-
- case SKIN_ROTATION_180:
- switch (sym) {
- case SDLK_LEFT: sym = SDLK_RIGHT; break;
- case SDLK_RIGHT: sym = SDLK_LEFT; break;
- case SDLK_UP: sym = SDLK_DOWN; break;
- case SDLK_DOWN: sym = SDLK_UP; break;
- }
- break;
-
- case SKIN_ROTATION_270:
- switch (sym) {
- case SDLK_LEFT: sym = SDLK_UP; break;
- case SDLK_RIGHT: sym = SDLK_DOWN; break;
- case SDLK_UP: sym = SDLK_RIGHT; break;
- case SDLK_DOWN: sym = SDLK_LEFT; break;
- }
- break;
-
- default: ;
- }
- return sym;
-}
-
-#if USE_KEYSET
-static AndroidKeyCode
-skin_keyboard_key_to_code( SkinKeyboard* keyboard,
- unsigned sym,
- int mod,
- int down )
-{
- AndroidKeyCode code = 0;
- int mod0 = mod;
- SkinKeyCommand command;
-
- /* first, handle the arrow keys directly */
- /* rotate them if necessary */
- sym = skin_keyboard_rotate_sym(keyboard, sym);
- mod &= (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT);
-
- switch (sym) {
- case SDLK_LEFT: code = kKeyCodeDpadLeft; break;
- case SDLK_RIGHT: code = kKeyCodeDpadRight; break;
- case SDLK_UP: code = kKeyCodeDpadUp; break;
- case SDLK_DOWN: code = kKeyCodeDpadDown; break;
- default: ;
- }
-
- if (code != 0) {
- D("handling arrow (sym=%d mod=%d)", sym, mod);
- if (!keyboard->raw_keys) {
- int doCapL, doCapR, doAltL, doAltR;
-
- if (!down) {
- LastKey* k = skin_keyboard_find_last(keyboard, sym);
- if (k != NULL) {
- mod = k->mod;
- skin_keyboard_remove_last( keyboard, sym );
- }
- } else {
- skin_keyboard_add_last( keyboard, sym, mod, 0);
- }
-
- doCapL = (mod & 0x7ff) & KMOD_LSHIFT;
- doCapR = (mod & 0x7ff) & KMOD_RSHIFT;
- doAltL = (mod & 0x7ff) & KMOD_LALT;
- doAltR = (mod & 0x7ff) & KMOD_RALT;
-
- if (down) {
- if (doAltL) skin_keyboard_add_key_event( keyboard, kKeyCodeAltLeft, 1 );
- if (doAltR) skin_keyboard_add_key_event( keyboard, kKeyCodeAltRight, 1 );
- if (doCapL) skin_keyboard_add_key_event( keyboard, kKeyCodeCapLeft, 1 );
- if (doCapR) skin_keyboard_add_key_event( keyboard, kKeyCodeCapRight, 1 );
- }
- skin_keyboard_add_key_event(keyboard, code, down);
-
- if (!down) {
- if (doCapR) skin_keyboard_add_key_event( keyboard, kKeyCodeCapRight, 0 );
- if (doCapL) skin_keyboard_add_key_event( keyboard, kKeyCodeCapLeft, 0 );
- if (doAltR) skin_keyboard_add_key_event( keyboard, kKeyCodeAltRight, 0 );
- if (doAltL) skin_keyboard_add_key_event( keyboard, kKeyCodeAltLeft, 0 );
- }
- code = 0;
- }
- return code;
- }
-
- /* special case for keypad keys, ignore them here if numlock is on */
- if ((mod0 & KMOD_NUM) != 0) {
- switch (sym) {
- case SDLK_KP0:
- case SDLK_KP1:
- case SDLK_KP2:
- case SDLK_KP3:
- case SDLK_KP4:
- case SDLK_KP5:
- case SDLK_KP6:
- case SDLK_KP7:
- case SDLK_KP8:
- case SDLK_KP9:
- case SDLK_KP_PLUS:
- case SDLK_KP_MINUS:
- case SDLK_KP_MULTIPLY:
- case SDLK_KP_DIVIDE:
- case SDLK_KP_EQUALS:
- case SDLK_KP_PERIOD:
- case SDLK_KP_ENTER:
- return 0;
- }
- }
-
- /* now try all keyset combos */
- command = skin_keyset_get_command( keyboard->kset, sym, mod );
- if (command != SKIN_KEY_COMMAND_NONE) {
- D("handling command %s from (sym=%d, mod=%d, str=%s)",
- skin_key_command_to_str(command), sym, mod, skin_key_symmod_to_str(sym,mod));
- skin_keyboard_cmd( keyboard, command, down );
- return 0;
- }
- D("could not handle (sym=%d, mod=%d, str=%s)", sym, mod,
- skin_key_symmod_to_str(sym,mod));
- return -1;
-}
-#else /* !USE_KEYSET */
-/* this will look for non-Unicode key strokes, e.g. arrows, F1, F2, etc...
- * note that we have some special handling for shift-<arrow>, these will
- * be emulated as two key strokes on the device
- */
-static AndroidKeyCode
-skin_keyboard_key_to_code( SkinKeyboard* keyboard,
- unsigned sym,
- int mod,
- int down )
-{
- AndroidKeyCode code = 0;
- int doAltShift = 0;
-
- sym = skin_keyboard_rotate_sym(keyboard, sym);
-
- switch (sym) {
- case SDLK_LEFT: code = kKeyCodeDpadLeft; doAltShift = 1; break;
- case SDLK_RIGHT: code = kKeyCodeDpadRight; doAltShift = 1; break;
- case SDLK_UP: code = kKeyCodeDpadUp; doAltShift = 1; break;
- case SDLK_DOWN: code = kKeyCodeDpadDown; doAltShift = 1; break;
- case SDLK_HOME: code = kKeyCodeHome; break;
- case SDLK_BACKSPACE: code = kKeyCodeDel; doAltShift = 1; break;
- case SDLK_ESCAPE: code = kKeyCodeBack; break;
- case SDLK_RETURN: code = kKeyCodeNewline; doAltShift = 1; break;
- case SDLK_F1: code = kKeyCodeSoftLeft; break;
- case SDLK_F2: code = kKeyCodeSoftRight; break;
- case SDLK_F3: code = kKeyCodeCall; break;
- case SDLK_F4: code = kKeyCodeEndCall; break;
- case SDLK_F5: code = kKeyCodeSearch; break;
- case SDLK_F7: code = kKeyCodePower; break;
-
- case SDLK_F8: /* network connect/disconnect */
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_TOGGLE_NETWORK, 1 );
- }
- return 0;
-
-#ifdef CONFIG_TRACE
- case SDLK_F9: /* start tracing */
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_TOGGLE_TRACING, 1 );
- }
- return 0;
-
- case SDLK_F10: /* stop tracing */
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_TOGGLE_TRACING, 1 );
- }
- return 0;
-#endif
-
- case SDLK_F12: /* change orientation */
- if (down && (mod & (KMOD_LCTRL | KMOD_RCTRL)) != 0) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_CHANGE_LAYOUT, +1 );
- }
- return 0;
-
- case SDLK_PAGEUP: return kKeyCodeSoftLeft;
- case SDLK_PAGEDOWN: return kKeyCodeSoftRight;
-
- case SDLK_t:
- if (down && (mod & (KMOD_LCTRL| KMOD_RCTRL)) != 0) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_TOGGLE_TRACKBALL, 1 );
- return 0;
- }
- break;
-
- case SDLK_KP5:
- if ((mod & (KMOD_LCTRL | KMOD_RCTRL)) != 0)
- code = kKeyCodeCamera;
- break;
- }
-
- if (code != 0) {
- if (doAltShift && !keyboard->raw_keys) {
- int doCapL, doCapR, doAltL, doAltR;
-
- if (!down) {
- LastKey* k = skin_keyboard_find_last(keyboard, sym);
- if (k != NULL) {
- mod = k->mod;
- skin_keyboard_remove_last( keyboard, sym );
- }
- } else {
- skin_keyboard_add_last( keyboard, sym, mod, 0);
- }
-
- doCapL = (mod & 0x7ff) & KMOD_LSHIFT;
- doCapR = (mod & 0x7ff) & KMOD_RSHIFT;
- doAltL = (mod & 0x7ff) & KMOD_LALT;
- doAltR = (mod & 0x7ff) & KMOD_RALT;
-
- if (down) {
- if (doAltL) skin_keyboard_add_key_event( keyboard, kKeyCodeAltLeft, 1 );
- if (doAltR) skin_keyboard_add_key_event( keyboard, kKeyCodeAltRight, 1 );
- if (doCapL) skin_keyboard_add_key_event( keyboard, kKeyCodeCapLeft, 1 );
- if (doCapR) skin_keyboard_add_key_event( keyboard, kKeyCodeCapRight, 1 );
- }
- skin_keyboard_add_key_event(keyboard, code, down);
-
- if (!down) {
- if (doCapR) skin_keyboard_add_key_event( keyboard, kKeyCodeCapRight, 0 );
- if (doCapL) skin_keyboard_add_key_event( keyboard, kKeyCodeCapLeft, 0 );
- if (doAltR) skin_keyboard_add_key_event( keyboard, kKeyCodeAltRight, 0 );
- if (doAltL) skin_keyboard_add_key_event( keyboard, kKeyCodeAltLeft, 0 );
- }
- code = 0;
- }
- return code;
- }
-
- if ((mod & KMOD_NUM) == 0) {
- switch (sym) {
- case SDLK_KP8: return kKeyCodeDpadUp;
- case SDLK_KP2: return kKeyCodeDpadDown;
- case SDLK_KP4: return kKeyCodeDpadLeft;
- case SDLK_KP6: return kKeyCodeDpadRight;
- case SDLK_KP5: return kKeyCodeDpadCenter;
-
- case SDLK_KP_PLUS: return kKeyCodeVolumeUp;
- case SDLK_KP_MINUS: return kKeyCodeVolumeDown;
-
- case SDLK_KP_MULTIPLY:
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_ONION_ALPHA_UP, 1 );
- }
- return 0;
-
- case SDLK_KP_DIVIDE:
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_ONION_ALPHA_DOWN, 1 );
- }
- return 0;
-
- case SDLK_KP7:
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV, 1 );
- }
- return 0;
-
- case SDLK_KP9:
- if (down) {
- skin_keyboard_cmd( keyboard, SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT, 1 );
- }
- return 0;
- }
- }
- return -1;
-}
-#endif /* !USE_KEYSET */
-
-/* this gets called only if the reverse unicode mapping didn't work
- * or wasn't used (when in raw keys mode)
- */
-static AndroidKeyCode
-skin_keyboard_raw_key_to_code(SkinKeyboard* kb, unsigned sym, int down)
-{
- switch(sym){
- case SDLK_1: return kKeyCode1;
- case SDLK_2: return kKeyCode2;
- case SDLK_3: return kKeyCode3;
- case SDLK_4: return kKeyCode4;
- case SDLK_5: return kKeyCode5;
- case SDLK_6: return kKeyCode6;
- case SDLK_7: return kKeyCode7;
- case SDLK_8: return kKeyCode8;
- case SDLK_9: return kKeyCode9;
- case SDLK_0: return kKeyCode0;
-
- case SDLK_q: return kKeyCodeQ;
- case SDLK_w: return kKeyCodeW;
- case SDLK_e: return kKeyCodeE;
- case SDLK_r: return kKeyCodeR;
- case SDLK_t: return kKeyCodeT;
- case SDLK_y: return kKeyCodeY;
- case SDLK_u: return kKeyCodeU;
- case SDLK_i: return kKeyCodeI;
- case SDLK_o: return kKeyCodeO;
- case SDLK_p: return kKeyCodeP;
- case SDLK_a: return kKeyCodeA;
- case SDLK_s: return kKeyCodeS;
- case SDLK_d: return kKeyCodeD;
- case SDLK_f: return kKeyCodeF;
- case SDLK_g: return kKeyCodeG;
- case SDLK_h: return kKeyCodeH;
- case SDLK_j: return kKeyCodeJ;
- case SDLK_k: return kKeyCodeK;
- case SDLK_l: return kKeyCodeL;
- case SDLK_z: return kKeyCodeZ;
- case SDLK_x: return kKeyCodeX;
- case SDLK_c: return kKeyCodeC;
- case SDLK_v: return kKeyCodeV;
- case SDLK_b: return kKeyCodeB;
- case SDLK_n: return kKeyCodeN;
- case SDLK_m: return kKeyCodeM;
- case SDLK_COMMA: return kKeyCodeComma;
- case SDLK_PERIOD: return kKeyCodePeriod;
- case SDLK_SPACE: return kKeyCodeSpace;
- case SDLK_SLASH: return kKeyCodeSlash;
- case SDLK_RETURN: return kKeyCodeNewline;
- case SDLK_BACKSPACE: return kKeyCodeDel;
-
-/* these are qwerty keys not on a device keyboard */
- case SDLK_TAB: return kKeyCodeTab;
- case SDLK_BACKQUOTE: return kKeyCodeGrave;
- case SDLK_MINUS: return kKeyCodeMinus;
- case SDLK_EQUALS: return kKeyCodeEquals;
- case SDLK_LEFTBRACKET: return kKeyCodeLeftBracket;
- case SDLK_RIGHTBRACKET: return kKeyCodeRightBracket;
- case SDLK_BACKSLASH: return kKeyCodeBackslash;
- case SDLK_SEMICOLON: return kKeyCodeSemicolon;
- case SDLK_QUOTE: return kKeyCodeApostrophe;
-
- case SDLK_RSHIFT: return kKeyCodeCapRight;
- case SDLK_LSHIFT: return kKeyCodeCapLeft;
- case SDLK_RMETA: return kKeyCodeSym;
- case SDLK_LMETA: return kKeyCodeSym;
- case SDLK_RALT: return kKeyCodeAltRight;
- case SDLK_LALT: return kKeyCodeAltLeft;
- case SDLK_RCTRL: return kKeyCodeSym;
- case SDLK_LCTRL: return kKeyCodeSym;
-
- default:
- /* fprintf(stderr,"* unknown sdl keysym %d *\n", sym); */
- return -1;
- }
-}
-
-
-static void
-skin_keyboard_do_key_event( SkinKeyboard* kb,
- AndroidKeyCode code,
- int down )
-{
- if (kb->press_func) {
- kb->press_func( kb->press_opaque, code, down );
- }
- skin_keyboard_add_key_event(kb, code, down);
-}
-
-
-int
-skin_keyboard_process_unicode_event( SkinKeyboard* kb, unsigned int unicode, int down )
-{
- const AKeyCharmap* cmap = kb->charmap;
- int n;
-
- if (unicode == 0)
- return 0;
-
- /* check base keys */
- for (n = 0; n < cmap->num_entries; n++) {
- if (cmap->entries[n].base == unicode) {
- skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
- return 1;
- }
- }
-
- /* check caps + keys */
- for (n = 0; n < cmap->num_entries; n++) {
- if (cmap->entries[n].caps == unicode) {
- if (down)
- skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
- skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
- if (!down)
- skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
- return 2;
- }
- }
-
- /* check fn + keys */
- for (n = 0; n < cmap->num_entries; n++) {
- if (cmap->entries[n].fn == unicode) {
- if (down)
- skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
- skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
- if (!down)
- skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
- return 2;
- }
- }
-
- /* check caps + fn + keys */
- for (n = 0; n < cmap->num_entries; n++) {
- if (cmap->entries[n].caps_fn == unicode) {
- if (down) {
- skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
- skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
- }
- skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
- if (!down) {
- skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
- skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
- }
- return 3;
- }
- }
-
- /* no match */
- return 0;
-}
-
-
-void
-skin_keyboard_enable( SkinKeyboard* keyboard,
- int enabled )
-{
- keyboard->enabled = enabled;
- if (enabled) {
- SDL_EnableUNICODE(!keyboard->raw_keys);
- SDL_EnableKeyRepeat(0,0);
- }
-}
-
-void
-skin_keyboard_process_event( SkinKeyboard* kb, SDL_Event* ev, int down )
-{
- unsigned code;
- int unicode = ev->key.keysym.unicode;
- int sym = ev->key.keysym.sym;
- int mod = ev->key.keysym.mod;
-
- /* ignore key events if we're not enabled */
- if (!kb->enabled) {
- printf( "ignoring key event sym=%d mod=0x%x unicode=%d\n",
- sym, mod, unicode );
- return;
- }
-
- /* first, try the keyboard-mode-independent keys */
- code = skin_keyboard_key_to_code( kb, sym, mod, down );
- if (code == 0)
- return;
-
- if ((int)code > 0) {
- skin_keyboard_do_key_event(kb, code, down);
- skin_keyboard_flush(kb);
- return;
- }
-
- /* Ctrl-K is used to switch between 'unicode' and 'raw' modes */
- if (sym == SDLK_k)
- {
- int mod2 = mod & 0x7ff;
-
- if ( mod2 == KMOD_LCTRL || mod2 == KMOD_RCTRL ) {
- if (down) {
- skin_keyboard_clear_last(kb);
- kb->raw_keys = !kb->raw_keys;
- SDL_EnableUNICODE(!kb->raw_keys);
- D( "switching keyboard to %s mode", kb->raw_keys ? "raw" : "unicode" );
- }
- return;
- }
- }
-
- if (!kb->raw_keys) {
- /* ev->key.keysym.unicode is only valid on keydown events, and will be 0
- * on the corresponding keyup ones, so remember the set of last pressed key
- * syms to "undo" the job
- */
- if ( !down && unicode == 0 ) {
- LastKey* k = skin_keyboard_find_last(kb, sym);
- if (k != NULL) {
- unicode = k->unicode;
- skin_keyboard_remove_last(kb, sym);
- }
- }
- }
- if (!kb->raw_keys &&
- skin_keyboard_process_unicode_event( kb, unicode, down ) > 0)
- {
- if (down)
- skin_keyboard_add_last( kb, sym, mod, unicode );
-
- skin_keyboard_flush( kb );
- return;
- }
-
- code = skin_keyboard_raw_key_to_code( kb, sym, down );
-
- if ( !kb->raw_keys &&
- (code == kKeyCodeAltLeft || code == kKeyCodeAltRight ||
- code == kKeyCodeCapLeft || code == kKeyCodeCapRight ||
- code == kKeyCodeSym) )
- return;
-
- if (code == -1) {
- D("ignoring keysym %d", sym );
- } else if (code > 0) {
- skin_keyboard_do_key_event(kb, code, down);
- skin_keyboard_flush(kb);
- }
-}
-
-
-SkinKeyboard*
-skin_keyboard_create_from_aconfig( AConfig* aconfig, int use_raw_keys )
-{
- SkinKeyboard* kb;
- const char* charmap_name = "qwerty";
- AConfig* node;
-
- ANEW0(kb);
-
- node = aconfig_find( aconfig, "keyboard" );
- if (node != NULL)
- charmap_name = aconfig_str(node, "charmap", charmap_name);
-
- {
- int nn;
-
- for (nn = 0; nn < android_charmap_count; nn++) {
- if ( !strcmp(android_charmaps[nn]->name, charmap_name) ) {
- kb->charmap = android_charmaps[nn];
- break;
- }
- }
-
- if (!kb->charmap) {
- fprintf(stderr, "### warning, skin requires unknown '%s' charmap, reverting to '%s'\n",
- charmap_name, android_charmaps[0]->name );
- kb->charmap = android_charmaps[0];
- }
- }
- kb->raw_keys = use_raw_keys;
- kb->enabled = 0;
-
- /* add default keyset */
- if (android_keyset)
- kb->kset = android_keyset;
- else
- kb->kset = skin_keyset_new_from_text( skin_keyset_get_default() );
-
- return kb;
-}
-
-void
-skin_keyboard_free( SkinKeyboard* keyboard )
-{
- if (keyboard) {
- AFREE(keyboard);
- }
-}
diff --git a/android/skin/keyboard.h b/android/skin/keyboard.h
deleted file mode 100644
index 45efd18..0000000
--- a/android/skin/keyboard.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_KEYBOARD_H
-#define _ANDROID_SKIN_KEYBOARD_H
-
-#include "android/charmap.h"
-#include "android/config.h"
-#include "android/skin/image.h" /* for SkinRotation */
-#include "android/skin/keyset.h"
-#include <SDL.h>
-
-typedef struct SkinKeyboard SkinKeyboard;
-
-typedef void (*SkinKeyCommandFunc)( void* opaque, SkinKeyCommand command, int param );
-
-typedef void (*SkinKeyEventFunc)( void* opaque, AndroidKeyCode code, int down );
-
-extern SkinKeyboard* skin_keyboard_create_from_aconfig( AConfig* aconfig, int use_raw_keys );
-
-extern void skin_keyboard_set_keyset( SkinKeyboard* keyboard, SkinKeyset* kset );
-
-extern const char* skin_keyboard_charmap_name( SkinKeyboard* keyboard );
-
-extern void skin_keyboard_free( SkinKeyboard* keyboard );
-
-extern void skin_keyboard_enable( SkinKeyboard* keyboard,
- int enabled );
-
-extern void skin_keyboard_on_command( SkinKeyboard* keyboard,
- SkinKeyCommandFunc cmd_func,
- void* cmd_opaque );
-
-extern void skin_keyboard_set_rotation( SkinKeyboard* keyboard,
- SkinRotation rotation );
-
-extern void skin_keyboard_on_key_press( SkinKeyboard* keyboard,
- SkinKeyEventFunc press_func,
- void* press_opaque );
-
-extern void skin_keyboard_process_event( SkinKeyboard* keyboard, SDL_Event* ev, int down );
-extern int skin_keyboard_process_unicode_event( SkinKeyboard* kb, unsigned int unicode, int down );
-
-extern void skin_keyboard_add_key_event( SkinKeyboard* k, unsigned code, unsigned down );
-extern void skin_keyboard_flush( SkinKeyboard* kb );
-
-/* defined in android_main.c */
-extern SkinKeyboard* android_emulator_get_keyboard( void );
-
-#endif /* _ANDROID_SKIN_KEYBOARD_H */
-
diff --git a/android/skin/keyset.c b/android/skin/keyset.c
deleted file mode 100644
index 7a92971..0000000
--- a/android/skin/keyset.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/keyset.h"
-#include "android/utils/debug.h"
-#include "android/utils/bufprint.h"
-#include "android/android.h"
-#include <SDL.h>
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(keys)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) VERBOSE_PRINT(keys,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-#define _SKIN_KEY_COMMAND(x,y) #x ,
-static const char* const command_strings[ SKIN_KEY_COMMAND_MAX ] = {
- SKIN_KEY_COMMAND_LIST
-};
-#undef _SKIN_KEY_COMMAND
-
-const char*
-skin_key_command_to_str( SkinKeyCommand cmd )
-{
- if (cmd > SKIN_KEY_COMMAND_NONE && cmd < SKIN_KEY_COMMAND_MAX)
- return command_strings[cmd];
-
- return NULL;
-}
-
-SkinKeyCommand
-skin_key_command_from_str( const char* str, int len )
-{
- int nn;
- if (len < 0)
- len = strlen(str);
- for (nn = 0; nn < SKIN_KEY_COMMAND_MAX; nn++) {
- const char* cmd = command_strings[nn];
-
- if ( !memcmp( cmd, str, len ) && cmd[len] == 0 )
- return (SkinKeyCommand) nn;
- }
- return SKIN_KEY_COMMAND_NONE;
-}
-
-
-#define _SKIN_KEY_COMMAND(x,y) y ,
-static const char* const command_descriptions[ SKIN_KEY_COMMAND_MAX ] = {
- SKIN_KEY_COMMAND_LIST
-};
-#undef _SKIN_KEY_COMMAND
-
-const char*
-skin_key_command_description( SkinKeyCommand cmd )
-{
- if (cmd > SKIN_KEY_COMMAND_NONE && cmd < SKIN_KEY_COMMAND_MAX)
- return command_descriptions[cmd];
-
- return NULL;
-}
-
-#define _KEYSYM1_(x) _KEYSYM_(x,x)
-
-#define _KEYSYM_LIST \
- _KEYSYM1_(BACKSPACE) \
- _KEYSYM1_(TAB) \
- _KEYSYM1_(CLEAR) \
- _KEYSYM_(RETURN,ENTER) \
- _KEYSYM1_(PAUSE) \
- _KEYSYM1_(ESCAPE) \
- _KEYSYM1_(SPACE) \
- _KEYSYM_(EXCLAIM,EXCLAM) \
- _KEYSYM_(QUOTEDBL,DOUBLEQUOTE) \
- _KEYSYM_(HASH,HASH) \
- _KEYSYM1_(DOLLAR) \
- _KEYSYM1_(AMPERSAND) \
- _KEYSYM1_(QUOTE) \
- _KEYSYM_(LEFTPAREN,LPAREN) \
- _KEYSYM_(RIGHTPAREN,RPAREN) \
- _KEYSYM1_(ASTERISK) \
- _KEYSYM1_(PLUS) \
- _KEYSYM1_(COMMA) \
- _KEYSYM1_(MINUS) \
- _KEYSYM1_(PERIOD) \
- _KEYSYM1_(SLASH) \
- _KEYSYM1_(0) \
- _KEYSYM1_(1) \
- _KEYSYM1_(2) \
- _KEYSYM1_(3) \
- _KEYSYM1_(4) \
- _KEYSYM1_(5) \
- _KEYSYM1_(6) \
- _KEYSYM1_(7) \
- _KEYSYM1_(8) \
- _KEYSYM1_(9) \
- _KEYSYM1_(COLON) \
- _KEYSYM1_(SEMICOLON) \
- _KEYSYM1_(LESS) \
- _KEYSYM_(EQUALS,EQUAL) \
- _KEYSYM1_(GREATER) \
- _KEYSYM1_(QUESTION) \
- _KEYSYM1_(AT) \
- _KEYSYM1_(LEFTBRACKET) \
- _KEYSYM1_(BACKSLASH) \
- _KEYSYM1_(RIGHTBRACKET) \
- _KEYSYM1_(CARET) \
- _KEYSYM1_(UNDERSCORE) \
- _KEYSYM1_(BACKQUOTE) \
- _KEYSYM_(a,A) \
- _KEYSYM_(b,B) \
- _KEYSYM_(c,C) \
- _KEYSYM_(d,D) \
- _KEYSYM_(e,E) \
- _KEYSYM_(f,F) \
- _KEYSYM_(g,G) \
- _KEYSYM_(h,H) \
- _KEYSYM_(i,I) \
- _KEYSYM_(j,J) \
- _KEYSYM_(k,K) \
- _KEYSYM_(l,L) \
- _KEYSYM_(m,M) \
- _KEYSYM_(n,N) \
- _KEYSYM_(o,O) \
- _KEYSYM_(p,P) \
- _KEYSYM_(q,Q) \
- _KEYSYM_(r,R) \
- _KEYSYM_(s,S) \
- _KEYSYM_(t,T) \
- _KEYSYM_(u,U) \
- _KEYSYM_(v,V) \
- _KEYSYM_(w,W) \
- _KEYSYM_(x,X) \
- _KEYSYM_(y,Y) \
- _KEYSYM_(z,Z) \
- _KEYSYM1_(DELETE) \
- _KEYSYM_(KP_PLUS,KEYPAD_PLUS) \
- _KEYSYM_(KP_MINUS,KEYPAD_MINUS) \
- _KEYSYM_(KP_MULTIPLY,KEYPAD_MULTIPLY) \
- _KEYSYM_(KP_DIVIDE,KEYPAD_DIVIDE) \
- _KEYSYM_(KP_ENTER,KEYPAD_ENTER) \
- _KEYSYM_(KP_PERIOD,KEYPAD_PERIOD) \
- _KEYSYM_(KP_EQUALS,KEYPAD_EQUALS) \
- _KEYSYM_(KP1,KEYPAD_1) \
- _KEYSYM_(KP2,KEYPAD_2) \
- _KEYSYM_(KP3,KEYPAD_3) \
- _KEYSYM_(KP4,KEYPAD_4) \
- _KEYSYM_(KP5,KEYPAD_5) \
- _KEYSYM_(KP6,KEYPAD_6) \
- _KEYSYM_(KP7,KEYPAD_7) \
- _KEYSYM_(KP8,KEYPAD_8) \
- _KEYSYM_(KP9,KEYPAD_9) \
- _KEYSYM_(KP0,KEYPAD_0) \
- _KEYSYM1_(UP) \
- _KEYSYM1_(DOWN) \
- _KEYSYM1_(RIGHT) \
- _KEYSYM1_(LEFT) \
- _KEYSYM1_(INSERT) \
- _KEYSYM1_(HOME) \
- _KEYSYM1_(END) \
- _KEYSYM1_(PAGEUP) \
- _KEYSYM1_(PAGEDOWN) \
- _KEYSYM1_(F1) \
- _KEYSYM1_(F2) \
- _KEYSYM1_(F3) \
- _KEYSYM1_(F4) \
- _KEYSYM1_(F5) \
- _KEYSYM1_(F6) \
- _KEYSYM1_(F7) \
- _KEYSYM1_(F8) \
- _KEYSYM1_(F9) \
- _KEYSYM1_(F10) \
- _KEYSYM1_(F11) \
- _KEYSYM1_(F12) \
- _KEYSYM1_(F13) \
- _KEYSYM1_(F14) \
- _KEYSYM1_(F15) \
- _KEYSYM1_(SCROLLOCK) \
- _KEYSYM1_(SYSREQ) \
- _KEYSYM1_(PRINT) \
- _KEYSYM1_(BREAK) \
-
-#define _KEYSYM_(x,y) { SDLK_##x, #y },
-static const struct { int _sym; const char* _str; } keysym_names[] =
-{
- _KEYSYM_LIST
- { 0, NULL }
-};
-#undef _KEYSYM_
-
-int
-skin_keysym_str_count( void )
-{
- return sizeof(keysym_names)/sizeof(keysym_names[0])-1;
-}
-
-const char*
-skin_keysym_str( int index )
-{
- if (index >= 0 && index < skin_keysym_str_count())
- return keysym_names[index]._str;
-
- return NULL;
-}
-
-const char*
-skin_key_symmod_to_str( int sym, int mod )
-{
- static char temp[32];
- char* p = temp;
- char* end = p + sizeof(temp);
- int nn;
-
- if ((mod & KMOD_LCTRL) != 0) {
- p = bufprint(p, end, "Ctrl-");
- }
- if ((mod & KMOD_RCTRL) != 0) {
- p = bufprint(p, end, "RCtrl-");
- }
- if ((mod & KMOD_LSHIFT) != 0) {
- p = bufprint(p, end, "Shift-");
- }
- if ((mod & KMOD_RSHIFT) != 0) {
- p = bufprint(p, end, "RShift-");
- }
- if ((mod & KMOD_LALT) != 0) {
- p = bufprint(p, end, "Alt-");
- }
- if ((mod & KMOD_RALT) != 0) {
- p = bufprint(p, end, "RAlt-");
- }
- for (nn = 0; keysym_names[nn]._sym != 0; nn++) {
- if (keysym_names[nn]._sym == sym) {
- p = bufprint(p, end, "%s", keysym_names[nn]._str);
- return temp;;
- }
- }
-
- if (sym >= 32 && sym <= 127) {
- p = bufprint(p, end, "%c", sym);
- return temp;
- }
-
- return NULL;
-}
-
-
-int
-skin_key_symmod_from_str( const char* str, int *psym, int *pmod )
-{
- int mod = 0;
- int match = 1;
- int nn;
- const char* s0 = str;
- static const struct { const char* prefix; int mod; } mods[] =
- {
- { "^", KMOD_LCTRL },
- { "Ctrl", KMOD_LCTRL },
- { "ctrl", KMOD_LCTRL },
- { "RCtrl", KMOD_RCTRL },
- { "rctrl", KMOD_RCTRL },
- { "Alt", KMOD_LALT },
- { "alt", KMOD_LALT },
- { "RAlt", KMOD_RALT },
- { "ralt", KMOD_RALT },
- { "Shift", KMOD_LSHIFT },
- { "shift", KMOD_LSHIFT },
- { "RShift", KMOD_RSHIFT },
- { "rshift", KMOD_RSHIFT },
- { NULL, 0 }
- };
-
- while (match) {
- match = 0;
- for (nn = 0; mods[nn].prefix != NULL; nn++) {
- const char* prefix = mods[nn].prefix;
- int len = strlen(prefix);
-
- if ( !memcmp(str, prefix, len) ) {
- str += len;
- match = 1;
- mod |= mods[nn].mod;
- if (str[0] == '-' && str[1] != 0)
- str++;
- break;
- }
- }
- }
-
- for (nn = 0; keysym_names[nn]._sym; nn++) {
-#ifdef _WIN32
- if ( !stricmp(str, keysym_names[nn]._str) )
-#else
- if ( !strcasecmp(str, keysym_names[nn]._str) )
-#endif
- {
- *psym = keysym_names[nn]._sym;
- *pmod = mod;
- return 0;
- }
- }
-
- D("%s: can't find sym value for '%s' (mod=%d, str=%s)", __FUNCTION__, s0, mod, str);
- return -1;
-}
-
-
-typedef struct {
- int sym;
- int mod;
- SkinKeyCommand command;
-} SkinKeyItem;
-
-
-struct SkinKeyset {
- int num_items;
- int max_items;
- SkinKeyItem* items;
-};
-
-
-static int
-skin_keyset_add( SkinKeyset* kset, int sym, int mod, SkinKeyCommand command )
-{
- SkinKeyItem* item = kset->items;
- SkinKeyItem* end = item + kset->num_items;
- SkinKeyItem* first = NULL;
- int count = 0;
-
- D( "adding binding %s to %s", skin_key_command_to_str(command), skin_key_symmod_to_str(sym,mod));
- for ( ; item < end; item++) {
- if (item->command == command) {
- if (!first)
- first = item;
- if (++count == SKIN_KEY_COMMAND_MAX_BINDINGS) {
- /* replace the first (oldest) one in the list */
- first->sym = sym;
- first->mod = mod;
- return 0;
- }
- continue;
- }
- if (item->sym == sym && item->mod == mod) {
- /* replace a (sym,mod) binding */
- item->command = command;
- return 0;
- }
- }
- if (kset->num_items >= kset->max_items) {
- int old_size = kset->max_items;
- int new_size = old_size + (old_size >> 1) + 4;
- SkinKeyItem* new_items = realloc( kset->items, new_size*sizeof(SkinKeyItem) );
- if (new_items == NULL) {
- return -1;
- }
- kset->items = new_items;
- kset->max_items = new_size;
- }
- item = kset->items + kset->num_items++;
- item->command = command;
- item->sym = sym;
- item->mod = mod;
- return 1;
-}
-
-
-SkinKeyset*
-skin_keyset_new ( AConfig* root )
-{
- SkinKeyset* kset = calloc(1, sizeof(*kset));
- AConfig* node = root->first_child;;
-
- if (kset == NULL)
- return NULL;
-
- for ( ; node != NULL; node = node->next )
- {
- SkinKeyCommand command;
- int sym, mod;
- char* p;
-
- command = skin_key_command_from_str( node->name, -1 );
- if (command == SKIN_KEY_COMMAND_NONE) {
- D( "ignoring unknown keyset command '%s'", node->name );
- continue;
- }
- p = (char*)node->value;
- while (*p) {
- char* q = strpbrk( p, " \t,:" );
- if (q == NULL)
- q = p + strlen(p);
-
- if (q > p) {
- int len = q - p;
- char keys[24];
- if (len+1 >= (int)sizeof(keys)) {
- D("key binding too long: '%s'", p);
- }
- else {
- memcpy( keys, p, len );
- keys[len] = 0;
- if ( skin_key_symmod_from_str( keys, &sym, &mod ) < 0 ) {
- D( "ignoring unknown keys '%s' for command '%s'",
- keys, node->name );
- } else {
- skin_keyset_add( kset, sym, mod, command );
- }
- }
- } else if (*q)
- q += 1;
-
- p = q;
- }
- }
- return kset;
-}
-
-
-SkinKeyset*
-skin_keyset_new_from_text( const char* text )
-{
- AConfig* root = aconfig_node("","");
- char* str = strdup(text);
- SkinKeyset* result;
-
- D("kset new from:\n%s", text);
- aconfig_load( root, str );
- result = skin_keyset_new( root );
- free(str);
- D("kset done result=%p", result);
- return result;
-}
-
-
-void
-skin_keyset_free( SkinKeyset* kset )
-{
- if (kset) {
- free(kset->items);
- kset->items = NULL;
- kset->num_items = 0;
- kset->max_items = 0;
- free(kset);
- }
-}
-
-
-extern int
-skin_keyset_get_bindings( SkinKeyset* kset,
- SkinKeyCommand command,
- SkinKeyBinding* bindings )
-{
- if (kset) {
- int count = 0;
- SkinKeyItem* item = kset->items;
- SkinKeyItem* end = item + kset->num_items;
-
- for ( ; item < end; item++ ) {
- if (item->command == command) {
- bindings->sym = item->sym;
- bindings->mod = item->mod;
- bindings ++;
- if ( ++count >= SKIN_KEY_COMMAND_MAX_BINDINGS ) {
- /* shouldn't happen, but be safe */
- break;
- }
- }
- }
- return count;
- }
- return -1;
-}
-
-
-/* retrieve the command corresponding to a given (sym,mod) pair. returns SKIN_KEY_COMMAND_NONE if not found */
-SkinKeyCommand
-skin_keyset_get_command( SkinKeyset* kset, int sym, int mod )
-{
- if (kset) {
- SkinKeyItem* item = kset->items;
- SkinKeyItem* end = item + kset->num_items;
-
- for ( ; item < end; item++ ) {
- if (item->sym == sym && item->mod == mod) {
- return item->command;
- }
- }
- }
- return SKIN_KEY_COMMAND_NONE;
-}
-
-
-const char*
-skin_keyset_get_default( void )
-{
- return
- "BUTTON_CALL F3\n"
- "BUTTON_HANGUP F4\n"
- "BUTTON_HOME Home\n"
- "BUTTON_BACK Escape\n"
- "BUTTON_MENU F2, PageUp\n"
- "BUTTON_STAR Shift-F2, PageDown\n"
- "BUTTON_POWER F7\n"
- "BUTTON_SEARCH F5\n"
- "BUTTON_CAMERA Ctrl-Keypad_5, Ctrl-F3\n"
- "BUTTON_VOLUME_UP Keypad_Plus, Ctrl-F5\n"
- "BUTTON_VOLUME_DOWN Keypad_Minus, Ctrl-F6\n"
-
- "TOGGLE_NETWORK F8\n"
- "TOGGLE_TRACING F9\n"
- "TOGGLE_FULLSCREEN Alt-Enter\n"
-
- "BUTTON_DPAD_CENTER Keypad_5\n"
- "BUTTON_DPAD_UP Keypad_8\n"
- "BUTTON_DPAD_LEFT Keypad_4\n"
- "BUTTON_DPAD_RIGHT Keypad_6\n"
- "BUTTON_DPAD_DOWN Keypad_2\n"
-
- "TOGGLE_TRACKBALL F6\n"
- "SHOW_TRACKBALL Delete\n"
-
- "CHANGE_LAYOUT_PREV Keypad_7, Ctrl-F11\n"
- "CHANGE_LAYOUT_NEXT Keypad_9, Ctrl-F12\n"
- "ONION_ALPHA_UP Keypad_Multiply\n"
- "ONION_ALPHA_DOWN Keypad_Divide\n"
- ;
-}
diff --git a/android/skin/keyset.h b/android/skin/keyset.h
deleted file mode 100644
index d68d6a7..0000000
--- a/android/skin/keyset.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_KEYSET_H_
-#define _ANDROID_SKIN_KEYSET_H_
-
-#include "android/config.h"
-
-/* A SkinKeySet maps keystrokes to specific commands. we have a few hard-coded
- * keysets in the emulator binary, and the user can define its own if he wants
- * to...
- */
-typedef struct SkinKeyset SkinKeyset;
-
-#define SKIN_KEY_COMMAND_LIST \
- _SKIN_KEY_COMMAND(NONE,"no key") \
- _SKIN_KEY_COMMAND(BUTTON_HOME,"Home button") \
- _SKIN_KEY_COMMAND(BUTTON_MENU,"Menu (Soft-Left) button") \
- _SKIN_KEY_COMMAND(BUTTON_STAR,"Star (Soft-Right) button") \
- _SKIN_KEY_COMMAND(BUTTON_BACK,"Back button") \
- _SKIN_KEY_COMMAND(BUTTON_CALL,"Call/Dial button") \
- _SKIN_KEY_COMMAND(BUTTON_HANGUP,"Hangup/EndCall button") \
- _SKIN_KEY_COMMAND(BUTTON_POWER,"Power button") \
- _SKIN_KEY_COMMAND(BUTTON_SEARCH,"Search button") \
- _SKIN_KEY_COMMAND(BUTTON_VOLUME_UP,"Volume up button") \
- _SKIN_KEY_COMMAND(BUTTON_VOLUME_DOWN,"Volume down button") \
- _SKIN_KEY_COMMAND(BUTTON_CAMERA,"Camera button") \
- _SKIN_KEY_COMMAND(CHANGE_LAYOUT_PREV,"switch to previous layout") \
- _SKIN_KEY_COMMAND(CHANGE_LAYOUT_NEXT,"switch to next layout") \
- _SKIN_KEY_COMMAND(TOGGLE_NETWORK,"toggle cell network on/off") \
- _SKIN_KEY_COMMAND(TOGGLE_TRACING,"toggle code profiling") \
- _SKIN_KEY_COMMAND(TOGGLE_FULLSCREEN,"toggle fullscreen mode") \
- _SKIN_KEY_COMMAND(TOGGLE_TRACKBALL,"toggle trackball mode") \
- _SKIN_KEY_COMMAND(SHOW_TRACKBALL,"show trackball") \
- _SKIN_KEY_COMMAND(BUTTON_DPAD_CENTER,"DPad center") \
- _SKIN_KEY_COMMAND(BUTTON_DPAD_LEFT,"DPad left") \
- _SKIN_KEY_COMMAND(BUTTON_DPAD_RIGHT,"DPad right") \
- _SKIN_KEY_COMMAND(BUTTON_DPAD_UP,"DPad up") \
- _SKIN_KEY_COMMAND(BUTTON_DPAD_DOWN,"DPad down") \
- _SKIN_KEY_COMMAND(ONION_ALPHA_UP,"increase onion alpha") \
- _SKIN_KEY_COMMAND(ONION_ALPHA_DOWN,"decrease onion alpha") \
-
-
-/* the list of commands in the emulator */
-#define _SKIN_KEY_COMMAND(x,y) SKIN_KEY_COMMAND_##x,
-typedef enum {
- SKIN_KEY_COMMAND_LIST
- SKIN_KEY_COMMAND_MAX // do not remove
-} SkinKeyCommand;
-#undef _SKIN_KEY_COMMAND
-
-/* retrieve the textual name of a given command, this is the command name without
- * the "SKIN_KEY_COMMAND_" prefix. returns NULL if command is NONE or invalid
- * the result is a static constant string that must not be freed
- */
-extern const char* skin_key_command_to_str ( SkinKeyCommand command );
-
-/* convert a string into a SkinKeyCommand. returns SKIN_COMMAND_NONE if the string
- * is unknown
- */
-extern SkinKeyCommand skin_key_command_from_str( const char* str, int len );
-
-/* returns a short human-friendly description of the command */
-extern const char* skin_key_command_description( SkinKeyCommand cmd );
-
-/* returns the number of keysym string descriptors */
-extern int skin_keysym_str_count( void );
-
-/* return the n-th keysym string descriptor */
-extern const char* skin_keysym_str( int index );
-
-/* convert a (sym,mod) pair into a descriptive string. e.g. "Ctrl-K" or "Alt-A", etc..
- * result is a static string that is overwritten on each call
- */
-extern const char* skin_key_symmod_to_str ( int sym, int mod );
-
-/* convert a key binding description into a (sym,mod) pair. returns 0 on success, -1
- * if the string cannot be parsed.
- */
-extern int skin_key_symmod_from_str ( const char* str, int *psym, int *pmod );
-
-/* create a new keyset from a configuration tree node */
-extern SkinKeyset* skin_keyset_new ( AConfig* root );
-extern SkinKeyset* skin_keyset_new_from_text( const char* text );
-
-/* destroy a given keyset */
-extern void skin_keyset_free( SkinKeyset* kset );
-
-/* maximum number of key bindings per command. one command can be bound to several
- * key bindings for convenience
- */
-#define SKIN_KEY_COMMAND_MAX_BINDINGS 3
-
-/* a structure that describe a key binding */
-typedef struct {
- int sym; // really a SDL key symbol
- int mod; // really a SDL key modifier
-} SkinKeyBinding;
-
-/* return the number of keyboard bindings for a given command. results are placed in the 'bindings' array
- * which must have at least SKIN_KEY_MAX_BINDINGS items */
-extern int skin_keyset_get_bindings( SkinKeyset* kset,
- SkinKeyCommand command,
- SkinKeyBinding* bindings );
-
-/* return the command for a given keypress - SKIN_KEY_COMMAND_NONE is returned if unknown */
-extern SkinKeyCommand skin_keyset_get_command( SkinKeyset* kset, int sym, int mod );
-
-extern const char* skin_keyset_get_default( void );
-
-/* in android_main.c */
-extern SkinKeyset* android_keyset;
-
-#endif /* _ANDROID_SKIN_KEYSET_H_ */
diff --git a/android/skin/rect.c b/android/skin/rect.c
deleted file mode 100644
index 93e8bc1..0000000
--- a/android/skin/rect.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/rect.h"
-#include <limits.h>
-
-#define SKIN_POS_INITIALIZER { 0, 0 }
-
-void
-skin_pos_rotate( SkinPos* dst, SkinPos* src, SkinRotation rotation )
-{
- int x = src->x;
- int y = src->y;
-
- switch ( rotation & 3 ) {
- case SKIN_ROTATION_0:
- dst->x = x;
- dst->y = y;
- break;
-
- case SKIN_ROTATION_90:
- dst->x = -y;
- dst->y = x;
- break;
-
- case SKIN_ROTATION_180:
- dst->x = -x;
- dst->y = -y;
- break;
-
- default:
- dst->x = y;
- dst->y = -x;
- }
-}
-
-
-#define SKIN_SIZE_INITIALIZER { 0, 0 }
-
-int
-skin_size_contains( SkinSize* size, int x, int y )
-{
- return ( (unsigned) x < (unsigned) size->w &&
- (unsigned) y < (unsigned) size->h );
-}
-
-void
-skin_size_rotate( SkinSize* dst, SkinSize* src, SkinRotation rot )
-{
- int w = src->w;
- int h = src->h;
-
- if ((rot & 1) != 0) {
- dst->w = h;
- dst->h = w;
- } else {
- dst->w = w;
- dst->h = h;
- }
-}
-
-/** SKIN RECTANGLES
- **/
-#define SKIN_RECT_INITIALIZER { SKIN_POS_INITIALIZER, SKIN_SIZE_INITIALIZER }
-
-void
-skin_rect_init( SkinRect* r, int x, int y, int w, int h )
-{
- if (w < 0 || h < 0)
- x = y = w = h = 0;
-
- r->pos.x = x;
- r->pos.y = y;
- r->size.w = w;
- r->size.h = h;
-}
-
-
-void
-skin_rect_translate( SkinRect* r, int dx, int dy )
-{
- r->pos.x += dx;
- r->pos.y += dy;
-}
-
-
-void
-skin_rect_rotate( SkinRect* dst, SkinRect* src, SkinRotation rot )
-{
- int x, y, w, h;
-
- switch (rot & 3) {
- case SKIN_ROTATION_90:
- x = src->pos.x;
- y = src->pos.y;
- w = src->size.w;
- h = src->size.h;
- dst->pos.x = -(y + h);
- dst->pos.y = x;
- dst->size.w = h;
- dst->size.h = w;
- break;
-
- case SKIN_ROTATION_180:
- dst->pos.x = -(src->pos.x + src->size.w);
- dst->pos.y = -(src->pos.y + src->size.h);
- dst->size = src->size;
- break;
-
- case SKIN_ROTATION_270:
- x = src->pos.x;
- y = src->pos.y;
- w = src->size.w;
- h = src->size.h;
- dst->pos.x = y;
- dst->pos.y = -(x + w);
- dst->size.w = h;
- dst->size.h = w;
- break;
-
- default:
- dst[0] = src[0];
- }
-}
-
-
-int
-skin_rect_contains( SkinRect* r, int x, int y )
-{
- return ( (unsigned)(x - r->pos.x) < (unsigned)r->size.w &&
- (unsigned)(y - r->pos.y) < (unsigned)r->size.h );
-}
-
-SkinOverlap
-skin_rect_contains_rect( SkinRect *r1, SkinRect *r2 )
-{
- SkinBox a, b;
-
- skin_box_from_rect( &a, r1 );
- skin_box_from_rect( &b, r2 );
-
- if (a.x2 <= b.x1 || b.x2 <= a.x1 || a.y2 <= b.y1 || b.y2 <= a.y1) {
- return SKIN_OUTSIDE;
- }
-
- if (b.x1 >= a.x1 && b.x2 <= a.x2 && b.y1 >= a.y1 && b.y2 <= a.y2) {
- return SKIN_INSIDE;
- }
-
- return SKIN_OVERLAP;
-}
-
-
-int
-skin_rect_intersect( SkinRect* result, SkinRect* r1, SkinRect* r2 )
-{
- SkinBox a, b, r;
-
- skin_box_from_rect( &a, r1 );
- skin_box_from_rect( &b, r2 );
-
- if (a.x2 <= b.x1 || b.x2 <= a.x1 || a.y2 <= b.y1 || b.y2 <= a.y1) {
- result->pos.x = result->pos.y = result->size.w = result->size.h = 0;
- return 0;
- }
-
- r.x1 = (a.x1 > b.x1) ? a.x1 : b.x1;
- r.x2 = (a.x2 < b.x2) ? a.x2 : b.x2;
- r.y1 = (a.y1 > b.y1) ? a.y1 : b.y1;
- r.y2 = (a.y2 < b.y2) ? a.y2 : b.y2;
-
- skin_box_to_rect( &r, result );
- return 1;
-}
-
-int
-skin_rect_equals( SkinRect* r1, SkinRect* r2 )
-{
- return (r1->pos.x == r2->pos.x && r1->pos.y == r2->pos.y &&
- r1->size.w == r2->size.w && r2->size.h == r2->size.h);
-}
-
-/** SKIN BOXES
- **/
-void
-skin_box_minmax_init( SkinBox* box )
-{
- box->x1 = box->y1 = INT_MAX;
- box->x2 = box->y2 = INT_MIN;
-}
-
-void
-skin_box_minmax_update( SkinBox* a, SkinRect* r )
-{
- SkinBox b[1];
-
- skin_box_from_rect(b, r);
-
- if (b->x1 < a->x1) a->x1 = b->x1;
- if (b->y1 < a->y1) a->y1 = b->y1;
- if (b->x2 > a->x2) a->x2 = b->x2;
- if (b->y2 > a->y2) a->y2 = b->y2;
-}
-
-int
-skin_box_minmax_to_rect( SkinBox* box, SkinRect* r )
-{
- if (box->x1 > box->x2) {
- r->pos.x = r->pos.y = r->size.w = r->size.h = 0;
- return 0;
- }
- skin_box_to_rect( box, r );
- return 1;
-}
-
-void
-skin_box_from_rect( SkinBox* box, SkinRect* r )
-{
- box->x1 = r->pos.x;
- box->y1 = r->pos.y;
- box->x2 = r->size.w + box->x1;
- box->y2 = r->size.h + box->y1;
-}
-
-void
-skin_box_to_rect( SkinBox* box, SkinRect* r )
-{
- r->pos.x = box->x1;
- r->pos.y = box->y1;
- r->size.w = box->x2 - box->x1;
- r->size.h = box->y2 - box->y1;
-}
-
diff --git a/android/skin/rect.h b/android/skin/rect.h
deleted file mode 100644
index 757f888..0000000
--- a/android/skin/rect.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_RECT_H
-#define _ANDROID_SKIN_RECT_H
-
-/** Rectangles
- **/
-
-typedef enum {
- SKIN_ROTATION_0,
- SKIN_ROTATION_90,
- SKIN_ROTATION_180,
- SKIN_ROTATION_270
-} SkinRotation;
-
-typedef struct {
- int x, y;
-} SkinPos;
-
-extern void skin_pos_rotate( SkinPos* dst, SkinPos* src, SkinRotation rot );
-
-typedef struct {
- int w, h;
-} SkinSize;
-
-extern void skin_size_rotate( SkinSize* dst, SkinSize* src, SkinRotation rot );
-extern int skin_size_contains( SkinSize* size, int x, int y );
-
-
-typedef struct {
- SkinPos pos;
- SkinSize size;
-} SkinRect;
-
-extern void skin_rect_init ( SkinRect* r, int x, int y, int w, int h );
-extern void skin_rect_translate( SkinRect* r, int dx, int dy );
-extern void skin_rect_rotate ( SkinRect* dst, SkinRect* src, SkinRotation rotation );
-extern int skin_rect_contains ( SkinRect* r, int x, int y );
-extern int skin_rect_intersect( SkinRect* result, SkinRect* r1, SkinRect* r2 );
-extern int skin_rect_equals ( SkinRect* r1, SkinRect* r2 );
-
-typedef enum {
- SKIN_OUTSIDE = 0,
- SKIN_INSIDE = 1,
- SKIN_OVERLAP = 2
-} SkinOverlap;
-
-extern SkinOverlap skin_rect_contains_rect( SkinRect *r1, SkinRect *r2 );
-
-typedef struct {
- int x1, y1;
- int x2, y2;
-} SkinBox;
-
-extern void skin_box_init( SkinBox* box, int x1, int y1, int x2, int y2 );
-extern void skin_box_minmax_init( SkinBox* box );
-extern void skin_box_minmax_update( SkinBox* box, SkinRect* rect );
-extern int skin_box_minmax_to_rect( SkinBox* box, SkinRect* rect );
-extern void skin_box_from_rect( SkinBox* box, SkinRect* rect );
-extern void skin_box_to_rect( SkinBox* box, SkinRect* rect );
-
-#endif /* _ANDROID_SKIN_RECT_H */
diff --git a/android/skin/region.c b/android/skin/region.c
deleted file mode 100644
index a5f26a5..0000000
--- a/android/skin/region.c
+++ /dev/null
@@ -1,1448 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/region.h"
-#include <limits.h>
-#include <string.h>
-#include <stdlib.h> /* malloc/free */
-
-/*************************************************************************
- *************************************************************************
- ****
- **** ASSERTION SUPPORT
- ****
- ****
- ****/
-
-#ifdef UNIT_TEST
-#include <stdlib.h>
-#include <stdio.h>
-static void
-_rpanic(void)
-{
- *((char*)(void*)0) = 1; /* should SEGFAULT */
- /* put a breakpoint here */
- exit(1);
-}
-
-#define RASSERT(cond) \
- ({ if (!(cond)) { fprintf(stderr, "%s:%d:%s: assertion failed: %s", \
- __FILE__, __LINE__, __FUNCTION__, #cond ); _rpanic(); } })
-
-#else
-#define RASSERT(cond) ((void)0)
-#endif
-
-
-/*************************************************************************
- *************************************************************************
- ****
- **** IMPLEMENTATION DETAILS
- ****
- ****
- ****/
-
-/* this implementation of regions encodes the the region's spans with the
- following format:
-
- region ::= yband+ YSENTINEL
- yband ::= YTOP YBOTTOM scanline
- scanline ::= span+ XSENTINEL
- span ::= XLEFT XRIGHT
-
- XSENTINEL ::= 0x7fff
- YSENTINEL := 0x7fff
-
- all values are sorted in increasing order, which means that:
-
- - YTOP1 < YBOTTOM1 <= YTOP2 < YBOTTOM2 <= .... < YSENTINEL
- - XLEFT1 < XRIGHT1 < XLEFT2 < XRIGHT2 < .... < XSENTINEL
- (in a given scanline)
-*/
-
-/* convenience shortbuts */
-typedef SkinRegionRun Run;
-typedef SkinRegion Region;
-
-#define RUNS_RECT_COUNT 6 /* YTOP YBOT XLEFT XRIGHT XSENTINEL YSENTINEL */
-
-#define XSENTINEL SKIN_REGION_SENTINEL
-#define YSENTINEL SKIN_REGION_SENTINEL
-
-#define RUNS_EMPTY ((Run*)(void*)(-1))
-#define RUNS_RECT ((Run*)(void*)(0))
-
-static __inline__ int
-region_isEmpty( Region* r )
-{
- return r->runs == RUNS_EMPTY;
-}
-
-static __inline__ int
-region_isRect( Region* r )
-{
- return r->runs == RUNS_RECT;
-}
-
-static __inline__ int
-region_isComplex( Region* r )
-{
- return r->runs != RUNS_EMPTY && r->runs != RUNS_RECT;
-}
-
-/** RunStore: ref-counted storage for runs
- **/
-
-typedef struct {
- int refcount;
- int count;
-} RunStore;
-
-static void
-runstore_free( RunStore* s )
-{
- free(s);
-}
-
-static RunStore*
-runstore_alloc( int count )
-{
- RunStore* s = malloc( sizeof(*s) + sizeof(Run)*count );
- RASSERT(s != NULL);
- s->count = count;
- s->refcount = 1;
- return s;
-}
-
-static RunStore*
-runstore_edit( RunStore* s )
-{
- RunStore* s2;
-
- if (s->refcount == 1)
- return s;
-
- s2 = runstore_alloc( s->count );
- if (s2) {
- memcpy( s2, s, sizeof(*s) + s->count*sizeof(Run) );
- s->refcount -= 1;
- s2->refcount = 1;
- }
- return s2;
-}
-
-static void
-runstore_unrefp( RunStore* *ps )
-{
- RunStore* s = *ps;
- if (s != NULL) {
- if (s->refcount <= 0)
- runstore_free(s);
- *ps = NULL;
- }
-}
-
-static RunStore*
-runstore_ref( RunStore* s )
-{
- if (s) s->refcount += 1;
- return s;
-}
-
-static __inline__ RunStore*
-runstore_from_runs( Run* runs )
-{
- RASSERT(runs != RUNS_EMPTY);
- RASSERT(runs != RUNS_RECT);
- return (RunStore*)runs - 1;
-}
-
-static __inline__ Run*
-runstore_to_runs( RunStore* s )
-{
- RASSERT(s != NULL);
- return (Run*)(s + 1);
-}
-
-static Run*
-region_edit( Region* r )
-{
- RunStore* s;
-
- RASSERT(region_isComplex(r));
-
- s = runstore_from_runs(r->runs);
- s = runstore_edit(s);
- r->runs = runstore_to_runs(s);
- return r->runs;
-}
-
-/** Run parsing
- **/
-
-static Run*
-runs_next_scanline( Run* runs )
-{
- RASSERT(runs[0] != YSENTINEL && runs[1] != YSENTINEL );
- runs += 2;
- do { runs += 1; } while (runs[-1] != XSENTINEL);
- return runs;
-}
-
-static Run*
-runs_find_y( Run* runs, int y )
-{
- do {
- int ybot, ytop = runs[0];
-
- if (y < ytop)
- return NULL;
-
- ybot = runs[1];
- if (y < ybot)
- return runs;
-
- runs = runs_next_scanline( runs );
- } while (runs[0] != YSENTINEL);
-
- return NULL;
-}
-
-static void
-runs_set_rect( Run* runs, SkinRect* rect )
-{
- runs[0] = rect->pos.y;
- runs[1] = rect->pos.y + rect->size.h;
- runs[2] = rect->pos.x;
- runs[3] = rect->pos.x + rect->size.w;
- runs[4] = XSENTINEL;
- runs[5] = YSENTINEL;
-}
-
-static Run*
-runs_copy_scanline( Run* dst, Run* src )
-{
- RASSERT(src[0] != YSENTINEL);
- RASSERT(src[1] != YSENTINEL);
- dst[0] = src[0];
- dst[1] = src[1];
- src += 2;
- dst += 2;
- do { *dst++ = *src++; } while (src[-1] != XSENTINEL);
- return dst;
-}
-
-static Run*
-runs_copy_scanline_adj( Run* dst, Run* src, int ytop, int ybot )
-{
- Run* runs2 = runs_copy_scanline( dst, src );
- dst[0] = (Run) ytop;
- dst[1] = (Run) ybot;
- return runs2;
-}
-
-static __inline__ Run*
-runs_add_span( Run* dst, int left, int right )
-{
- dst[0] = (Run) left;
- dst[1] = (Run) right;
- return dst + 2;
-}
-
-static __inline__ int
-runs_get_count( Run* runs )
-{
- RunStore* s = runstore_from_runs(runs);
- return s->count;
-}
-
-
-static void
-runs_coalesce_band( Run* *psrc_spans, Run* *pdst_spans, SkinBox* minmax )
-{
- Run* sspan = *psrc_spans;
- Run* dspan = *pdst_spans;
- int pleft = sspan[0];
- int pright = sspan[1];
- int xleft, xright;
-
- RASSERT(pleft != XSENTINEL);
- RASSERT(pright != XSENTINEL);
- RASSERT(pleft < pright);
-
- if (pleft < minmax->x1) minmax->x1 = pleft;
-
- sspan += 2;
- xleft = sspan[0];
-
- while (xleft != XSENTINEL)
- {
- xright = sspan[1];
- RASSERT(xright != XSENTINEL);
- RASSERT(xleft < xright);
-
- if (xleft == pright) {
- pright = xright;
- } else {
- dspan[0] = (Run) pleft;
- dspan[1] = (Run) pright;
- dspan += 2;
- }
- sspan += 2;
- xleft = sspan[0];
- }
- dspan[0] = (Run) pleft;
- dspan[1] = (Run) pright;
- dspan[2] = XSENTINEL;
- dspan += 3;
- sspan += 1; /* skip XSENTINEL */
-
- if (pright > minmax->x2) minmax->x2 = pright;
-
- *psrc_spans = sspan;
- *pdst_spans = dspan;
-}
-
-
-static int
-runs_coalesce( Run* dst, Run* src, SkinBox* minmax )
-{
- Run* prev = NULL;
- Run* dst0 = dst;
- int ytop = src[0];
- int ybot;
-
- while (ytop != YSENTINEL)
- {
- Run* sspan = src + 2;
- Run* dspan = dst + 2;
-
- ybot = src[1];
- RASSERT( ytop < ybot );
- RASSERT( ybot != YSENTINEL );
- RASSERT( src[2] != XSENTINEL );
-
- if (ytop < minmax->y1) minmax->y1 = ytop;
- if (ybot > minmax->y2) minmax->y2 = ybot;
-
- dst[0] = (Run) ytop;
- dst[1] = (Run) ybot;
-
- runs_coalesce_band( &sspan, &dspan, minmax );
-
- if (prev && prev[1] == dst[0] && (dst-prev) == (dspan-dst) &&
- !memcmp(prev+2, dst+2, (dspan-dst-2)*sizeof(Run)))
- {
- /* coalesce two identical bands */
- prev[1] = dst[1];
- }
- else
- {
- prev = dst;
- dst = dspan;
- }
- src = sspan;
- ytop = src[0];
- }
- dst[0] = YSENTINEL;
- return (dst + 1 - dst0);
-}
-
-/*************************************************************************
- *************************************************************************
- ****
- **** PUBLIC API
- ****
- ****/
-
-void
-skin_region_init_empty( SkinRegion* r )
-{
- /* empty region */
- r->bounds.pos.x = r->bounds.pos.y = 0;
- r->bounds.size.w = r->bounds.size.h = 0;
- r->runs = RUNS_EMPTY;
-}
-
-void
-skin_region_init( SkinRegion* r, int x1, int y1, int x2, int y2 )
-{
- if (x1 >= x2 || y1 >= y2) {
- skin_region_init_empty(r);
- return;
- }
- r->bounds.pos.x = x1;
- r->bounds.pos.y = y1;
- r->bounds.size.w = x2 - x1;
- r->bounds.size.h = y2 - y1;
- r->runs = RUNS_RECT;
-}
-
-void
-skin_region_init_rect( SkinRegion* r, SkinRect* rect )
-{
- if (rect == NULL || rect->size.w <= 0 || rect->size.h <= 0) {
- skin_region_init_empty(r);
- return;
- }
- r->bounds = rect[0];
- r->runs = RUNS_RECT;
-}
-
-void
-skin_region_init_box( SkinRegion* r, SkinBox* box )
-{
- if (box == NULL || box->x1 >= box->x2 || box->y1 >= box->y2) {
- skin_region_init_empty(r);
- return;
- }
- r->bounds.pos.x = box->x1;
- r->bounds.pos.y = box->y1;
- r->bounds.size.w = box->x2 - box->x1;
- r->bounds.size.h = box->y2 - box->y1;
- r->runs = RUNS_RECT;
-}
-
-void
-skin_region_init_copy( SkinRegion* r, SkinRegion* src )
-{
- if (src == NULL || region_isEmpty(src))
- skin_region_init_empty(r);
- else {
- r[0] = src[0];
- if (region_isComplex(src)) {
- RunStore* s = runstore_from_runs(r->runs);
- runstore_ref(s);
- }
- }
-}
-
-
-void
-skin_region_reset( SkinRegion* r )
-{
- if (r != NULL) {
- if (region_isComplex(r)) {
- RunStore* s = runstore_from_runs(r->runs);
- runstore_unrefp( &s );
- }
- skin_region_init_empty(r);
- }
-}
-
-
-
-void
-skin_region_copy( SkinRegion* r, SkinRegion* src )
-{
- skin_region_reset(r);
- skin_region_init_copy(r, src);
-}
-
-
-int
-skin_region_equals( SkinRegion* r1, SkinRegion* r2 )
-{
- Run *runs1, *runs2;
- RunStore *store1, *store2;
-
- if (r1 == r2)
- return 1;
-
- if (!skin_rect_equals( &r1->bounds, &r2->bounds ))
- return 0;
-
- runs1 = r1->runs;
- runs2 = r2->runs;
-
- if (runs1 == runs2) /* empties and rects */
- return 1;
-
- if ( !region_isComplex(r1) || !region_isComplex(r2) )
- return 0;
-
- store1 = runstore_from_runs(runs1);
- store2 = runstore_from_runs(runs2);
-
- if (store1->count == store2->count &&
- !memcmp( (char*)runs1, (char*)runs2, store1->count*sizeof(Run) ) )
- return 1;
-
- return 0;
-}
-
-void
-skin_region_translate( SkinRegion* r, int dx, int dy )
-{
- Run* runs;
-
- if (region_isEmpty(r))
- return;
-
- skin_rect_translate( &r->bounds, dx, dy );
- if (region_isRect(r))
- return;
-
- runs = region_edit(r);
- while (runs[0] != YSENTINEL) {
- int ytop = runs[0];
- int ybot = runs[1];
-
- RASSERT(ybot != YSENTINEL);
- runs[0] = (Run)(ytop + dy);
- runs[1] = (Run)(ybot + dy);
- runs += 2;
- while (runs[0] != XSENTINEL) {
- int xleft = runs[0];
- int xright = runs[1];
- RASSERT(xright != YSENTINEL);
- runs[0] = (Run)(xleft + dx);
- runs[1] = (Run)(xright + dx);
- runs += 2;
- }
- runs += 1;
- }
-}
-
-void
-skin_region_get_bounds( SkinRegion* r, SkinRect* bounds )
-{
- if (r != NULL) {
- bounds[0] = r->bounds;
- } else {
- bounds->pos.x = bounds->pos.y = 0;
- bounds->size.w = bounds->size.h = 0;
- }
-}
-
-int
-skin_region_is_empty( SkinRegion* r )
-{
- return region_isEmpty(r);
-}
-
-int
-skin_region_is_rect( SkinRegion* r )
-{
- return region_isRect(r);
-}
-
-int
-skin_region_is_complex( SkinRegion* r )
-{
- return region_isComplex(r);
-}
-
-void
-skin_region_swap( SkinRegion* r, SkinRegion* r2 )
-{
- SkinRegion tmp;
- tmp = r[0];
- r[0] = r2[0];
- r2[0] = tmp;
-}
-
-
-SkinOverlap
-skin_region_contains( SkinRegion* r, int x, int y )
-{
- if (region_isEmpty(r))
- return SKIN_OUTSIDE;
- if (region_isRect(r)) {
- return skin_rect_contains(&r->bounds,x,y);
- } else {
- Run* runs = runs_find_y( r->runs, y );
- if (runs != NULL) {
- runs += 2;
- do {
- int xright, xleft = runs[0];
-
- if (x < xleft) // also x < xleft == XSENTINEL
- break;
- xright = runs[1];
- if (xright == XSENTINEL)
- break;
- if (x < xright)
- return SKIN_INSIDE;
- runs += 2;
- } while (runs[0] != XSENTINEL);
- }
- return SKIN_OUTSIDE;
- }
-}
-
-
-SkinOverlap
-skin_region_contains_rect( SkinRegion* r, SkinRect* rect )
-{
- SkinRegion r2[1];
- skin_region_init_rect( r2, rect );
- return skin_region_test_intersect( r, r2 );
-}
-
-
-SkinOverlap
-skin_region_contains_box( SkinRegion* r, SkinBox* b )
-{
- SkinRegion r2[1];
-
- skin_region_init_box( r2, b );
- return skin_region_test_intersect( r, r2 );
-}
-
-
-
-#define FLAG_REGION_1 (1 << 0)
-#define FLAG_REGION_2 (1 << 1)
-#define FLAG_REGION_BOTH (1 << 2)
-
-SkinOverlap
-skin_region_test_intersect( SkinRegion* r1,
- SkinRegion* r2 )
-{
- Run *runs1, *runs2;
- Run run2_tmp[ RUNS_RECT_COUNT ];
- SkinRect r;
-
- if (region_isEmpty(r1) || region_isEmpty(r2))
- return SKIN_OUTSIDE;
-
- if ( !skin_rect_intersect( &r, &r1->bounds, &r2->bounds) )
- return SKIN_OUTSIDE;
-
- if (region_isRect(r1)) {
- if (region_isRect(r2)) {
- return skin_rect_contains_rect(&r1->bounds, &r2->bounds);
- } else {
- SkinRegion* tmp = r1;
- r1 = r2;
- r2 = tmp;
- }
- }
- /* here r1 is guaranteed to be complex, r2 is either rect of complex */
- runs1 = r1->runs;
- if (region_isRect(r2)) {
- runs2 = run2_tmp;
- runs_set_rect(runs2, &r2->bounds);
- }
- else {
- runs2 = r2->runs;
- }
-
- {
- int flags = 0;
-
- while (runs1[0] != YSENTINEL && runs2[0] != YSENTINEL)
- {
- int ytop1 = runs1[0];
- int ybot1 = runs1[1];
- int ytop2 = runs2[0];
- int ybot2 = runs2[1];
-
- if (ybot1 <= ytop2)
- {
- /* band1 over band2 */
- flags |= FLAG_REGION_1;
- runs1 = runs_next_scanline( runs1 );
- }
- else if (ybot2 <= ytop1)
- {
- /* band2 over band1 */
- flags |= FLAG_REGION_2;
- runs2 = runs_next_scanline( runs2 );
- }
- else /* band1 and band2 overlap */
- {
- Run* span1;
- Run* span2;
- int ybot;
-
- if (ytop1 < ytop2) {
- flags |= FLAG_REGION_1;
- ytop1 = ytop2;
- } else if (ytop2 < ytop1) {
- flags |= FLAG_REGION_2;
- ytop2 = ytop1;
- }
-
- ybot = (ybot1 < ybot2) ? ybot1 : ybot2;
-
- span1 = runs1 + 2;
- span2 = runs2 + 2;
-
- while (span1[0] != XSENTINEL && span2[0] != XSENTINEL)
- {
- int xleft1 = span1[0];
- int xright1 = span1[1];
- int xleft2 = span2[0];
- int xright2 = span2[1];
-
- RASSERT(xright1 != XSENTINEL);
- RASSERT(xright2 != XSENTINEL);
-
- if (xright1 <= xleft2) {
- flags |= FLAG_REGION_1;
- span1 += 2;
- }
- else if (xright2 <= xleft1) {
- flags |= FLAG_REGION_2;
- span2 += 2;
- }
- else {
- int xright;
-
- if (xleft1 < xleft2) {
- flags |= FLAG_REGION_1;
- xleft1 = xleft2;
- } else if (xleft2 < xleft1) {
- flags |= FLAG_REGION_2;
- xleft2 = xleft1;
- }
-
- xright = (xright1 < xright2) ? xright1 : xright2;
-
- flags |= FLAG_REGION_BOTH;
-
- if (xright == xright1)
- span1 += 2;
- if (xright == xright2)
- span2 += 2;
- }
- }
-
- if (span1[0] != XSENTINEL) {
- flags |= FLAG_REGION_1;
- }
-
- if (span2[0] != XSENTINEL) {
- flags |= FLAG_REGION_2;
- }
-
- if (ybot == ybot1)
- runs1 = runs_next_scanline( runs1 );
-
- if (ybot == ybot2)
- runs2 = runs_next_scanline( runs2 );
- }
- }
-
- if (runs1[0] != YSENTINEL) {
- flags |= FLAG_REGION_1;
- }
-
- if (runs2[0] != YSENTINEL) {
- flags |= FLAG_REGION_2;
- }
-
- if ( !(flags & FLAG_REGION_BOTH) ) {
- /* no intersection at all */
- return SKIN_OUTSIDE;
- }
-
- if ( (flags & FLAG_REGION_2) != 0 ) {
- /* intersection + overlap */
- return SKIN_OVERLAP;
- }
-
- return SKIN_INSIDE;
- }
-}
-
-typedef struct {
- Run* runs1;
- Run* runs2;
- Run* runs_base;
- Run* runs;
- RunStore* store;
- Region result[1];
- Run runs1_rect[ RUNS_RECT_COUNT ];
- Run runs2_rect[ RUNS_RECT_COUNT ];
-} RegionOperator;
-
-
-static void
-region_operator_init( RegionOperator* o,
- Region* r1,
- Region* r2 )
-{
- int run1_count, run2_count;
- int maxruns;
-
- RASSERT( !region_isEmpty(r1) );
- RASSERT( !region_isEmpty(r2) );
-
- if (region_isRect(r1)) {
- run1_count = RUNS_RECT_COUNT;
- o->runs1 = o->runs1_rect;
- runs_set_rect( o->runs1, &r1->bounds );
- } else {
- o->runs1 = r1->runs;
- run1_count = runs_get_count(r1->runs);
- }
-
- if (region_isRect(r2)) {
- run2_count = RUNS_RECT_COUNT;
- o->runs2 = o->runs2_rect;
- runs_set_rect( o->runs2, &r2->bounds );
- } else {
- o->runs2 = r2->runs;
- run2_count = runs_get_count(r2->runs);
- }
-
- maxruns = run1_count < run2_count ? run2_count : run1_count;
- o->store = runstore_alloc( 3*maxruns );
- o->runs_base = runstore_to_runs(o->store);
-}
-
-
-static void
-region_operator_do( RegionOperator* o, int wanted )
-{
- Run* runs1 = o->runs1;
- Run* runs2 = o->runs2;
- Run* runs = o->runs_base;
- int ytop1 = runs1[0];
- int ytop2 = runs2[0];
-
- if (ytop1 != YSENTINEL && ytop2 != YSENTINEL)
- {
- int ybot1, ybot2;
-
- while (ytop1 != YSENTINEL && ytop2 != YSENTINEL)
- {
- int ybot;
-
- ybot1 = runs1[1];
- ybot2 = runs2[1];
-
- RASSERT(ybot1 != YSENTINEL);
- RASSERT(ybot2 != YSENTINEL);
-
- if (ybot1 <= ytop2) {
- if (wanted & FLAG_REGION_1)
- runs = runs_copy_scanline_adj( runs, runs1, ytop1, ybot1 );
- runs1 = runs_next_scanline( runs1 );
- ytop1 = runs1[0];
- continue;
- }
-
- if (ybot2 <= ytop1) {
- if (wanted & FLAG_REGION_2)
- runs = runs_copy_scanline_adj( runs, runs2, ytop2, ybot2 );
- runs2 = runs_next_scanline(runs2);
- ytop2 = runs2[0];
- continue;
- }
-
- if (ytop1 < ytop2) {
- if (wanted & FLAG_REGION_1)
- runs = runs_copy_scanline_adj( runs, runs1, ytop1, ytop2 );
- ytop1 = ytop2;
- }
- else if (ytop2 < ytop1) {
- if (wanted & FLAG_REGION_2)
- runs = runs_copy_scanline_adj( runs, runs2, ytop2, ytop1 );
- ytop2 = ytop1;
- }
-
- ybot = (ybot1 <= ybot2) ? ybot1 : ybot2;
-
- runs[0] = (Run) ytop1;
- runs[1] = (Run) ybot;
-
- /* do the common band */
- {
- Run* span1 = runs1 + 2;
- Run* span2 = runs2 + 2;
- Run* span = runs + 2;
- int xleft1 = span1[0];
- int xleft2 = span2[0];
- int xright1, xright2;
-
- while (xleft1 != XSENTINEL && xleft2 != XSENTINEL)
- {
- int xright;
-
- xright1 = span1[1];
- xright2 = span2[1];
-
- RASSERT(xright1 != XSENTINEL);
- RASSERT(xright2 != XSENTINEL);
-
- if (xright1 <= xleft2) {
- if (wanted & FLAG_REGION_1)
- span = runs_add_span( span, xleft1, xright1 );
- span1 += 2;
- xleft1 = span1[0];
- continue;
- }
-
- if (xright2 <= xleft1) {
- if (wanted & FLAG_REGION_2)
- span = runs_add_span( span, xleft2, xright2 );
- span2 += 2;
- xleft2 = span2[0];
- continue;
- }
-
- if (xleft1 < xleft2) {
- if (wanted & FLAG_REGION_1)
- span = runs_add_span( span, xleft1, xleft2 );
- xleft1 = xleft2;
- }
-
- else if (xleft2 < xleft1) {
- if (wanted & FLAG_REGION_2)
- span = runs_add_span( span, xleft2, xleft1 );
- xleft2 = xleft1;
- }
-
- xright = (xright1 <= xright2) ? xright1 : xright2;
-
- if (wanted & FLAG_REGION_BOTH)
- span = runs_add_span( span, xleft1, xright );
-
- xleft1 = xleft2 = xright;
-
- if (xright == xright1) {
- span1 += 2;
- xleft1 = span1[0];
- }
- if (xright == xright2) {
- span2 += 2;
- xleft2 = span2[0];
- }
- }
-
- if (wanted & FLAG_REGION_1) {
- while (xleft1 != XSENTINEL) {
- RASSERT(span1[1] != XSENTINEL);
- span[0] = (Run) xleft1;
- span[1] = span1[1];
- span += 2;
- span1 += 2;
- xleft1 = span1[0];
- }
- }
-
- if (wanted & FLAG_REGION_2) {
- while (xleft2 != XSENTINEL) {
- RASSERT(span2[1] != XSENTINEL);
- span[0] = (Run) xleft2;
- span[1] = span2[1];
- span += 2;
- span2 += 2;
- xleft2 = span2[0];
- }
- }
-
- if (span > runs + 2) {
- span[0] = XSENTINEL;
- runs = span + 1;
- }
- }
-
- ytop1 = ytop2 = ybot;
-
- if (ybot == ybot1) {
- runs1 = runs_next_scanline( runs1 );
- ytop1 = runs1[0];
- }
- if (ybot == ybot2) {
- runs2 = runs_next_scanline( runs2 );
- ytop2 = runs2[0];
- }
- }
- }
-
- if ((wanted & FLAG_REGION_1) != 0) {
- while (ytop1 != YSENTINEL) {
- runs = runs_copy_scanline_adj( runs, runs1, ytop1, runs1[1] );
- runs1 = runs_next_scanline(runs1);
- ytop1 = runs1[0];
- }
- }
-
- if ((wanted & FLAG_REGION_2) != 0) {
- while (ytop2 != YSENTINEL) {
- runs = runs_copy_scanline_adj( runs, runs2, ytop2, runs2[1] );
- runs2 = runs_next_scanline(runs2);
- ytop2 = runs2[0];
- }
- }
-
- runs[0] = YSENTINEL;
- o->runs = runs + 1;
-}
-
-/* returns 1 if the result is not empty */
-static int
-region_operator_done( RegionOperator* o )
-{
- Run* src = o->runs;
- int count;
- SkinBox minmax;
- RunStore* store;
-
- if (src <= o->runs_base + 1) {
- /* result is empty */
- skin_region_init_empty( o->result );
- return 0;
- }
-
- /* coalesce the temp runs in-place and compute the corresponding bounds */
- minmax.x1 = minmax.y1 = INT_MAX;
- minmax.x2 = minmax.y2 = INT_MIN;
-
- count = runs_coalesce( o->runs_base, o->runs_base, &minmax );
- if (count == 1) {
- /* result is empty */
- skin_region_init_empty( o->result );
- }
- else
- {
- skin_box_to_rect( &minmax, &o->result->bounds );
- if (count == RUNS_RECT_COUNT) {
- o->result->runs = RUNS_RECT;
- }
- else
- {
- /* result is complex */
- store = runstore_alloc( count );
- o->result->runs = runstore_to_runs(store);
- memcpy( o->result->runs, o->runs_base, count*sizeof(Run) );
- }
- }
-
- /* release temporary runstore */
- runstore_unrefp( &o->store );
-
- return region_isEmpty(o->result);
-}
-
-
-
-int
-skin_region_intersect( SkinRegion* r, SkinRegion* r2 )
-{
- RegionOperator oper[1];
-
- if (region_isEmpty(r))
- return 0;
-
- if (region_isEmpty(r2))
- return 1;
-
- if ( skin_rect_contains_rect( &r->bounds, &r2->bounds ) == SKIN_OUTSIDE ) {
- skin_region_init_empty(r);
- return 0;
- }
-
- region_operator_init( oper, r, r2 );
- region_operator_do( oper, FLAG_REGION_BOTH );
- region_operator_done( oper );
-
- skin_region_swap( r, oper->result );
- skin_region_reset( oper->result );
-
- return region_isEmpty( r );
-}
-
-
-/* performs r = (intersect r (region+_from_rect rect)), returns true iff
- the resulting region is not empty */
-int
-skin_region_intersect_rect( SkinRegion* r, SkinRect* rect )
-{
- Region r2[1];
-
- skin_region_init_rect( r2, rect );
- return skin_region_intersect( r, r2 );
-}
-
-/* performs r = (union r r2) */
-void
-skin_region_union( SkinRegion* r, SkinRegion* r2 )
-{
- RegionOperator oper[1];
-
- if (region_isEmpty(r)) {
- skin_region_copy(r, r2);
- return;
- }
-
- if (region_isEmpty(r2))
- return;
-
- region_operator_init( oper, r, r2 );
- region_operator_do( oper, FLAG_REGION_1|FLAG_REGION_2|FLAG_REGION_BOTH );
- region_operator_done( oper );
-
- skin_region_swap( r, oper->result );
- skin_region_reset( oper->result );
-}
-
-void
-skin_region_union_rect( SkinRegion* r, SkinRect* rect )
-{
- Region r2[1];
-
- skin_region_init_rect(r2, rect);
- return skin_region_union( r, r2 );
-}
-
-/* performs r = (difference r r2) */
-void
-skin_region_substract( SkinRegion* r, SkinRegion* r2 )
-{
- RegionOperator oper[1];
-
- if (region_isEmpty(r) || region_isEmpty(r2))
- return;
-
- if ( skin_rect_contains_rect( &r->bounds, &r2->bounds ) == SKIN_OUTSIDE ) {
- skin_region_init_empty(r);
- return;
- }
-
- region_operator_init( oper, r, r2 );
- region_operator_do( oper, FLAG_REGION_1 );
- region_operator_done( oper );
-
- skin_region_swap( r, oper->result );
- skin_region_reset( oper->result );
-}
-
-void
-skin_region_substract_rect( SkinRegion* r, SkinRect* rect )
-{
- Region r2[1];
-
- skin_region_init_rect(r2, rect);
- return skin_region_substract( r, r2 );
-}
-
-/* performs r = (xor r r2) */
-void
-skin_region_xor( SkinRegion* r, SkinRegion* r2 )
-{
- RegionOperator oper[1];
-
- if (region_isEmpty(r)) {
- skin_region_copy(r, r2);
- return;
- }
-
- if (region_isEmpty(r2))
- return;
-
- if ( skin_rect_contains_rect( &r->bounds, &r2->bounds ) == SKIN_OUTSIDE ) {
- skin_region_init_empty(r);
- return;
- }
-
- region_operator_init( oper, r, r2 );
- region_operator_do( oper, FLAG_REGION_1 );
- region_operator_done( oper );
-
- skin_region_swap( r, oper->result );
- skin_region_reset( oper->result );
-}
-
-
-void
-skin_region_iterator_init( SkinRegionIterator* iter,
- SkinRegion* region )
-{
- iter->region = region;
- iter->band = NULL;
- iter->span = NULL;
-}
-
-int
-skin_region_iterator_next( SkinRegionIterator* iter, SkinRect *rect )
-{
- static const Run dummy[ 2 ] = { XSENTINEL, YSENTINEL };
-
- Run* span = iter->span;
- Run* band = iter->band;
-
- if (span == NULL) {
- Region* r = iter->region;
- if (region_isEmpty(r))
- return 0;
- if (region_isRect(r)) {
- rect[0] = r->bounds;
- iter->span = (Run*) dummy;
- return 1;
- }
- iter->band = band = r->runs;
- iter->span = span = r->runs + 2;
- }
- else if (band == NULL)
- return 0;
-
- while (span[0] == XSENTINEL) {
- band = span + 1;
- if (band[0] == YSENTINEL || band[1] == YSENTINEL)
- return 0;
-
- iter->band = band;
- iter->span = span = band + 2;
- }
-
- if (span[1] == XSENTINEL)
- return 0;
-
- rect->pos.y = band[0];
- rect->pos.x = span[0];
- rect->size.h = band[1] - band[0];
- rect->size.w = span[1] - span[0];
-
- iter->span = span + 2;
- return 1;
-}
-
-int
-skin_region_iterator_next_box( SkinRegionIterator* iter, SkinBox *box )
-{
- SkinRect rect;
- int result = skin_region_iterator_next( iter, &rect );
-
- if (result)
- skin_box_from_rect( box, &rect );
-
- return result;
-}
-
-#ifdef UNIT_TEST
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "skin_rect.c"
-
-static void
-panic(void)
-{
- *((char*)0) = 1;
- exit(0);
-}
-
-static void
-_expectCompare( Region* r, const SkinBox* boxes, int count )
-{
- if (count == 0) {
- if ( !skin_region_is_empty(r) ) {
- printf( " result is not empty\n" );
- panic();
- }
- }
- else if (count == 1) {
- SkinRect rect1, rect2;
- if ( !skin_region_is_rect(r) ) {
- printf( " result is not a rectangle\n" );
- panic();
- }
- skin_region_get_bounds( r, &rect1 );
- skin_box_to_rect( (SkinBox*)boxes, &rect2 );
- if ( !skin_rect_equals( &rect1, &rect2 ) ) {
- printf( " result is (%d,%d,%d,%d), expected (%d,%d,%d,%d)\n",
- rect1.pos.x, rect1.pos.y,
- rect1.pos.x + rect1.size.w, rect1.pos.y + rect1.size.h,
- rect2.pos.x, rect2.pos.y,
- rect2.pos.x + rect2.size.w, rect2.pos.y + rect2.size.h );
- panic();
- }
- }
- else {
- SkinRegionIterator iter;
- SkinBox b;
- int n;
-
- skin_region_iterator_init( &iter, r );
- n = 0;
- while (n < count) {
- if ( !skin_region_iterator_next_box( &iter, &b ) ) {
- printf( "missing region box (%d, %d, %d, %d)\n",
- boxes->x1, boxes->y1, boxes->x2, boxes->y2 );
- panic();
- }
-
- if (b.x1 != boxes->x1 || b.x2 != boxes->x2||
- b.y1 != boxes->y1 || b.y2 != boxes->y2)
- {
- printf( "invalid region box (%d,%d,%d,%d) expecting (%d,%d,%d,%d)\n",
- b.x1, b.y1, b.x2, b.y2,
- boxes->x1, boxes->y1, boxes->x2, boxes->y2 );
- panic();
- }
- boxes += 1;
- n += 1;
- }
-
- if ( skin_region_iterator_next_box( &iter, &b ) ) {
- printf( "excess region box (%d,%d,%d,%d)\n",
- b.x1, b.y1, b.x2, b.y2 );
- panic();
- }
- }
-}
-
-
-static void
-expectEmptyRegion( Region* r )
-{
- printf( "expectEmptyRegion: " );
- if (!skin_region_is_empty(r)) {
- printf( "region not empty !!\n" );
- panic();
- }
- printf( "ok\n" );
-}
-
-static void
-expectTestIntersect( Region* r1, Region* r2, SkinOverlap overlap )
-{
- SkinOverlap result;
- printf( "expectTestIntersect(%d): ", overlap );
- result = skin_region_test_intersect(r1, r2);
- if (result != overlap) {
- printf( "bad result %d, expected %d\n", result, overlap );
- panic();
- }
- printf( "ok\n" );
-}
-
-static void
-expectRectRegion( Region* r, int x1, int y1, int x2, int y2 )
-{
- SkinRect rect;
- SkinBox b;
-
- printf( "expectRectRegion(%d,%d,%d,%d): ",x1,y1,x2,y2 );
- if (!skin_region_is_rect(r)) {
- printf( "region not rect !!\n" );
- panic();
- }
-
- skin_region_get_bounds( r, &rect );
- skin_box_from_rect( &b, &rect );
-
- if (b.x1 != x1 || b.x2 != x2 || b.y1 != y1 || b.y2 != y2) {
- printf( "rect region bounds are (%d,%d,%d,%d), expecting (%d,%d,%d,%d)\n",
- b.x1, b.y1, b.x2, b.y2, x1, y1, x2, y2 );
- panic();
- }
- printf( "ok\n" );
-}
-
-static void
-expectComplexRegion( Region* r, const SkinBox* boxes, int count )
-{
- SkinRegionIterator iter;
- SkinBox b;
- int n;
-
- printf( "expectComplexRegion(): " );
- if (!skin_region_is_complex(r)) {
- printf( "region is not complex !!\n" );
- panic();
- }
- _expectCompare( r, boxes, count );
- printf( "ok\n" );
-}
-
-static void
-expectIntersect( Region* r1, Region* r2, const SkinBox* boxes, int count )
-{
- SkinRegion r[1];
-
- printf( "expectIntersect(%d): ", count );
- skin_region_init_copy( r, r1 );
- skin_region_intersect( r, r2 );
- _expectCompare( r, boxes, count );
- printf( "ok\n" );
-}
-
-static void
-expectUnion( Region* r1, Region* r2, const SkinBox* boxes, int count )
-{
- SkinRegion r[1];
-
- printf( "expectUnion(%d): ", count );
- skin_region_init_copy( r, r1 );
- skin_region_union( r, r2 );
- _expectCompare( r, boxes, count );
- printf( "ok\n" );
-}
-
-
-static void
-expectSubstract( Region* r1, Region* r2, const SkinBox* boxes, int count )
-{
- SkinRegion r[1];
-
- printf( "expectSubstract(%d): ", count );
- skin_region_init_copy( r, r1 );
- skin_region_substract( r, r2 );
- _expectCompare( r, boxes, count );
- printf( "ok\n" );
-}
-
-
-int main( void )
-{
- SkinRegion r[1], r2[1];
-
- skin_region_init_empty( r );
- expectEmptyRegion( r );
-
- skin_region_init( r, 10, 20, 110, 120 );
- expectRectRegion( r, 10, 20, 110, 120 );
-
- skin_region_translate( r, 50, 80 );
- expectRectRegion( r, 60, 100, 160, 200 );
-
- skin_region_init( r, 10, 10, 40, 40 );
- skin_region_init( r2, 20, 20, 50, 50 );
- expectTestIntersect( r, r2, SKIN_OVERLAP );
-
- skin_region_translate(r2, +20, + 20 );
- expectTestIntersect( r, r2, SKIN_OUTSIDE );
-
- skin_region_translate(r2, -30, -30 );
- expectTestIntersect( r, r2, SKIN_INSIDE );
-
- {
- static const SkinBox result1[1] = {
- { 20, 20, 40, 40 }
- };
- static const SkinBox result2[3] = {
- { 10, 10, 40, 20 },
- { 10, 20, 50, 40 },
- { 20, 40, 50, 50 },
- };
- static const SkinBox result3[2] = {
- { 10, 10, 40, 20 },
- { 10, 20, 20, 40 },
- };
-
- skin_region_init( r, 10, 10, 40, 40 );
- skin_region_init( r2, 20, 20, 50, 50 );
- expectIntersect( r, r2, result1, 1 );
- expectUnion( r, r2, result2, 3 );
- expectSubstract( r, r2, result3, 2 );
- }
-
- return 0;
-}
-
-#endif /* UNIT_TEST */
diff --git a/android/skin/region.h b/android/skin/region.h
deleted file mode 100644
index 9ac4103..0000000
--- a/android/skin/region.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_REGION_H
-#define _ANDROID_SKIN_REGION_H
-
-#include "android/skin/rect.h"
-
-typedef struct SkinRegion SkinRegion;
-
-extern void skin_region_init_empty( SkinRegion* r );
-extern void skin_region_init( SkinRegion* r, int x1, int y1, int x2, int y2 );
-extern void skin_region_init_rect( SkinRegion* r, SkinRect* rect );
-extern void skin_region_init_box( SkinRegion* r, SkinBox* box );
-extern void skin_region_init_copy( SkinRegion* r, SkinRegion* r2 );
-extern void skin_region_reset( SkinRegion* r );
-
-/* finalize region, then copy src into it */
-extern void skin_region_copy( SkinRegion* r, SkinRegion* src );
-
-/* compare two regions for equality */
-extern int skin_region_equals( SkinRegion* r1, SkinRegion* r2 );
-
-/* swap two regions */
-extern void skin_region_swap( SkinRegion* r, SkinRegion* r2 );
-
-extern int skin_region_is_empty( SkinRegion* r );
-extern int skin_region_is_rect( SkinRegion* r );
-extern int skin_region_is_complex( SkinRegion* r );
-extern void skin_region_get_bounds( SkinRegion* r, SkinRect* bounds );
-
-extern void skin_region_translate( SkinRegion* r, int dx, int dy );
-
-extern SkinOverlap skin_region_contains( SkinRegion* r, int x, int y );
-
-extern SkinOverlap skin_region_contains_rect( SkinRegion* r,
- SkinRect* rect );
-
-extern SkinOverlap skin_region_contains_box( SkinRegion* r, SkinBox* b );
-
-/* returns overlap mode for "is r2 inside r1" */
-extern SkinOverlap skin_region_test_intersect( SkinRegion* r1,
- SkinRegion* r2 );
-
-/* performs r = (intersect r r2), returns true if the resulting region
- is not empty */
-extern int skin_region_intersect ( SkinRegion* r, SkinRegion* r2 );
-extern int skin_region_intersect_rect( SkinRegion* r, SkinRect* rect );
-
-/* performs r = (intersect r (region+_from_rect rect)), returns true iff
- the resulting region is not empty */
-
-/* performs r = (union r r2) */
-extern void skin_region_union ( SkinRegion* r, SkinRegion* r2 );
-extern void skin_region_union_rect( SkinRegion* r, SkinRect* rect );
-
-/* performs r = (difference r r2) */
-extern void skin_region_substract ( SkinRegion* r, SkinRegion* r2 );
-extern void skin_region_substract_rect( SkinRegion* r, SkinRect* rect );
-
-/* performs r = (xor r r2) */
-extern void skin_region_xor( SkinRegion* r, SkinRegion* r2 );
-
-typedef struct SkinRegionIterator SkinRegionIterator;
-
-/* iterator */
-extern void skin_region_iterator_init( SkinRegionIterator* iter,
- SkinRegion* r );
-
-extern int skin_region_iterator_next( SkinRegionIterator* iter,
- SkinRect *rect );
-
-extern int skin_rection_iterator_next_box( SkinRegionIterator* iter,
- SkinBox *box );
-
-/* the following should be considered private definitions. they're only here
- to allow clients to allocate SkinRegion objects themselves... */
-
-typedef signed short SkinRegionRun;
-#define SKIN_REGION_SENTINEL 0x7fff
-
-struct SkinRegion
-{
- SkinRect bounds;
- SkinRegionRun* runs;
-};
-
-struct SkinRegionIterator
-{
- SkinRegion* region;
- SkinRegionRun* band;
- SkinRegionRun* span;
-};
-
-#endif /* _ANDROID_SKIN_REGION_H */
diff --git a/android/skin/scaler.c b/android/skin/scaler.c
deleted file mode 100644
index 59e212f..0000000
--- a/android/skin/scaler.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/scaler.h"
-#include <stdint.h>
-#include <math.h>
-
-struct SkinScaler {
- double scale;
- double xdisp, ydisp;
- double invscale;
- int valid;
-};
-
-static SkinScaler _scaler0;
-
-SkinScaler*
-skin_scaler_create( void )
-{
- _scaler0.scale = 1.0;
- _scaler0.xdisp = 0.0;
- _scaler0.ydisp = 0.0;
- _scaler0.invscale = 1.0;
- return &_scaler0;
-}
-
-/* change the scale of a given scaler. returns 0 on success, or -1 in case of
- * problem (unsupported scale) */
-int
-skin_scaler_set( SkinScaler* scaler, double scale, double xdisp, double ydisp )
-{
- /* right now, we only support scales in the 0.5 .. 1.0 range */
- if (scale < 0.1)
- scale = 0.1;
- else if (scale > 6.0)
- scale = 6.0;
-
- scaler->scale = scale;
- scaler->xdisp = xdisp;
- scaler->ydisp = ydisp;
- scaler->invscale = 1/scale;
- scaler->valid = 1;
-
- return 0;
-}
-
-void
-skin_scaler_free( SkinScaler* scaler )
-{
- scaler=scaler;
-}
-
-typedef struct {
- SDL_Rect rd; /* destination rectangle */
- int sx, sy; /* source start position in 16.16 format */
- int ix, iy; /* source increments in 16.16 format */
- int src_pitch;
- int src_w;
- int src_h;
- int dst_pitch;
- uint8_t* dst_line;
- uint8_t* src_line;
- double scale;
-} ScaleOp;
-
-
-#define ARGB_SCALE_GENERIC scale_generic
-#define ARGB_SCALE_05_TO_10 scale_05_to_10
-#define ARGB_SCALE_UP_BILINEAR scale_up_bilinear
-#define ARGB_SCALE_UP_QUICK_4x4 scale_up_quick_4x4
-
-#include "android/skin/argb.h"
-
-
-void
-skin_scaler_scale( SkinScaler* scaler,
- SDL_Surface* dst_surface,
- SDL_Surface* src_surface,
- int sx,
- int sy,
- int sw,
- int sh )
-{
- ScaleOp op;
-
- if ( !scaler->valid )
- return;
-
- SDL_LockSurface( src_surface );
- SDL_LockSurface( dst_surface );
- {
- op.scale = scaler->scale;
- op.src_pitch = src_surface->pitch;
- op.src_line = src_surface->pixels;
- op.src_w = src_surface->w;
- op.src_h = src_surface->h;
- op.dst_pitch = dst_surface->pitch;
- op.dst_line = dst_surface->pixels;
-
- /* compute the destination rectangle */
- op.rd.x = (int)(sx * scaler->scale + scaler->xdisp);
- op.rd.y = (int)(sy * scaler->scale + scaler->ydisp);
- op.rd.w = (int)(ceil((sx + sw) * scaler->scale + scaler->xdisp)) - op.rd.x;
- op.rd.h = (int)(ceil((sy + sh) * scaler->scale + scaler->ydisp)) - op.rd.y;
-
- /* compute the starting source position in 16.16 format
- * and the corresponding increments */
- op.sx = (int)((op.rd.x - scaler->xdisp) * scaler->invscale * 65536);
- op.sy = (int)((op.rd.y - scaler->ydisp) * scaler->invscale * 65536);
-
- op.ix = (int)( scaler->invscale * 65536 );
- op.iy = op.ix;
-
- op.dst_line += op.rd.x*4 + op.rd.y*op.dst_pitch;
-
- if (op.scale >= 0.5 && op.scale <= 1.0)
- scale_05_to_10( &op );
- else if (op.scale > 1.0)
- scale_up_bilinear( &op );
- else
- scale_generic( &op );
- }
- SDL_UnlockSurface( dst_surface );
- SDL_UnlockSurface( src_surface );
-
- SDL_UpdateRects( dst_surface, 1, &op.rd );
-}
diff --git a/android/skin/scaler.h b/android/skin/scaler.h
deleted file mode 100644
index 4e0ec5a..0000000
--- a/android/skin/scaler.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_SCALER_H
-#define _ANDROID_SKIN_SCALER_H
-
-#include "android/skin/image.h"
-
-typedef struct SkinScaler SkinScaler;
-
-/* create a new image scaler. by default, it uses a scale of 1.0 */
-extern SkinScaler* skin_scaler_create( void );
-
-/* change the scale of a given scaler. returns 0 on success, or -1 in case of
- * problem (unsupported scale) */
-extern int skin_scaler_set( SkinScaler* scaler,
- double scale,
- double xDisp,
- double yDisp );
-
-extern void skin_scaler_free( SkinScaler* scaler );
-
-extern void skin_scaler_scale( SkinScaler* scaler,
- SDL_Surface* dst,
- SDL_Surface* src,
- int sx,
- int sy,
- int sw,
- int sh );
-
-#endif /* _ANDROID_SKIN_SCALER_H */
diff --git a/android/skin/surface.c b/android/skin/surface.c
deleted file mode 100644
index 4424bd8..0000000
--- a/android/skin/surface.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/surface.h"
-#include "android/skin/argb.h"
-#include <SDL.h>
-
-#define DEBUG 1
-
-#if DEBUG
-#include "android/utils/debug.h"
-#define D(...) VERBOSE_PRINT(surface,__VA_ARGS__)
-#else
-#define D(...) ((void)0)
-#endif
-
-struct SkinSurface {
- int refcount;
- uint32_t* pixels;
- SDL_Surface* surface;
- SkinSurfaceDoneFunc done_func;
- void* done_user;
-};
-
-static void
-skin_surface_free( SkinSurface* s )
-{
- if (s->done_func) {
- s->done_func( s->done_user );
- s->done_func = NULL;
- }
- if (s->surface) {
- SDL_FreeSurface(s->surface);
- s->surface = NULL;
- }
- free(s);
-}
-
-extern SkinSurface*
-skin_surface_ref( SkinSurface* surface )
-{
- if (surface)
- surface->refcount += 1;
- return surface;
-}
-
-extern void
-skin_surface_unrefp( SkinSurface* *psurface )
-{
- SkinSurface* surf = *psurface;
- if (surf) {
- if (--surf->refcount <= 0)
- skin_surface_free(surf);
- *psurface = NULL;
- }
-}
-
-
-void
-skin_surface_set_done( SkinSurface* s, SkinSurfaceDoneFunc done_func, void* done_user )
-{
- s->done_func = done_func;
- s->done_user = done_user;
-}
-
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
-# define ARGB32_R_MASK 0xff000000
-# define ARGB32_G_MASK 0x00ff0000
-# define ARGB32_B_MASK 0x0000ff00
-# define ARGB32_A_MASK 0x000000ff
-#else
-# define ARGB32_R_MASK 0x000000ff
-# define ARGB32_G_MASK 0x0000ff00
-# define ARGB32_B_MASK 0x00ff0000
-# define ARGB32_A_MASK 0xff000000
-#endif
-
-static SDL_Surface*
-_sdl_surface_create_rgb( int width,
- int height,
- int depth,
- int flags )
-{
- Uint32 rmask, gmask, bmask, amask;
-
- if (depth == 8) {
- rmask = gmask = bmask = 0;
- amask = 0xff;
- } else if (depth == 32) {
- rmask = ARGB32_R_MASK;
- gmask = ARGB32_G_MASK;
- bmask = ARGB32_B_MASK;
- amask = ARGB32_A_MASK;
- } else
- return NULL;
-
- return SDL_CreateRGBSurface( flags, width, height, depth,
- rmask, gmask, bmask, amask );
-}
-
-
-static SDL_Surface*
-_sdl_surface_create_rgb_from( int width,
- int height,
- int pitch,
- void* pixels,
- int depth )
-{
- Uint32 rmask, gmask, bmask, amask;
-
- if (depth == 8) {
- rmask = gmask = bmask = 0;
- amask = 0xff;
- } else if (depth == 32) {
- rmask = ARGB32_R_MASK;
- gmask = ARGB32_G_MASK;
- bmask = ARGB32_B_MASK;
- amask = ARGB32_A_MASK;
- } else
- return NULL;
-
- return SDL_CreateRGBSurfaceFrom( pixels, width, height, pitch, depth,
- rmask, gmask, bmask, amask );
-}
-
-
-static SkinSurface*
-_skin_surface_create( SDL_Surface* surface,
- void* pixels )
-{
- SkinSurface* s = malloc(sizeof(*s));
- if (s != NULL) {
- s->refcount = 1;
- s->pixels = pixels;
- s->surface = surface;
- s->done_func = NULL;
- s->done_user = NULL;
- }
- else {
- SDL_FreeSurface(surface);
- free(pixels);
- D( "not enough memory to allocate new skin surface !" );
- }
- return s;
-}
-
-
-SkinSurface*
-skin_surface_create_fast( int w, int h )
-{
- SDL_Surface* surface;
-
- surface = _sdl_surface_create_rgb( w, h, 32, SDL_HWSURFACE );
- if (surface == NULL) {
- surface = _sdl_surface_create_rgb( w, h, 32, SDL_SWSURFACE );
- if (surface == NULL) {
- D( "could not create fast %dx%d ARGB32 surface: %s",
- w, h, SDL_GetError() );
- return NULL;
- }
- }
- return _skin_surface_create( surface, NULL );
-}
-
-
-SkinSurface*
-skin_surface_create_slow( int w, int h )
-{
- SDL_Surface* surface;
-
- surface = _sdl_surface_create_rgb( w, h, 32, SDL_SWSURFACE );
- if (surface == NULL) {
- D( "could not create slow %dx%d ARGB32 surface: %s",
- w, h, SDL_GetError() );
- return NULL;
- }
- return _skin_surface_create( surface, NULL );
-}
-
-
-SkinSurface*
-skin_surface_create_argb32_from(
- int w,
- int h,
- int pitch,
- uint32_t* pixels,
- int do_copy )
-{
- SDL_Surface* surface;
- uint32_t* pixcopy = NULL;
-
- if (do_copy) {
- size_t size = h*pitch;
- pixcopy = malloc( size );
- if (pixcopy == NULL && size > 0) {
- D( "not enough memory to create %dx%d ARGB32 surface",
- w, h );
- return NULL;
- }
- memcpy( pixcopy, pixels, size );
- }
-
- surface = _sdl_surface_create_rgb_from( w, h, pitch,
- pixcopy ? pixcopy : pixels,
- 32 );
- if (surface == NULL) {
- D( "could not create %dx%d slow ARGB32 surface: %s",
- w, h, SDL_GetError() );
- return NULL;
- }
- return _skin_surface_create( surface, pixcopy );
-}
-
-
-
-
-extern int
-skin_surface_lock( SkinSurface* s, SkinSurfacePixels *pix )
-{
- if (!s || !s->surface) {
- D( "error: trying to lock stale surface %p", s );
- return -1;
- }
- if ( SDL_LockSurface( s->surface ) != 0 ) {
- D( "could not lock surface %p: %s", s, SDL_GetError() );
- return -1;
- }
- pix->w = s->surface->w;
- pix->h = s->surface->h;
- pix->pitch = s->surface->pitch;
- pix->pixels = s->surface->pixels;
- return 0;
-}
-
-/* unlock a slow surface that was previously locked */
-extern void
-skin_surface_unlock( SkinSurface* s )
-{
- if (s && s->surface)
- SDL_UnlockSurface( s->surface );
-}
-
-
-#if 0
-static uint32_t
-skin_surface_map_argb( SkinSurface* s, uint32_t c )
-{
- if (s && s->surface) {
- return SDL_MapRGBA( s->surface->format,
- ((c) >> 16) & 255,
- ((c) >> 8) & 255,
- ((c) & 255),
- ((c) >> 24) & 255 );
- }
- return 0x00000000;
-}
-#endif
-
-typedef struct {
- int x;
- int y;
- int w;
- int h;
- int sx;
- int sy;
-
- uint8_t* dst_line;
- int dst_pitch;
- SDL_Surface* dst_lock;
-
- uint8_t* src_line;
- int src_pitch;
- SDL_Surface* src_lock;
- uint32_t src_color;
-
-} SkinBlit;
-
-
-static int
-skin_blit_init_fill( SkinBlit* blit,
- SkinSurface* dst,
- SkinRect* dst_rect,
- uint32_t color )
-{
- int x = dst_rect->pos.x;
- int y = dst_rect->pos.y;
- int w = dst_rect->size.w;
- int h = dst_rect->size.h;
- int delta;
-
- if (x < 0) {
- w += x;
- x = 0;
- }
- delta = (x + w) - dst->surface->w;
- if (delta > 0)
- w -= delta;
-
- if (y < 0) {
- h += y;
- y = 0;
- }
- delta = (y + h) - dst->surface->h;
- if (delta > 0)
- h -= delta;
-
- if (w <= 0 || h <= 0)
- return 0;
-
- blit->x = x;
- blit->y = y;
- blit->w = w;
- blit->h = h;
-
- if ( !SDL_LockSurface(dst->surface) )
- return 0;
-
- blit->dst_lock = dst->surface;
- blit->dst_pitch = dst->surface->pitch;
- blit->dst_line = dst->surface->pixels + y*blit->dst_pitch;
-
- blit->src_lock = NULL;
- blit->src_color = color;
-
- return 1;
-}
-
-static int
-skin_blit_init_blit( SkinBlit* blit,
- SkinSurface* dst,
- SkinPos* dst_pos,
- SkinSurface* src,
- SkinRect* src_rect )
-{
- int x = dst_pos->x;
- int y = dst_pos->y;
- int sx = src_rect->pos.x;
- int sy = src_rect->pos.y;
- int w = src_rect->size.w;
- int h = src_rect->size.h;
- int delta;
-
- if (x < 0) {
- w += x;
- sx -= x;
- x = 0;
- }
- if (sx < 0) {
- w += sx;
- x -= sx;
- sx = 0;
- }
-
- delta = (x + w) - dst->surface->w;
- if (delta > 0)
- w -= delta;
-
- delta = (sx + w) - src->surface->w;
- if (delta > 0)
- w -= delta;
-
- if (y < 0) {
- h += y;
- sy += y;
- y = 0;
- }
- if (sy < 0) {
- h += sy;
- y -= sy;
- sy = 0;
- }
- delta = (y + h) - dst->surface->h;
- if (delta > 0)
- h -= delta;
-
- delta = (sy + h) - src->surface->h;
-
- if (w <= 0 || h <= 0)
- return 0;
-
- blit->x = x;
- blit->y = y;
- blit->w = w;
- blit->h = h;
-
- blit->sx = sx;
- blit->sy = sy;
-
- if ( !SDL_LockSurface(dst->surface) )
- return 0;
-
- blit->dst_lock = dst->surface;
- blit->dst_pitch = dst->surface->pitch;
- blit->dst_line = (uint8_t*) dst->surface->pixels + y*blit->dst_pitch;
-
- if ( !SDL_LockSurface(src->surface) ) {
- SDL_UnlockSurface(dst->surface);
- return 0;
- }
-
- blit->src_lock = src->surface;
- blit->src_pitch = src->surface->pitch;
- blit->src_line = (uint8_t*) src->surface->pixels + sy*blit->src_pitch;
-
- return 1;
-}
-
-static void
-skin_blit_done( SkinBlit* blit )
-{
- if (blit->src_lock)
- SDL_UnlockSurface( blit->src_lock );
- if (blit->dst_lock)
- SDL_UnlockSurface( blit->dst_lock );
- ARGB_DONE;
-}
-
-typedef void (*SkinLineFillFunc)( uint32_t* dst, uint32_t color, int len );
-typedef void (*SkinLineBlitFunc)( uint32_t* dst, const uint32_t* src, int len );
-
-static void
-skin_line_fill_copy( uint32_t* dst, uint32_t color, int len )
-{
- uint32_t* end = dst + len;
-
- while (dst + 4 <= end) {
- dst[0] = dst[1] = dst[2] = dst[3] = color;
- dst += 4;
- }
- while (dst < end) {
- dst[0] = color;
- dst += 1;
- }
-}
-
-static void
-skin_line_fill_srcover( uint32_t* dst, uint32_t color, int len )
-{
- uint32_t* end = dst + len;
- uint32_t alpha = (color >> 24);
-
- if (alpha == 255)
- {
- skin_line_fill_copy(dst, color, len);
- }
- else
- {
- ARGB_DECL(src_c);
- ARGB_DECL_ZERO();
-
- alpha = 255 - alpha;
- alpha += (alpha >> 7);
-
- ARGB_UNPACK(src_c,color);
-
- for ( ; dst < end; dst++ )
- {
- ARGB_DECL(dst_c);
-
- ARGB_READ(dst_c,dst);
- ARGB_MULSHIFT(dst_c,dst_c,alpha,8);
- ARGB_ADD(dst_c,src_c);
- ARGB_WRITE(dst_c,dst);
- }
- }
-}
-
-static void
-skin_line_fill_dstover( uint32_t* dst, uint32_t color, int len )
-{
- uint32_t* end = dst + len;
- ARGB_DECL(src_c);
- ARGB_DECL_ZERO();
-
- ARGB_UNPACK(src_c,color);
-
- for ( ; dst < end; dst++ )
- {
- ARGB_DECL(dst_c);
- ARGB_DECL(val);
-
- uint32_t alpha;
-
- ARGB_READ(dst_c,dst);
- alpha = 256 - (dst[0] >> 24);
- ARGB_MULSHIFT(val,src_c,alpha,8);
- ARGB_ADD(val,dst_c);
- ARGB_WRITE(val,dst);
- }
-}
-
-extern void
-skin_surface_fill( SkinSurface* dst,
- SkinRect* rect,
- uint32_t argb_premul,
- SkinBlitOp blitop )
-{
- SkinLineFillFunc fill;
- SkinBlit blit[1];
-
- switch (blitop) {
- case SKIN_BLIT_COPY: fill = skin_line_fill_copy; break;
- case SKIN_BLIT_SRCOVER: fill = skin_line_fill_srcover; break;
- case SKIN_BLIT_DSTOVER: fill = skin_line_fill_dstover; break;
- default: return;
- }
-
- if ( skin_blit_init_fill( blit, dst, rect, argb_premul ) ) {
- uint8_t* line = blit->dst_line;
- int pitch = blit->dst_pitch;
- uint8_t* end = line + pitch*blit->h;
-
- for ( ; line != end; line += pitch )
- fill( (uint32_t*)line + blit->x, argb_premul, blit->w );
- }
-}
-
-
-static void
-skin_line_blit_copy( uint32_t* dst, const uint32_t* src, int len )
-{
- memcpy( (char*)dst, (const char*)src, len*4 );
-}
-
-
-
-static void
-skin_line_blit_srcover( uint32_t* dst, const uint32_t* src, int len )
-{
- uint32_t* end = dst + len;
- ARGB_DECL_ZERO();
-
- for ( ; dst < end; dst++ ) {
- ARGB_DECL(s);
- ARGB_DECL(d);
- ARGB_DECL(v);
- uint32_t alpha;
-
- ARGB_READ(s,src);
- alpha = (src[0] >> 24);
- if (alpha > 0) {
- ARGB_READ(d,dst);
- alpha = 256 - alpha;
- ARGB_MULSHIFT(v,d,alpha,8);
- ARGB_ADD(v,d);
- ARGB_WRITE(v,dst);
- }
- }
-}
-
-static void
-skin_line_blit_dstover( uint32_t* dst, const uint32_t* src, int len )
-{
- uint32_t* end = dst + len;
- ARGB_DECL_ZERO();
-
- for ( ; dst < end; dst++ ) {
- ARGB_DECL(s);
- ARGB_DECL(d);
- ARGB_DECL(v);
- uint32_t alpha;
-
- ARGB_READ(d,dst);
- alpha = (dst[0] >> 24);
- if (alpha < 255) {
- ARGB_READ(s,src);
- alpha = 256 - alpha;
- ARGB_MULSHIFT(v,s,alpha,8);
- ARGB_ADD(v,s);
- ARGB_WRITE(v,dst);
- }
- }
-}
-
-
-extern void
-skin_surface_blit( SkinSurface* dst,
- SkinPos* dst_pos,
- SkinSurface* src,
- SkinRect* src_rect,
- SkinBlitOp blitop )
-{
- SkinLineBlitFunc func;
- SkinBlit blit[1];
-
- switch (blitop) {
- case SKIN_BLIT_COPY: func = skin_line_blit_copy; break;
- case SKIN_BLIT_SRCOVER: func = skin_line_blit_srcover; break;
- case SKIN_BLIT_DSTOVER: func = skin_line_blit_dstover; break;
- default: return;
- }
-
- if ( skin_blit_init_blit( blit, dst, dst_pos, src, src_rect ) ) {
- uint8_t* line = blit->dst_line;
- uint8_t* sline = blit->src_line;
- int pitch = blit->dst_pitch;
- int spitch = blit->src_pitch;
- uint8_t* end = line + pitch*blit->h;
-
- for ( ; line != end; line += pitch, sline += spitch )
- func( (uint32_t*)line + blit->x, (uint32_t*)sline + blit->sx, blit->w );
-
- skin_blit_done(blit);
- }
-}
diff --git a/android/skin/surface.h b/android/skin/surface.h
deleted file mode 100644
index 39ab439..0000000
--- a/android/skin/surface.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_SURFACE_H
-#define _ANDROID_SKIN_SURFACE_H
-
-#include "android/skin/region.h"
-#include <stdint.h>
-
-/* a SkinSurface models a 32-bit ARGB pixel image that can be blitted to or from
- */
-typedef struct SkinSurface SkinSurface;
-
-/* increment surface's reference count */
-extern SkinSurface* skin_surface_ref( SkinSurface* surface );
-
-/* decrement a surface's reference count. takes the surface's address as parameter.
- it will be set to NULL on exit */
-extern void skin_surface_unrefp( SkinSurface* *psurface );
-
-/* sets a callback that will be called when the surface is destroyed.
- * used NULL for done_func to disable it
- */
-typedef void (*SkinSurfaceDoneFunc)( void* user );
-
-extern void skin_surface_set_done( SkinSurface* s, SkinSurfaceDoneFunc done_func, void* done_user );
-
-
-/* there are two kinds of surfaces:
-
- - fast surfaces, whose content can be placed in video memory or
- RLE-compressed for faster blitting and blending. the pixel format
- used internally might be something very different from ARGB32.
-
- - slow surfaces, whose content (pixel buffer) can be accessed and modified
- with _lock()/_unlock() but may be blitted far slower since they reside in
- system memory.
-*/
-
-/* create a 'fast' surface that contains a copy of an input ARGB32 pixmap */
-extern SkinSurface* skin_surface_create_fast( int w, int h );
-
-/* create an empty 'slow' surface containing an ARGB32 pixmap */
-extern SkinSurface* skin_surface_create_slow( int w, int h );
-
-/* create a 'slow' surface from a given pixel buffer. if 'do_copy' is TRUE, then
- * the content of 'pixels' is copied into a heap-allocated buffer. otherwise
- * the data will be used directly.
- */
-extern SkinSurface* skin_surface_create_argb32_from(
- int w,
- int h,
- int pitch,
- uint32_t* pixels,
- int do_copy );
-
-/* surface pixels information for slow surfaces */
-typedef struct {
- int w;
- int h;
- int pitch;
- uint32_t* pixels;
-} SkinSurfacePixels;
-
-/* lock a slow surface, and returns its pixel information.
- returns 0 in case of success, -1 otherwise */
-extern int skin_surface_lock ( SkinSurface* s, SkinSurfacePixels *pix );
-
-/* unlock a slow surface that was previously locked */
-extern void skin_surface_unlock( SkinSurface* s );
-
-/* list of composition operators for the blit routine */
-typedef enum {
- SKIN_BLIT_COPY = 0,
- SKIN_BLIT_SRCOVER,
- SKIN_BLIT_DSTOVER,
-} SkinBlitOp;
-
-
-/* blit a surface into another one */
-extern void skin_surface_blit( SkinSurface* dst,
- SkinPos* dst_pos,
- SkinSurface* src,
- SkinRect* src_rect,
- SkinBlitOp blitop );
-
-/* blit a colored rectangle into a destination surface */
-extern void skin_surface_fill( SkinSurface* dst,
- SkinRect* rect,
- uint32_t argb_premul,
- SkinBlitOp blitop );
-
-#endif /* _ANDROID_SKIN_SURFACE_H */
diff --git a/android/skin/trackball.c b/android/skin/trackball.c
deleted file mode 100644
index b18923a..0000000
--- a/android/skin/trackball.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/trackball.h"
-#include "android/skin/image.h"
-#include "android/utils/system.h"
-#include <math.h>
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** T R A C K B A L L *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-// a 3-d vector
-typedef double VectorRec[3];
-typedef double* Vector;
-
-/* define FIX16_IS_FLOAT to use floats for computations */
-#define FIX16_IS_FLOAT
-
-#ifdef FIX16_IS_FLOAT
-typedef float Fix16;
-#define FIX16_ONE 1.0
-#define FIX16_FROM_FLOAT(x) (x)
-#define FIX16_TO_FLOAT(x) (x)
-
-#else
-typedef int Fix16;
-
-#define FIX16_SHIFT 16
-#define FIX16_ONE (1 << FIX16_SHIFT)
-#define FIX16_FROM_FLOAT(x) (Fix16)((x) * FIX16_ONE)
-#define FIX16_TO_FLOAT(x) ((x)/(1.0*FIX16_ONE))
-
-#endif
-
-typedef Fix16 Fix16VectorRec[3];
-typedef Fix16* Fix16Vector;
-
-static Fix16
-fixedvector_len( Fix16Vector v )
-{
- double x = FIX16_TO_FLOAT(v[0]);
- double y = FIX16_TO_FLOAT(v[1]);
- double z = FIX16_TO_FLOAT(v[2]);
- double len = sqrt( x*x + y*y + z*z );
-
- return FIX16_FROM_FLOAT(len);
-}
-
-static void
-fixedvector_from_vector( Fix16Vector f, Vector v )
-{
- f[0] = FIX16_FROM_FLOAT(v[0]);
- f[1] = FIX16_FROM_FLOAT(v[1]);
- f[2] = FIX16_FROM_FLOAT(v[2]);
-}
-
-
-#ifdef FIX16_IS_FLOAT
-static double
-fixedvector_dot( Fix16Vector u, Fix16Vector v )
-{
- return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
-}
-#else
-static Fix16
-fixedvector_dot( Fix16Vector u, Fix16Vector v )
-{
- long long t;
-
- t = (long long)u[0] * v[0] + (long long)u[1] * v[1] + (long long)u[2] * v[2];
- return (Fix16)(t >> FIX16_SHIFT);
-}
-#endif
-
-static int
-norm( int dx, int dy )
-{
- return (int) sqrt( dx*1.0*dx + dy*1.0*dy );
-}
-
-/*** ROTATOR: used to rotate the reference axis when mouse motion happens
- ***/
-
-typedef struct
-{
- VectorRec d;
- VectorRec n;
- double angle;
-
-} RotatorRec, *Rotator;
-
-
-#define ANGLE_FACTOR (M_PI/200)
-
-static void
-rotator_reset( Rotator rot, int dx, int dy )
-{
- double len = sqrt( dx*dx + dy*dy );
- double zx, zy;
-
- if (len < 1e-3 ) {
- zx = 1.;
- zy = 0;
- } else {
- zx = dx / len;
- zy = dy / len;
- }
- rot->d[0] = zx;
- rot->d[1] = zy;
- rot->d[2] = 0.;
-
- rot->n[0] = -rot->d[1];
- rot->n[1] = rot->d[0];
- rot->n[2] = 0;
-
- rot->angle = len * ANGLE_FACTOR;
-}
-
-static void
-rotator_apply( Rotator rot, double* vec )
-{
- double d, n, z, d2, z2, cs, sn;
-
- /* project on D, N, Z */
- d = vec[0]*rot->d[0] + vec[1]*rot->d[1];
- n = vec[0]*rot->n[0] + vec[1]*rot->n[1];
- z = vec[2];
-
- /* rotate on D, Z */
- cs = cos( rot->angle );
- sn = sin( rot->angle );
-
- d2 = cs*d + sn*z;
- z2 = -sn*d + cs*z;
-
- /* project on X, Y, Z */
- vec[0] = d2*rot->d[0] + n*rot->n[0];
- vec[1] = d2*rot->d[1] + n*rot->n[1];
- vec[2] = z2;
-}
-
-/*** TRACKBALL OBJECT
- ***/
-typedef struct { int x, y, offset, alpha; Fix16VectorRec f; } SphereCoordRec, *SphereCoord;
-
-typedef struct SkinTrackBall
-{
- int diameter;
- unsigned* pixels;
- SDL_Surface* surface;
- VectorRec axes[3]; /* current ball axes */
-
-#define DOT_GRID 3 /* number of horizontal and vertical cells per side grid */
-#define DOT_CELLS 2 /* number of random dots per cell */
-#define DOT_MAX (6*DOT_GRID*DOT_GRID*DOT_CELLS) /* total number of dots */
-#define DOT_RANDOM_X 1007 /* horizontal random range in each cell */
-#define DOT_RANDOM_Y 1007 /* vertical random range in each cell */
-
-#define DOT_THRESHOLD FIX16_FROM_FLOAT(0.17)
-
- Fix16VectorRec dots[ DOT_MAX ];
-
- SphereCoordRec* sphere_map;
- int sphere_count;
-
- unsigned ball_color;
- unsigned dot_color;
- unsigned ring_color;
-
- Uint32 ticks_last; /* ticks since last move */
- int acc_x;
- int acc_y;
- int acc_threshold;
- double acc_scale;
-
- /* rotation applied to events send to the system */
- SkinRotation rotation;
-
-} TrackBallRec, *TrackBall;
-
-
-/* The following constants are used to better mimic a real trackball.
- *
- * ACC_THRESHOLD is used to filter small ball movements out.
- * If the length of the relative mouse motion is smaller than this
- * constant, then no corresponding ball event will be sent to the
- * system.
- *
- * ACC_SCALE is used to scale the relative mouse motion vector into
- * the corresponding ball motion vector.
- */
-#define ACC_THRESHOLD 20
-#define ACC_SCALE 0.2
-
-static void
-trackball_init( TrackBall ball, int diameter, int ring,
- unsigned ball_color, unsigned dot_color,
- unsigned ring_color )
-{
- int diameter2 = diameter + ring*2;
-
- memset( ball, 0, sizeof(*ball) );
-
- ball->acc_threshold = ACC_THRESHOLD;
- ball->acc_scale = ACC_SCALE;
-
- /* init SDL surface */
- ball->diameter = diameter2;
- ball->ball_color = ball_color;
- ball->dot_color = dot_color;
- ball->ring_color = ring_color;
-
- ball->rotation = SKIN_ROTATION_0;
-
- ball->pixels = (unsigned*)calloc( diameter2*diameter2, sizeof(unsigned) );
- ball->surface = sdl_surface_from_argb32( ball->pixels, diameter2, diameter2 );
-
- /* init axes */
- ball->axes[0][0] = 1.; ball->axes[0][1] = 0.; ball->axes[0][2] = 0.;
- ball->axes[1][0] = 0.; ball->axes[1][1] = 1.; ball->axes[1][2] = 0.;
- ball->axes[2][0] = 0.; ball->axes[2][1] = 0.; ball->axes[2][2] = 1.;
-
- /* init dots */
- {
- int side, nn = 0;
-
- for (side = 0; side < 6; side++) {
- VectorRec origin, axis1, axis2;
- int xx, yy;
-
- switch (side) {
- case 0:
- origin[0] = -1; origin[1] = -1; origin[2] = +1;
- axis1 [0] = 1; axis1 [1] = 0; axis1 [2] = 0;
- axis2 [0] = 0; axis2 [1] = 1; axis2 [2] = 0;
- break;
- case 1:
- origin[0] = -1; origin[1] = -1; origin[2] = -1;
- axis1 [0] = 1; axis1 [1] = 0; axis1 [2] = 0;
- axis2 [0] = 0; axis2 [1] = 1; axis2 [2] = 0;
- break;
- case 2:
- origin[0] = +1; origin[1] = -1; origin[2] = -1;
- axis1 [0] = 0; axis1 [1] = 0; axis1 [2] = 1;
- axis2 [0] = 0; axis2 [1] = 1; axis2 [2] = 0;
- break;
- case 3:
- origin[0] = -1; origin[1] = -1; origin[2] = -1;
- axis1 [0] = 0; axis1 [1] = 0; axis1 [2] = 1;
- axis2 [0] = 0; axis2 [1] = 1; axis2 [2] = 0;
- break;
- case 4:
- origin[0] = -1; origin[1] = -1; origin[2] = -1;
- axis1 [0] = 1; axis1 [1] = 0; axis1 [2] = 0;
- axis2 [0] = 0; axis2 [1] = 0; axis2 [2] = 1;
- break;
- default:
- origin[0] = -1; origin[1] = +1; origin[2] = -1;
- axis1 [0] = 1; axis1 [1] = 0; axis1 [2] = 0;
- axis2 [0] = 0; axis2 [1] = 0; axis2 [2] = 1;
- }
-
- for (xx = 0; xx < DOT_GRID; xx++) {
- double tx = xx*(2./DOT_GRID);
- for (yy = 0; yy < DOT_GRID; yy++) {
- double ty = yy*(2./DOT_GRID);
- double x0 = origin[0] + axis1[0]*tx + axis2[0]*ty;
- double y0 = origin[1] + axis1[1]*tx + axis2[1]*ty;
- double z0 = origin[2] + axis1[2]*tx + axis2[2]*ty;
- int cc;
- for (cc = 0; cc < DOT_CELLS; cc++) {
- double h = (rand() % DOT_RANDOM_X)/((double)DOT_RANDOM_X*DOT_GRID/2);
- double v = (rand() % DOT_RANDOM_Y)/((double)DOT_RANDOM_Y*DOT_GRID/2);
- double x = x0 + axis1[0]*h + axis2[0]*v;
- double y = y0 + axis1[1]*h + axis2[1]*v;
- double z = z0 + axis1[2]*h + axis2[2]*v;
- double invlen = 1/sqrt( x*x + y*y + z*z );
-
- ball->dots[nn][0] = FIX16_FROM_FLOAT(x*invlen);
- ball->dots[nn][1] = FIX16_FROM_FLOAT(y*invlen);
- ball->dots[nn][2] = FIX16_FROM_FLOAT(z*invlen);
- nn++;
- }
- }
- }
- }
- }
-
- /* init sphere */
- {
- int diameter2 = diameter + 2*ring;
- double radius = diameter*0.5;
- double radius2 = diameter2*0.5;
- int xx, yy;
- int empty = 0, total = 0;
-
- ball->sphere_map = calloc( diameter2*diameter2, sizeof(SphereCoordRec) );
-
- for (yy = 0; yy < diameter2; yy++) {
- for (xx = 0; xx < diameter2; xx++) {
- double x0 = xx - radius2;
- double y0 = yy - radius2;
- double r0 = sqrt( x0*x0 + y0*y0 );
- SphereCoord coord = &ball->sphere_map[total];
-
- if (r0 <= radius) { /* ball pixel */
- double rx = x0/radius;
- double ry = y0/radius;
- double rz = sqrt( 1.0 - rx*rx - ry*ry );
-
- coord->x = xx;
- coord->y = yy;
- coord->offset = xx + yy*diameter2;
- coord->alpha = 256;
- coord->f[0] = FIX16_FROM_FLOAT(rx);
- coord->f[1] = FIX16_FROM_FLOAT(ry);
- coord->f[2] = FIX16_FROM_FLOAT(rz);
- if (r0 >= radius-1.) {
- coord->alpha = 256*(radius - r0);
- }
- /* illumination model */
- {
-#define LIGHT_X -2.0
-#define LIGHT_Y -2.5
-#define LIGHT_Z 5.0
-
- double lx = LIGHT_X - rx;
- double ly = LIGHT_Y - ry;
- double lz = LIGHT_Z - rz;
- double lir = 1/sqrt(lx*lx + ly*ly + lz*lz);
- double cosphi = lir*(lx*rx + ly*ry + lz*rz);
- double scale = 1.1*cosphi + 0.3;
-
- if (scale < 0)
- scale = 0;
-
- coord->alpha = coord->alpha * scale;
- }
- total++;
- } else if (r0 <= radius2) { /* ring pixel */
- coord->x = xx;
- coord->y = yy;
- coord->offset = xx + yy*diameter2;
- coord->alpha = 0;
- if (r0 >= radius2-1.) {
- coord->alpha = -256*(r0 - (radius2-1.));
- }
- total++;
-
- } else /* outside pixel */
- empty++;
- }
- }
- ball->sphere_count = total;
- }
-}
-
-static int
-trackball_contains( TrackBall ball, int x, int y )
-{
- return ( (unsigned)(x) < (unsigned)ball->diameter &&
- (unsigned)(y) < (unsigned)ball->diameter );
-}
-
-static void
-trackball_done( TrackBall ball )
-{
- free( ball->sphere_map );
- ball->sphere_map = NULL;
- ball->sphere_count = 0;
-
- if (ball->surface) {
- SDL_FreeSurface( ball->surface );
- ball->surface = NULL;
- }
-
- if (ball->pixels) {
- free( ball->pixels );
- ball->pixels = NULL;
- }
-}
-
-/*** TRACKBALL SPHERE PIXELS
- ***/
-static unsigned
-color_blend( unsigned from, unsigned to, int alpha )
-{
- unsigned from_ag = (from >> 8) & 0x00ff00ff;
- unsigned to_ag = (to >> 8) & 0x00ff00ff;
- unsigned from_rb = from & 0x00ff00ff;
- unsigned to_rb = to & 0x00ff00ff;
- unsigned result_ag = (from_ag + (alpha*(to_ag - from_ag) >> 8)) & 0xff00ff;
- unsigned result_rb = (from_rb + (alpha*(to_rb - from_rb) >> 8)) & 0xff00ff;
-
- return (result_ag << 8) | result_rb;
-}
-
-static int
-trackball_move( TrackBall ball, int dx, int dy )
-{
- RotatorRec rot[1];
- Uint32 now = SDL_GetTicks();
-
- ball->acc_x += dx;
- ball->acc_y += dy;
-
- if ( norm( ball->acc_x, ball->acc_y ) > ball->acc_threshold )
- {
- int ddx = ball->acc_x * ball->acc_scale;
- int ddy = ball->acc_y * ball->acc_scale;
- int ddt;
-
- ball->acc_x = 0;
- ball->acc_y = 0;
-
- switch (ball->rotation) {
- case SKIN_ROTATION_0:
- break;
-
- case SKIN_ROTATION_90:
- ddt = ddx;
- ddx = ddy;
- ddy = -ddt;
- break;
-
- case SKIN_ROTATION_180:
- ddx = -ddx;
- ddy = -ddy;
- break;
-
- case SKIN_ROTATION_270:
- ddt = ddx;
- ddx = -ddy;
- ddy = ddt;
- break;
- }
-
- kbd_mouse_event(ddx, ddy, 1, 0);
- }
-
- rotator_reset( rot, dx, dy );
- rotator_apply( rot, ball->axes[0] );
- rotator_apply( rot, ball->axes[1] );
- rotator_apply( rot, ball->axes[2] );
-
- if ( ball->ticks_last == 0 )
- ball->ticks_last = now;
- else if ( now > ball->ticks_last + (1000/60) ) {
- ball->ticks_last = now;
- return 1;
- }
- return 0;
-}
-
-#define BACK_COLOR 0x00000000
-#define LIGHT_COLOR 0xffffffff
-
-static void
-trackball_refresh( TrackBall ball )
-{
- int diameter = ball->diameter;
- unsigned* pixels = ball->pixels;
- Fix16VectorRec faxes[3];
- Fix16 dot_threshold = DOT_THRESHOLD * diameter;
- int nn;
-
- SDL_LockSurface( ball->surface );
-
- fixedvector_from_vector( (Fix16Vector)&faxes[0], (Vector)&ball->axes[0] );
- fixedvector_from_vector( (Fix16Vector)&faxes[1], (Vector)&ball->axes[1] );
- fixedvector_from_vector( (Fix16Vector)&faxes[2], (Vector)&ball->axes[2] );
-
- for (nn = 0; nn < ball->sphere_count; nn++) {
- SphereCoord coord = &ball->sphere_map[nn];
- unsigned color = BACK_COLOR;
-
- if (coord->alpha > 0) {
- /* are we near one of the points ? */
- Fix16 ax = fixedvector_dot( (Fix16Vector)&coord->f, (Fix16Vector)&faxes[0] );
- Fix16 ay = fixedvector_dot( (Fix16Vector)&coord->f, (Fix16Vector)&faxes[1] );
- Fix16 az = fixedvector_dot( (Fix16Vector)&coord->f, (Fix16Vector)&faxes[2] );
-
- Fix16 best_dist = FIX16_ONE;
- int pp;
-
- color = ball->ball_color;
-
- for (pp = 0; pp < DOT_MAX; pp++) {
- Fix16VectorRec d;
- Fix16 dist;
-
- d[0] = ball->dots[pp][0] - ax;
- d[1] = ball->dots[pp][1] - ay;
- d[2] = ball->dots[pp][2] - az;
-
- if (d[0] > dot_threshold || d[0] < -dot_threshold ||
- d[1] > dot_threshold || d[1] < -dot_threshold ||
- d[2] > dot_threshold || d[2] < -dot_threshold )
- continue;
-
- dist = fixedvector_len( (Fix16Vector)&d );
-
- if (dist < best_dist)
- best_dist = dist;
- }
- if (best_dist < DOT_THRESHOLD) {
- int a = 256*(DOT_THRESHOLD - best_dist) / DOT_THRESHOLD;
- color = color_blend( color, ball->dot_color, a );
- }
-
- if (coord->alpha < 256) {
- int a = coord->alpha;
- color = color_blend( ball->ring_color, color, a );
- }
- else if (coord->alpha > 256) {
- int a = (coord->alpha - 256);
- color = color_blend( color, LIGHT_COLOR, a );
- }
- }
- else /* coord->alpha <= 0 */
- {
- color = ball->ring_color;
-
- if (coord->alpha < 0) {
- int a = -coord->alpha;
- color = color_blend( color, BACK_COLOR, a );
- }
- }
-
- pixels[coord->x + diameter*coord->y] = color;
- }
- SDL_UnlockSurface( ball->surface );
-}
-
-void
-trackball_draw( TrackBall ball, int x, int y, SDL_Surface* dst )
-{
- SDL_Rect d;
-
- d.x = x;
- d.y = y;
- d.w = ball->diameter;
- d.h = ball->diameter;
-
- SDL_BlitSurface( ball->surface, NULL, dst, &d );
- SDL_UpdateRects( dst, 1, &d );
-}
-
-
-SkinTrackBall*
-skin_trackball_create ( SkinTrackBallParameters* params )
-{
- TrackBall ball;
-
- ANEW0(ball);
- trackball_init( ball,
- params->diameter,
- params->ring,
- params->ball_color,
- params->dot_color,
- params->ring_color );
- return ball;
-}
-
-int
-skin_trackball_contains( SkinTrackBall* ball, int x, int y )
-{
- return trackball_contains(ball, x, y);
-}
-
-int
-skin_trackball_move( SkinTrackBall* ball, int dx, int dy )
-{
- return trackball_move(ball, dx, dy);
-}
-
-void
-skin_trackball_refresh ( SkinTrackBall* ball )
-{
- trackball_refresh(ball);
-}
-
-void
-skin_trackball_draw( SkinTrackBall* ball, int x, int y, SDL_Surface* dst )
-{
- trackball_draw(ball, x, y, dst);
-}
-
-void
-skin_trackball_destroy ( SkinTrackBall* ball )
-{
- if (ball) {
- trackball_done(ball);
- AFREE(ball);
- }
-}
-
-void
-skin_trackball_rect( SkinTrackBall* ball, SDL_Rect* rect )
-{
- rect->x = 0;
- rect->y = 0;
- rect->w = ball->diameter;
- rect->h = ball->diameter;
-}
-
-
-void
-skin_trackball_set_rotation( SkinTrackBall* ball, SkinRotation rotation )
-{
- ball->rotation = rotation & 3;
-}
diff --git a/android/skin/trackball.h b/android/skin/trackball.h
deleted file mode 100644
index 06aa606..0000000
--- a/android/skin/trackball.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_SKIN_TRACKBALL_H
-#define _ANDROID_SKIN_TRACKBALL_H
-
-#include <SDL.h>
-#include "android/skin/rect.h"
-
-typedef struct SkinTrackBall SkinTrackBall;
-
-typedef struct SkinTrackBallParameters
-{
- int diameter;
- int ring;
- unsigned ball_color;
- unsigned dot_color;
- unsigned ring_color;
-}
-SkinTrackBallParameters;
-
-
-extern SkinTrackBall* skin_trackball_create ( SkinTrackBallParameters* params );
-extern void skin_trackball_rect ( SkinTrackBall* ball, SDL_Rect* rect );
-extern int skin_trackball_contains( SkinTrackBall* ball, int x, int y );
-extern int skin_trackball_move ( SkinTrackBall* ball, int dx, int dy );
-extern void skin_trackball_refresh ( SkinTrackBall* ball );
-extern void skin_trackball_draw ( SkinTrackBall* ball, int x, int y, SDL_Surface* dst );
-extern void skin_trackball_destroy ( SkinTrackBall* ball );
-
-/* this sets the rotation that will be applied to mouse events sent to the system */
-extern void skin_trackball_set_rotation( SkinTrackBall* ball, SkinRotation rotation);
-
-#endif /* END */
-
diff --git a/android/skin/window.c b/android/skin/window.c
deleted file mode 100644
index 6612ffe..0000000
--- a/android/skin/window.c
+++ /dev/null
@@ -1,1516 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/skin/window.h"
-#include "android/skin/image.h"
-#include "android/skin/scaler.h"
-#include "android/charmap.h"
-#include "android/utils/debug.h"
-#include "android/utils/display.h"
-#include <SDL_syswm.h>
-#include "qemu-common.h"
-#include <math.h>
-
-#include "framebuffer.h"
-
-/* when shrinking, we reduce the pixel ratio by this fixed amount */
-#define SHRINK_SCALE 0.6
-
-/* maximum value of LCD brighness */
-#define LCD_BRIGHTNESS_MIN 0
-#define LCD_BRIGHTNESS_DEFAULT 128
-#define LCD_BRIGHTNESS_MAX 255
-
-typedef struct Background {
- SkinImage* image;
- SkinRect rect;
- SkinPos origin;
-} Background;
-
-static void
-background_done( Background* back )
-{
- skin_image_unref( &back->image );
-}
-
-static void
-background_init( Background* back, SkinBackground* sback, SkinLocation* loc, SkinRect* frame )
-{
- SkinRect r;
-
- back->image = skin_image_rotate( sback->image, loc->rotation );
- skin_rect_rotate( &r, &sback->rect, loc->rotation );
- r.pos.x += loc->anchor.x;
- r.pos.y += loc->anchor.y;
-
- back->origin = r.pos;
- skin_rect_intersect( &back->rect, &r, frame );
-}
-
-static void
-background_redraw( Background* back, SkinRect* rect, SDL_Surface* surface )
-{
- SkinRect r;
-
- if (skin_rect_intersect( &r, rect, &back->rect ) )
- {
- SDL_Rect rd, rs;
-
- rd.x = r.pos.x;
- rd.y = r.pos.y;
- rd.w = r.size.w;
- rd.h = r.size.h;
-
- rs.x = r.pos.x - back->origin.x;
- rs.y = r.pos.y - back->origin.y;
- rs.w = r.size.w;
- rs.h = r.size.h;
-
- SDL_BlitSurface( skin_image_surface(back->image), &rs, surface, &rd );
- //SDL_UpdateRects( surface, 1, &rd );
- }
-}
-
-
-typedef struct ADisplay {
- SkinRect rect;
- SkinPos origin;
- SkinRotation rotation;
- SkinSize datasize; /* framebuffer size */
- void* data; /* framebuffer pixels */
- QFrameBuffer* qfbuff;
- SkinImage* onion; /* onion image */
- SkinRect onion_rect; /* onion rect, if any */
- int brightness;
-} ADisplay;
-
-static void
-display_done( ADisplay* disp )
-{
- disp->data = NULL;
- disp->qfbuff = NULL;
- skin_image_unref( &disp->onion );
-}
-
-static int
-display_init( ADisplay* disp, SkinDisplay* sdisp, SkinLocation* loc, SkinRect* frame )
-{
- skin_rect_rotate( &disp->rect, &sdisp->rect, loc->rotation );
- disp->rect.pos.x += loc->anchor.x;
- disp->rect.pos.y += loc->anchor.y;
-
- disp->rotation = (loc->rotation + sdisp->rotation) & 3;
- switch (disp->rotation) {
- case SKIN_ROTATION_0:
- disp->origin = disp->rect.pos;
- break;
-
- case SKIN_ROTATION_90:
- disp->origin.x = disp->rect.pos.x + disp->rect.size.w;
- disp->origin.y = disp->rect.pos.y;
- break;
-
- case SKIN_ROTATION_180:
- disp->origin.x = disp->rect.pos.x + disp->rect.size.w;
- disp->origin.y = disp->rect.pos.y + disp->rect.size.h;
- break;
-
- default:
- disp->origin.x = disp->rect.pos.x;
- disp->origin.y = disp->rect.pos.y + disp->rect.size.h;
- break;
- }
- skin_size_rotate( &disp->datasize, &sdisp->rect.size, sdisp->rotation );
- skin_rect_intersect( &disp->rect, &disp->rect, frame );
-#if 0
- fprintf(stderr, "... display_init rect.pos(%d,%d) rect.size(%d,%d) datasize(%d,%d)\n",
- disp->rect.pos.x, disp->rect.pos.y,
- disp->rect.size.w, disp->rect.size.h,
- disp->datasize.w, disp->datasize.h);
-#endif
- disp->qfbuff = sdisp->qfbuff;
- disp->data = sdisp->qfbuff->pixels;
- disp->onion = NULL;
-
- disp->brightness = LCD_BRIGHTNESS_DEFAULT;
-
- return (disp->data == NULL) ? -1 : 0;
-}
-
-static __inline__ uint32_t rgb565_to_argb32( uint32_t pix )
-{
- uint32_t r = ((pix & 0xf800) << 8) | ((pix & 0xe000) << 3);
- uint32_t g = ((pix & 0x07e0) << 5) | ((pix & 0x0600) >> 1);
- uint32_t b = ((pix & 0x001f) << 3) | ((pix & 0x001c) >> 2);
-
- return 0xff000000 | r | g | b;
-}
-
-
-static void
-display_set_onion( ADisplay* disp, SkinImage* onion, SkinRotation rotation, int blend )
-{
- int onion_w, onion_h;
- SkinRect* rect = &disp->rect;
- SkinRect* orect = &disp->onion_rect;
-
- rotation = (rotation + disp->rotation) & 3;
-
- skin_image_unref( &disp->onion );
- disp->onion = skin_image_clone_full( onion, rotation, blend );
-
- onion_w = skin_image_w(disp->onion);
- onion_h = skin_image_h(disp->onion);
-
- switch (rotation) {
- case SKIN_ROTATION_0:
- orect->pos = rect->pos;
- break;
-
- case SKIN_ROTATION_90:
- orect->pos.x = rect->pos.x + rect->size.w - onion_w;
- orect->pos.y = rect->pos.y;
- break;
-
- case SKIN_ROTATION_180:
- orect->pos.x = rect->pos.x + rect->size.w - onion_w;
- orect->pos.y = rect->pos.y + rect->size.h - onion_h;
- break;
-
- default:
- orect->pos.x = rect->pos.x;
- orect->pos.y = rect->pos.y + rect->size.h - onion_h;
- }
- orect->size.w = onion_w;
- orect->size.h = onion_h;
-}
-
-#define DOT_MATRIX 0
-
-#if DOT_MATRIX
-
-static void
-dotmatrix_dither_argb32( unsigned char* pixels, int x, int y, int w, int h, int pitch )
-{
- static const unsigned dotmatrix_argb32[16] = {
- 0x003f00, 0x00003f, 0x3f0000, 0x000000,
- 0x3f3f3f, 0x000000, 0x3f3f3f, 0x000000,
- 0x3f0000, 0x000000, 0x003f00, 0x00003f,
- 0x3f3f3f, 0x000000, 0x3f3f3f, 0x000000
- };
-
- int yy = y & 3;
-
- pixels += 4*x + y*pitch;
-
- for ( ; h > 0; h-- ) {
- unsigned* line = (unsigned*) pixels;
- int nn, xx = x & 3;
-
- for (nn = 0; nn < w; nn++) {
- unsigned c = line[nn];
-
- c = c - ((c >> 2) & dotmatrix_argb32[(yy << 2)|xx]);
-
- xx = (xx + 1) & 3;
- line[nn] = c;
- }
-
- yy = (yy + 1) & 3;
- pixels += pitch;
- }
-}
-
-#endif /* DOT_MATRIX */
-
-/* technical note about the lightness emulation
- *
- * we try to emulate something that looks like the Dream's
- * non-linear LCD lightness, without going too dark or bright.
- *
- * the default lightness is around 105 (about 40%) and we prefer
- * to keep full RGB colors at that setting, to not alleviate
- * developers who will not understand why the emulator's colors
- * look slightly too dark.
- *
- * we also want to implement a 'bright' mode by de-saturating
- * colors towards bright white.
- *
- * All of this leads to the implementation below that looks like
- * the following:
- *
- * if (level == MIN)
- * screen is off
- *
- * if (level > MIN && level < LOW)
- * interpolate towards black, with
- * MINALPHA = 0.2
- * alpha = MINALPHA + (1-MINALPHA)*(level-MIN)/(LOW-MIN)
- *
- * if (level >= LOW && level <= HIGH)
- * keep full RGB colors
- *
- * if (level > HIGH)
- * interpolate towards bright white, with
- * MAXALPHA = 0.6
- * alpha = MAXALPHA*(level-HIGH)/(MAX-HIGH)
- *
- * we probably want some sort of power law instead of interpolating
- * linearly, but frankly, this is sufficient for most uses.
- */
-
-#define LCD_BRIGHTNESS_LOW 80
-#define LCD_BRIGHTNESS_HIGH 180
-
-#define LCD_ALPHA_LOW_MIN 0.2
-#define LCD_ALPHA_HIGH_MAX 0.6
-
-/* treat as special value to turn screen off */
-#define LCD_BRIGHTNESS_OFF LCD_BRIGHTNESS_MIN
-
-static void
-lcd_brightness_argb32( unsigned char* pixels, SkinRect* r, int pitch, int brightness )
-{
- const unsigned b_min = LCD_BRIGHTNESS_MIN;
- const unsigned b_max = LCD_BRIGHTNESS_MAX;
- const unsigned b_low = LCD_BRIGHTNESS_LOW;
- const unsigned b_high = LCD_BRIGHTNESS_HIGH;
-
- unsigned alpha = brightness;
- int w = r->size.w;
- int h = r->size.h;
-
- if (alpha <= b_min)
- alpha = b_min;
- else if (alpha > b_max)
- alpha = b_max;
-
- pixels += 4*r->pos.x + r->pos.y*pitch;
-
- if (alpha < b_low)
- {
- const unsigned alpha_min = (255*LCD_ALPHA_LOW_MIN);
- const unsigned alpha_range = (255 - alpha_min);
-
- alpha = alpha_min + ((alpha - b_min)*alpha_range) / (b_low - b_min);
-
- for ( ; h > 0; h-- ) {
- unsigned* line = (unsigned*) pixels;
- int nn;
-
- for (nn = 0; nn < w; nn++) {
- unsigned c = line[nn];
- unsigned ag = (c >> 8) & 0x00ff00ff;
- unsigned rb = (c) & 0x00ff00ff;
-
- ag = (ag*alpha) & 0xff00ff00;
- rb = ((rb*alpha) >> 8) & 0x00ff00ff;
-
- line[nn] = (unsigned)(ag | rb);
- }
- pixels += pitch;
- }
- }
- else if (alpha > LCD_BRIGHTNESS_HIGH) /* 'superluminous' mode */
- {
- const unsigned alpha_max = (255*LCD_ALPHA_HIGH_MAX);
- const unsigned alpha_range = (255-alpha_max);
- unsigned ialpha;
-
- alpha = ((alpha - b_high)*alpha_range) / (b_max - b_high);
- ialpha = 255-alpha;
-
- for ( ; h > 0; h-- ) {
- unsigned* line = (unsigned*) pixels;
- int nn;
-
- for (nn = 0; nn < w; nn++) {
- unsigned c = line[nn];
- unsigned ag = (c >> 8) & 0x00ff00ff;
- unsigned rb = (c) & 0x00ff00ff;
-
- /* interpolate towards bright white, i.e. 0x00ffffff */
- ag = ((ag*ialpha + 0x00ff00ff*alpha)) & 0xff00ff00;
- rb = ((rb*ialpha + 0x00ff00ff*alpha) >> 8) & 0x00ff00ff;
-
- line[nn] = (unsigned)(ag | rb);
- }
- pixels += pitch;
- }
- }
-}
-
-
-/* this is called when the LCD framebuffer is off */
-static void
-lcd_off_argb32( unsigned char* pixels, SkinRect* r, int pitch )
-{
- int x = r->pos.x;
- int y = r->pos.y;
- int w = r->size.w;
- int h = r->size.h;
-
- pixels += 4*x + y*pitch;
- for ( ; h > 0; h-- ) {
- memset( pixels, 0, w*4 );
- pixels += pitch;
- }
-}
-
-
-static void
-display_redraw( ADisplay* disp, SkinRect* rect, SDL_Surface* surface )
-{
- SkinRect r;
-
- if (skin_rect_intersect( &r, rect, &disp->rect ))
- {
- int x = r.pos.x - disp->rect.pos.x;
- int y = r.pos.y - disp->rect.pos.y;
- int w = r.size.w;
- int h = r.size.h;
- int disp_w = disp->rect.size.w;
- int disp_h = disp->rect.size.h;
- int dst_pitch = surface->pitch;
- uint8_t* dst_line = (uint8_t*)surface->pixels + r.pos.x*4 + r.pos.y*dst_pitch;
- int src_pitch = disp->datasize.w*2;
- uint8_t* src_line = (uint8_t*)disp->data;
- int yy, xx;
-#if 0
- fprintf(stderr, "--- display redraw r.pos(%d,%d) r.size(%d,%d) "
- "disp.pos(%d,%d) disp.size(%d,%d) datasize(%d,%d) rect.pos(%d,%d) rect.size(%d,%d)\n",
- r.pos.x - disp->rect.pos.x, r.pos.y - disp->rect.pos.y, w, h, disp->rect.pos.x, disp->rect.pos.y,
- disp->rect.size.w, disp->rect.size.h, disp->datasize.w, disp->datasize.h,
- rect->pos.x, rect->pos.y, rect->size.w, rect->size.h );
-#endif
- SDL_LockSurface( surface );
-
- if (disp->brightness == LCD_BRIGHTNESS_OFF)
- {
- lcd_off_argb32( surface->pixels, &r, dst_pitch );
- }
- else
- {
- switch ( disp->rotation & 3 )
- {
- case ANDROID_ROTATION_0:
- src_line += x*2 + y*src_pitch;
-
- for (yy = h; yy > 0; yy--)
- {
- uint32_t* dst = (uint32_t*)dst_line;
- uint16_t* src = (uint16_t*)src_line;
-
- for (xx = 0; xx < w; xx++) {
- dst[xx] = rgb565_to_argb32(src[xx]);
- }
- src_line += src_pitch;
- dst_line += dst_pitch;
- }
- break;
-
- case ANDROID_ROTATION_90:
- src_line += y*2 + (disp_w - x - 1)*src_pitch;
-
- for (yy = h; yy > 0; yy--)
- {
- uint32_t* dst = (uint32_t*)dst_line;
- uint8_t* src = src_line;
-
- for (xx = w; xx > 0; xx--)
- {
- dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
- src -= src_pitch;
- dst += 1;
- }
- src_line += 2;
- dst_line += dst_pitch;
- }
- break;
-
- case ANDROID_ROTATION_180:
- src_line += (disp_w -1 - x)*2 + (disp_h-1-y)*src_pitch;
-
- for (yy = h; yy > 0; yy--)
- {
- uint16_t* src = (uint16_t*)src_line;
- uint32_t* dst = (uint32_t*)dst_line;
-
- for (xx = w; xx > 0; xx--) {
- dst[0] = rgb565_to_argb32(src[0]);
- src -= 1;
- dst += 1;
- }
-
- src_line -= src_pitch;
- dst_line += dst_pitch;
- }
- break;
-
- default: /* ANDROID_ROTATION_270 */
- src_line += (disp_h-1-y)*2 + x*src_pitch;
-
- for (yy = h; yy > 0; yy--)
- {
- uint32_t* dst = (uint32_t*)dst_line;
- uint8_t* src = src_line;
-
- for (xx = w; xx > 0; xx--) {
- dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
- dst += 1;
- src += src_pitch;
- }
- src_line -= 2;
- dst_line += dst_pitch;
- }
- }
-#if DOT_MATRIX
- dotmatrix_dither_argb32( surface->pixels, r.pos.x, r.pos.y, r.size.w, r.size.h, surface->pitch );
-#endif
- /* apply lightness */
- lcd_brightness_argb32( surface->pixels, &r, surface->pitch, disp->brightness );
- }
- SDL_UnlockSurface( surface );
-
- /* Apply onion skin */
- if (disp->onion != NULL) {
- SkinRect r2;
-
- if ( skin_rect_intersect( &r2, &r, &disp->onion_rect ) ) {
- SDL_Rect rs, rd;
-
- rd.x = r2.pos.x;
- rd.y = r2.pos.y;
- rd.w = r2.size.w;
- rd.h = r2.size.h;
-
- rs.x = rd.x - disp->onion_rect.pos.x;
- rs.y = rd.y - disp->onion_rect.pos.y;
- rs.w = rd.w;
- rs.h = rd.h;
-
- SDL_BlitSurface( skin_image_surface(disp->onion), &rs, surface, &rd );
- }
- }
-
- SDL_UpdateRect( surface, r.pos.x, r.pos.y, w, h );
- }
-}
-
-
-typedef struct Button {
- SkinImage* image;
- SkinRect rect;
- SkinPos origin;
- Background* background;
- unsigned keycode;
- int down;
-} Button;
-
-static void
-button_done( Button* button )
-{
- skin_image_unref( &button->image );
- button->background = NULL;
-}
-
-static void
-button_init( Button* button, SkinButton* sbutton, SkinLocation* loc, Background* back, SkinRect* frame )
-{
- SkinRect r;
-
- button->image = skin_image_rotate( sbutton->image, loc->rotation );
- button->background = back;
- button->keycode = sbutton->keycode;
- button->down = 0;
-
- skin_rect_rotate( &r, &sbutton->rect, loc->rotation );
- r.pos.x += loc->anchor.x;
- r.pos.y += loc->anchor.y;
- button->origin = r.pos;
- skin_rect_intersect( &button->rect, &r, frame );
-}
-
-static void
-button_redraw( Button* button, SkinRect* rect, SDL_Surface* surface )
-{
- SkinRect r;
-
- if (skin_rect_intersect( &r, rect, &button->rect ))
- {
- if ( button->down && button->image != SKIN_IMAGE_NONE )
- {
- SDL_Rect rs, rd;
-
- rs.x = r.pos.x - button->origin.x;
- rs.y = r.pos.y - button->origin.y;
- rs.w = r.size.w;
- rs.h = r.size.h;
-
- rd.x = r.pos.x;
- rd.y = r.pos.y;
- rd.w = r.size.w;
- rd.h = r.size.h;
-
- if (button->image != SKIN_IMAGE_NONE) {
- SDL_BlitSurface( skin_image_surface(button->image), &rs, surface, &rd );
- if (button->down > 1)
- SDL_BlitSurface( skin_image_surface(button->image), &rs, surface, &rd );
- }
- }
- }
-}
-
-
-typedef struct {
- char tracking;
- char inside;
- SkinPos pos;
- ADisplay* display;
-} FingerState;
-
-static void
-finger_state_reset( FingerState* finger )
-{
- finger->tracking = 0;
- finger->inside = 0;
-}
-
-typedef struct {
- Button* pressed;
- Button* hover;
-} ButtonState;
-
-static void
-button_state_reset( ButtonState* button )
-{
- button->pressed = NULL;
- button->hover = NULL;
-}
-
-typedef struct {
- char tracking;
- SkinTrackBall* ball;
- SkinRect rect;
- SkinWindow* window;
-} BallState;
-
-static void
-ball_state_reset( BallState* state, SkinWindow* window )
-{
- state->tracking = 0;
- state->ball = NULL;
-
- state->rect.pos.x = 0;
- state->rect.pos.y = 0;
- state->rect.size.w = 0;
- state->rect.size.h = 0;
- state->window = window;
-}
-
-static void
-ball_state_redraw( BallState* state, SkinRect* rect, SDL_Surface* surface )
-{
- SkinRect r;
-
- if (skin_rect_intersect( &r, rect, &state->rect ))
- skin_trackball_draw( state->ball, 0, 0, surface );
-}
-
-static void
-ball_state_show( BallState* state, int enable )
-{
- if (enable) {
- if ( !state->tracking ) {
- state->tracking = 1;
- SDL_ShowCursor(0);
- SDL_WM_GrabInput( SDL_GRAB_ON );
- skin_trackball_refresh( state->ball );
- skin_window_redraw( state->window, &state->rect );
- }
- } else {
- if ( state->tracking ) {
- state->tracking = 0;
- SDL_WM_GrabInput( SDL_GRAB_OFF );
- SDL_ShowCursor(1);
- skin_window_redraw( state->window, &state->rect );
- }
- }
-}
-
-
-static void
-ball_state_set( BallState* state, SkinTrackBall* ball )
-{
- ball_state_show( state, 0 );
-
- state->ball = ball;
- if (ball != NULL) {
- SDL_Rect sr;
-
- skin_trackball_rect( ball, &sr );
- state->rect.pos.x = sr.x;
- state->rect.pos.y = sr.y;
- state->rect.size.w = sr.w;
- state->rect.size.h = sr.h;
- }
-}
-
-typedef struct Layout {
- int num_buttons;
- int num_backgrounds;
- int num_displays;
- unsigned color;
- Button* buttons;
- Background* backgrounds;
- ADisplay* displays;
- SkinRect rect;
- SkinLayout* slayout;
-} Layout;
-
-#define LAYOUT_LOOP_BUTTONS(layout,button) \
- do { \
- Button* __button = (layout)->buttons; \
- Button* __button_end = __button + (layout)->num_buttons; \
- for ( ; __button < __button_end; __button ++ ) { \
- Button* button = __button;
-
-#define LAYOUT_LOOP_END_BUTTONS \
- } \
- } while (0);
-
-#define LAYOUT_LOOP_DISPLAYS(layout,display) \
- do { \
- ADisplay* __display = (layout)->displays; \
- ADisplay* __display_end = __display + (layout)->num_displays; \
- for ( ; __display < __display_end; __display ++ ) { \
- ADisplay* display = __display;
-
-#define LAYOUT_LOOP_END_DISPLAYS \
- } \
- } while (0);
-
-
-static void
-layout_done( Layout* layout )
-{
- int nn;
-
- for (nn = 0; nn < layout->num_buttons; nn++)
- button_done( &layout->buttons[nn] );
-
- for (nn = 0; nn < layout->num_backgrounds; nn++)
- background_done( &layout->backgrounds[nn] );
-
- for (nn = 0; nn < layout->num_displays; nn++)
- display_done( &layout->displays[nn] );
-
- qemu_free( layout->buttons );
- layout->buttons = NULL;
-
- qemu_free( layout->backgrounds );
- layout->backgrounds = NULL;
-
- qemu_free( layout->displays );
- layout->displays = NULL;
-
- layout->num_buttons = 0;
- layout->num_backgrounds = 0;
- layout->num_displays = 0;
-}
-
-static int
-layout_init( Layout* layout, SkinLayout* slayout )
-{
- int n_buttons, n_backgrounds, n_displays;
-
- /* first, count the number of elements of each kind */
- n_buttons = 0;
- n_backgrounds = 0;
- n_displays = 0;
-
- layout->color = slayout->color;
- layout->slayout = slayout;
-
- SKIN_LAYOUT_LOOP_LOCS(slayout,loc)
- SkinPart* part = loc->part;
-
- if ( part->background->valid )
- n_backgrounds += 1;
- if ( part->display->valid )
- n_displays += 1;
-
- SKIN_PART_LOOP_BUTTONS(part, sbutton)
- n_buttons += 1;
- sbutton=sbutton;
- SKIN_PART_LOOP_END
- SKIN_LAYOUT_LOOP_END
-
- layout->num_buttons = n_buttons;
- layout->num_backgrounds = n_backgrounds;
- layout->num_displays = n_displays;
-
- /* now allocate arrays, then populate them */
- layout->buttons = qemu_mallocz( sizeof(Button) * n_buttons );
- layout->backgrounds = qemu_mallocz( sizeof(Background) * n_backgrounds );
- layout->displays = qemu_mallocz( sizeof(ADisplay) * n_displays );
-
- if (layout->buttons == NULL && n_buttons > 0) goto Fail;
- if (layout->backgrounds == NULL && n_backgrounds > 0) goto Fail;
- if (layout->displays == NULL && n_displays > 0) goto Fail;
-
- n_buttons = 0;
- n_backgrounds = 0;
- n_displays = 0;
-
- layout->rect.pos.x = 0;
- layout->rect.pos.y = 0;
- layout->rect.size = slayout->size;
-
- SKIN_LAYOUT_LOOP_LOCS(slayout,loc)
- SkinPart* part = loc->part;
- Background* back = NULL;
-
- if ( part->background->valid ) {
- back = layout->backgrounds + n_backgrounds;
- background_init( back, part->background, loc, &layout->rect );
- n_backgrounds += 1;
- }
- if ( part->display->valid ) {
- ADisplay* disp = layout->displays + n_displays;
- display_init( disp, part->display, loc, &layout->rect );
- n_displays += 1;
- }
-
- SKIN_PART_LOOP_BUTTONS(part, sbutton)
- Button* button = layout->buttons + n_buttons;
- button_init( button, sbutton, loc, back, &layout->rect );
- n_buttons += 1;
- SKIN_PART_LOOP_END
- SKIN_LAYOUT_LOOP_END
-
- return 0;
-
-Fail:
- layout_done(layout);
- return -1;
-}
-
-struct SkinWindow {
- SDL_Surface* surface;
- Layout layout;
- SkinPos pos;
- FingerState finger;
- ButtonState button;
- BallState ball;
- char enabled;
- char fullscreen;
- char no_display;
-
- char enable_touch;
- char enable_trackball;
- char enable_dpad;
- char enable_qwerty;
-
- SkinImage* onion;
- SkinRotation onion_rotation;
- int onion_alpha;
-
- int x_pos;
- int y_pos;
-
- SkinScaler* scaler;
- int shrink;
- double shrink_scale;
- unsigned* shrink_pixels;
- SDL_Surface* shrink_surface;
-
- double effective_scale;
- double effective_x;
- double effective_y;
-};
-
-static void
-add_finger_event(unsigned x, unsigned y, unsigned state)
-{
- //fprintf(stderr, "::: finger %d,%d %d\n", x, y, state);
- kbd_mouse_event(x, y, 0, state);
-}
-
-static void
-skin_window_find_finger( SkinWindow* window,
- int x,
- int y )
-{
- FingerState* finger = &window->finger;
-
- /* find the display that contains this movement */
- finger->display = NULL;
- finger->inside = 0;
-
- if (!window->enable_touch)
- return;
-
- LAYOUT_LOOP_DISPLAYS(&window->layout,disp)
- if ( skin_rect_contains( &disp->rect, x, y ) ) {
- finger->inside = 1;
- finger->display = disp;
- finger->pos.x = x - disp->origin.x;
- finger->pos.y = y - disp->origin.y;
-
- skin_pos_rotate( &finger->pos, &finger->pos, -disp->rotation );
- break;
- }
- LAYOUT_LOOP_END_DISPLAYS
-}
-
-static void
-skin_window_move_mouse( SkinWindow* window,
- int x,
- int y )
-{
- FingerState* finger = &window->finger;
- ButtonState* button = &window->button;
-
- if (finger->tracking) {
- ADisplay* disp = finger->display;
- char inside = 1;
- int dx = x - disp->rect.pos.x;
- int dy = y - disp->rect.pos.y;
-
- if (dx < 0) {
- dx = 0;
- inside = 0;
- }
- else if (dx >= disp->rect.size.w) {
- dx = disp->rect.size.w - 1;
- inside = 0;
- }
- if (dy < 0) {
- dy = 0;
- inside = 0;
- } else if (dy >= disp->rect.size.h) {
- dy = disp->rect.size.h-1;
- inside = 0;
- }
- finger->inside = inside;
- finger->pos.x = dx + (disp->rect.pos.x - disp->origin.x);
- finger->pos.y = dy + (disp->rect.pos.y - disp->origin.y);
-
- skin_pos_rotate( &finger->pos, &finger->pos, -disp->rotation );
- }
-
- {
- Button* hover = button->hover;
-
- if (hover) {
- if ( skin_rect_contains( &hover->rect, x, y ) )
- return;
-
- hover->down = 0;
- skin_window_redraw( window, &hover->rect );
- button->hover = NULL;
- }
-
- hover = NULL;
- LAYOUT_LOOP_BUTTONS( &window->layout, butt )
- if ( skin_rect_contains( &butt->rect, x, y ) ) {
- hover = butt;
- break;
- }
- LAYOUT_LOOP_END_BUTTONS
-
- /* filter DPAD and QWERTY buttons right here */
- if (hover != NULL) {
- switch (hover->keycode) {
- /* these correspond to the DPad */
- case kKeyCodeDpadUp:
- case kKeyCodeDpadDown:
- case kKeyCodeDpadLeft:
- case kKeyCodeDpadRight:
- case kKeyCodeDpadCenter:
- if (!window->enable_dpad)
- hover = NULL;
- break;
-
- /* these correspond to non-qwerty buttons */
- case kKeyCodeSoftLeft:
- case kKeyCodeSoftRight:
- case kKeyCodeVolumeUp:
- case kKeyCodeVolumeDown:
- case kKeyCodePower:
- case kKeyCodeHome:
- case kKeyCodeBack:
- case kKeyCodeCall:
- case kKeyCodeEndCall:
- break;
-
- /* all the rest is assumed to be qwerty */
- default:
- if (!window->enable_qwerty)
- hover = NULL;
- }
- }
-
- if (hover != NULL) {
- hover->down = 1;
- skin_window_redraw( window, &hover->rect );
- button->hover = hover;
- }
- }
-}
-
-static void
-skin_window_trackball_press( SkinWindow* window, int down )
-{
- send_key_event( kKeyCodeBtnMouse, down );
-}
-
-static void
-skin_window_trackball_move( SkinWindow* window, int xrel, int yrel )
-{
- BallState* state = &window->ball;
-
- if ( skin_trackball_move( state->ball, xrel, yrel ) ) {
- skin_trackball_refresh( state->ball );
- skin_window_redraw( window, &state->rect );
- }
-}
-
-void
-skin_window_set_trackball( SkinWindow* window, SkinTrackBall* ball )
-{
- BallState* state = &window->ball;
-
- ball_state_set( state, ball );
-}
-
-void
-skin_window_show_trackball( SkinWindow* window, int enable )
-{
- BallState* state = &window->ball;
-
- if (state->ball != NULL && window->enable_trackball) {
- ball_state_show(state, enable);
- }
-}
-
-
-static int skin_window_reset_internal (SkinWindow*, SkinLayout*);
-
-SkinWindow*
-skin_window_create( SkinLayout* slayout, int x, int y, double scale, int no_display )
-{
- SkinWindow* window = qemu_mallocz(sizeof(*window));
-
- window->shrink_scale = scale;
- window->shrink = (scale != 1.0);
- window->scaler = skin_scaler_create();
- window->no_display = no_display;
-
- /* enable everything by default */
- window->enable_touch = 1;
- window->enable_trackball = 1;
- window->enable_dpad = 1;
- window->enable_qwerty = 1;
-
- window->x_pos = x;
- window->y_pos = y;
-
- if (skin_window_reset_internal(window, slayout) < 0) {
- skin_window_free( window );
- return NULL;
- }
- //SDL_WM_SetCaption( "Android Emulator", "Android Emulator" );
-
- SDL_WM_SetPos( x, y );
- if ( !SDL_WM_IsFullyVisible( 1 ) ) {
- dprint( "emulator window was out of view and was recentred\n" );
- }
-
- return window;
-}
-
-void
-skin_window_enable_touch( SkinWindow* window, int enabled )
-{
- window->enable_touch = !!enabled;
-}
-
-void
-skin_window_enable_trackball( SkinWindow* window, int enabled )
-{
- window->enable_trackball = !!enabled;
-}
-
-void
-skin_window_enable_dpad( SkinWindow* window, int enabled )
-{
- window->enable_dpad = !!enabled;
-}
-
-void
-skin_window_enable_qwerty( SkinWindow* window, int enabled )
-{
- window->enable_qwerty = !!enabled;
-}
-
-void
-skin_window_set_title( SkinWindow* window, const char* title )
-{
- if (window && title)
- SDL_WM_SetCaption( title, title );
-}
-
-static void
-skin_window_resize( SkinWindow* window )
-{
- /* now resize window */
- if (window->surface) {
- SDL_FreeSurface(window->surface);
- window->surface = NULL;
- }
-
- if (window->shrink_surface) {
- SDL_FreeSurface(window->shrink_surface);
- window->shrink_surface = NULL;
- }
-
- if (window->shrink_pixels) {
- qemu_free(window->shrink_pixels);
- window->shrink_pixels = NULL;
- }
-
- if ( !window->no_display ) {
- int layout_w = window->layout.rect.size.w;
- int layout_h = window->layout.rect.size.h;
- int window_w = layout_w;
- int window_h = layout_h;
- int window_x = window->x_pos;
- int window_y = window->y_pos;
- int flags;
- SDL_Surface* surface;
- double scale = 1.0;
- int fullscreen = window->fullscreen;
-
- if (fullscreen) {
- if (get_nearest_monitor_rect(&window_x, &window_y,
- &window_w, &window_h) < 0) {
- fullscreen = 0;
- } else {
- double x_scale = window_w * 1.0 / layout_w;
- double y_scale = window_h * 1.0 / layout_h;
-
- scale = (x_scale <= y_scale) ? x_scale : y_scale;
- }
- }
- else if (window->shrink) {
- scale = window->shrink_scale;
- window_w = (int) ceil(layout_w*scale);
- window_h = (int) ceil(layout_h*scale);
- }
-
- {
- char temp[32];
- sprintf(temp,"SDL_VIDEO_WINDOW_POS=%d,%d",window_x,window_y);
- putenv(temp);
- putenv("SDL_VIDEO_WINDOW_FORCE_VISIBLE=1");
- }
-
- flags = SDL_SWSURFACE;
- if (fullscreen) {
- flags |= SDL_FULLSCREEN;
- }
- surface = SDL_SetVideoMode( window_w, window_h, 32, flags );
- if (surface == NULL) {
- fprintf(stderr, "### Error: could not create or resize SDL window: %s\n", SDL_GetError() );
- exit(1);
- }
-
- SDL_WM_SetPos( window_x, window_y );
-
- window->effective_scale = scale;
- window->effective_x = 0;
- window->effective_y = 0;
-
- if (fullscreen) {
- window->effective_x = (window_w - layout_w*scale)*0.5;
- window->effective_y = (window_h - layout_h*scale)*0.5;
- }
-
- if (scale == 1.0)
- window->surface = surface;
- else
- {
- window_w = (int) ceil(window_w / scale );
- window_h = (int) ceil(window_h / scale );
-
- window->shrink_surface = surface;
- window->shrink_pixels = qemu_mallocz( window_w * window_h * 4 );
- if (window->shrink_pixels == NULL) {
- fprintf(stderr, "### Error: could not allocate memory for rescaling surface\n");
- exit(1);
- }
- window->surface = sdl_surface_from_argb32( window->shrink_pixels, window_w, window_h );
- if (window->surface == NULL) {
- fprintf(stderr, "### Error: could not create or resize SDL window: %s\n", SDL_GetError() );
- exit(1);
- }
- skin_scaler_set( window->scaler, scale, window->effective_x, window->effective_y );
- }
- }
-}
-
-static int
-skin_window_reset_internal ( SkinWindow* window, SkinLayout* slayout )
-{
- Layout layout;
- ADisplay* disp;
-
- if ( layout_init( &layout, slayout ) < 0 )
- return -1;
-
- disp = window->layout.displays;
-
- layout_done( &window->layout );
- window->layout = layout;
-
- disp = window->layout.displays;
- if (disp != NULL && window->onion)
- display_set_onion( disp,
- window->onion,
- window->onion_rotation,
- window->onion_alpha );
-
- skin_window_resize(window);
-
- finger_state_reset( &window->finger );
- button_state_reset( &window->button );
- ball_state_reset( &window->ball, window );
-
- skin_window_redraw( window, NULL );
-
- if (slayout->event_type != 0) {
- kbd_generic_event( slayout->event_type, slayout->event_code, slayout->event_value );
- }
-
- return 0;
-}
-
-int
-skin_window_reset ( SkinWindow* window, SkinLayout* slayout )
-{
- if (!window->fullscreen) {
- SDL_WM_GetPos(&window->x_pos, &window->y_pos);
- }
- return skin_window_reset_internal( window, slayout );
-}
-
-void
-skin_window_set_lcd_brightness( SkinWindow* window, int brightness )
-{
- ADisplay* disp = window->layout.displays;
-
- if (disp != NULL) {
- disp->brightness = brightness;
- skin_window_redraw( window, NULL );
- }
-}
-
-void
-skin_window_free ( SkinWindow* window )
-{
- if (window) {
- if (window->surface) {
- SDL_FreeSurface(window->surface);
- window->surface = NULL;
- }
- if (window->shrink_surface) {
- SDL_FreeSurface(window->shrink_surface);
- window->shrink_surface = NULL;
- }
- if (window->shrink_pixels) {
- qemu_free(window->shrink_pixels);
- window->shrink_pixels = NULL;
- }
- if (window->onion) {
- skin_image_unref( &window->onion );
- window->onion_rotation = SKIN_ROTATION_0;
- }
- if (window->scaler) {
- skin_scaler_free(window->scaler);
- window->scaler = NULL;
- }
- layout_done( &window->layout );
- qemu_free(window);
- }
-}
-
-void
-skin_window_set_onion( SkinWindow* window,
- SkinImage* onion,
- SkinRotation onion_rotation,
- int onion_alpha )
-{
- ADisplay* disp;
- SkinImage* old = window->onion;
-
- window->onion = skin_image_ref(onion);
- window->onion_rotation = onion_rotation;
- window->onion_alpha = onion_alpha;
-
- skin_image_unref( &old );
-
- disp = window->layout.displays;
-
- if (disp != NULL)
- display_set_onion( disp, window->onion, onion_rotation, onion_alpha );
-}
-
-static void
-skin_window_update_shrink( SkinWindow* window, SkinRect* rect )
-{
- skin_scaler_scale( window->scaler, window->shrink_surface, window->surface,
- rect->pos.x, rect->pos.y, rect->size.w, rect->size.h );
-}
-
-void
-skin_window_set_scale( SkinWindow* window, double scale )
-{
- window->shrink = (scale != 1.0);
- window->shrink_scale = scale;
-
- skin_window_resize( window );
- skin_window_redraw( window, NULL );
-}
-
-void
-skin_window_redraw( SkinWindow* window, SkinRect* rect )
-{
- if (window != NULL && window->surface != NULL) {
- Layout* layout = &window->layout;
-
- if (rect == NULL)
- rect = &layout->rect;
-
- {
- SkinRect r;
-
- if ( skin_rect_intersect( &r, rect, &layout->rect ) ) {
- SDL_Rect rd;
- rd.x = r.pos.x;
- rd.y = r.pos.y;
- rd.w = r.size.w;
- rd.h = r.size.h;
-
- SDL_FillRect( window->surface, &rd, layout->color );
- }
- }
-
- {
- Background* back = layout->backgrounds;
- Background* end = back + layout->num_backgrounds;
- for ( ; back < end; back++ )
- background_redraw( back, rect, window->surface );
- }
-
- {
- ADisplay* disp = layout->displays;
- ADisplay* end = disp + layout->num_displays;
- for ( ; disp < end; disp++ )
- display_redraw( disp, rect, window->surface );
- }
-
- {
- Button* button = layout->buttons;
- Button* end = button + layout->num_buttons;
- for ( ; button < end; button++ )
- button_redraw( button, rect, window->surface );
- }
-
- if ( window->ball.tracking )
- ball_state_redraw( &window->ball, rect, window->surface );
-
- if (window->effective_scale != 1.0)
- skin_window_update_shrink( window, rect );
- else
- {
- SDL_Rect rd;
- rd.x = rect->pos.x;
- rd.y = rect->pos.y;
- rd.w = rect->size.w;
- rd.h = rect->size.h;
-
- SDL_UpdateRects( window->surface, 1, &rd );
- }
- }
-}
-
-void
-skin_window_toggle_fullscreen( SkinWindow* window )
-{
- if (window && window->surface) {
- if (!window->fullscreen)
- SDL_WM_GetPos( &window->x_pos, &window->y_pos );
-
- window->fullscreen = !window->fullscreen;
- skin_window_resize( window );
- skin_window_redraw( window, NULL );
- }
-}
-
-void
-skin_window_get_display( SkinWindow* window, ADisplayInfo *info )
-{
- ADisplay* disp = window->layout.displays;
-
- if (disp != NULL) {
- info->width = disp->datasize.w;
- info->height = disp->datasize.h;
- info->rotation = disp->rotation;
- info->data = disp->data;
- } else {
- info->width = 0;
- info->height = 0;
- info->rotation = SKIN_ROTATION_0;
- info->data = NULL;
- }
-}
-
-
-static void
-skin_window_map_to_scale( SkinWindow* window, int *x, int *y )
-{
- *x = (*x - window->effective_x) / window->effective_scale;
- *y = (*y - window->effective_y) / window->effective_scale;
-}
-
-void
-skin_window_process_event( SkinWindow* window, SDL_Event* ev )
-{
- Button* button;
- int mx, my;
-
- if (!window->surface)
- return;
-
- switch (ev->type) {
- case SDL_MOUSEBUTTONDOWN:
- if ( window->ball.tracking ) {
- skin_window_trackball_press( window, 1 );
- break;
- }
-
- mx = ev->button.x;
- my = ev->button.y;
- skin_window_map_to_scale( window, &mx, &my );
- skin_window_move_mouse( window, mx, my );
- skin_window_find_finger( window, mx, my );
-#if 0
- printf("down: x=%d y=%d fx=%d fy=%d fis=%d\n",
- ev->button.x, ev->button.y, window->finger.pos.x,
- window->finger.pos.y, window->finger.inside);
-#endif
- if (window->finger.inside) {
- window->finger.tracking = 1;
- add_finger_event(window->finger.pos.x, window->finger.pos.y, 1);
- } else {
- window->button.pressed = NULL;
- button = window->button.hover;
- if(button) {
- button->down += 1;
- skin_window_redraw( window, &button->rect );
- window->button.pressed = button;
- if(button->keycode) {
- send_key_event(button->keycode, 1);
- }
- }
- }
- break;
-
- case SDL_MOUSEBUTTONUP:
- if ( window->ball.tracking ) {
- skin_window_trackball_press( window, 0 );
- break;
- }
- button = window->button.pressed;
- mx = ev->button.x;
- my = ev->button.y;
- skin_window_map_to_scale( window, &mx, &my );
- if (button)
- {
- button->down = 0;
- skin_window_redraw( window, &button->rect );
- if(button->keycode) {
- send_key_event(button->keycode, 0);
- }
- window->button.pressed = NULL;
- window->button.hover = NULL;
- skin_window_move_mouse( window, mx, my );
- }
- else if (window->finger.tracking)
- {
- skin_window_move_mouse( window, mx, my );
- window->finger.tracking = 0;
- add_finger_event( window->finger.pos.x, window->finger.pos.y, 0);
- }
- break;
-
- case SDL_MOUSEMOTION:
- if ( window->ball.tracking ) {
- skin_window_trackball_move( window, ev->motion.xrel, ev->motion.yrel );
- break;
- }
- mx = ev->button.x;
- my = ev->button.y;
- skin_window_map_to_scale( window, &mx, &my );
- if ( !window->button.pressed )
- {
- skin_window_move_mouse( window, mx, my );
- if ( window->finger.tracking ) {
- add_finger_event( window->finger.pos.x, window->finger.pos.y, 1 );
- }
- }
- break;
- }
-}
-
-static ADisplay*
-skin_window_display( SkinWindow* window )
-{
- return window->layout.displays;
-}
-
-void
-skin_window_update_display( SkinWindow* window, int x, int y, int w, int h )
-{
- ADisplay* disp = skin_window_display(window);
-
- if ( !window->surface )
- return;
-
- if (disp != NULL) {
- SkinRect r;
- r.pos.x = x;
- r.pos.y = y;
- r.size.w = w;
- r.size.h = h;
-
- skin_rect_rotate( &r, &r, disp->rotation );
- r.pos.x += disp->origin.x;
- r.pos.y += disp->origin.y;
-
- if (window->effective_scale != 1.0)
- skin_window_redraw( window, &r );
- else
- display_redraw( disp, &r, window->surface );
- }
-}
diff --git a/android/skin/window.h b/android/skin/window.h
deleted file mode 100644
index 3e92e40..0000000
--- a/android/skin/window.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _SKIN_WINDOW_H
-#define _SKIN_WINDOW_H
-
-#include "android/skin/file.h"
-#include "android/skin/trackball.h"
-#include <SDL.h>
-
-typedef struct SkinWindow SkinWindow;
-
-extern SkinWindow* skin_window_create( SkinLayout* layout,
- int x,
- int y,
- double scale,
- int no_display );
-
-extern void skin_window_enable_touch( SkinWindow* window, int enabled );
-extern void skin_window_enable_trackball( SkinWindow* window, int enabled );
-extern void skin_window_enable_dpad( SkinWindow* window, int enabled );
-extern void skin_window_enable_qwerty( SkinWindow* window, int enabled );
-
-extern int skin_window_reset ( SkinWindow* window, SkinLayout* layout );
-extern void skin_window_free ( SkinWindow* window );
-extern void skin_window_redraw( SkinWindow* window, SkinRect* rect );
-extern void skin_window_process_event( SkinWindow* window, SDL_Event* ev );
-
-extern void skin_window_set_onion( SkinWindow* window,
- SkinImage* onion,
- SkinRotation rotation,
- int alpha );
-
-extern void skin_window_set_scale( SkinWindow* window,
- double scale );
-
-extern void skin_window_set_title( SkinWindow* window,
- const char* title );
-
-extern void skin_window_set_trackball( SkinWindow* window, SkinTrackBall* ball );
-extern void skin_window_show_trackball( SkinWindow* window, int enable );
-extern void skin_window_toggle_fullscreen( SkinWindow* window );
-
-/* change the brightness of the emulator LCD screen. 'brightness' will be clamped to 0..255 */
-extern void skin_window_set_lcd_brightness( SkinWindow* window, int brightness );
-
-typedef struct {
- int width;
- int height;
- SkinRotation rotation;
- void* data;
-} ADisplayInfo;
-
-extern void skin_window_get_display( SkinWindow* window, ADisplayInfo *info );
-extern void skin_window_update_display( SkinWindow* window, int x, int y, int w, int h );
-
-#endif /* _SKIN_WINDOW_H */
diff --git a/android/tools/gen-hw-config.py b/android/tools/gen-hw-config.py
deleted file mode 100755
index 928ccc5..0000000
--- a/android/tools/gen-hw-config.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python
-#
-# This software is licensed under the terms of the GNU General Public
-# License version 2, as published by the Free Software Foundation, and
-# may be copied, distributed, and modified under those terms.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# this script is used to generate 'android/avd/hw-config.h' by
-# parsing 'android/avd/hardware-properties.ini'
-#
-#
-import sys, os, string, re
-
-# location of source file, relative to current program directory
-relativeSourcePath = "../avd/hardware-properties.ini"
-
-# location of target file, relative to current program directory
-relativeTargetPath = "../avd/hw-config-defs.h"
-
-def quoteStringForC(str):
- """quote a string so it can be used in C"""
- return '\\"'.join('"'+p+'"' for p in str.split('"'))
-
-# a dictionary that maps item types as they appear in the .ini
-# file into macro names in the generated C header
-#
-typesToMacros = {
- 'integer': 'HWCFG_INT',
- 'string': 'HWCFG_STRING',
- 'boolean': 'HWCFG_BOOL',
- 'diskSize': 'HWCFG_DISKSIZE',
- 'double': 'HWCFG_DOUBLE'
- }
-
-# the list of macro names
-macroNames = typesToMacros.values()
-
-# target program header
-targetHeader = """\
-/* this file is automatically generated from 'hardware-properties.ini'
- * DO NOT EDIT IT. To re-generate it, use android/tools/gen-hw-config.py'
- */"""
-
-# locate source and target
-programDir = os.path.dirname(sys.argv[0])
-sourceFile = os.path.normpath(os.path.join(programDir,relativeSourcePath))
-targetFile = os.path.normpath(os.path.join(programDir,relativeTargetPath))
-
-# parse the source file and record items
-# I would love to use Python's ConfigParser, but it doesn't
-# support files without sections, or multiply defined items
-#
-items = []
-lastItem = None
-
-class Item:
- def __init__(self,name):
- self.name = name
- self.type = type
- self.default = None
- self.abstract = ""
- self.description = ""
-
- def add(self,key,val):
- if key == 'type':
- self.type = val
- elif key == 'default':
- self.default = val
- elif key == 'abstract':
- self.abstract = val
- elif key == 'description':
- self.description = val
-
-for line in open(sourceFile):
- line = line.strip()
- # ignore empty lines and comments
- if len(line) == 0 or line[0] in ";#":
- continue
- key, value = line.split('=')
-
- key = key.strip()
- value = value.strip()
-
- if key == 'name':
- if lastItem: items.append(lastItem)
- lastItem = Item(value)
- else:
- lastItem.add(key, value)
-
-if lastItem:
- items.append(lastItem)
-
-
-print targetHeader
-
-# write guards to prevent bad compiles
-for m in macroNames:
- print """\
-#ifndef %(macro)s
-#error %(macro)s not defined
-#endif""" % { 'macro':m }
-print ""
-
-for item in items:
- if item.type == None:
- sys.stderr.write("ignoring config item with no type '%s'\n" % item.name)
- continue
-
- if not typesToMacros.has_key(item.type):
- sys.stderr.write("ignoring config item with unknown type '%s': '%s'\n" % \
- (item.type, item.name))
- continue
-
- if item.default == None:
- sys.stderr.write("ignoring config item with no default '%s' */" % item.name)
- continue
-
- # convert dots into underscores
- varMacro = typesToMacros[item.type]
- varNameStr = quoteStringForC(item.name)
- varName = item.name.replace(".","_")
- varDefault = item.default
- varAbstract = quoteStringForC(item.abstract)
- varDesc = quoteStringForC(item.description)
-
- if item.type in [ 'string', 'boolean', 'diskSize' ]:
- # quote default value for strings
- varDefault = quoteStringForC(varDefault)
-
- print "%s(\n %s,\n %s,\n %s,\n %s,\n %s)\n" % \
- (varMacro,varName,varNameStr,varDefault,varAbstract,varDesc)
-
-
-for m in macroNames:
- print "#undef %s" % m
-
-print "/* end of auto-generated file */"
diff --git a/android/utils/bufprint.c b/android/utils/bufprint.c
deleted file mode 100644
index 4309a4b..0000000
--- a/android/utils/bufprint.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include "android/utils/bufprint.h"
-#include "android/utils/path.h"
-#include "android/utils/debug.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# include "windows.h"
-# include "shlobj.h"
-#else
-# include <unistd.h>
-# include <sys/stat.h>
-#endif
-
-#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
-
-
-/** USEFUL STRING BUFFER FUNCTIONS
- **/
-
-char*
-vbufprint( char* buffer,
- char* buffer_end,
- const char* fmt,
- va_list args )
-{
- int len = vsnprintf( buffer, buffer_end - buffer, fmt, args );
- if (len < 0 || buffer+len >= buffer_end) {
- if (buffer < buffer_end)
- buffer_end[-1] = 0;
- return buffer_end;
- }
- return buffer + len;
-}
-
-char*
-bufprint(char* buffer, char* end, const char* fmt, ... )
-{
- va_list args;
- char* result;
-
- va_start(args, fmt);
- result = vbufprint(buffer, end, fmt, args);
- va_end(args);
- return result;
-}
-
-/** USEFUL DIRECTORY SUPPORT
- **
- ** bufprint_app_dir() returns the directory where the emulator binary is located
- **
- ** get_android_home() returns a user-specific directory where the emulator will
- ** store its writable data (e.g. config files, profiles, etc...).
- ** on Unix, this is $HOME/.android, on Windows, this is something like
- ** "%USERPROFILE%/Local Settings/AppData/Android" on XP, and something different
- ** on Vista.
- **
- ** both functions return a string that must be freed by the caller
- **/
-
-#ifdef __linux__
-char*
-bufprint_app_dir(char* buff, char* end)
-{
- char path[1024];
- int len;
- char* x;
-
- len = readlink("/proc/self/exe", path, sizeof(path));
- if (len <= 0 || len >= (int)sizeof(path)) goto Fail;
- path[len] = 0;
-
- x = strrchr(path, '/');
- if (x == 0) goto Fail;
- *x = 0;
-
- return bufprint(buff, end, "%s", path);
-Fail:
- fprintf(stderr,"cannot locate application directory\n");
- exit(1);
- return end;
-}
-
-#elif defined(__APPLE__)
-/* the following hack is needed in order to build with XCode 3.1
- * don't ask me why, but it seems that there were changes in the
- * GCC compiler that we don't have in our pre-compiled version
- */
-#ifndef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
-#define __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ MAC_OS_X_VERSION_10_4
-#endif
-#import <Carbon/Carbon.h>
-#include <unistd.h>
-
-char*
-bufprint_app_dir(char* buff, char* end)
-{
- ProcessSerialNumber psn;
- CFDictionaryRef dict;
- CFStringRef value;
- char s[PATH_MAX];
- char* x;
-
- GetCurrentProcess(&psn);
- dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
- value = (CFStringRef)CFDictionaryGetValue(dict,
- CFSTR("CFBundleExecutable"));
- CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8);
- x = strrchr(s, '/');
- if (x == 0) goto fail;
- *x = 0;
-
- return bufprint(buff, end, "%s", s);
-fail:
- fprintf(stderr,"cannot locate application directory\n");
- exit(1);
- return end;
-}
-#elif defined _WIN32
-char*
-bufprint_app_dir(char* buff, char* end)
-{
- char appDir[MAX_PATH];
- int len;
- char* sep;
-
- len = GetModuleFileName( 0, appDir, sizeof(appDir)-1 );
- if (len == 0) {
- fprintf(stderr, "PANIC CITY!!\n");
- exit(1);
- }
- if (len >= (int)sizeof(appDir)) {
- len = sizeof(appDir)-1;
- appDir[len] = 0;
- }
-
- sep = strrchr(appDir, '\\');
- if (sep)
- *sep = 0;
-
- return bufprint(buff, end, "%s", appDir);
-}
-#else
-char*
-bufprint_app_dir(char* buff, char* end)
-{
- return bufprint(buff, end, ".");
-}
-#endif
-
-#define _ANDROID_PATH ".android"
-
-char*
-bufprint_config_path(char* buff, char* end)
-{
-#ifdef _WIN32
- const char* home = getenv("ANDROID_SDK_HOME");
- if (home != NULL) {
- return bufprint(buff, end, "%s\\%s", home, _ANDROID_PATH );
- } else {
- char path[MAX_PATH];
-
- SHGetFolderPath( NULL, CSIDL_PROFILE,
- NULL, 0, path);
-
- return bufprint(buff, end, "%s\\%s", path, _ANDROID_PATH );
- }
-#else
- const char* home = getenv("HOME");
- if (home == NULL)
- home = "/tmp";
- return bufprint(buff, end, "%s/%s", home, _ANDROID_PATH );
-#endif
-}
-
-char*
-bufprint_config_file(char* buff, char* end, const char* suffix)
-{
- char* p;
- p = bufprint_config_path(buff, end);
- p = bufprint(p, end, PATH_SEP "%s", suffix);
- return p;
-}
-
-char*
-bufprint_temp_dir(char* buff, char* end)
-{
-#ifdef _WIN32
- char path[MAX_PATH];
- DWORD retval;
-
- retval = GetTempPath( sizeof(path), path );
- if (retval > sizeof(path) || retval == 0) {
- D( "can't locate TEMP directory" );
- strncpy(path, "C:\\Temp", sizeof(path) );
- }
- strncat( path, "\\AndroidEmulator", sizeof(path)-1 );
- path_mkdir(path, 0744);
-
- return bufprint(buff, end, "%s", path);
-#else
- const char* tmppath = "/tmp/android";
- mkdir(tmppath, 0744);
- return bufprint(buff, end, "%s", tmppath );
-#endif
-}
-
-char*
-bufprint_temp_file(char* buff, char* end, const char* suffix)
-{
- char* p;
- p = bufprint_temp_dir(buff, end);
- p = bufprint(p, end, PATH_SEP "%s", suffix);
- return p;
-}
-
diff --git a/android/utils/bufprint.h b/android/utils/bufprint.h
deleted file mode 100644
index 32d64dc..0000000
--- a/android/utils/bufprint.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef _ANDROID_UTILS_BUFPRINT_H
-#define _ANDROID_UTILS_BUFPRINT_H
-
-#include <stdarg.h>
-
-/** FORMATTED BUFFER PRINTING
- **
- ** bufprint() allows your to easily and safely append formatted string
- ** content to a given bounded character buffer, in a way that is easier
- ** to use than raw snprintf()
- **
- ** 'buffer' is the start position in the buffer,
- ** 'buffend' is the end of the buffer, the function assumes (buffer <= buffend)
- ** 'format' is a standard printf-style format string, followed by any number
- ** of formatting arguments
- **
- ** the function returns the next position in the buffer if everything fits
- ** in it. in case of overflow or formatting error, it will always return "buffend"
- **
- ** this allows you to chain several calls to bufprint() and only check for
- ** overflow at the end, for exemple:
- **
- ** char buffer[1024];
- ** char* p = buffer;
- ** char* end = p + sizeof(buffer);
- **
- ** p = bufprint(p, end, "%s/%s", first, second);
- ** p = bufprint(p, end, "/%s", third);
- ** if (p >= end) ---> overflow
- **
- ** as a convenience, the appended string is zero-terminated if there is no overflow.
- ** (this means that even if p >= end, the content of "buffer" is zero-terminated)
- **
- ** vbufprint() is a variant that accepts a va_list argument
- **/
-
-extern char* vbufprint(char* buffer, char* buffend, const char* fmt, va_list args );
-extern char* bufprint (char* buffer, char* buffend, const char* fmt, ... );
-
-/** USEFUL DIRECTORY SUPPORT
- **
- ** bufprint_add_dir() appends the application's directory to a given bounded buffer
- **
- ** bufprint_config_path() appends the applications' user-specific configuration directory
- ** to a bounded buffer. on Unix this is usually ~/.android, and something a bit more
- ** complex on Windows
- **
- ** bufprint_config_file() appends the name of a file or directory relative to the
- ** user-specific configuration directory to a bounded buffer. this really is equivalent
- ** to concat-ing the config path + path separator + 'suffix'
- **
- ** bufprint_temp_dir() appends the temporary directory's path to a given bounded buffer
- **
- ** bufprint_temp_file() appens the name of a file or directory relative to the
- ** temporary directory. equivalent to concat-ing the temp path + path separator + 'suffix'
- **/
-
-extern char* bufprint_app_dir (char* buffer, char* buffend);
-extern char* bufprint_config_path(char* buffer, char* buffend);
-extern char* bufprint_config_file(char* buffer, char* buffend, const char* suffix);
-extern char* bufprint_temp_dir (char* buffer, char* buffend);
-extern char* bufprint_temp_file (char* buffer, char* buffend, const char* suffix);
-
-#endif /* _ANDROID_UTILS_BUFPRINT_H */
diff --git a/android/utils/debug.c b/android/utils/debug.c
deleted file mode 100644
index 32936d2..0000000
--- a/android/utils/debug.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/debug.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-void
-dprint( const char* format, ... )
-{
- va_list args;
- va_start( args, format );
- fprintf( stdout, "emulator: ");
- vfprintf( stdout, format, args );
- fprintf( stdout, "\n" );
- va_end( args );
-}
-
-void
-dprintn( const char* format, ... )
-{
- va_list args;
- va_start( args, format );
- vfprintf( stdout, format, args );
- va_end( args );
-}
-
-void
-dprintnv( const char* format, va_list args )
-{
- vfprintf( stdout, format, args );
-}
-
-
-void
-dwarning( const char* format, ... )
-{
- va_list args;
- va_start( args, format );
- dprintn( "emulator: WARNING: " );
- dprintnv( format, args );
- dprintn( "\n" );
- va_end( args );
-}
-
-
-void
-derror( const char* format, ... )
-{
- va_list args;
- va_start( args, format );
- dprintn( "emulator: ERROR: " );
- dprintnv( format, args );
- dprintn( "\n" );
- va_end( args );
-}
-
-/** STDOUT/STDERR REDIRECTION
- **
- ** allows you to shut temporarily shutdown stdout/stderr
- ** this is useful to get rid of debug messages from ALSA and esd
- ** on Linux.
- **/
-static int stdio_disable_count;
-static int stdio_save_out_fd;
-static int stdio_save_err_fd;
-
-#ifdef _WIN32
-extern void
-stdio_disable( void )
-{
- if (++stdio_disable_count == 1) {
- int null_fd, out_fd, err_fd;
- fflush(stdout);
- out_fd = _fileno(stdout);
- err_fd = _fileno(stderr);
- stdio_save_out_fd = _dup(out_fd);
- stdio_save_err_fd = _dup(err_fd);
- null_fd = _open( "NUL", _O_WRONLY );
- _dup2(null_fd, out_fd);
- _dup2(null_fd, err_fd);
- close(null_fd);
- }
-}
-
-extern void
-stdio_enable( void )
-{
- if (--stdio_disable_count == 0) {
- int out_fd, err_fd;
- fflush(stdout);
- out_fd = _fileno(stdout);
- err_fd = _fileno(stderr);
- _dup2(stdio_save_out_fd, out_fd);
- _dup2(stdio_save_err_fd, err_fd);
- _close(stdio_save_out_fd);
- _close(stdio_save_err_fd);
- }
-}
-#else
-extern void
-stdio_disable( void )
-{
- if (++stdio_disable_count == 1) {
- int null_fd, out_fd, err_fd;
- fflush(stdout);
- out_fd = fileno(stdout);
- err_fd = fileno(stderr);
- stdio_save_out_fd = dup(out_fd);
- stdio_save_err_fd = dup(err_fd);
- null_fd = open( "/dev/null", O_WRONLY );
- dup2(null_fd, out_fd);
- dup2(null_fd, err_fd);
- close(null_fd);
- }
-}
-
-extern void
-stdio_enable( void )
-{
- if (--stdio_disable_count == 0) {
- int out_fd, err_fd;
- fflush(stdout);
- out_fd = fileno(stdout);
- err_fd = fileno(stderr);
- dup2(stdio_save_out_fd, out_fd);
- dup2(stdio_save_err_fd, err_fd);
- close(stdio_save_out_fd);
- close(stdio_save_err_fd);
- }
-}
-#endif
diff --git a/android/utils/debug.h b/android/utils/debug.h
deleted file mode 100644
index fdf93c9..0000000
--- a/android/utils/debug.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_DEBUG_H
-#define _ANDROID_UTILS_DEBUG_H
-
-#include <stdarg.h>
-
-#define VERBOSE_TAG_LIST \
- _VERBOSE_TAG(init, "emulator initialization") \
- _VERBOSE_TAG(console, "control console") \
- _VERBOSE_TAG(modem, "emulated GSM modem") \
- _VERBOSE_TAG(radio, "emulated GSM AT Command channel") \
- _VERBOSE_TAG(keys, "key bindings & presses") \
- _VERBOSE_TAG(slirp, "internal router/firewall") \
- _VERBOSE_TAG(timezone, "host timezone detection" ) \
- _VERBOSE_TAG(socket, "network sockets") \
- _VERBOSE_TAG(proxy, "network proxy support") \
- _VERBOSE_TAG(audio, "audio sub-system") \
- _VERBOSE_TAG(audioin, "audio input backend") \
- _VERBOSE_TAG(audioout, "audio output backend") \
- _VERBOSE_TAG(surface, "video surface support") \
- _VERBOSE_TAG(qemud, "qemud multiplexer daemon") \
- _VERBOSE_TAG(gps, "emulated GPS") \
- _VERBOSE_TAG(nand_limits, "nand/flash read/write thresholding") \
- _VERBOSE_TAG(hw_control, "emulated power/flashlight/led/vibrator") \
- _VERBOSE_TAG(avd_config, "android virtual device configuration") \
-
-#define _VERBOSE_TAG(x,y) VERBOSE_##x,
-typedef enum {
- VERBOSE_TAG_LIST
- VERBOSE_MAX /* do not remove */
-} VerboseTag;
-#undef _VERBOSE_TAG
-
-/* defined in android_main.c */
-extern unsigned long android_verbose;
-
-#define VERBOSE_ENABLE(tag) \
- android_verbose |= (1 << VERBOSE_##tag)
-
-#define VERBOSE_DISABLE(tag) \
- android_verbose &= (1 << VERBOSE_##tag)
-
-#define VERBOSE_CHECK(tag) \
- ((android_verbose & (1 << VERBOSE_##tag)) != 0)
-
-#define VERBOSE_CHECK_ANY() \
- (android_verbose != 0)
-
-#define VERBOSE_PRINT(tag,...) \
- do { if (VERBOSE_CHECK(tag)) dprint(__VA_ARGS__); } while (0)
-
-/** DEBUG TRACE SUPPORT
- **
- ** debug messages can be sent by calling these function
- **
- ** 'dprint' prints the message, then appends a '\n\
- ** 'dprintn' simply prints the message as is
- ** 'dprintnv' allows you to use a va_list argument
- ** 'dwarning' prints a warning message, then appends a '\n'
- ** 'derror' prints a severe error message, then appends a '\n'
- */
-
-extern void dprint( const char* format, ... );
-extern void dprintn( const char* format, ... );
-extern void dprintnv( const char* format, va_list args );
-extern void dwarning( const char* format, ... );
-extern void derror( const char* format, ... );
-
-/** STDOUT/STDERR REDIRECTION
- **
- ** allows you to shut temporarily shutdown stdout/stderr
- ** this is useful to get rid of debug messages from ALSA and esd
- ** on Linux.
- **/
-
-extern void stdio_disable( void );
-extern void stdio_enable( void );
-
-/* */
-
-#endif /* _ANDROID_UTILS_DEBUG_H */
diff --git a/android/utils/dirscanner.c b/android/utils/dirscanner.c
deleted file mode 100644
index fc63ef0..0000000
--- a/android/utils/dirscanner.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/dirscanner.h"
-#include "android/utils/bufprint.h"
-#include "qemu-common.h"
-#include <stddef.h>
-
-#define DIRSCANNER_BASE \
- char root[PATH_MAX]; \
- int rootLen; \
- char full[PATH_MAX]; \
-
-
-#if _WIN32
-
-#include <io.h>
-
-struct DirScanner {
- DIRSCANNER_BASE
- intptr_t findIndex1;
- struct _finddata_t findData;
-};
-
-/* note: findIndex1 contains the find index + 1
- * so a value of 0 means 'invalid'
- */
-
-static int
-_dirScannerInit( DirScanner* s )
-{
- char* p = s->root + s->rootLen;
- char* end = s->root + sizeof s->root;
- int ret;
-
- /* create file spec by appending \* to root */
- p = bufprint(p, end, "\\*");
- if (p >= end)
- return -1;
-
- ret = _findfirst(s->root, &s->findData);
-
- s->findIndex1 = ret+1;
- return ret;
-}
-
-static void
-_dirScanner_done( DirScanner* s )
-{
- if (s->findIndex1 > 0) {
- _findclose(s->findIndex1-1);
- s->findIndex1 = 0;
- }
-}
-
-const char*
-dirScanner_next( DirScanner* s )
-{
- char* ret = NULL;
-
- if (!s || s->findIndex1 <= 0)
- return NULL;
-
- while (ret == NULL) {
- ret = s->findData.name;
-
- /* ignore special directories */
- if (!strcmp(ret, ".") || !strcmp(ret, "..")) {
- ret = NULL;
- }
- /* find next one */
- if (_findnext(s->findIndex1-1, &s->findData) < 0) {
- _dirScanner_done(s);
- break;
- }
- }
- return ret;
-}
-
-#else /* !_WIN32 */
-
-#include <dirent.h>
-struct DirScanner {
- DIRSCANNER_BASE
- DIR* dir;
- struct dirent* entry;
-};
-
-static int
-_dirScannerInit( DirScanner* s )
-{
- s->dir = opendir(s->root);
-
- if (s->dir == NULL)
- return -1;
-
- s->entry = NULL;
- return 0;
-}
-
-static void
-_dirScanner_done( DirScanner* s )
-{
- if (s->dir) {
- closedir(s->dir);
- s->dir = NULL;
- }
-}
-
-const char*
-dirScanner_next( DirScanner* s )
-{
- char* ret = NULL;
-
- if (!s || s->dir == NULL)
- return NULL;
-
- for (;;)
- {
- /* read new entry if needed */
- s->entry = readdir(s->dir);
- if (s->entry == NULL) {
- _dirScanner_done(s);
- break;
- }
-
- /* ignore special directories */
- ret = s->entry->d_name;
-
- if (!strcmp(ret,".") || !strcmp(ret,"..")) {
- ret = NULL;
- continue;
- }
- break;
- }
- return ret;
-}
-
-#endif /* !_WIN32 */
-
-DirScanner*
-dirScanner_new ( const char* rootPath )
-{
- DirScanner* s = qemu_mallocz(sizeof *s);
- char* p = s->root;
- char* end = p + sizeof s->root;
-
- p = bufprint(p, end, "%s", rootPath);
- if (p >= end)
- goto FAIL;
-
- s->rootLen = (p - s->root);
-
- if (_dirScannerInit(s) < 0)
- goto FAIL;
-
- return s;
-
-FAIL:
- dirScanner_free(s);
- return NULL;
-}
-
-
-void
-dirScanner_free( DirScanner* s )
-{
- if (!s)
- return;
-
- _dirScanner_done(s);
- qemu_free(s);
-}
-
-
-const char*
-dirScanner_nextFull( DirScanner* s )
-{
- const char* name = dirScanner_next(s);
- char* p;
- char* end;
-
- if (name == NULL)
- return NULL;
-
- p = s->full;
- end = p + sizeof s->full;
-
- p = bufprint(p, end, "%.*s/%s", s->rootLen, s->root, name);
- if (p >= end) {
- /* ignore if the full name is too long */
- return dirScanner_nextFull(s);
- }
- return s->full;
-}
diff --git a/android/utils/dirscanner.h b/android/utils/dirscanner.h
deleted file mode 100644
index 871b05e..0000000
--- a/android/utils/dirscanner.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_DIR_H
-#define _ANDROID_UTILS_DIR_H
-
-/* simple utility to parse directories for files */
-/* needed because Unix and Windows don't use the same stuff */
-
-typedef struct DirScanner DirScanner;
-
-/* Create a new directory scanner object from a given rootPath.
- * returns NULL in case of failure (error code in errno)
- */
-DirScanner* dirScanner_new ( const char* rootPath );
-
-/* Destroy a given directory scanner. You must always call
- * this function to release proper system resources.
- */
-void dirScanner_free( DirScanner* s );
-
-/* Get the name of the next file from a directory scanner.
- * Returns NULL when there is no more elements in the list.
- *
- * This is only the file name, use dirScanner_nextFull to
- * get its full path.
- *
- * This will never return '.' and '..'.
- *
- * The returned string is owned by the scanner, and will
- * change on the next call to this function or when the
- * scanner is destroyed.
- */
-const char* dirScanner_next( DirScanner* s );
-
-/* A variant of dirScanner_next() which returns the full path
- * to the next directory element.
- */
-const char* dirScanner_nextFull( DirScanner* s );
-
-/* */
-
-#endif /* _ANDROID_UTILS_DIR_H */
diff --git a/android/utils/display-quartz.m b/android/utils/display-quartz.m
deleted file mode 100644
index 594657e..0000000
--- a/android/utils/display-quartz.m
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-/* this is the Quartz-specific implementation of
- * <android/utils/display.h>
- */
-
-#include "android/utils/display.h"
-#include "android/utils/debug.h"
-
-#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
-
-#include <stdio.h>
-#include <Cocoa/Cocoa.h>
-#include <Carbon/Carbon.h>
-#include <SDL_syswm.h>
-
-int
-get_monitor_resolution( int *px_dpi, int *py_dpi )
-{
- fprintf(stderr, "emulator: FIXME: implement get_monitor_resolution on OS X\n" );
- return -1;
-}
-
-int
-get_nearest_monitor_rect( int *x, int *y, int *width, int *height )
-{
- SDL_SysWMinfo info;
- NSWindow* window;
-
- SDL_VERSION(&info.version);
- if ( SDL_GetWMInfo(&info) < 0 ) {
- D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError());
- return -1;
- }
- window = info.nsWindowPtr;
- if (window == NULL) {
- D( "%s: SDL_GetWMInfo() returned NULL NSWindow ptr",
- __FUNCTION__ );
- return -1;
- }
- else
- {
- NSRect frame = [ window frame ];
- int fx1 = frame.origin.x;
- int fy1 = frame.origin.y;
- int fx2 = frame.size.width + fx1;
- int fy2 = frame.size.height + fy1;
- NSArray* screens = [ NSScreen screens ];
- unsigned int count = [ screens count ];
- int bestScreen = -1;
- int bestArea = 0;
-
- unsigned int n;
- printf( "window frame (%d,%d) (%d,%d)\n", fx1, fy1, fx2, fy2 );
-
- /* we need to compute which screen has the most window pixels */
- for (n = 0; n < count; n++) {
- NSScreen* screen = [ screens objectAtIndex: n ];
- NSRect vis = [ screen visibleFrame ];
- int vx1 = vis.origin.x;
- int vy1 = vis.origin.y;
- int vx2 = vis.size.width + vx1;
- int vy2 = vis.size.height + vy1;
- int cx1, cx2, cy1, cy2, cArea;
-
- //printf( "screen %d/%d frame (%d,%d) (%d,%d)\n", n+1, count,
- // vx1, vy1, vx2, vy2 );
-
- if (fx1 >= vx2 || vx1 >= fx2 || fy1 >= vy2 || vy1 >= fy2)
- continue;
-
- cx1 = (fx1 < vx1) ? vx1 : fx1;
- cx2 = (fx2 > vx2) ? vx2 : fx2;
- cy1 = (fy1 < vy1) ? vy1 : fy1;
- cy2 = (fy2 > vy2) ? vy2 : fy2;
-
- if (cx1 >= cx2 || cy1 >= cy2)
- continue;
-
- cArea = (cx2-cx1)*(cy2-cy1);
-
- if (bestScreen < 0 || cArea > bestArea) {
- bestScreen = n;
- bestArea = cArea;
- }
- }
- if (bestScreen < 0)
- bestScreen = 0;
-
- {
- NSScreen* screen = [ screens objectAtIndex: bestScreen ];
- NSRect vis = [ screen visibleFrame ];
-
- *x = vis.origin.x;
- *y = vis.origin.y;
- *width = vis.size.width;
- *height = vis.size.height;
- }
- return 0;
- }
-};
diff --git a/android/utils/display.c b/android/utils/display.c
deleted file mode 100644
index e1ba507..0000000
--- a/android/utils/display.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include "android/utils/display.h"
-#include "android/utils/debug.h"
-
-#define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
-
-/** HOST RESOLUTION SETTINGS
- **
- ** return the main monitor's DPI resolution according to the host device
- ** beware: this is not always reliable or even obtainable.
- **
- ** returns 0 on success, or -1 in case of error (e.g. the system returns funky values)
- **/
-
-/** NOTE: the following code assumes that we exclusively use X11 on Linux, and Quartz on OS X
- **/
-
-#ifdef _WIN32
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <SDL_syswm.h>
-
-int
-get_monitor_resolution( int *px_dpi, int *py_dpi )
-{
- HDC displayDC = CreateDC( "DISPLAY", NULL, NULL, NULL );
- int xdpi, ydpi;
-
- if (displayDC == NULL) {
- D( "%s: could not get display DC\n", __FUNCTION__ );
- return -1;
- }
- xdpi = GetDeviceCaps( displayDC, LOGPIXELSX );
- ydpi = GetDeviceCaps( displayDC, LOGPIXELSY );
-
- /* sanity checks */
- if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) {
- D( "%s: bad resolution: xpi=%d ydpi=%d", __FUNCTION__,
- xdpi, ydpi );
- return -1;
- }
-
- *px_dpi = xdpi;
- *py_dpi = ydpi;
- return 0;
-}
-
-int
-get_nearest_monitor_rect( int *x, int *y, int *width, int *height )
-{
- SDL_SysWMinfo info;
- HMONITOR monitor;
- MONITORINFO monitorInfo;
-
- SDL_VERSION(&info.version);
-
- if ( !SDL_GetWMInfo(&info) ) {
- D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError());
- return -1;
- }
-
- monitor = MonitorFromWindow( info.window, MONITOR_DEFAULTTONEAREST );
- monitorInfo.cbSize = sizeof(monitorInfo);
- GetMonitorInfo( monitor, &monitorInfo );
-
- *x = monitorInfo.rcMonitor.left;
- *y = monitorInfo.rcMonitor.top;
- *width = monitorInfo.rcMonitor.right - *x;
- *height = monitorInfo.rcMonitor.bottom - *y;
-
- D("%s: found (x,y,w,h)=(%d,%d,%d,%d)", __FUNCTION__,
- *x, *y, *width, *height);
-
- return 0;
-}
-
-
-#elif defined __APPLE__
-
-/* the real implementation is in display-quartz.m, but
- * unfortunately, the Android build system doesn't know
- * how to build Objective-C sources, so provide stubs
- * here instead.
- *
- * CONFIG_NO_COCOA is set by Makefile.android
- */
-
-#ifdef CONFIG_NO_COCOA
-int
-get_monitor_resolution( int *px_dpi, int *py_dpi )
-{
- return -1;
-}
-
-int
-get_nearest_monitor_rect( int *x, int *y, int *width, int *height )
-{
- return -1;
-}
-#endif /* CONFIG_NO_COCOA */
-
-#else /* Linux and others */
-#include <SDL.h>
-#include <SDL_syswm.h>
-#include <dlfcn.h>
-#include <X11/Xlib.h>
-#define MM_PER_INCH 25.4
-
-#define DYNLINK_FUNCTIONS \
- DYNLINK_FUNC(int,XDefaultScreen,(Display*)) \
- DYNLINK_FUNC(int,XDisplayWidth,(Display*,int)) \
- DYNLINK_FUNC(int,XDisplayWidthMM,(Display*,int)) \
- DYNLINK_FUNC(int,XDisplayHeight,(Display*,int)) \
- DYNLINK_FUNC(int,XDisplayHeightMM,(Display*,int)) \
-
-#define DYNLINK_FUNCTIONS_INIT \
- x11_dynlink_init
-
-#include "dynlink.h"
-
-static int x11_lib_inited;
-static void* x11_lib;
-
-int
-x11_lib_init( void )
-{
- if (!x11_lib_inited) {
- x11_lib_inited = 1;
-
- x11_lib = dlopen( "libX11.so", RTLD_NOW );
-
- if (x11_lib == NULL) {
- x11_lib = dlopen( "libX11.so.6", RTLD_NOW );
- }
- if (x11_lib == NULL) {
- D("%s: Could not find libX11.so on this machine",
- __FUNCTION__);
- return -1;
- }
-
- if (x11_dynlink_init(x11_lib) < 0) {
- D("%s: didn't find necessary symbols in libX11.so",
- __FUNCTION__);
- dlclose(x11_lib);
- x11_lib = NULL;
- }
- }
- return x11_lib ? 0 : -1;
-}
-
-
-int
-get_monitor_resolution( int *px_dpi, int *py_dpi )
-{
- SDL_SysWMinfo info;
- Display* display;
- int screen;
- int width, width_mm, height, height_mm, xdpi, ydpi;
-
- SDL_VERSION(&info.version);
-
- if ( !SDL_GetWMInfo(&info) ) {
- D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError());
- return -1;
- }
-
- if (x11_lib_init() < 0)
- return -1;
-
- display = info.info.x11.display;
- screen = FF(XDefaultScreen)(display);
-
- width = FF(XDisplayWidth)(display, screen);
- width_mm = FF(XDisplayWidthMM)(display, screen);
- height = FF(XDisplayHeight)(display, screen);
- height_mm = FF(XDisplayHeightMM)(display, screen);
-
- if (width_mm <= 0 || height_mm <= 0) {
- D( "%s: bad screen dimensions: width_mm = %d, height_mm = %d",
- __FUNCTION__, width_mm, height_mm);
- return -1;
- }
-
- D( "%s: found screen width=%d height=%d width_mm=%d height_mm=%d",
- __FUNCTION__, width, height, width_mm, height_mm );
-
- xdpi = width * MM_PER_INCH / width_mm;
- ydpi = height * MM_PER_INCH / height_mm;
-
- if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) {
- D( "%s: bad resolution: xpi=%d ydpi=%d", __FUNCTION__,
- xdpi, ydpi );
- return -1;
- }
-
- *px_dpi = xdpi;
- *py_dpi = ydpi;
-
- return 0;
-}
-
-int
-get_nearest_monitor_rect( int *x, int *y, int *width, int *height )
-{
- SDL_SysWMinfo info;
- Display* display;
- int screen;
-
- SDL_VERSION(&info.version);
-
- if ( !SDL_GetWMInfo(&info) ) {
- D( "%s: SDL_GetWMInfo() failed: %s", __FUNCTION__, SDL_GetError());
- return -1;
- }
-
- if (x11_lib_init() < 0)
- return -1;
-
- display = info.info.x11.display;
- screen = FF(XDefaultScreen)(display);
-
- *x = 0;
- *y = 0;
- *width = FF(XDisplayWidth)(display, screen);
- *height = FF(XDisplayHeight)(display, screen);
-
- D("%s: found (x,y,w,h)=(%d,%d,%d,%d)", __FUNCTION__,
- *x, *y, *width, *height);
-
- return 0;
-}
-
-#endif
diff --git a/android/utils/display.h b/android/utils/display.h
deleted file mode 100644
index 7254aca..0000000
--- a/android/utils/display.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef _ANDROID_UTILS_DISPLAY_H
-#define _ANDROID_UTILS_DISPLAY_H
-
-/** HOST RESOLUTION SETTINGS
- **
- ** return the main monitor's DPI resolution according to the host device
- ** beware: this is not always reliable or even obtainable.
- **
- ** returns 0 on success, or -1 in case of error (e.g. the system returns funky values)
- **/
-extern int get_monitor_resolution( int *px_dpi, int *py_dpi );
-
-/** return the size in pixels of the nearest monitor for the current window.
- ** this is used to implement full-screen presentation mode.
- **/
-
-extern int get_nearest_monitor_rect( int *x, int *y, int *width, int *height );
-
-#endif /* _ANDROID_UTILS_DISPLAY_H */
diff --git a/android/utils/filelock.c b/android/utils/filelock.c
deleted file mode 100644
index a8b18da..0000000
--- a/android/utils/filelock.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include "android/utils/filelock.h"
-#include "android/utils/path.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <fcntl.h>
-#ifdef _WIN32
-# include <process.h>
-# include <windows.h>
-# include <tlhelp32.h>
-#else
-# include <sys/types.h>
-# include <unistd.h>
-# include <signal.h>
-#endif
-
-#define D(...) ((void)0)
-
-#ifndef CHECKED
-# ifdef _WIN32
-# define CHECKED(ret, call) (ret) = (call)
-# else
-# define CHECKED(ret, call) do { (ret) = (call); } while ((ret) < 0 && errno == EINTR)
-# endif
-#endif
-
-/** FILE LOCKS SUPPORT
- **
- ** a FileLock is useful to prevent several emulator instances from using the same
- ** writable file (e.g. the userdata.img disk images).
- **
- ** create a FileLock object with filelock_create(), ithis function should return NULL
- ** only if the corresponding file path could not be locked.
- **
- ** all file locks are automatically released and destroyed when the program exits.
- ** the filelock_lock() function can also detect stale file locks that can linger
- ** when the emulator crashes unexpectedly, and will happily clean them for you
- **
- ** here's how it works, three files are used:
- ** file - the data file accessed by the emulator
- ** lock - a lock file (file + '.lock')
- ** temp - a temporary file make unique with mkstemp
- **
- ** when locking:
- ** create 'temp' and store our pid in it
- ** attemp to link 'lock' to 'temp'
- ** if the link succeeds, we obtain the lock
- ** unlink 'temp'
- **
- ** when unlocking:
- ** unlink 'lock'
- **
- **
- ** on Windows, 'lock' is a directory name. locking is equivalent to
- ** creating it...
- **
- **/
-
-struct FileLock
-{
- const char* file;
- const char* lock;
- char* temp;
- int locked;
- FileLock* next;
-};
-
-/* used to cleanup all locks at emulator exit */
-static FileLock* _all_filelocks;
-
-
-#define LOCK_NAME ".lock"
-#define TEMP_NAME ".tmp-XXXXXX"
-
-#ifdef _WIN32
-#define PIDFILE_NAME "pid"
-#endif
-
-/* returns 0 on success, -1 on failure */
-static int
-filelock_lock( FileLock* lock )
-{
- int ret;
-#ifdef _WIN32
- int pidfile_fd = -1;
-
- ret = _mkdir( lock->lock );
- if (ret < 0) {
- if (errno == ENOENT) {
- D( "could not access directory '%s', check path elements", lock->lock );
- return -1;
- } else if (errno != EEXIST) {
- D( "_mkdir(%s): %s", lock->lock, strerror(errno) );
- return -1;
- }
-
- /* if we get here, it's because the .lock directory already exists */
- /* check to see if there is a pid file in it */
- D("directory '%s' already exist, waiting a bit to ensure that no other emulator instance is starting", lock->lock );
- {
- int _sleep = 200;
- int tries;
-
- for ( tries = 4; tries > 0; tries-- )
- {
- pidfile_fd = open( lock->temp, O_RDONLY );
-
- if (pidfile_fd >= 0)
- break;
-
- Sleep( _sleep );
- _sleep *= 2;
- }
- }
-
- if (pidfile_fd < 0) {
- D( "no pid file in '%s', assuming stale directory", lock->lock );
- }
- else
- {
- /* read the pidfile, and check wether the corresponding process is still running */
- char buf[16];
- int len, lockpid;
- HANDLE processSnapshot;
- PROCESSENTRY32 pe32;
- int is_locked = 0;
-
- len = read( pidfile_fd, buf, sizeof(buf)-1 );
- if (len < 0) {
- D( "could not read pid file '%s'", lock->temp );
- close( pidfile_fd );
- return -1;
- }
- buf[len] = 0;
- lockpid = atoi(buf);
-
- /* PID 0 is the IDLE process, and 0 is returned in case of invalid input */
- if (lockpid == 0)
- lockpid = -1;
-
- close( pidfile_fd );
-
- pe32.dwSize = sizeof( PROCESSENTRY32 );
- processSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
-
- if ( processSnapshot == INVALID_HANDLE_VALUE ) {
- D( "could not retrieve the list of currently active processes\n" );
- is_locked = 1;
- }
- else if ( !Process32First( processSnapshot, &pe32 ) )
- {
- D( "could not retrieve first process id\n" );
- CloseHandle( processSnapshot );
- is_locked = 1;
- }
- else
- {
- do {
- if (pe32.th32ProcessID == lockpid) {
- is_locked = 1;
- break;
- }
- } while (Process32Next( processSnapshot, &pe32 ) );
-
- CloseHandle( processSnapshot );
- }
-
- if (is_locked) {
- D( "the file '%s' is locked by process ID %d\n", lock->file, lockpid );
- return -1;
- }
- }
- }
-
- /* write our PID into the pid file */
- pidfile_fd = open( lock->temp, O_WRONLY | O_CREAT | O_TRUNC );
- if (pidfile_fd < 0) {
- if (errno == EACCES) {
- if ( path_delete_file( lock->temp ) < 0 ) {
- D( "could not remove '%s': %s\n", lock->temp, strerror(errno) );
- return -1;
- }
- pidfile_fd = open( lock->temp, O_WRONLY | O_CREAT | O_TRUNC );
- }
- if (pidfile_fd < 0) {
- D( "could not create '%s': %s\n", lock->temp, strerror(errno) );
- return -1;
- }
- }
-
- {
- char buf[16];
- sprintf( buf, "%ld", GetCurrentProcessId() );
- ret = write( pidfile_fd, buf, strlen(buf) );
- close(pidfile_fd);
- if (ret < 0) {
- D( "could not write PID to '%s'\n", lock->temp );
- return -1;
- }
- }
-
- lock->locked = 1;
- return 0;
-#else
- int temp_fd = -1;
- int lock_fd = -1;
- int rc, tries, _sleep;
- FILE* f = NULL;
- char pid[8];
- struct stat st_temp;
-
- strcpy( lock->temp, lock->file );
- strcat( lock->temp, TEMP_NAME );
- temp_fd = mkstemp( lock->temp );
-
- if (temp_fd < 0) {
- D("cannot create locking temp file '%s'", lock->temp );
- goto Fail;
- }
-
- sprintf( pid, "%d", getpid() );
- ret = write( temp_fd, pid, strlen(pid)+1 );
- if (ret < 0) {
- D( "cannot write to locking temp file '%s'", lock->temp);
- goto Fail;
- }
- close( temp_fd );
- temp_fd = -1;
-
- CHECKED(rc, lstat( lock->temp, &st_temp ));
- if (rc < 0) {
- D( "can't properly stat our locking temp file '%s'", lock->temp );
- goto Fail;
- }
-
- /* now attempt to link the temp file to the lock file */
- _sleep = 0;
- for ( tries = 4; tries > 0; tries-- )
- {
- struct stat st_lock;
- int rc;
-
- if (_sleep > 0) {
- if (_sleep > 2000000) {
- D( "cannot acquire lock file '%s'", lock->lock );
- goto Fail;
- }
- usleep( _sleep );
- }
- _sleep += 200000;
-
- /* the return value of link() is buggy on NFS */
- CHECKED(rc, link( lock->temp, lock->lock ));
-
- CHECKED(rc, lstat( lock->lock, &st_lock ));
- if (rc == 0 &&
- st_temp.st_rdev == st_lock.st_rdev &&
- st_temp.st_ino == st_lock.st_ino )
- {
- /* SUCCESS */
- lock->locked = 1;
- CHECKED(rc, unlink( lock->temp ));
- return 0;
- }
-
- /* if we get there, it means that the link() call failed */
- /* check the lockfile to see if it is stale */
- if (rc == 0) {
- char buf[16];
- time_t now;
- int lockpid = 0;
- int lockfd;
- int stale = 2; /* means don't know */
- struct stat st;
-
- CHECKED(rc, time( &now));
- st.st_mtime = now - 120;
-
- CHECKED(lockfd, open( lock->lock,O_RDONLY ));
- if ( lockfd >= 0 ) {
- int len;
-
- CHECKED(len, read( lockfd, buf, sizeof(buf)-1 ));
- buf[len] = 0;
- lockpid = atoi(buf);
-
- CHECKED(rc, fstat( lockfd, &st ));
- if (rc == 0)
- now = st.st_atime;
-
- CHECKED(rc, close(lockfd));
- }
- /* if there is a PID, check that it is still alive */
- if (lockpid > 0) {
- CHECKED(rc, kill( lockpid, 0 ));
- if (rc == 0 || errno == EPERM) {
- stale = 0;
- } else if (rc < 0 && errno == ESRCH) {
- stale = 1;
- }
- }
- if (stale == 2) {
- /* no pid, stale if the file is older than 1 minute */
- stale = (now >= st.st_mtime + 60);
- }
-
- if (stale) {
- D( "removing stale lockfile '%s'", lock->lock );
- CHECKED(rc, unlink( lock->lock ));
- _sleep = 0;
- tries++;
- }
- }
- }
- D("file '%s' is already in use by another process", lock->file );
-
-Fail:
- if (f)
- fclose(f);
-
- if (temp_fd >= 0) {
- close(temp_fd);
- }
-
- if (lock_fd >= 0) {
- close(lock_fd);
- }
-
- unlink( lock->lock );
- unlink( lock->temp );
- return -1;
-#endif
-}
-
-void
-filelock_release( FileLock* lock )
-{
- if (lock->locked) {
-#ifdef _WIN32
- path_delete_file( (char*)lock->temp );
- rmdir( (char*)lock->lock );
-#else
- unlink( (char*)lock->lock );
-#endif
- lock->locked = 0;
- }
-}
-
-static void
-filelock_atexit( void )
-{
- FileLock* lock;
-
- for (lock = _all_filelocks; lock != NULL; lock = lock->next)
- filelock_release( lock );
-}
-
-/* create a file lock */
-FileLock*
-filelock_create( const char* file )
-{
- int file_len = strlen(file);
- int lock_len = file_len + sizeof(LOCK_NAME);
-#ifdef _WIN32
- int temp_len = lock_len + 1 + sizeof(PIDFILE_NAME);
-#else
- int temp_len = file_len + sizeof(TEMP_NAME);
-#endif
- int total_len = sizeof(FileLock) + file_len + lock_len + temp_len + 3;
-
- FileLock* lock = malloc(total_len);
-
- lock->file = (const char*)(lock + 1);
- memcpy( (char*)lock->file, file, file_len+1 );
-
- lock->lock = lock->file + file_len + 1;
- memcpy( (char*)lock->lock, file, file_len+1 );
- strcat( (char*)lock->lock, LOCK_NAME );
-
- lock->temp = (char*)lock->lock + lock_len + 1;
-#ifdef _WIN32
- snprintf( (char*)lock->temp, temp_len, "%s\\" PIDFILE_NAME, lock->lock );
-#else
- lock->temp[0] = 0;
-#endif
- lock->locked = 0;
-
- if (filelock_lock(lock) < 0) {
- free(lock);
- return NULL;
- }
-
- lock->next = _all_filelocks;
- _all_filelocks = lock;
-
- if (lock->next == NULL)
- atexit( filelock_atexit );
-
- return lock;
-}
diff --git a/android/utils/filelock.h b/android/utils/filelock.h
deleted file mode 100644
index 9bc86b5..0000000
--- a/android/utils/filelock.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef _ANDROID_UTILS_FILELOCK_H
-#define _ANDROID_UTILS_FILELOCK_H
-
-/** FILE LOCKS SUPPORT
- **
- ** a FileLock is useful to prevent several emulator instances from using the same
- ** writable file (e.g. the userdata.img disk images).
- **
- ** create a FileLock object with filelock_create(), the function will return
- ** NULL only if the corresponding path is already locked by another emulator
- ** of if the path is read-only.
- **
- ** note that 'path' can designate a non-existing path and that the lock creation
- ** function can detect stale file locks that can longer when the emulator
- ** crashes unexpectedly, and will happily clean them for you.
- **
- ** you can call filelock_release() to release a file lock explicitely. otherwise
- ** all file locks are automatically released when the program exits.
- **/
-
-typedef struct FileLock FileLock;
-
-extern FileLock* filelock_create ( const char* path );
-extern void filelock_release( FileLock* lock );
-
-#endif /* _ANDROID_UTILS_FILELOCK_H */
diff --git a/android/utils/ini.c b/android/utils/ini.c
deleted file mode 100644
index 56e40f2..0000000
--- a/android/utils/ini.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/ini.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <errno.h>
-#include "android/utils/debug.h"
-#include "android/utils/system.h" /* for ASTRDUP */
-#include "osdep.h"
-
-/* W() is used to print warnings, D() to print debugging info */
-#define W(...) dwarning(__VA_ARGS__)
-#define D(...) VERBOSE_PRINT(avd_config,__VA_ARGS__)
-
-/* a simple .ini file parser and container for Android
- * no sections support. see android/utils/ini.h for
- * more details on the supported file format.
- */
-typedef struct {
- char* key;
- char* value;
-} IniPair;
-
-struct IniFile {
- int numPairs;
- int maxPairs;
- IniPair* pairs;
-};
-
-void
-iniFile_free( IniFile* i )
-{
- int nn;
- for (nn = 0; nn < i->numPairs; nn++) {
- AFREE(i->pairs[nn].key);
- i->pairs[nn].key = NULL;
- i->pairs[nn].value = NULL;
- }
- AFREE(i->pairs);
- AFREE(i);
-}
-
-static IniFile*
-iniFile_alloc( void )
-{
- IniFile* i;
-
- ANEW0(i);
- return i;
-}
-
-static void
-iniFile_addPair( IniFile* i, const char* key, int keyLen,
- const char* value, int valueLen )
-{
- IniPair* pair;
-
- if (i->numPairs >= i->maxPairs) {
- int oldMax = i->maxPairs;
- int newMax = oldMax + (oldMax >> 1) + 4;
-
- AARRAY_RENEW(i->pairs, newMax);
- i->maxPairs = newMax;
- }
-
- pair = i->pairs + i->numPairs;
-
- AARRAY_NEW(pair->key, keyLen + valueLen + 2);
- memcpy(pair->key, key, keyLen);
- pair->key[keyLen] = 0;
-
- pair->value = pair->key + keyLen + 1;
- memcpy(pair->value, value, valueLen);
- pair->value[valueLen] = 0;
-
- i->numPairs += 1;
-}
-
-const char*
-iniFile_getValue( IniFile* i, const char* key )
-{
- if (i && key) {
- int nn;
-
- for (nn = 0; nn < i->numPairs; nn++) {
- if (!strcmp(i->pairs[nn].key,key))
- return i->pairs[nn].value;
- }
- }
- return NULL;
-}
-
-int
-iniFile_getPairCount( IniFile* i )
-{
- return i ? i->numPairs : 0;
-}
-
-void
-iniFile_getPair( IniFile* i,
- int index,
- const char* *pKey,
- const char* *pValue )
-{
- const char* key = NULL;
- const char* value = NULL;
-
- if (i && index >= 0 && index < i->numPairs) {
- key = i->pairs[index].key;
- value = i->pairs[index].value;
- }
- *pKey = key;
- *pValue = value;
-}
-
-/* NOTE: we avoid using <ctype.h> functions to avoid locale-specific
- * behaviour that can be the source of strange bugs.
- */
-
-static const char*
-skipSpaces( const char* p )
-{
- while (*p == ' ' || *p == '\t')
- p ++;
- return p;
-}
-
-static const char*
-skipToEOL( const char* p )
-{
- while (*p && (*p != '\n' && *p != '\r'))
- p ++;
-
- if (*p) {
- p ++;
- if (p[-1] == '\r' && p[0] == '\n')
- p ++;
- }
- return p;
-}
-
-static int
-isKeyStartChar( int c )
-{
- return ((unsigned)(c-'a') < 26 ||
- (unsigned)(c-'A') < 26 ||
- c == '_');
-}
-
-static int
-isKeyChar( int c )
-{
- return isKeyStartChar(c) || ((unsigned)(c-'0') < 10) || (c == '.') || (c == '-');
-}
-
-IniFile*
-iniFile_newFromMemory( const char* text, const char* fileName )
-{
- const char* p = text;
- IniFile* ini = iniFile_alloc();
- int lineno = 0;
-
- if (!fileName)
- fileName = "<unknownFile>";
-
- D("%s: parsing as .ini file", fileName);
-
- while (*p) {
- const char* key;
- int keyLen;
- const char* value;
- int valueLen;
-
- lineno += 1;
-
- /* skip leading whitespace */
- p = skipSpaces(p);
-
- /* skip comments and empty lines */
- if (*p == 0 || *p == ';' || *p == '#' || *p == '\n' || *p == '\r') {
- p = skipToEOL(p);
- continue;
- }
-
- /* check the key name */
- key = p++;
- if (!isKeyStartChar(*key)) {
- p = skipToEOL(p);
- W("%s:%d: key name doesn't start with valid character. line ignored",
- fileName, lineno);
- continue;
- }
-
- while (isKeyChar(*p))
- p++;
-
- keyLen = p - key;
- p = skipSpaces(p);
-
- /* check the equal */
- if (*p != '=') {
- W("%s:%d: missing expected assignment operator (=). line ignored",
- fileName, lineno);
- p = skipToEOL(p);
- continue;
- }
- p += 1;
-
- /* skip spaces before the value */
- p = skipSpaces(p);
- value = p;
-
- /* find the value */
- while (*p && (*p != '\n' && *p != '\r'))
- p += 1;
-
- /* remove trailing spaces */
- while (p > value && (p[-1] == ' ' || p[-1] == '\t'))
- p --;
-
- valueLen = p - value;
-
- iniFile_addPair(ini, key, keyLen, value, valueLen);
- D("%s:%d: KEY='%.*s' VALUE='%.*s'", fileName, lineno,
- keyLen, key, valueLen, value);
-
- p = skipToEOL(p);
- }
-
- return ini;
-}
-
-IniFile*
-iniFile_newFromFile( const char* filepath )
-{
- FILE* fp = fopen(filepath, "rt");
- char* text;
- long size;
- IniFile* ini = NULL;
-
- if (fp == NULL) {
- D("could not open .ini file: %s: %s",
- filepath, strerror(errno));
- return NULL;
- }
-
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- /* avoid reading a very large file that was passed by mistake
- * this threshold is quite liberal.
- */
-#define MAX_INI_FILE_SIZE 655360
-
- if (size < 0 || size > MAX_INI_FILE_SIZE) {
- W("hardware configuration file '%s' too large (%ld bytes)",
- filepath, size);
- goto EXIT;
- }
-
- /* read the file, add a sentinel at the end of it */
- AARRAY_NEW(text, size+1);
- fread(text, 1, size, fp);
- text[size] = 0;
-
- ini = iniFile_newFromMemory(text, filepath);
- AFREE(text);
-
-EXIT:
- fclose(fp);
- return ini;
-}
-
-char*
-iniFile_getString( IniFile* f, const char* key )
-{
- const char* val = iniFile_getValue(f, key);
-
- if (!val)
- return NULL;
-
- return ASTRDUP(val);
-}
-
-int
-iniFile_getInteger( IniFile* f, const char* key, int defaultValue )
-{
- const char* valueStr = iniFile_getValue(f, key);
- int value = defaultValue;
-
- if (valueStr != NULL) {
- char* end;
- long l = strtol(valueStr, &end, 10);
- if (end != NULL && end[0] == 0 && (int)l == l)
- value = l;
- }
- return value;
-}
-
-double
-iniFile_getDouble( IniFile* f, const char* key, double defaultValue )
-{
- const char* valueStr = iniFile_getValue(f, key);
- double value = defaultValue;
-
- if (valueStr != NULL) {
- char* end;
- double d = strtod(valueStr, &end);
- if (end != NULL && end[0] == 0)
- value = d;
- }
- return value;
-}
-
-int
-iniFile_getBoolean( IniFile* f, const char* key, const char* defaultValue )
-{
- const char* value = iniFile_getValue(f, key);
-
- if (!value)
- value = defaultValue;
-
- if (!strcmp(value,"1") ||
- !strcmp(value,"yes") ||
- !strcmp(value,"YES") ||
- !strcmp(value,"true") ||
- !strcmp(value,"TRUE"))
- {
- return 1;
- }
- else
- return 0;
-}
-
-int64_t
-iniFile_getDiskSize( IniFile* f, const char* key, const char* defaultValue )
-{
- const char* valStr = iniFile_getValue(f, key);
- int64_t value = 0;
-
- if (!valStr)
- valStr = defaultValue;
-
- if (valStr != NULL) {
- char* end;
-
- value = strtoll(valStr, &end, 10);
- if (*end == 'k' || *end == 'K')
- value *= 1024ULL;
- else if (*end == 'm' || *end == 'M')
- value *= 1024*1024ULL;
- else if (*end == 'g' || *end == 'G')
- value *= 1024*1024*1024ULL;
- }
- return value;
-}
-
-int64_t
-iniFile_getInt64( IniFile* f, const char* key, int64_t defaultValue )
-{
- const char* valStr = iniFile_getValue(f, key);
- int64_t value = defaultValue;
-
- if (valStr != NULL) {
- char* end;
- int64_t d;
-
- d = strtoll(valStr, &end, 10);
- if (end != NULL && end[0] == 0)
- value = d;
- }
- return value;
-}
-
diff --git a/android/utils/ini.h b/android/utils/ini.h
deleted file mode 100644
index bc8193e..0000000
--- a/android/utils/ini.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_INI_H
-#define _ANDROID_UTILS_INI_H
-
-#include <stdint.h>
-
-/* the emulator supports a simple .ini file format for its configuration
- * files. Here's the BNF for it:
- *
- * file := <line>*
- * line := <comment> | <LF> | <assignment>
- * comment := (';'|'#') <noLF>* <LF>
- * assignment := <space>* <keyName> <space>* '=' <space>* <valueString> <space>* <LF>
- * keyName := <keyNameStartChar> <keyNameChar>*
- * keyNameStartChar := [A-Za-z_]
- * keyNameChar := [A-Za-z0-9_.-]
- * valueString := <noLF>*
- * space := ' ' | '\t'
- * LF := '\r\n' | '\n' | '\r'
- * noLF := [^<LF>]
- *
- * Or, in English:
- *
- * - no support for sections
- * - empty lines are ignored, as well as lines beginning with ';' or '#'
- * - lines must be of the form: "<keyName> = <value>"
- * - key names must start with a letter or an underscore
- * - other key name characters can be letters, digits, underscores, dots or dashes
- *
- * - leading and trailing space are allowed and ignored before/after the key name
- * and before/after the value
- *
- * - there is no restriction on the value, except that it can't contain
- * leading/trailing space/tab characters or newline/charfeed characters
- *
- * - empty values are possible, and will be stored as an empty string.
- * - any badly formatted line is discarded (and will print a warning)
- *
- */
-
-/* an opaque structure used to model an .ini configuration file */
-typedef struct IniFile IniFile;
-
-/* creates a new IniFile object from a config file loaded in memory.
- * 'fileName' is only used when writing a warning to stderr in case
- * of badly formed output
- */
-IniFile* iniFile_newFromMemory( const char* text, const char* fileName );
-
-/* creates a new IniFile object from a file path,
- * returns NULL if the file cannot be opened.
- */
-IniFile* iniFile_newFromFile( const char* filePath);
-
-/* free an IniFile object */
-void iniFile_free( IniFile* f );
-
-/* returns the number of (key.value) pairs in an IniFile */
-int iniFile_getPairCount( IniFile* f );
-
-/* return a specific (key,value) pair from an IniFile.
- * if the index is not correct, both '*pKey' and '*pValue' will be
- * set to NULL.
- *
- * you should probably use iniFile_getValue() and its variants instead
- */
-void iniFile_getPair( IniFile* f,
- int index,
- const char* *pKey,
- const char* *pValue );
-
-/* returns the value of a given key from an IniFile.
- * NULL if the key is not assigned in the corresponding configuration file
- */
-const char* iniFile_getValue( IniFile* f, const char* key );
-
-/* returns a copy of the value of a given key, or NULL
- */
-char* iniFile_getString( IniFile* f, const char* key );
-
-/* returns an integer value, or a default in case the value string is
- * missing or badly formatted
- */
-int iniFile_getInteger( IniFile* f, const char* key, int defaultValue );
-
-/* returns a 64-bit integer value, or a default in case the value string is
- * missing or badly formatted
- */
-int64_t iniFile_getInt64( IniFile* f, const char* key, int64_t defaultValue );
-
-/* returns a double value, or a default in case the value string is
- * missing or badly formatted
- */
-double iniFile_getDouble( IniFile* f, const char* key, double defaultValue );
-
-/* returns a copy of a given key's value, if any, or NULL if it is missing
- * caller must call free() to release it */
-char* iniFile_getString( IniFile* f, const char* key );
-
-/* parses a key value as a boolean. Accepted values are "1", "0", "yes", "YES",
- * "no" and "NO". Returns either 1 or 0.
- * note that the default value must be provided as a string too
- */
-int iniFile_getBoolean( IniFile* f, const char* key, const char* defaultValue );
-
-/* parses a key value as a disk size. this means it can be an integer followed
- * by a suffix that can be one of "mMkKgG" which correspond to KiB, MiB and GiB
- * multipliers.
- *
- * NOTE: we consider that 1K = 1024, not 1000.
- */
-int64_t iniFile_getDiskSize( IniFile* f, const char* key, const char* defaultValue );
-
-/* */
-
-#endif /* _ANDROID_UTILS_INI_H */
diff --git a/android/utils/misc.c b/android/utils/misc.c
deleted file mode 100644
index 818ab78..0000000
--- a/android/utils/misc.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include "android/utils/misc.h"
-#include "android/utils/stralloc.h"
-#include "android/utils/debug.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-extern void
-print_tabular( const char** strings, int count,
- const char* prefix, int width )
-{
- int nrows, ncols, r, c, n, maxw = 0;
-
- for (n = 0; n < count; n++) {
- int len = strlen(strings[n]);
- if (len > maxw)
- maxw = len;
- }
- maxw += 2;
- ncols = width/maxw;
- nrows = (count + ncols-1)/ncols;
-
- for (r = 0; r < nrows; r++) {
- printf( "%s", prefix );
- for (c = 0; c < ncols; c++) {
- int index = c*nrows + r;
- if (index >= count) {
- break;
- }
- printf( "%-*s", maxw, strings[index] );
- }
- printf( "\n" );
- }
-}
-
-extern void
-string_translate_char( char* str, char from, char to )
-{
- char* p = str;
- while (p != NULL && (p = strchr(p, from)) != NULL)
- *p++ = to;
-}
-
-extern void
-buffer_translate_char( char* buff,
- unsigned buffLen,
- const char* src,
- char fromChar,
- char toChar )
-{
- int len = strlen(src);
-
- if (len >= buffLen)
- len = buffLen-1;
-
- memcpy(buff, src, len);
- buff[len] = 0;
-
- string_translate_char( buff, fromChar, toChar );
-}
-
-
-/** TEMP CHAR STRINGS
- **
- ** implement a circular ring of temporary string buffers
- **/
-
-typedef struct Temptring {
- struct TempString* next;
- char* buffer;
- int size;
-} TempString;
-
-#define MAX_TEMP_STRINGS 16
-
-static TempString _temp_strings[ MAX_TEMP_STRINGS ];
-static int _temp_string_n;
-
-extern char*
-tempstr_get( int size )
-{
- TempString* t = &_temp_strings[_temp_string_n];
-
- if ( ++_temp_string_n >= MAX_TEMP_STRINGS )
- _temp_string_n = 0;
-
- size += 1; /* reserve 1 char for terminating zero */
-
- if (t->size < size) {
- t->buffer = realloc( t->buffer, size );
- if (t->buffer == NULL) {
- derror( "%s: could not allocate %d bytes",
- __FUNCTION__, size );
- exit(1);
- }
- t->size = size;
- }
- return t->buffer;
-}
-
-extern char*
-tempstr_format( const char* fmt, ... )
-{
- va_list args;
- char* result;
- STRALLOC_DEFINE(s);
- va_start(args, fmt);
- stralloc_formatv(s, fmt, args);
- va_end(args);
- result = stralloc_to_tempstr(s);
- stralloc_reset(s);
- return result;
-}
-
-/** QUOTING
- **
- ** dumps a human-readable version of a string. this replaces
- ** newlines with \n, etc...
- **/
-
-extern const char*
-quote_bytes( const char* str, int len )
-{
- STRALLOC_DEFINE(s);
- char* q;
-
- stralloc_add_quote_bytes( s, str, len );
- q = stralloc_to_tempstr( s );
- stralloc_reset(s);
- return q;
-}
-
-extern const char*
-quote_str( const char* str )
-{
- int len = strlen(str);
- return quote_bytes( str, len );
-}
-
-/** HEXADECIMAL CHARACTER SEQUENCES
- **/
-
-static int
-hexdigit( int c )
-{
- unsigned d;
-
- d = (unsigned)(c - '0');
- if (d < 10) return d;
-
- d = (unsigned)(c - 'a');
- if (d < 6) return d+10;
-
- d = (unsigned)(c - 'A');
- if (d < 6) return d+10;
-
- return -1;
-}
-
-int
-hex2int( const uint8_t* hex, int len )
-{
- int result = 0;
- while (len > 0) {
- int c = hexdigit(*hex++);
- if (c < 0)
- return -1;
-
- result = (result << 4) | c;
- len --;
- }
- return result;
-}
-
-void
-int2hex( uint8_t* hex, int len, int val )
-{
- static const uint8_t hexchars[16] = "0123456789abcdef";
- while ( --len >= 0 )
- *hex++ = hexchars[(val >> (len*4)) & 15];
-}
diff --git a/android/utils/misc.h b/android/utils/misc.h
deleted file mode 100644
index 0db1e28..0000000
--- a/android/utils/misc.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_MISC_H
-#define _ANDROID_UTILS_MISC_H
-
-#include <stdint.h>
-
-/** TABULAR OUTPUT
- **
- ** prints a list of strings in row/column format
- **
- **/
-
-extern void print_tabular( const char** strings, int count,
- const char* prefix, int width );
-
-/** CHARACTER TRANSLATION
- **
- ** converts one character into another in strings
- **/
-
-extern void buffer_translate_char( char* buff,
- unsigned buffLen,
- const char* src,
- char fromChar,
- char toChar );
-
-extern void string_translate_char( char* str, char from, char to );
-
-/** TEMP CHAR STRINGS
- **
- ** implement a circular ring of temporary string buffers
- **/
-
-extern char* tempstr_get( int size );
-extern char* tempstr_format( const char* fmt, ... );
-
-/** QUOTING
- **
- ** dumps a human-readable version of a string. this replaces
- ** newlines with \n, etc...
- **/
-
-extern const char* quote_bytes( const char* str, int len );
-extern const char* quote_str( const char* str );
-
-/** DECIMAL AND HEXADECIMAL CHARACTER SEQUENCES
- **/
-
-/* decodes a sequence of 'len' hexadecimal chars from 'hex' into
- * an integer. returns -1 in case of error (i.e. badly formed chars)
- */
-extern int hex2int( const uint8_t* hex, int len );
-
-/* encodes an integer 'val' into 'len' hexadecimal charaters into 'hex' */
-extern void int2hex( uint8_t* hex, int len, int val );
-
-#endif /* _ANDROID_UTILS_MISC_H */
diff --git a/android/utils/path.c b/android/utils/path.c
deleted file mode 100644
index 9dd238e..0000000
--- a/android/utils/path.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/* Copyright (C) 2007-2009 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/path.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-#include <process.h>
-#include <shlobj.h>
-#include <tlhelp32.h>
-#include <io.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <limits.h>
-#include <winbase.h>
-#else
-#include <unistd.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <signal.h>
-#endif
-
-#define D(...) ((void)0)
-
-#ifndef CHECKED
-# ifdef _WIN32
-# define CHECKED(ret, call) (ret) = (call)
-# else
-# define CHECKED(ret, call) do { (ret) = (call); } while ((ret) < 0 && errno == EINTR)
-# endif
-#endif
-
-/** PATH HANDLING ROUTINES
- **
- ** path_parent() can be used to return the n-level parent of a given directory
- ** this understands . and .. when encountered in the input path
- **/
-
-static __inline__ int
-ispathsep(int c)
-{
-#ifdef _WIN32
- return (c == '/' || c == '\\');
-#else
- return (c == '/');
-#endif
-}
-
-char*
-path_parent( const char* path, int levels )
-{
- const char* end = path + strlen(path);
- char* result;
-
- while (levels > 0) {
- const char* base;
-
- /* trim any trailing path separator */
- while (end > path && ispathsep(end[-1]))
- end--;
-
- base = end;
- while (base > path && !ispathsep(base[-1]))
- base--;
-
- if (base <= path) /* we can't go that far */
- return NULL;
-
- if (end == base+1 && base[0] == '.')
- goto Next;
-
- if (end == base+2 && base[0] == '.' && base[1] == '.') {
- levels += 1;
- goto Next;
- }
-
- levels -= 1;
-
- Next:
- end = base - 1;
- }
- result = malloc( end-path+1 );
- if (result != NULL) {
- memcpy( result, path, end-path );
- result[end-path] = 0;
- }
- return result;
-}
-
-
-/** MISC FILE AND DIRECTORY HANDLING
- **/
-
-ABool
-path_exists( const char* path )
-{
- int ret;
- CHECKED(ret, access(path, F_OK));
- return (ret == 0) || (errno != ENOENT);
-}
-
-/* checks that a path points to a regular file */
-ABool
-path_is_regular( const char* path )
-{
- int ret;
- struct stat st;
-
- CHECKED(ret, stat(path, &st));
- if (ret < 0)
- return 0;
-
- return S_ISREG(st.st_mode);
-}
-
-
-/* checks that a path points to a directory */
-ABool
-path_is_dir( const char* path )
-{
- int ret;
- struct stat st;
-
- CHECKED(ret, stat(path, &st));
- if (ret < 0)
- return 0;
-
- return S_ISDIR(st.st_mode);
-}
-
-/* checks that one can read/write a given (regular) file */
-ABool
-path_can_read( const char* path )
-{
- int ret;
- CHECKED(ret, access(path, R_OK));
- return (ret == 0);
-}
-
-ABool
-path_can_write( const char* path )
-{
- int ret;
- CHECKED(ret, access(path, R_OK));
- return (ret == 0);
-}
-
-/* try to make a directory. returns 0 on success, -1 on failure
- * (error code in errno) */
-APosixStatus
-path_mkdir( const char* path, int mode )
-{
-#ifdef _WIN32
- (void)mode;
- return _mkdir(path);
-#else
- int ret;
- CHECKED(ret, mkdir(path, mode));
- return ret;
-#endif
-}
-
-static APosixStatus
-path_mkdir_recursive( char* path, unsigned len, int mode )
-{
- char old_c;
- int ret;
- unsigned len2;
-
- /* get rid of trailing separators */
- while (len > 0 && ispathsep(path[len-1]))
- len -= 1;
-
- if (len == 0) {
- errno = ENOENT;
- return -1;
- }
-
- /* check that the parent exists, 'len2' is the length of
- * the parent part of the path */
- len2 = len-1;
- while (len2 > 0 && !ispathsep(path[len2-1]))
- len2 -= 1;
-
- if (len2 > 0) {
- old_c = path[len2];
- path[len2] = 0;
- ret = 0;
- if ( !path_exists(path) ) {
- /* the parent doesn't exist, so try to create it */
- ret = path_mkdir_recursive( path, len2, mode );
- }
- path[len2] = old_c;
-
- if (ret < 0)
- return ret;
- }
-
- /* at this point, we now the parent exists */
- old_c = path[len];
- path[len] = 0;
- ret = path_mkdir( path, mode );
- path[len] = old_c;
-
- return ret;
-}
-
-/* ensure that a given directory exists, create it if not,
- 0 on success, -1 on failure (error code in errno) */
-APosixStatus
-path_mkdir_if_needed( const char* path, int mode )
-{
- int ret = 0;
-
- if (!path_exists(path)) {
- ret = path_mkdir(path, mode);
-
- if (ret < 0 && errno == ENOENT) {
- char temp[MAX_PATH];
- unsigned len = (unsigned)strlen(path);
-
- if (len > sizeof(temp)-1) {
- errno = EINVAL;
- return -1;
- }
- memcpy( temp, path, len );
- temp[len] = 0;
-
- return path_mkdir_recursive(temp, len, mode);
- }
- }
- return ret;
-}
-
-/* return the size of a given file in '*psize'. returns 0 on
- * success, -1 on failure (error code in errno) */
-APosixStatus
-path_get_size( const char* path, uint64_t *psize )
-{
-#ifdef _WIN32
- /* avoid _stat64 which is only defined in MSVCRT.DLL, not CRTDLL.DLL */
- /* do not use OpenFile() because it has strange search behaviour that could */
- /* result in getting the size of a different file */
- LARGE_INTEGER size;
- HANDLE file = CreateFile( /* lpFilename */ path,
- /* dwDesiredAccess */ GENERIC_READ,
- /* dwSharedMode */ FILE_SHARE_READ|FILE_SHARE_WRITE,
- /* lpSecurityAttributes */ NULL,
- /* dwCreationDisposition */ OPEN_EXISTING,
- /* dwFlagsAndAttributes */ 0,
- /* hTemplateFile */ NULL );
- if (file == INVALID_HANDLE_VALUE) {
- /* ok, just to play fair */
- errno = ENOENT;
- return -1;
- }
- if (!GetFileSizeEx(file, &size)) {
- /* maybe we tried to get the size of a pipe or something like that ? */
- *psize = 0;
- }
- else {
- *psize = (uint64_t) size.QuadPart;
- }
- CloseHandle(file);
- return 0;
-#else
- int ret;
- struct stat st;
-
- CHECKED(ret, stat(path, &st));
- if (ret == 0) {
- *psize = (uint64_t) st.st_size;
- }
- return ret;
-#endif
-}
-
-
-/** OTHER FILE UTILITIES
- **
- ** path_empty_file() creates an empty file at a given path location.
- ** if the file already exists, it is truncated without warning
- **
- ** path_copy_file() copies one file into another.
- **
- ** both functions return 0 on success, and -1 on error
- **/
-
-APosixStatus
-path_empty_file( const char* path )
-{
-#ifdef _WIN32
- int fd = _creat( path, S_IWRITE );
-#else
- /* on Unix, only allow the owner to read/write, since the file *
- * may contain some personal data we don't want to see exposed */
- int fd = creat(path, S_IRUSR | S_IWUSR);
-#endif
- if (fd >= 0) {
- close(fd);
- return 0;
- }
- return -1;
-}
-
-APosixStatus
-path_copy_file( const char* dest, const char* source )
-{
- int fd, fs, result = -1;
-
- /* if the destination doesn't exist, create it */
- if ( access(source, F_OK) < 0 ||
- path_empty_file(dest) < 0) {
- return -1;
- }
-
-#ifdef _WIN32
- fd = _open(dest, _O_RDWR | _O_BINARY);
- fs = _open(source, _O_RDONLY | _O_BINARY);
-#else
- fd = creat(dest, S_IRUSR | S_IWUSR);
- fs = open(source, S_IREAD);
-#endif
- if (fs >= 0 && fd >= 0) {
- char buf[4096];
- ssize_t total = 0;
- ssize_t n;
- result = 0; /* success */
- while ((n = read(fs, buf, 4096)) > 0) {
- if (write(fd, buf, n) != n) {
- /* write failed. Make it return -1 so that an
- * empty file be created. */
- D("Failed to copy '%s' to '%s': %s (%d)",
- source, dest, strerror(errno), errno);
- result = -1;
- break;
- }
- total += n;
- }
- }
-
- if (fs >= 0) {
- close(fs);
- }
- if (fd >= 0) {
- close(fd);
- }
- return result;
-}
-
-
-APosixStatus
-path_delete_file( const char* path )
-{
-#ifdef _WIN32
- int ret = _unlink( path );
- if (ret == -1 && errno == EACCES) {
- /* a first call to _unlink will fail if the file is set read-only */
- /* we can however try to change its mode first and call unlink */
- /* again... */
- ret = _chmod( path, _S_IREAD | _S_IWRITE );
- if (ret == 0)
- ret = _unlink( path );
- }
- return ret;
-#else
- return unlink(path);
-#endif
-}
-
-
-void*
-path_load_file(const char *fn, size_t *pSize)
-{
- char* data;
- int sz;
- int fd;
-
- if (pSize)
- *pSize = 0;
-
- data = NULL;
-
- fd = open(fn, O_BINARY | O_RDONLY);
- if(fd < 0) return NULL;
-
- do {
- sz = lseek(fd, 0, SEEK_END);
- if(sz < 0) break;
-
- if (pSize)
- *pSize = (size_t) sz;
-
- if (lseek(fd, 0, SEEK_SET) != 0)
- break;
-
- data = (char*) malloc(sz + 1);
- if(data == NULL) break;
-
- if (read(fd, data, sz) != sz)
- break;
-
- close(fd);
- data[sz] = 0;
-
- return data;
- } while (0);
-
- close(fd);
-
- if(data != NULL)
- free(data);
-
- return NULL;
-}
-
diff --git a/android/utils/path.h b/android/utils/path.h
deleted file mode 100644
index 10436c6..0000000
--- a/android/utils/path.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (C) 2007-2009 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_PATH_H
-#define _ANDROID_UTILS_PATH_H
-
-#include <android/utils/system.h>
-#include <stdint.h> /* for uint64_t */
-
-/** MISC FILE AND DIRECTORY HANDLING
- **/
-
-/* O_BINARY is required in the MS C library to avoid opening file
- * in text mode (the default, ahhhhh)
- */
-#if !defined(_WIN32) && !defined(O_BINARY)
-# define O_BINARY 0
-#endif
-
-/* define PATH_SEP as a string containing the directory separateor */
-#ifdef _WIN32
-# define PATH_SEP "\\"
-#else
-# define PATH_SEP "/"
-#endif
-
-/* get MAX_PATH, note that PATH_MAX is set to 260 on Windows for
- * stupid backwards-compatibility reason, though any 32-bit version
- * of the OS handles much much longer paths
- */
-#ifdef _WIN32
-# undef MAX_PATH
-# define MAX_PATH 1024
-# undef PATH_MAX
-# define PATH_MAX MAX_PATH
-#else
-# include <limits.h>
-# define MAX_PATH PATH_MAX
-#endif
-
-/* checks that a given file exists */
-extern ABool path_exists( const char* path );
-
-/* checks that a path points to a regular file */
-extern ABool path_is_regular( const char* path );
-
-/* checks that a path points to a directory */
-extern ABool path_is_dir( const char* path );
-
-/* checks that one can read/write a given (regular) file */
-extern ABool path_can_read( const char* path );
-extern ABool path_can_write( const char* path );
-
-/* try to make a directory */
-extern APosixStatus path_mkdir( const char* path, int mode );
-
-/* ensure that a given directory exists, create it if not,
- 0 on success, -1 on error */
-extern APosixStatus path_mkdir_if_needed( const char* path, int mode );
-
-/* return the size of a given file in '*psize'. returns 0 on
- * success, -1 on failure (error code in errno) */
-extern APosixStatus path_get_size( const char* path, uint64_t *psize );
-
-/* path_parent() can be used to return the n-level parent of a given directory
- * this understands . and .. when encountered in the input path.
- *
- * the returned string must be freed by the caller.
- */
-extern char* path_parent( const char* path, int levels );
-
-/** OTHER FILE UTILITIES
- **
- ** path_empty_file() creates an empty file at a given path location.
- ** if the file already exists, it is truncated without warning
- **
- ** path_copy_file() copies one file into another.
- **
- ** unlink_file() is equivalent to unlink() on Unix, on Windows,
- ** it will handle the case where _unlink() fails because the file is
- ** read-only by trying to change its access rights then calling _unlink()
- ** again.
- **
- ** these functions return 0 on success, and -1 on error
- **
- ** load_text_file() reads a file into a heap-allocated memory block,
- ** and appends a 0 to it. the caller must free it
- **/
-
-/* creates an empty file at a given location. If the file already
- * exists, it is truncated without warning. returns 0 on success,
- * or -1 on failure.
- */
-extern APosixStatus path_empty_file( const char* path );
-
-/* copies on file into another one. 0 on success, -1 on failure
- * (error code in errno). Does not work on directories */
-extern APosixStatus path_copy_file( const char* dest, const char* source );
-
-/* unlink/delete a given file. Note that on Win32, this will
- * fail if the program has an opened handle to the file
- */
-extern APosixStatus path_delete_file( const char* path );
-
-/* try to load a given file into a heap-allocated block.
- * if 'pSize' is not NULL, this will set the file's size in '*pSize'
- * note that this actually zero-terminates the file for convenience.
- * In case of failure, NULL is returned and the error code is in errno
- */
-extern void* path_load_file( const char* path, size_t *pSize );
-
-/* */
-
-#endif /* _ANDROID_UTILS_PATH_H */
diff --git a/android/utils/reflist.c b/android/utils/reflist.c
deleted file mode 100644
index bc604cd..0000000
--- a/android/utils/reflist.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/reflist.h"
-#include <stdlib.h>
-#include <string.h>
-
-void
-areflist_setEmpty(ARefList* l)
-{
- if (l->iteration > 0) {
- /* deferred empty, set all items to NULL
- * to stop iterations */
- void** items = areflist_items(l);
- memset(items, 0, l->count*sizeof(items[0]));
- l->iteration |= 1;
- } else {
- /* direct empty */
- if (l->max > 1) {
- free(l->u.items);
- l->max = 1;
- }
- }
- l->count = 0;
-}
-
-int
-areflist_indexOf(ARefList* l, void* item)
-{
- if (item) {
- void** items = (l->max == 1) ? &l->u.item0 : l->u.items;
- void** end = items + l->count;
- void** ii = items;
-
- for ( ; ii < end; ii += 1 )
- if (*ii == item)
- return (ii - items);
- }
- return -1;
-}
-
-static void
-areflist_grow(ARefList* l, int count)
-{
- int newcount = l->count + count;
- if (newcount > l->max) {
- int oldmax = l->max == 1 ? 0 : l->max;
- int newmax = oldmax;
- void** olditems = l->max == 1 ? NULL : l->u.items;
- void** newitems;
-
- while (oldmax < newcount)
- oldmax += (oldmax >> 1) + 4;
-
- newitems = realloc(olditems, newmax*sizeof(newitems[0]));
-
- l->u.items = newitems;
- l->max = (uint16_t) newmax;
- }
-}
-
-
-void
-areflist_add(ARefList* l, void* item)
-{
- if (item) {
- void** items;
-
- if (l->count >= l->max) {
- areflist_grow(l, 1);
- }
- items = areflist_items(l);
- items[l->count] = item;
- l->count += 1;
- }
-}
-
-void*
-areflist_pop(ARefList* l)
-{
- void* item = NULL;
- void** items = areflist_items(l);
-
- if (l->count > 0) {
- if (l->iteration > 0) {
- /* deferred deletion */
- int nn;
- for (nn = l->count-1; nn > 0; nn--) {
- item = items[nn];
- if (item != NULL) {
- l->count -= 1;
- return item;
- }
- }
- } else {
- /* normal pop */
- item = items[--l->count];
- if (l->count <= 0 && l->max > 1) {
- free(l->u.items);
- l->max = 1;
- }
- }
- }
- return item;
-}
-
-ABool
-areflist_del(ARefList* l, void* item)
-{
- if (item) {
- int index = areflist_indexOf(l, item);
- if (index >= 0) {
- void** items = areflist_items(l);
-
- if (l->iteration > 0) {
- /* deferred deletion */
- items[index] = NULL;
- l->iteration |= 1;
- } else {
- /* direct deletion */
- if (l->max > 1) {
- memmove(items + index, items + index + 1, l->count - index - 1);
- if (--l->count == 0) {
- free(l->u.items);
- l->max = 1;
- }
- } else {
- l->u.item0 = NULL;
- l->count = 0;
- }
- }
- return 1;
- }
- }
- return 0;
-}
-
-void
-_areflist_remove_deferred(ARefList* l)
-{
- if (l->iteration & 1) {
- /* remove all NULL elements from the array */
- void** items = areflist_items(l);
- int rr = 0;
- int ww = 0;
- for ( ; rr < l->count; rr++ ) {
- if (items[rr] != NULL)
- items[ww++] = items[rr];
- }
- l->count = (int16_t) ww;
-
- /* if the list is empty, release its array */
- if (l->count == 0 && l->max > 1) {
- free(l->u.items);
- l->max = 1;
- }
- }
- l->iteration = 0;
-}
-
-void
-areflist_copy(ARefList* dst, ARefList* src)
-{
- dst[0] = src[0];
-
- if (src->max > 1) {
- dst->u.items = malloc( dst->count*sizeof(void*) );
- dst->max = dst->count;
- }
-}
-
-void*
-areflist_get(ARefList* l, int n)
-{
- if ((unsigned)n >= (unsigned)l->count)
- return NULL;
-
- if (l->max == 1)
- return l->u.item0;
-
- return l->u.items[n];
-}
-
-void**
-areflist_at(ARefList* l, int n)
-{
- void** items;
-
- if ((unsigned)n >= (unsigned)l->count)
- return NULL;
-
- items = (l->max == 1) ? &l->u.item0 : l->u.items;
-
- return items + n;
-}
diff --git a/android/utils/reflist.h b/android/utils/reflist.h
deleted file mode 100644
index dffaef8..0000000
--- a/android/utils/reflist.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_REFLIST_H
-#define _ANDROID_UTILS_REFLIST_H
-
-#include "android/utils/system.h"
-
-/* definitions for a smart list of references to generic objects.
- * supports safe deletion and addition while they are being iterated
- * with AREFLIST_FOREACH() macro
- */
-
-typedef struct ARefList {
- uint16_t count, max;
- uint16_t iteration;
- union {
- struct ARefList* next;
- void* item0;
- void** items;
- } u;
-} ARefList;
-
-AINLINED void
-areflist_init(ARefList* l)
-{
- l->count = 0;
- l->max = 1;
- l->iteration = 0;
-}
-
-void areflist_setEmpty(ARefList* l);
-
-AINLINED void
-areflist_done(ARefList* l)
-{
- areflist_setEmpty(l);
-}
-
-AINLINED ABool
-areflist_isEmpty(ARefList* l)
-{
- return (l->count == 0);
-}
-
-int areflist_indexOf(ARefList* l, void* item);
-
-AINLINED ABool
-areflist_has(ARefList* l, void* item)
-{
- return areflist_indexOf(l, item) >= 0;
-}
-
-/* if 'item' is not NULL, append it to the list. An item
- * can be added several times to a list */
-void areflist_add(ARefList* l, void* item);
-
-/* if 'item' is not NULL, try to remove it from the list */
-/* returns TRUE iff the item was found in the list */
-ABool areflist_del(ARefList* l, void* item);
-
-AINLINED void
-areflist_push(ARefList* l, void* item)
-{
- areflist_add(l, item);
-}
-
-void* areflist_pop(ARefList* l);
-
-AINLINED void**
-areflist_items(ARefList* l)
-{
- return (l->max == 1) ? &l->u.item0 : l->u.items;
-}
-
-AINLINED int
-areflist_count(ARefList* l)
-{
- return l->count;
-}
-
-/* return a pointer to the n-th list array entry,
- or NULL in case of invalid index */
-void** areflist_at(ARefList* l, int n);
-
-/* return the n-th array entry, or NULL in case of invalid index */
-void* areflist_get(ARefList* l, int n);
-
-/* used internally */
-void _areflist_remove_deferred(ARefList* l);
-
-#define AREFLIST_FOREACH(list_,item_,statement_) \
- ({ ARefList* _reflist = (list_); \
- int _reflist_i = 0; \
- int _reflist_n = _reflist->count; \
- _reflist->iteration += 2; \
- for ( ; _reflist_i < _reflist_n; _reflist_i++ ) { \
- void** __reflist_at = areflist_at(_reflist, _reflist_i); \
- void* item_ = *__reflist_at; \
- if (item_ != NULL) { \
- statement_; \
- } \
- } \
- _reflist->iteration -= 2; \
- if (_reflist->iteration == 1) \
- _areflist_remove_deferred(_reflist); \
- })
-
-/* use this to delete the currently iterated element */
-#define AREFLIST_DEL_ITERATED() \
- ({ *_reflist_at = NULL; \
- _reflist->iteration |= 1; })
-
-/* use this to replace the currently iterated element */
-#define AREFLIST_SET_ITERATED(item) \
- ({ *_reflist_at = (item); \
- if (item == NULL) _reflist->iteration |= 1; })
-
-void areflist_copy(ARefList* dst, ARefList* src);
-
-#endif /* _ANDROID_UTILS_REFLIST_H */
diff --git a/android/utils/stralloc.c b/android/utils/stralloc.c
deleted file mode 100644
index 2a924e4..0000000
--- a/android/utils/stralloc.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include "android/utils/stralloc.h"
-#include "android/utils/debug.h"
-#include "android/utils/misc.h"
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-
-extern void
-stralloc_tabular( stralloc_t* out,
- const char** strings, int count,
- const char* prefix, int width )
-{
- int nrows, ncols, r, c, n, maxw = 0;
-
- for (n = 0; n < count; n++) {
- int len = strlen(strings[n]);
- if (len > maxw)
- maxw = len;
- }
- maxw += 2;
- ncols = width/maxw;
- nrows = (count + ncols-1)/ncols;
-
- for (r = 0; r < nrows; r++) {
- stralloc_add_str( out, prefix );
- for (c = 0; c < ncols; c++) {
- int index = c*nrows + r;
- if (index >= count) {
- break;
- }
- stralloc_add_format( out, "%-*s", maxw, strings[index] );
- }
- stralloc_add_str( out, "\n" );
- }
-}
-
-/** DYNAMIC STRINGS
- **/
-
-extern void
-stralloc_reset( stralloc_t* s )
-{
- free(s->s);
- s->s = NULL;
- s->n = 0;
- s->a = 0;
-}
-
-extern void
-stralloc_ready( stralloc_t* s, unsigned int len )
-{
- unsigned old_max = s->a;
- unsigned new_max = old_max;
-
- while (new_max < len) {
- unsigned new_max2 = new_max + (new_max >> 1) + 16;
- if (new_max2 < new_max)
- new_max2 = UINT_MAX;
- new_max = new_max2;
- }
-
- s->s = realloc( s->s, new_max );
- if (s->s == NULL) {
- derror( "%s: not enough memory to reallocate %ld bytes",
- __FUNCTION__, new_max );
- exit(1);
- }
- s->a = new_max;
-}
-
-extern void
-stralloc_readyplus( stralloc_t* s, unsigned int len )
-{
- unsigned len2 = s->n + len;
-
- if (len2 < s->n) { /* overflow ? */
- derror("%s: trying to grow by too many bytes: %ld",
- __FUNCTION__, len);
- exit(1);
- }
- stralloc_ready( s, len2 );
-}
-
-extern void
-stralloc_copy( stralloc_t* s, stralloc_t* from )
-{
- stralloc_ready(s, from->n);
- memcpy( s->s, from->s, from->n );
- s->n = from->n;
-}
-
-extern void
-stralloc_append( stralloc_t* s, stralloc_t* from )
-{
- stralloc_readyplus( s, from->n );
- memcpy( s->s + s->n, from->s, from->n );
- s->n += from->n;
-}
-
-extern void
-stralloc_add_c( stralloc_t* s, int c )
-{
- stralloc_add_bytes( s, (char*)&c, 1 );
-}
-
-extern void
-stralloc_add_str( stralloc_t* s, const char* str )
-{
- stralloc_add_bytes( s, str, strlen(str) );
-}
-
-extern void
-stralloc_add_bytes( stralloc_t* s, const void* from, unsigned len )
-{
- stralloc_readyplus( s, len );
- memcpy( s->s + s->n, from, len );
- s->n += len;
-}
-
-extern char*
-stralloc_cstr( stralloc_t* s )
-{
- stralloc_readyplus( s, 1 );
- s->s[s->n] = 0;
- return s->s;
-}
-
-extern char*
-stralloc_to_tempstr( stralloc_t* s )
-{
- char* q = tempstr_get( s->n );
-
- memcpy( q, s->s, s->n );
- q[s->n] = 0;
- return q;
-}
-
-extern void
-stralloc_formatv( stralloc_t* s, const char* fmt, va_list args )
-{
- stralloc_reset(s);
- stralloc_ready(s,10);
-
- while (1) {
- int n;
- va_list args2;
-
- va_copy(args2, args);
- n = vsnprintf( s->s, s->a, fmt, args2 );
- va_end(args2);
-
- /* funky old C libraries returns -1 when truncation occurs */
- if (n > -1 && n < s->a) {
- s->n = n;
- break;
- }
- if (n > -1) { /* we now precisely what we need */
- stralloc_ready( s, n+1 );
- } else {
- stralloc_ready( s, s->a*2 );
- }
- }
-}
-
-
-extern void
-stralloc_format( stralloc_t* s, const char* fmt, ... )
-{
- va_list args;
- va_start(args, fmt);
- stralloc_formatv(s, fmt, args);
- va_end(args);
-}
-
-extern void
-stralloc_add_formatv( stralloc_t* s, const char* fmt, va_list args )
-{
- STRALLOC_DEFINE(s2);
- stralloc_formatv(s2, fmt, args);
- stralloc_append( s, s2 );
- stralloc_reset( s2 );
-}
-
-extern void
-stralloc_add_format( stralloc_t* s, const char* fmt, ... )
-{
- va_list args;
- va_start(args, fmt);
- stralloc_add_formatv( s, fmt, args );
- va_end(args);
-}
-
-extern void
-stralloc_add_quote_c( stralloc_t* s, int c )
-{
- stralloc_add_quote_bytes( s, (char*)&c, 1 );
-}
-
-extern void
-stralloc_add_quote_str( stralloc_t* s, const char* str )
-{
- stralloc_add_quote_bytes( s, str, strlen(str) );
-}
-
-extern void
-stralloc_add_quote_bytes( stralloc_t* s, const void* from, unsigned len )
-{
- uint8_t* p = (uint8_t*) from;
- uint8_t* end = p + len;
-
- for ( ; p < end; p++ ) {
- int c = p[0];
-
- if (c == '\\') {
- stralloc_add_str( s, "\\\\" );
- } else if (c >= ' ' && c < 128) {
- stralloc_add_c( s, c );
- } else if (c == '\n') {
- stralloc_add_str( s, "\\n" );
- } else if (c == '\t') {
- stralloc_add_str( s, "\\t" );
- } else if (c == '\r') {
- stralloc_add_str( s, "\\r" );
- } else {
- stralloc_add_format( s, "\\x%02x", c );
- }
- }
-}
-
-extern void
-stralloc_add_hex( stralloc_t* s, unsigned value, int num_digits )
-{
- const char hexdigits[16] = "0123456789abcdef";
- int nn;
-
- if (num_digits <= 0)
- return;
-
- stralloc_readyplus(s, num_digits);
- for (nn = num_digits-1; nn >= 0; nn--) {
- s->s[s->n+nn] = hexdigits[value & 15];
- value >>= 4;
- }
- s->n += num_digits;
-}
-
-extern void
-stralloc_add_hexdump( stralloc_t* s, void* base, int size, const char* prefix )
-{
- uint8_t* p = (uint8_t*)base;
- const int max_count = 16;
- int prefix_len = strlen(prefix);
-
- while (size > 0) {
- int count = size > max_count ? max_count : size;
- int count2;
- int n;
-
- stralloc_add_bytes( s, prefix, prefix_len );
- stralloc_add_hex( s, p[0], 2 );
-
- for (n = 1; n < count; n++) {
- stralloc_add_c( s, ' ' );
- stralloc_add_hex( s, p[n], 2 );
- }
-
- count2 = 4 + 3*(max_count - count);
- stralloc_readyplus( s, count2 );
- memset( s->s + s->n, ' ', count2 );
- s->n += count2;
-
- stralloc_readyplus(s, count+1);
- for (n = 0; n < count; n++) {
- int c = p[n];
-
- if (c < 32 || c > 127)
- c = '.';
-
- s->s[s->n++] = c;
- }
- s->s[s->n++] = '\n';
-
- size -= count;
- p += count;
- }
-}
-
diff --git a/android/utils/stralloc.h b/android/utils/stralloc.h
deleted file mode 100644
index 4d17060..0000000
--- a/android/utils/stralloc.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef _ANDROID_UTILS_STRALLOC_H
-#define _ANDROID_UTILS_STRALLOC_H
-
-#include <stddef.h>
-#include <stdarg.h>
-
-/** DYNAMIC STRINGS
- **/
-
-typedef struct {
- char* s;
- unsigned n;
- unsigned a;
-} stralloc_t;
-
-#define STRALLOC_INIT { NULL, 0, 0 }
-#define STRALLOC_DEFINE(s) stralloc_t s[1] = { STRALLOC_INIT }
-
-extern void stralloc_reset( stralloc_t* s );
-extern void stralloc_ready( stralloc_t* s, unsigned len );
-extern void stralloc_readyplus( stralloc_t* s, unsigned len );
-
-extern void stralloc_copy( stralloc_t* s, stralloc_t* from );
-extern void stralloc_append( stralloc_t* s, stralloc_t* from );
-
-extern void stralloc_add_c( stralloc_t* s, int c );
-extern void stralloc_add_str( stralloc_t* s, const char* str );
-extern void stralloc_add_bytes( stralloc_t* s, const void* from, unsigned len );
-
-extern char* stralloc_cstr( stralloc_t* s );
-
-extern void stralloc_format( stralloc_t* s, const char* fmt, ... );
-extern void stralloc_formatv( stralloc_t* s, const char* fmt, va_list args );
-extern void stralloc_add_format( stralloc_t* s, const char* fmt, ... );
-
-extern void stralloc_add_quote_c( stralloc_t* s, int c );
-extern void stralloc_add_quote_str( stralloc_t* s, const char* str );
-extern void stralloc_add_quote_bytes( stralloc_t* s, const void* from, unsigned len );
-
-extern void stralloc_add_hex( stralloc_t* s, unsigned value, int num_digits );
-extern void stralloc_add_hexdump( stralloc_t* s, void* base, int size, const char* prefix );
-
-extern void stralloc_tabular( stralloc_t* s, const char** strings, int count,
- const char* prefix, int width );
-
-extern char* stralloc_to_tempstr( stralloc_t* s );
-
-#endif /* ANDROID_UTILS_STRALLOC_H */
diff --git a/android/utils/system.c b/android/utils/system.c
deleted file mode 100644
index e09fd6b..0000000
--- a/android/utils/system.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/system.h"
-#include <stdlib.h>
-#include <stdio.h>
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h> /* for Sleep */
-#else
-# include <unistd.h> /* for usleep */
-#endif
-
-void*
-android_alloc( size_t size )
-{
- void* block;
-
- if (size == 0)
- return NULL;
-
- block = malloc(size);
- if (block != NULL)
- return block;
-
- fprintf(stderr, "PANIC: not enough memory\n");
- exit(1);
- return NULL;
-}
-
-void*
-android_alloc0( size_t size )
-{
- void* block;
-
- if (size == 0)
- return NULL;
-
- block = calloc(1, size);
- if (block != NULL)
- return block;
-
- fprintf(stderr, "PANIC: not enough memory\n");
- exit(1);
- return NULL;
-}
-
-void*
-android_realloc( void* block, size_t size )
-{
- void* block2;
-
- if (size == 0) {
- free(block);
- return NULL;
- }
- block2 = realloc(block, size);
- if (block2 != NULL)
- return block2;
-
- fprintf(stderr, "PANIC: not enough memory to reallocate %d bytes\n", size);
- exit(1);
- return NULL;
-}
-
-void
-android_free( void* block )
-{
- if (block)
- free(block);
-}
-
-char*
-android_strdup( const char* str )
-{
- int len;
- char* copy;
-
- if (str == NULL)
- return NULL;
-
- len = strlen(str);
- copy = malloc(len+1);
- memcpy(copy, str, len);
- copy[len] = 0;
-
- return copy;
-}
-
-#ifdef _WIN32
-char*
-win32_strsep(char** pline, const char* delim)
-{
- char* line = *pline;
- char* p = line;
-
- if (p == NULL)
- return NULL;
-
- for (;;) {
- int c = *p++;
- const char* q = delim;
-
- if (c == 0) {
- p = NULL;
- break;
- }
-
- while (*q) {
- if (*q == c) {
- p[-1] = 0;
- goto Exit;
- }
- q++;
- }
- }
-Exit:
- *pline = p;
- return line;
-}
-#endif
-
-
-void
-disable_sigalrm( signal_state_t *state )
-{
-#ifdef _WIN32
- (void)state;
-#else
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
- pthread_sigmask (SIG_BLOCK, &set, &state->old);
-#endif
-}
-
-void
-restore_sigalrm( signal_state_t *state )
-{
-#ifdef _WIN32
- (void)state;
-#else
- pthread_sigmask (SIG_SETMASK, &state->old, NULL);
-#endif
-}
-
-void
-sleep_ms( int timeout_ms )
-{
-#ifdef _WIN32
- if (timeout_ms <= 0)
- return;
-
- Sleep( timeout_ms );
-#else
- if (timeout_ms <= 0)
- return;
-
- BEGIN_NOSIGALRM
- usleep( timeout_ms*1000 );
- END_NOSIGALRM
-#endif
-}
diff --git a/android/utils/system.h b/android/utils/system.h
deleted file mode 100644
index 804aa7d..0000000
--- a/android/utils/system.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_SYSTEM_H
-#define _ANDROID_UTILS_SYSTEM_H
-
-#include <string.h>
-#include <stdint.h>
-
-/* the following functions perform 'checked allocations', i.e.
- * they abort if there is not enough memory.
- */
-
-/* checked malloc, only returns NULL if size is 0 */
-void* android_alloc( size_t size );
-
-/* checked calloc, only returns NULL if size is 0 */
-void* android_alloc0( size_t size );
-
-/* checked realloc, only returns NULL if size if 0 */
-void* android_realloc( void* block, size_t size );
-
-/* free memory block */
-void android_free( void* block );
-
-/* convenience macros */
-
-#define AZERO(p) memset((char*)(p),0,sizeof(*(p)))
-#define ANEW(p) (p = android_alloc(sizeof(*p)))
-#define ANEW0(p) (p = android_alloc0(sizeof(*p)))
-#define AFREE(p) android_free(p)
-
-#define AMEM_ZERO(dst,size) memset((char*)(dst), 0, (size_t)(size))
-#define AMEM_COPY(dst,src,size) memcpy((char*)(dst),(const char*)(src),(size_t)(size))
-#define AMEM_MOVE(dst,src,size) memmove((char*)(dst),(const char*)(src),(size_t)(size))
-
-#define AARRAY_NEW(p,count) ((p) = android_alloc(sizeof(*p)*(count)))
-#define AARRAY_NEW0(p,count) ((p) = android_alloc0(sizeof(*p)*(count)))
-
-#define AARRAY_RENEW(p,count) ((p) = android_realloc((p),sizeof(*(p))*(count)))
-
-#define AARRAY_COPY(dst,src,count) AMEM_COPY(dst,src,(count)*sizeof((dst)[0]))
-#define AARRAY_MOVE(dst,src,count) AMEM_MOVE(dst,src,(count)*sizeof((dst)[0]))
-#define AARRAY_ZERO(dst,count) AMEM_ZERO(dst,(count)*sizeof((dst)[0]))
-
-#define AARRAY_STATIC_LEN(a) (sizeof((a))/sizeof((a)[0]))
-
-#define AINLINED static __inline__
-
-/* unlike strdup(), this accepts NULL as valid input (and will return NULL then) */
-char* android_strdup(const char* src);
-
-#define ASTRDUP(str) android_strdup(str)
-
-/* used for functions that return a Posix-style status code, i.e.
- * 0 means success, -1 means failure with the error code in 'errno'
- */
-typedef int APosixStatus;
-
-/* used for functions that return or accept a boolean type */
-typedef int ABool;
-
-/** Stringification macro
- **/
-#ifndef STRINGIFY
-#define _STRINGIFY(x) #x
-#define STRINGIFY(x) _STRINGIFY(x)
-#endif
-
-/** Concatenation macros
- **/
-#ifndef GLUE
-#define _GLUE(x,y) x##y
-#define GLUE(x,y) _GLUE(x,y)
-
-#define _GLUE3(x,y,z) x##y##z
-#define GLUE3(x,y,z) _GLUE3(x,y,z)
-#endif
-
-/** Handle strsep() on Win32
- **/
-#ifdef _WIN32
-# undef strsep
-# define strsep win32_strsep
-extern char* win32_strsep(char** pline, const char* delim);
-#endif
-
-/** Handle strcasecmp on Windows
- **/
-#ifdef _WIN32
-# define strcasecmp stricmp
-#endif
-
-/** EINTR HANDLING
- **
- ** since QEMU uses SIGALRM pretty extensively, having a system call returning
- ** EINTR on Unix happens very frequently. provide a simple macro to guard against
- ** this.
- **/
-
-#ifdef _WIN32
-# define CHECKED(ret, call) (ret) = (call)
-#else
-# define CHECKED(ret, call) do { (ret) = (call); } while ((ret) < 0 && errno == EINTR)
-#endif
-
-/** SIGNAL HANDLING
- **
- ** the following can be used to block SIGALRM for a given period of time.
- ** use with caution, the QEMU execution loop uses SIGALRM extensively
- **
- **/
-#ifdef _WIN32
-typedef struct { int dumy; } signal_state_t;
-#else
-#include <signal.h>
-typedef struct { sigset_t old; } signal_state_t;
-#endif
-
-extern void disable_sigalrm( signal_state_t *state );
-extern void restore_sigalrm( signal_state_t *state );
-
-#ifdef _WIN32
-
-#define BEGIN_NOSIGALRM \
- {
-
-#define END_NOSIGALRM \
- }
-
-#else /* !WIN32 */
-
-#define BEGIN_NOSIGALRM \
- { signal_state_t __sigalrm_state; \
- disable_sigalrm( &__sigalrm_state );
-
-#define END_NOSIGALRM \
- restore_sigalrm( &__sigalrm_state ); \
- }
-
-#endif /* !WIN32 */
-
-/** TIME HANDLING
- **
- ** sleep for a given time in milliseconds. note: this uses
- ** disable_sigalrm()/restore_sigalrm()
- **/
-
-extern void sleep_ms( int timeout );
-
-/* */
-
-#endif /* _ANDROID_UTILS_SYSTEM_H */
diff --git a/android/utils/tempfile.c b/android/utils/tempfile.c
deleted file mode 100644
index 6374c12..0000000
--- a/android/utils/tempfile.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include "android/utils/tempfile.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#else
-# include <unistd.h>
-#endif
-
-#define D(...) ((void)0)
-
-/** TEMP FILE SUPPORT
- **
- ** simple interface to create an empty temporary file on the system.
- **
- ** create the file with tempfile_create(), which returns a reference to a TempFile
- ** object, or NULL if your system is so weird it doesn't have a temporary directory.
- **
- ** you can then call tempfile_path() to retrieve the TempFile's real path to open
- ** it. the returned path is owned by the TempFile object and should not be freed.
- **
- ** all temporary files are destroyed when the program quits, unless you explicitely
- ** close them before that with tempfile_close()
- **/
-
-struct TempFile
-{
- const char* name;
- TempFile* next;
-};
-
-static void tempfile_atexit();
-static TempFile* _all_tempfiles;
-
-TempFile*
-tempfile_create( void )
-{
- TempFile* tempfile;
- const char* tempname = NULL;
-
-#ifdef _WIN32
- char temp_namebuff[MAX_PATH];
- char temp_dir[MAX_PATH];
- char *p = temp_dir, *end = p + sizeof(temp_dir);
- UINT retval;
-
- p = bufprint_temp_dir( p, end );
- if (p >= end) {
- D( "TEMP directory path is too long" );
- return NULL;
- }
-
- retval = GetTempFileName(temp_dir, "TMP", 0, temp_namebuff);
- if (retval == 0) {
- D( "can't create temporary file in '%s'", temp_dir );
- return NULL;
- }
-
- tempname = temp_namebuff;
-#else
-#define TEMPLATE "/tmp/.android-emulator-XXXXXX"
- int tempfd = -1;
- char template[512];
- char *p = template, *end = p + sizeof(template);
-
- p = bufprint_temp_file( p, end, "emulator-XXXXXX" );
- if (p >= end) {
- D( "Xcannot create temporary file in /tmp/android !!" );
- return NULL;
- }
-
- D( "template: %s", template );
- tempfd = mkstemp( template );
- if (tempfd < 0) {
- D("cannot create temporary file in /tmp/android !!");
- return NULL;
- }
- close(tempfd);
- tempname = template;
-#endif
- tempfile = malloc( sizeof(*tempfile) + strlen(tempname) + 1 );
- tempfile->name = (char*)(tempfile + 1);
- strcpy( (char*)tempfile->name, tempname );
-
- tempfile->next = _all_tempfiles;
- _all_tempfiles = tempfile;
-
- if ( !tempfile->next ) {
- atexit( tempfile_atexit );
- }
-
- return tempfile;
-}
-
-const char*
-tempfile_path(TempFile* temp)
-{
- return temp ? temp->name : NULL;
-}
-
-void
-tempfile_close(TempFile* tempfile)
-{
-#ifdef _WIN32
- DeleteFile(tempfile->name);
-#else
- unlink(tempfile->name);
-#endif
-}
-
-/** TEMP FILE CLEANUP
- **
- **/
-
-/* we don't expect to use many temporary files */
-#define MAX_ATEXIT_FDS 16
-
-typedef struct {
- int count;
- int fds[ MAX_ATEXIT_FDS ];
-} AtExitFds;
-
-static void
-atexit_fds_add( AtExitFds* t, int fd )
-{
- if (t->count < MAX_ATEXIT_FDS)
- t->fds[t->count++] = fd;
- else {
- dwarning("%s: over %d calls. Program exit may not cleanup all temporary files",
- __FUNCTION__, MAX_ATEXIT_FDS);
- }
-}
-
-static void
-atexit_fds_del( AtExitFds* t, int fd )
-{
- int nn;
- for (nn = 0; nn < t->count; nn++)
- if (t->fds[nn] == fd) {
- /* move the last element to the current position */
- t->count -= 1;
- t->fds[nn] = t->fds[t->count];
- break;
- }
-}
-
-static void
-atexit_fds_close_all( AtExitFds* t )
-{
- int nn;
- for (nn = 0; nn < t->count; nn++)
- close(t->fds[nn]);
-}
-
-static AtExitFds _atexit_fds[1];
-
-void
-atexit_close_fd(int fd)
-{
- if (fd >= 0)
- atexit_fds_add(_atexit_fds, fd);
-}
-
-void
-atexit_close_fd_remove(int fd)
-{
- if (fd >= 0)
- atexit_fds_del(_atexit_fds, fd);
-}
-
-static void
-tempfile_atexit( void )
-{
- TempFile* tempfile;
-
- atexit_fds_close_all( _atexit_fds );
-
- for (tempfile = _all_tempfiles; tempfile; tempfile = tempfile->next)
- tempfile_close(tempfile);
-}
diff --git a/android/utils/tempfile.h b/android/utils/tempfile.h
deleted file mode 100644
index 4264a84..0000000
--- a/android/utils/tempfile.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef _ANDROID_UTILS_TEMPFILE_H
-#define _ANDROID_UTILS_TEMPFILE_H
-
-/** TEMP FILE SUPPORT
- **
- ** simple interface to create an empty temporary file on the system.
- **
- ** create the file with tempfile_create(), which returns a reference to a TempFile
- ** object, or NULL if your system is so weird it doesn't have a temporary directory.
- **
- ** you can then call tempfile_path() to retrieve the TempFile's real path to open
- ** it. the returned path is owned by the TempFile object and should not be freed.
- **
- ** all temporary files are destroyed when the program quits, unless you explicitely
- ** close them before that with tempfile_close()
- **/
-
-typedef struct TempFile TempFile;
-
-extern TempFile* tempfile_create( void );
-extern const char* tempfile_path( TempFile* temp );
-extern void tempfile_close( TempFile* temp );
-
-/** TEMP FILE CLEANUP
- **
- ** We delete all temporary files in atexit()-registered callbacks.
- ** however, the Win32 DeleteFile is unable to remove a file unless
- ** all HANDLEs to it are closed in the terminating process.
- **
- ** Call 'atexit_close_fd' on a newly open-ed file descriptor to indicate
- ** that you want it closed in atexit() time. You should always call
- ** this function unless you're certain that the corresponding file
- ** cannot be temporary.
- **
- ** Call 'atexit_close_fd_remove' before explicitely closing a 'fd'
- **/
-extern void atexit_close_fd(int fd);
-extern void atexit_close_fd_remove(int fd);
-
-#endif /* _ANDROID_UTILS_TEMPFILE_H */
diff --git a/android/utils/timezone.c b/android/utils/timezone.c
deleted file mode 100644
index b5588a3..0000000
--- a/android/utils/timezone.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/utils/debug.h"
-#include "android/utils/timezone.h"
-#include "android/utils/bufprint.h"
-#include "android/android.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "qemu-common.h"
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(timezone)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) do { if (D_ACTIVE) fprintf(stderr, __VA_ARGS__); } while (0)
-#else
-# define D(...) ((void)0)
-#endif
-
-
-
-static const char* get_zoneinfo_timezone( void ); /* forward */
-
-static char android_timezone0[256];
-static const char* android_timezone;
-static int android_timezone_init;
-
-static int
-check_timezone_is_zoneinfo(const char* tz)
-{
- const char* slash1 = NULL, *slash2 = NULL;
-
- if (tz == NULL)
- return 0;
-
- /* the name must be of the form Area/Location or Area/Location/SubLocation */
- slash1 = strchr( tz, '/' );
- if (slash1 == NULL || slash1[1] == 0)
- return 0;
-
- slash2 = strchr( slash1+1, '/');
- if (slash2 != NULL) {
- if (slash2[1] == 0 || strchr(slash2+1, '/') != NULL)
- return 0;
- }
-
- return 1;
-}
-
-int
-timezone_set( const char* tzname )
-{
- int len;
-
- if ( !check_timezone_is_zoneinfo(tzname) )
- return -1;
-
- len = strlen(tzname);
- if (len > sizeof(android_timezone0)-1)
- return -1;
-
- strcpy( android_timezone0, tzname );
- android_timezone = android_timezone0;
- android_timezone_init = 1;
-
- return 0;
-}
-
-
-char*
-bufprint_zoneinfo_timezone( char* p, char* end )
-{
- const char* tz = get_zoneinfo_timezone();
-
- if (tz == NULL || !check_timezone_is_zoneinfo(tz))
- return bufprint(p, end, "Unknown/Unknown");
- else
- return bufprint(p, end, "%s", tz);
-}
-
-/* on OS X, the timezone directory is always /usr/share/zoneinfo
- * this makes things easy.
- */
-#ifdef __APPLE__
-
-#include <unistd.h>
-#include <limits.h>
-#define LOCALTIME_FILE "/etc/localtime"
-#define ZONEINFO_DIR "/usr/share/zoneinfo/"
-static const char*
-get_zoneinfo_timezone( void )
-{
- if (!android_timezone_init) {
- const char* tz = getenv("TZ");
- char buff[PATH_MAX+1];
-
- android_timezone_init = 1;
- if (tz == NULL) {
- int len = readlink(LOCALTIME_FILE, buff, sizeof(buff));
- if (len < 0) {
- dprint( "### WARNING: Could not read %s, something is very wrong on your system",
- LOCALTIME_FILE);
- return NULL;
- }
-
- buff[len] = 0;
- D("%s: %s points to %s\n", __FUNCTION__, LOCALTIME_FILE, buff);
- if ( memcmp(buff, ZONEINFO_DIR, sizeof(ZONEINFO_DIR)-1) ) {
- dprint( "### WARNING: %s does not point to %s, can't determine zoneinfo timezone name",
- LOCALTIME_FILE, ZONEINFO_DIR );
- return NULL;
- }
- tz = buff + sizeof(ZONEINFO_DIR)-1;
- if ( !check_timezone_is_zoneinfo(tz) ) {
- dprint( "### WARNING: %s does not point to zoneinfo-compatible timezone name\n", LOCALTIME_FILE );
- return NULL;
- }
- }
- pstrcpy( android_timezone0, sizeof(android_timezone0), tz );
- android_timezone = android_timezone0;
- }
- D( "found timezone %s", android_timezone );
- return android_timezone;
-}
-
-#endif /* __APPLE__ */
-
-/* on Linux, with glibc2, the zoneinfo directory can be changed with TZDIR environment variable
- * but should be /usr/share/zoneinfo by default. /etc/localtime is not guaranteed to exist on
- * all platforms, so if it doesn't, try $TZDIR/localtime, then /usr/share/zoneinfo/locatime
- * ugly, isn't it ?
- *
- * besides, modern Linux distribution don't make /etc/localtime a symlink but a straight copy of
- * the original timezone file. the only way to know which zoneinfo name to retrieve is to compare
- * it with all files in $TZDIR (at least those that match Area/Location or Area/Location/SubLocation
- */
-#ifdef __linux__
-
-#include <unistd.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-
-#define ZONEINFO_DIR "/usr/share/zoneinfo/"
-#define LOCALTIME_FILE1 "/etc/localtime"
-
-typedef struct {
- const char* localtime;
- struct stat localtime_st;
- char* path_end;
- char* path_root;
- char path[ PATH_MAX ];
-} ScanDataRec;
-
-static int
-compare_timezone_to_localtime( ScanDataRec* scan,
- const char* path )
-{
- struct stat st;
- int fd1, fd2, result = 0;
-
- D( "%s: comparing %s:", __FUNCTION__, path );
-
- if ( stat( path, &st ) < 0 ) {
- D( " can't stat: %s\n", strerror(errno) );
- return 0;
- }
-
- if ( st.st_size != scan->localtime_st.st_size ) {
- D( " size mistmatch (%lld != %lld)\n", st.st_size, scan->localtime_st.st_size );
- return 0;
- }
-
- fd1 = open( scan->localtime, O_RDONLY );
- if (fd1 < 0) {
- D(" can't open %s: %s\n", scan->localtime, strerror(errno) );
- return 0;
- }
- fd2 = open( path, O_RDONLY );
- if (fd2 < 0) {
- D(" can't open %s: %s\n", path, strerror(errno) );
- close(fd1);
- return 0;
- }
- do {
- off_t nn;
-
- for (nn = 0; nn < st.st_size; nn++) {
- char temp[2];
- int ret;
-
- do { ret = read(fd1, &temp[0], 1); } while (ret < 0 && errno == EINTR);
- if (ret < 0) break;
-
- do { ret = read(fd2, &temp[1], 1); } while (ret < 0 && errno == EINTR);
- if (ret < 0) break;
-
- if (temp[0] != temp[1])
- break;
- }
-
- result = (nn == st.st_size);
-
- } while (0);
-
- D( result ? " MATCH\n" : "no match\n" );
-
- close(fd2);
- close(fd1);
-
- return result;
-}
-
-static const char*
-scan_timezone_dir( ScanDataRec* scan,
- char* top,
- int depth )
-{
- DIR* d = opendir( scan->path );
- const char* result = NULL;
-
- D( "%s: entering '%s\n", __FUNCTION__, scan->path );
- if (d != NULL) {
- struct dirent* ent;
- while ((ent = readdir(d)) != NULL) {
- struct stat ent_st;
- char* p = top;
-
- if (ent->d_name[0] == '.') /* avoid hidden and special files */
- continue;
-
- p = bufprint( p, scan->path_end, "/%s", ent->d_name );
- if (p >= scan->path_end)
- continue;
-
- //D( "%s: scanning '%s'\n", __FUNCTION__, scan->path );
-
- if ( stat( scan->path, &ent_st ) < 0 )
- continue;
-
- if ( S_ISDIR(ent_st.st_mode) && depth < 2 )
- {
- //D( "%s: directory '%s'\n", __FUNCTION__, scan->path );
- result = scan_timezone_dir( scan, p, depth + 1 );
- if (result != NULL)
- break;
- }
- else if ( S_ISREG(ent_st.st_mode) && (depth >= 1 && depth <= 2) )
- {
- char* name = scan->path_root + 1;
-
- if ( check_timezone_is_zoneinfo( name ) )
- {
- if (compare_timezone_to_localtime( scan, scan->path ))
- {
- result = strdup( name );
- D( "%s: found '%s'\n", __FUNCTION__, result );
- break;
- }
- }
- else
- {
- //D( "%s: ignoring '%s'\n", __FUNCTION__, scan->path );
- }
- }
- }
- closedir(d);
- }
- return result;
-}
-
-static const char*
-get_zoneinfo_timezone( void )
-{
- if (!android_timezone_init)
- {
- const char* tz = getenv( "TZ" );
-
- android_timezone_init = 1;
-
- if ( tz != NULL && !check_timezone_is_zoneinfo(tz) ) {
- D( "%s: ignoring non zoneinfo formatted TZ environment variable: '%s'\n",
- __FUNCTION__, tz );
- tz = NULL;
- }
-
- if (tz == NULL) {
- char* tzdir = NULL;
- int tzdirlen = 0;
- char* localtime = NULL;
- int len;
- char temp[ PATH_MAX ];
-
- /* determine the correct timezone directory */
- {
- const char* env = getenv("TZDIR");
- const char* zoneinfo_dir = ZONEINFO_DIR;
-
- if (env == NULL)
- env = zoneinfo_dir;
-
- if ( access( env, R_OK ) != 0 ) {
- if ( env == zoneinfo_dir ) {
- fprintf( stderr,
- "### WARNING: could not find %s directory. unable to determine host timezone\n", env );
- } else {
- D( "%s: TZDIR does not point to valid directory, using %s instead\n",
- __FUNCTION__, zoneinfo_dir );
- env = zoneinfo_dir;
- }
- return NULL;
- }
- tzdir = strdup(env);
- }
-
- /* remove trailing slash, if any */
- len = strlen(tzdir);
- if (len > 0 && tzdir[len-1] == '/') {
- tzdir[len-1] = 0;
- len -= 1;
- }
- tzdirlen = len;
- D( "%s: found timezone dir as %s\n", __FUNCTION__, tzdir );
-
- /* try to find the localtime file */
- localtime = LOCALTIME_FILE1;
- if ( access( localtime, R_OK ) != 0 ) {
- char *p = temp, *end = p + sizeof(temp);
-
- p = bufprint( p, end, "%s/%s", tzdir, "localtime" );
- if (p >= end || access( temp, R_OK ) != 0 ) {
- fprintf( stderr, "### WARNING: could not find %s or %s. unable to determine host timezone\n",
- LOCALTIME_FILE1, temp );
- goto Exit;
- }
- localtime = temp;
- }
- localtime = strdup(localtime);
- D( "%s: found localtime file as %s\n", __FUNCTION__, localtime );
-
-#if 1
- /* if the localtime file is a link, make a quick check */
- len = readlink( localtime, temp, sizeof(temp)-1 );
- if (len >= 0 && len > tzdirlen + 2) {
- temp[len] = 0;
-
- /* verify that the link points to tzdir/<something> where <something> is a valid zoneinfo name */
- if ( !memcmp( temp, tzdir, tzdirlen ) && temp[tzdirlen] == '/' ) {
- if ( check_timezone_is_zoneinfo( temp + tzdirlen + 1 ) ) {
- /* we have it ! */
- tz = temp + tzdirlen + 1;
- D( "%s: found zoneinfo timezone %s from %s symlink\n", __FUNCTION__, tz, localtime );
- goto Exit;
- }
- D( "%s: %s link points to non-zoneinfo filename %s, comparing contents\n",
- __FUNCTION__, localtime, temp );
- }
- }
-#endif
-
- /* otherwise, parse all files under tzdir and see if we have something that looks like it */
- {
- ScanDataRec scan[1];
-
- if ( stat( localtime, &scan->localtime_st ) < 0 ) {
- fprintf( stderr, "### WARNING: can't access '%s', unable to determine host timezone\n",
- localtime );
- goto Exit;
- }
-
- scan->localtime = localtime;
- scan->path_end = scan->path + sizeof(scan->path);
- scan->path_root = bufprint( scan->path, scan->path_end, "%s", tzdir );
-
- tz = scan_timezone_dir( scan, scan->path_root, 0 );
- }
-
- Exit:
- if (tzdir)
- free(tzdir);
- if (localtime)
- free(localtime);
-
- if (tz == NULL)
- return NULL;
-
- pstrcpy( android_timezone0, sizeof(android_timezone0), tz );
- android_timezone = android_timezone0;
- }
- D( "found timezone %s\n", android_timezone );
- }
- return android_timezone;
-}
-
-#endif /* __linux__ */
-
-
-/* on Windows, we need to translate the Windows timezone into a ZoneInfo one */
-#ifdef _WIN32
-#include <time.h>
-
-typedef struct {
- const char* win_name;
- const char* zoneinfo_name;
-} Win32Timezone;
-
-/* table generated from http://unicode.org/cldr/data/diff/supplemental/windows_tzid.html */
-static const Win32Timezone _win32_timezones[] = {
- { "AUS Central Standard Time" , "Australia/Darwin" },
- { "AUS Eastern Standard Time" , "Australia/Sydney" },
- { "Acre Standard Time" , "America/Rio_Branco" },
- { "Afghanistan Standard Time" , "Asia/Kabul" },
- { "Africa_Central Standard Time" , "Africa/Kigali" },
- { "Africa_Eastern Standard Time" , "Africa/Kampala" },
- { "Africa_FarWestern Standard Time" , "Africa/El_Aaiun" },
- { "Africa_Southern Standard Time" , "Africa/Johannesburg" },
- { "Africa_Western Standard Time" , "Africa/Niamey" },
- { "Aktyubinsk Standard Time" , "Asia/Aqtobe" },
- { "Alaska Standard Time" , "America/Juneau" },
- { "Alaska_Hawaii Standard Time" , "America/Anchorage" },
- { "Alaskan Standard Time" , "America/Anchorage" },
- { "Almaty Standard Time" , "Asia/Almaty" },
- { "Amazon Standard Time" , "America/Manaus" },
- { "America_Central Standard Time" , "America/Winnipeg" },
- { "America_Eastern Standard Time" , "America/Panama" },
- { "America_Mountain Standard Time" , "America/Edmonton" },
- { "America_Pacific Standard Time" , "America/Vancouver" },
- { "Anadyr Standard Time" , "Asia/Anadyr" },
- { "Aqtau Standard Time" , "Asia/Aqtau" },
- { "Aqtobe Standard Time" , "Asia/Aqtobe" },
- { "Arab Standard Time" , "Asia/Riyadh" },
- { "Arabian Standard Time" , "Asia/Bahrain" },
- { "Arabic Standard Time" , "Asia/Baghdad" },
- { "Argentina Standard Time" , "America/Buenos_Aires" },
- { "Argentina_Western Standard Time" , "America/Mendoza" },
- { "Armenia Standard Time" , "Asia/Yerevan" },
- { "Ashkhabad Standard Time" , "Asia/Ashgabat" },
- { "Atlantic Standard Time" , "America/Curacao" },
- { "Australia_Central Standard Time" , "Australia/Adelaide" },
- { "Australia_CentralWestern Standard Time", "Australia/Eucla" },
- { "Australia_Eastern Standard Time" , "Australia/Sydney" },
- { "Australia_Western Standard Time" , "Australia/Perth" },
- { "Azerbaijan Standard Time" , "Asia/Baku" },
- { "Azores Standard Time" , "Atlantic/Azores" },
- { "Baku Standard Time" , "Asia/Baku" },
- { "Bangladesh Standard Time" , "Asia/Dhaka" },
- { "Bering Standard Time" , "America/Adak" },
- { "Bhutan Standard Time" , "Asia/Thimphu" },
- { "Bolivia Standard Time" , "America/La_Paz" },
- { "Borneo Standard Time" , "Asia/Kuching" },
- { "Brasilia Standard Time" , "America/Sao_Paulo" },
- { "British Standard Time" , "Europe/London" },
- { "Brunei Standard Time" , "Asia/Brunei" },
- { "Canada Central Standard Time" , "America/Regina" },
- { "Cape Verde Standard Time" , "Atlantic/Cape_Verde" },
- { "Cape_Verde Standard Time" , "Atlantic/Cape_Verde" },
- { "Caucasus Standard Time" , "Asia/Yerevan" },
- { "Cen. Australia Standard Time" , "Australia/Adelaide" },
- { "Central Standard Time" , "America/Chicago" },
- { "Central America Standard Time" , "America/Guatemala" },
- { "Central Asia Standard Time" , "Asia/Dhaka" },
- { "Central Brazilian Standard Time" , "America/Manaus" },
- { "Central Europe Standard Time" , "Europe/Prague" },
- { "Central European Standard Time" , "Europe/Warsaw" },
- { "Central Pacific Standard Time" , "Pacific/Guadalcanal" },
- { "Central Standard Time (Mexico)" , "America/Mexico_City" },
- { "Chamorro Standard Time" , "Pacific/Guam" },
- { "Changbai Standard Time" , "Asia/Harbin" },
- { "Chatham Standard Time" , "Pacific/Chatham" },
- { "Chile Standard Time" , "America/Santiago" },
- { "China Standard Time" , "Asia/Taipei" },
- { "Choibalsan Standard Time" , "Asia/Choibalsan" },
- { "Christmas Standard Time" , "Indian/Christmas" },
- { "Cocos Standard Time" , "Indian/Cocos" },
- { "Colombia Standard Time" , "America/Bogota" },
- { "Cook Standard Time" , "Pacific/Rarotonga" },
- { "Cuba Standard Time" , "America/Havana" },
- { "Dacca Standard Time" , "Asia/Dhaka" },
- { "Dateline Standard Time" , "Pacific/Kwajalein" },
- { "Davis Standard Time" , "Antarctica/Davis" },
- { "Dominican Standard Time" , "America/Santo_Domingo" },
- { "DumontDUrville Standard Time" , "Antarctica/DumontDUrville" },
- { "Dushanbe Standard Time" , "Asia/Dushanbe" },
- { "Dutch_Guiana Standard Time" , "America/Paramaribo" },
- { "E. Africa Standard Time" , "Africa/Nairobi" },
- { "E. Australia Standard Time" , "Australia/Brisbane" },
- { "E. Europe Standard Time" , "Europe/Minsk" },
- { "E. South America Standard Time" , "America/Sao_Paulo" },
- { "East_Timor Standard Time" , "Asia/Dili" },
- { "Easter Standard Time" , "Pacific/Easter" },
- { "Eastern Standard Time" , "America/New_York" },
- { "Ecuador Standard Time" , "America/Guayaquil" },
- { "Egypt Standard Time" , "Africa/Cairo" },
- { "Ekaterinburg Standard Time" , "Asia/Yekaterinburg" },
- { "Europe_Central Standard Time" , "Europe/Oslo" },
- { "Europe_Eastern Standard Time" , "Europe/Vilnius" },
- { "Europe_Western Standard Time" , "Atlantic/Canary" },
- { "FLE Standard Time" , "Europe/Helsinki" },
- { "Falkland Standard Time" , "Atlantic/Stanley" },
- { "Fiji Standard Time" , "Pacific/Fiji" },
- { "French_Guiana Standard Time" , "America/Cayenne" },
- { "French_Southern Standard Time" , "Indian/Kerguelen" },
- { "Frunze Standard Time" , "Asia/Bishkek" },
- { "GMT Standard Time" , "Europe/Dublin" },
- { "GTB Standard Time" , "Europe/Istanbul" },
- { "Galapagos Standard Time" , "Pacific/Galapagos" },
- { "Gambier Standard Time" , "Pacific/Gambier" },
- { "Georgia Standard Time" , "Asia/Tbilisi" },
- { "Georgian Standard Time" , "Asia/Tbilisi" },
- { "Gilbert_Islands Standard Time" , "Pacific/Tarawa" },
- { "Goose_Bay Standard Time" , "America/Goose_Bay" },
- { "Greenland Standard Time" , "America/Godthab" },
- { "Greenland_Central Standard Time" , "America/Scoresbysund" },
- { "Greenland_Eastern Standard Time" , "America/Scoresbysund" },
- { "Greenland_Western Standard Time" , "America/Godthab" },
- { "Greenwich Standard Time" , "Africa/Casablanca" },
- { "Guam Standard Time" , "Pacific/Guam" },
- { "Gulf Standard Time" , "Asia/Muscat" },
- { "Guyana Standard Time" , "America/Guyana" },
- { "Hawaii_Aleutian Standard Time" , "Pacific/Honolulu" },
- { "Hawaiian Standard Time" , "Pacific/Honolulu" },
- { "Hong_Kong Standard Time" , "Asia/Hong_Kong" },
- { "Hovd Standard Time" , "Asia/Hovd" },
- { "India Standard Time" , "Asia/Calcutta" },
- { "Indian_Ocean Standard Time" , "Indian/Chagos" },
- { "Indochina Standard Time" , "Asia/Vientiane" },
- { "Indonesia_Central Standard Time" , "Asia/Makassar" },
- { "Indonesia_Eastern Standard Time" , "Asia/Jayapura" },
- { "Indonesia_Western Standard Time" , "Asia/Jakarta" },
- { "Iran Standard Time" , "Asia/Tehran" },
- { "Irish Standard Time" , "Europe/Dublin" },
- { "Irkutsk Standard Time" , "Asia/Irkutsk" },
- { "Israel Standard Time" , "Asia/Jerusalem" },
- { "Japan Standard Time" , "Asia/Tokyo" },
- { "Jordan Standard Time" , "Asia/Amman" },
- { "Kamchatka Standard Time" , "Asia/Kamchatka" },
- { "Karachi Standard Time" , "Asia/Karachi" },
- { "Kashgar Standard Time" , "Asia/Kashgar" },
- { "Kazakhstan_Eastern Standard Time" , "Asia/Almaty" },
- { "Kazakhstan_Western Standard Time" , "Asia/Aqtobe" },
- { "Kizilorda Standard Time" , "Asia/Qyzylorda" },
- { "Korea Standard Time" , "Asia/Seoul" },
- { "Kosrae Standard Time" , "Pacific/Kosrae" },
- { "Krasnoyarsk Standard Time" , "Asia/Krasnoyarsk" },
- { "Kuybyshev Standard Time" , "Europe/Samara" },
- { "Kwajalein Standard Time" , "Pacific/Kwajalein" },
- { "Kyrgystan Standard Time" , "Asia/Bishkek" },
- { "Lanka Standard Time" , "Asia/Colombo" },
- { "Liberia Standard Time" , "Africa/Monrovia" },
- { "Line_Islands Standard Time" , "Pacific/Kiritimati" },
- { "Long_Shu Standard Time" , "Asia/Chongqing" },
- { "Lord_Howe Standard Time" , "Australia/Lord_Howe" },
- { "Macau Standard Time" , "Asia/Macau" },
- { "Magadan Standard Time" , "Asia/Magadan" },
- { "Malaya Standard Time" , "Asia/Kuala_Lumpur" },
- { "Malaysia Standard Time" , "Asia/Kuching" },
- { "Maldives Standard Time" , "Indian/Maldives" },
- { "Marquesas Standard Time" , "Pacific/Marquesas" },
- { "Marshall_Islands Standard Time" , "Pacific/Majuro" },
- { "Mauritius Standard Time" , "Indian/Mauritius" },
- { "Mawson Standard Time" , "Antarctica/Mawson" },
- { "Mexico Standard Time" , "America/Mexico_City" },
- { "Mexico Standard Time 2 Standard Time" , "America/Chihuahua" },
- { "Mid-Atlantic Standard Time" , "America/Noronha" },
- { "Middle East Standard Time" , "Asia/Beirut" },
- { "Mongolia Standard Time" , "Asia/Ulaanbaatar" },
- { "Montevideo Standard Time" , "America/Montevideo" },
- { "Moscow Standard Time" , "Europe/Moscow" },
- { "Mountain Standard Time" , "America/Denver" },
- { "Mountain Standard Time (Mexico)" , "America/Chihuahua" },
- { "Myanmar Standard Time" , "Asia/Rangoon" },
- { "N. Central Asia Standard Time" , "Asia/Novosibirsk" },
- { "Namibia Standard Time" , "Africa/Windhoek" },
- { "Nauru Standard Time" , "Pacific/Nauru" },
- { "Nepal Standard Time" , "Asia/Katmandu" },
- { "New Zealand Standard Time" , "Pacific/Auckland" },
- { "New_Caledonia Standard Time" , "Pacific/Noumea" },
- { "New_Zealand Standard Time" , "Pacific/Auckland" },
- { "Newfoundland Standard Time" , "America/St_Johns" },
- { "Niue Standard Time" , "Pacific/Niue" },
- { "Norfolk Standard Time" , "Pacific/Norfolk" },
- { "Noronha Standard Time" , "America/Noronha" },
- { "North Asia Standard Time" , "Asia/Krasnoyarsk" },
- { "North Asia East Standard Time" , "Asia/Ulaanbaatar" },
- { "North_Mariana Standard Time" , "Pacific/Saipan" },
- { "Novosibirsk Standard Time" , "Asia/Novosibirsk" },
- { "Omsk Standard Time" , "Asia/Omsk" },
- { "Oral Standard Time" , "Asia/Oral" },
- { "Pacific Standard Time" , "America/Los_Angeles" },
- { "Pacific SA Standard Time" , "America/Santiago" },
- { "Pacific Standard Time (Mexico)" , "America/Tijuana" },
- { "Pakistan Standard Time" , "Asia/Karachi" },
- { "Palau Standard Time" , "Pacific/Palau" },
- { "Papua_New_Guinea Standard Time" , "Pacific/Port_Moresby" },
- { "Paraguay Standard Time" , "America/Asuncion" },
- { "Peru Standard Time" , "America/Lima" },
- { "Philippines Standard Time" , "Asia/Manila" },
- { "Phoenix_Islands Standard Time" , "Pacific/Enderbury" },
- { "Pierre_Miquelon Standard Time" , "America/Miquelon" },
- { "Pitcairn Standard Time" , "Pacific/Pitcairn" },
- { "Ponape Standard Time" , "Pacific/Ponape" },
- { "Qyzylorda Standard Time" , "Asia/Qyzylorda" },
- { "Reunion Standard Time" , "Indian/Reunion" },
- { "Romance Standard Time" , "Europe/Paris" },
- { "Rothera Standard Time" , "Antarctica/Rothera" },
- { "Russian Standard Time" , "Europe/Moscow" },
- { "SA Eastern Standard Time" , "America/Buenos_Aires" },
- { "SA Pacific Standard Time" , "America/Bogota" },
- { "SA Western Standard Time" , "America/Caracas" },
- { "SE Asia Standard Time" , "Asia/Bangkok" },
- { "Sakhalin Standard Time" , "Asia/Sakhalin" },
- { "Samara Standard Time" , "Europe/Samara" },
- { "Samarkand Standard Time" , "Asia/Samarkand" },
- { "Samoa Standard Time" , "Pacific/Apia" },
- { "Seychelles Standard Time" , "Indian/Mahe" },
- { "Shevchenko Standard Time" , "Asia/Aqtau" },
- { "Singapore Standard Time" , "Asia/Singapore" },
- { "Solomon Standard Time" , "Pacific/Guadalcanal" },
- { "South Africa Standard Time" , "Africa/Johannesburg" },
- { "South_Georgia Standard Time" , "Atlantic/South_Georgia" },
- { "Sri Lanka Standard Time" , "Asia/Colombo" },
- { "Suriname Standard Time" , "America/Paramaribo" },
- { "Sverdlovsk Standard Time" , "Asia/Yekaterinburg" },
- { "Syowa Standard Time" , "Antarctica/Syowa" },
- { "Tahiti Standard Time" , "Pacific/Tahiti" },
- { "Taipei Standard Time" , "Asia/Taipei" },
- { "Tajikistan Standard Time" , "Asia/Dushanbe" },
- { "Tashkent Standard Time" , "Asia/Tashkent" },
- { "Tasmania Standard Time" , "Australia/Hobart" },
- { "Tbilisi Standard Time" , "Asia/Tbilisi" },
- { "Tokelau Standard Time" , "Pacific/Fakaofo" },
- { "Tokyo Standard Time" , "Asia/Tokyo" },
- { "Tonga Standard Time" , "Pacific/Tongatapu" },
- { "Truk Standard Time" , "Pacific/Truk" },
- { "Turkey Standard Time" , "Europe/Istanbul" },
- { "Turkmenistan Standard Time" , "Asia/Ashgabat" },
- { "Tuvalu Standard Time" , "Pacific/Funafuti" },
- { "US Eastern Standard Time" , "America/Indianapolis" },
- { "US Mountain Standard Time" , "America/Phoenix" },
- { "Uralsk Standard Time" , "Asia/Oral" },
- { "Uruguay Standard Time" , "America/Montevideo" },
- { "Urumqi Standard Time" , "Asia/Urumqi" },
- { "Uzbekistan Standard Time" , "Asia/Tashkent" },
- { "Vanuatu Standard Time" , "Pacific/Efate" },
- { "Venezuela Standard Time" , "America/Caracas" },
- { "Vladivostok Standard Time" , "Asia/Vladivostok" },
- { "Volgograd Standard Time" , "Europe/Volgograd" },
- { "Vostok Standard Time" , "Antarctica/Vostok" },
- { "W. Australia Standard Time" , "Australia/Perth" },
- { "W. Central Africa Standard Time" , "Africa/Lagos" },
- { "W. Europe Standard Time" , "Europe/Berlin" },
- { "Wake Standard Time" , "Pacific/Wake" },
- { "Wallis Standard Time" , "Pacific/Wallis" },
- { "West Asia Standard Time" , "Asia/Karachi" },
- { "West Pacific Standard Time" , "Pacific/Guam" },
- { "Yakutsk Standard Time" , "Asia/Yakutsk" },
- { "Yekaterinburg Standard Time" , "Asia/Yekaterinburg" },
- { "Yerevan Standard Time" , "Asia/Yerevan" },
- { "Yukon Standard Time" , "America/Yakutat" },
- { NULL, NULL }
-};
-
-static const char*
-get_zoneinfo_timezone( void )
-{
- if (!android_timezone_init)
- {
- char tzname[128];
- time_t t = time(NULL);
- struct tm* tm = localtime(&t);
- const Win32Timezone* win32tz = _win32_timezones;
-
- android_timezone_init = 1;
-
- if (!tm) {
- D("%s: could not determine current date/time\n", __FUNCTION__);
- return NULL;
- }
-
- memset(tzname, 0, sizeof(tzname));
- strftime(tzname, sizeof(tzname) - 1, "%Z", tm);
-
- for (win32tz = _win32_timezones; win32tz->win_name != NULL; win32tz++)
- if ( !strcmp(win32tz->win_name, tzname) ) {
- android_timezone = win32tz->zoneinfo_name;
- goto Exit;
- }
-
-#if 0 /* TODO */
- /* we didn't find it, this may come from localized versions of Windows. we're going to explore the registry,
- * as the code in Postgresql does...
- */
-#endif
- D( "%s: could not determine current timezone\n", __FUNCTION__ );
- return NULL;
- }
-Exit:
- D( "emulator: found timezone %s\n", android_timezone );
- return android_timezone;
-}
-
-#endif /* _WIN32 */
-
diff --git a/android/utils/timezone.h b/android/utils/timezone.h
deleted file mode 100644
index bf5f731..0000000
--- a/android/utils/timezone.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _ANDROID_UTILS_TIMEZONE_H
-#define _ANDROID_UTILS_TIMEZONE_H
-
-/* try to set the default host timezone, returns 0 on success, or -1 if
- * 'tzname' is not in zoneinfo format (e.g. Area/Location)
- */
-extern int timezone_set( const char* tzname );
-
-/* append the current host "zoneinfo" timezone name to a given buffer. note
- * that this is something like "America/Los_Angeles", and not the human-friendly "PST"
- * this is required by the Android emulated system...
- *
- * the implementation of this function is really tricky and is OS-dependent
- * on Unix systems, it needs to cater to the TZ environment variable, uhhh
- *
- * if TZ is defined to something like "CET" or "PST", this will return the name "Unknown/Unknown"
- */
-extern char* bufprint_zoneinfo_timezone( char* buffer, char* end );
-
-#endif /* _ANDROID_UTILS_TIMEZONE_H */
diff --git a/arm-dis.c b/arm-dis.c
deleted file mode 100644
index ee44292..0000000
--- a/arm-dis.c
+++ /dev/null
@@ -1,4165 +0,0 @@
-/* Instruction printing code for the ARM
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- 2007, Free Software Foundation, Inc.
- Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
- Modification by James G. Smith (jsmith@cygnus.co.uk)
-
- This file is part of libopcodes.
-
- This program is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Start of qemu specific additions. Mostly this is stub definitions
- for things we don't care about. */
-
-#include "dis-asm.h"
-#define FALSE 0
-#define TRUE (!FALSE)
-#define ATTRIBUTE_UNUSED __attribute__((unused))
-#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
-
-#define ARM_EXT_V1 0
-#define ARM_EXT_V2 0
-#define ARM_EXT_V2S 0
-#define ARM_EXT_V3 0
-#define ARM_EXT_V3M 0
-#define ARM_EXT_V4 0
-#define ARM_EXT_V4T 0
-#define ARM_EXT_V5 0
-#define ARM_EXT_V5T 0
-#define ARM_EXT_V5ExP 0
-#define ARM_EXT_V5E 0
-#define ARM_EXT_V5J 0
-#define ARM_EXT_V6 0
-#define ARM_EXT_V6K 0
-#define ARM_EXT_V6Z 0
-#define ARM_EXT_V6T2 0
-#define ARM_EXT_V7 0
-#define ARM_EXT_DIV 0
-
-/* Co-processor space extensions. */
-#define ARM_CEXT_XSCALE 0
-#define ARM_CEXT_MAVERICK 0
-#define ARM_CEXT_IWMMXT 0
-
-#define FPU_FPA_EXT_V1 0
-#define FPU_FPA_EXT_V2 0
-#define FPU_VFP_EXT_NONE 0
-#define FPU_VFP_EXT_V1xD 0
-#define FPU_VFP_EXT_V1 0
-#define FPU_VFP_EXT_V2 0
-#define FPU_MAVERICK 0
-#define FPU_VFP_EXT_V3 0
-#define FPU_NEON_EXT_V1 0
-
-int floatformat_ieee_single_little;
-/* Assume host uses ieee float. */
-static void floatformat_to_double (int *ignored, unsigned char *data,
- double *dest)
-{
- union {
- uint32_t i;
- float f;
- } u;
- u.i = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
- *dest = u.f;
-}
-
-/* End of qemu specific additions. */
-
-/* FIXME: Belongs in global header. */
-#ifndef strneq
-#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
-#endif
-
-#ifndef NUM_ELEM
-#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
-#endif
-
-struct opcode32
-{
- unsigned long arch; /* Architecture defining this insn. */
- unsigned long value, mask; /* Recognise insn if (op&mask)==value. */
- const char *assembler; /* How to disassemble this insn. */
-};
-
-struct opcode16
-{
- unsigned long arch; /* Architecture defining this insn. */
- unsigned short value, mask; /* Recognise insn if (op&mask)==value. */
- const char *assembler; /* How to disassemble this insn. */
-};
-
-/* print_insn_coprocessor recognizes the following format control codes:
-
- %% %
-
- %c print condition code (always bits 28-31 in ARM mode)
- %q print shifter argument
- %u print condition code (unconditional in ARM mode)
- %A print address for ldc/stc/ldf/stf instruction
- %B print vstm/vldm register list
- %C print vstr/vldr address operand
- %I print cirrus signed shift immediate: bits 0..3|4..6
- %F print the COUNT field of a LFM/SFM instruction.
- %P print floating point precision in arithmetic insn
- %Q print floating point precision in ldf/stf insn
- %R print floating point rounding mode
-
- %<bitfield>r print as an ARM register
- %<bitfield>d print the bitfield in decimal
- %<bitfield>k print immediate for VFPv3 conversion instruction
- %<bitfield>x print the bitfield in hex
- %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
- %<bitfield>f print a floating point constant if >7 else a
- floating point register
- %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
- %<bitfield>g print as an iWMMXt 64-bit register
- %<bitfield>G print as an iWMMXt general purpose or control register
- %<bitfield>D print as a NEON D register
- %<bitfield>Q print as a NEON Q register
-
- %y<code> print a single precision VFP reg.
- Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
- %z<code> print a double precision VFP reg
- Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
-
- %<bitfield>'c print specified char iff bitfield is all ones
- %<bitfield>`c print specified char iff bitfield is all zeroes
- %<bitfield>?ab... select from array of values in big endian order
-
- %L print as an iWMMXt N/M width field.
- %Z print the Immediate of a WSHUFH instruction.
- %l like 'A' except use byte offsets for 'B' & 'H'
- versions.
- %i print 5-bit immediate in bits 8,3..0
- (print "32" when 0)
- %r print register offset address for wldt/wstr instruction
-*/
-
-/* Common coprocessor opcodes shared between Arm and Thumb-2. */
-
-static const struct opcode32 coprocessor_opcodes[] =
-{
- /* XScale instructions. */
- {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
- {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
-
- /* Intel Wireless MMX technology instructions. */
-#define FIRST_IWMMXT_INSN 0x0e130130
-#define IWMMXT_INSN_COUNT 73
- {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
- {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
- {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
- {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
- {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
- {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
- {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
- {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
- {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
- {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
- {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
- {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
- {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
- {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
- {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
- {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
- {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
- {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
- {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
- {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
- {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
- {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
- {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
- {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
- {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
- {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
- {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
- {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
- {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
-
- /* Floating point coprocessor (FPA) instructions */
- {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
- {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
- {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
- {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
- {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
- {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
- {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
- {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
- {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
- {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
- {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
-
- /* Register load/store */
- {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
- {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
- {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
- {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
- {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
- {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
-
- /* Data transfer between ARM and NEON registers */
- {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
- {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
- {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
- {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
- {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
- {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
- {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
- {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
- {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
- {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
- {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
- {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
- {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
-
- /* Floating point coprocessor (VFP) instructions */
- {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
- {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "fmxr%c\tmvfr1, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "fmxr%c\tmvfr0, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
- {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
- {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
- {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
- {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr1"},
- {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr0"},
- {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
- {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
- {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
- {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
- {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
- {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
- {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
- {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def %16-19x>, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def %16-19x>"},
- {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
- {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
- {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
- {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
- {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
- {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
- {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
- {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
- {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
- {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
- {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
- {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
- {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
- {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
- {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
- {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
- {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
- {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"},
- {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"},
- {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"},
- {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
- {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
- {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
- {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
- {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
- {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
- {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
- {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
- {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
- {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
- {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
- {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
- {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
- {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
- {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
- {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
-
- /* Cirrus coprocessor instructions. */
- {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
- {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
- {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
- {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
- {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
- {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
- {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
- {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
- {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
-
- /* Generic coprocessor instructions */
- {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
- {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
- {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
- {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
- {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
- {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
- {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
-
- /* V6 coprocessor instructions */
- {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
- {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
-
- /* V5 coprocessor instructions */
- {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
- {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
- {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
- {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
- {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
-
- {0, 0, 0, 0}
-};
-
-/* Neon opcode table: This does not encode the top byte -- that is
- checked by the print_insn_neon routine, as it depends on whether we are
- doing thumb32 or arm32 disassembly. */
-
-/* print_insn_neon recognizes the following format control codes:
-
- %% %
-
- %c print condition code
- %A print v{st,ld}[1234] operands
- %B print v{st,ld}[1234] any one operands
- %C print v{st,ld}[1234] single->all operands
- %D print scalar
- %E print vmov, vmvn, vorr, vbic encoded constant
- %F print vtbl,vtbx register list
-
- %<bitfield>r print as an ARM register
- %<bitfield>d print the bitfield in decimal
- %<bitfield>e print the 2^N - bitfield in decimal
- %<bitfield>D print as a NEON D register
- %<bitfield>Q print as a NEON Q register
- %<bitfield>R print as a NEON D or Q register
- %<bitfield>Sn print byte scaled width limited by n
- %<bitfield>Tn print short scaled width limited by n
- %<bitfield>Un print long scaled width limited by n
-
- %<bitfield>'c print specified char iff bitfield is all ones
- %<bitfield>`c print specified char iff bitfield is all zeroes
- %<bitfield>?ab... select from array of values in big endian order */
-
-static const struct opcode32 neon_opcodes[] =
-{
- /* Extract */
- {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
- {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
-
- /* Move data element to all lanes */
- {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
- {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
- {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
-
- /* Table lookup */
- {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
-
- /* Two registers, miscellaneous */
- {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
- {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
- {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
- {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
- {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
- {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
- {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
-
- /* Three registers of the same length */
- {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
- {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
- {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
- {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
- {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
- {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
-
- /* One register and an immediate value */
- {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
- {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
-
- /* Two registers and a shift amount */
- {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
- {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
- {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
- {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
- {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
- {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
- {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
- {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
- {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
- {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
- {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
- {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
- {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
- {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
- {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
- {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
- {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
- {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
- {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
- {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
- {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
- {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
- {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
- {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
- {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
- {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
- {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
- {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
-
- /* Three registers of different lengths */
- {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
- {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
- {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
-
- /* Two registers and a scalar */
- {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
- {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
- {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
-
- /* Element and structure load/store */
- {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
- {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
- {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
- {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
- {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
- {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
- {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
- {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
- {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
- {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
- {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
-
- {0,0 ,0, 0}
-};
-
-/* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
- ordered: they must be searched linearly from the top to obtain a correct
- match. */
-
-/* print_insn_arm recognizes the following format control codes:
-
- %% %
-
- %a print address for ldr/str instruction
- %s print address for ldr/str halfword/signextend instruction
- %b print branch destination
- %c print condition code (always bits 28-31)
- %m print register mask for ldm/stm instruction
- %o print operand2 (immediate or register + shift)
- %p print 'p' iff bits 12-15 are 15
- %t print 't' iff bit 21 set and bit 24 clear
- %B print arm BLX(1) destination
- %C print the PSR sub type.
- %U print barrier type.
- %P print address for pli instruction.
-
- %<bitfield>r print as an ARM register
- %<bitfield>d print the bitfield in decimal
- %<bitfield>W print the bitfield plus one in decimal
- %<bitfield>x print the bitfield in hex
- %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
-
- %<bitfield>'c print specified char iff bitfield is all ones
- %<bitfield>`c print specified char iff bitfield is all zeroes
- %<bitfield>?ab... select from array of values in big endian order
-
- %e print arm SMI operand (bits 0..7,8..19).
- %E print the LSB and WIDTH fields of a BFI or BFC instruction.
- %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
-
-static const struct opcode32 arm_opcodes[] =
-{
- /* ARM instructions. */
- {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
- {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
- {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
- {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
-
- /* V7 instructions. */
- {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
- {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
- {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
- {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
- {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
-
- /* ARM V6T2 instructions. */
- {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
- {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
- {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
- {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
- {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
- {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
- {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
-
- /* ARM V6Z instructions. */
- {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
-
- /* ARM V6K instructions. */
- {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
- {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
- {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
- {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
- {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
- {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
- {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
-
- /* ARM V6K NOP hints. */
- {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
- {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
- {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
- {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
- {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
-
- /* ARM V6 instructions. */
- {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
- {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
- {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
- {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
- {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
- {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
- {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
- {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
- {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
- {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
- {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
- {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
- {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
- {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
- {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
- {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
- {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
- {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
- {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
- {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
- {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
- {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
- {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
- {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
- {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
- {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
- {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
- {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
-
- /* V5J instruction. */
- {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
-
- /* V5 Instructions. */
- {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
- {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
- {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
- {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
-
- /* V5E "El Segundo" Instructions. */
- {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
- {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
- {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
- {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
-
- {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
- {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
-
- {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
-
- {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
-
- {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
- {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
-
- {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
- {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
- {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
- {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
-
- /* ARM Instructions. */
- {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%6's%5?hb%c\t%12-15r, %s"},
- {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
- {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
- {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
- {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
- {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
- {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
- {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
- {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
- {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
- {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
- {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
- {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
- {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
- {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
- {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
- {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
- {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
- {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
- {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
- {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
- {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
- {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
- {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
- {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
- {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
- {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
- {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
- {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
- {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
- {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
- {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
-
- /* The rest. */
- {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
- {0, 0x00000000, 0x00000000, 0}
-};
-
-/* print_insn_thumb16 recognizes the following format control codes:
-
- %S print Thumb register (bits 3..5 as high number if bit 6 set)
- %D print Thumb register (bits 0..2 as high number if bit 7 set)
- %<bitfield>I print bitfield as a signed decimal
- (top bit of range being the sign bit)
- %N print Thumb register mask (with LR)
- %O print Thumb register mask (with PC)
- %M print Thumb register mask
- %b print CZB's 6-bit unsigned branch destination
- %s print Thumb right-shift immediate (6..10; 0 == 32).
- %c print the condition code
- %C print the condition code, or "s" if not conditional
- %x print warning if conditional an not at end of IT block"
- %X print "\t; unpredictable <IT:code>" if conditional
- %I print IT instruction suffix and operands
- %<bitfield>r print bitfield as an ARM register
- %<bitfield>d print bitfield as a decimal
- %<bitfield>H print (bitfield * 2) as a decimal
- %<bitfield>W print (bitfield * 4) as a decimal
- %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
- %<bitfield>B print Thumb branch destination (signed displacement)
- %<bitfield>c print bitfield as a condition code
- %<bitnum>'c print specified char iff bit is one
- %<bitnum>?ab print a if bit is one else print b. */
-
-static const struct opcode16 thumb_opcodes[] =
-{
- /* Thumb instructions. */
-
- /* ARM V6K no-argument instructions. */
- {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
- {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
- {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
- {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
- {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
- {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
-
- /* ARM V6T2 instructions. */
- {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
- {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
- {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
-
- /* ARM V6. */
- {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
- {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
- {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
- {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
- {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
-
- /* ARM V5 ISA extends Thumb. */
- {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
- /* This is BLX(2). BLX(1) is a 32-bit instruction. */
- {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
- /* ARM V4T ISA (Thumb v1). */
- {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
- /* Format 4. */
- {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
- /* format 13 */
- {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
- {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
- /* format 5 */
- {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
- {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
- {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
- {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
- /* format 14 */
- {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
- {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
- /* format 2 */
- {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
- {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
- {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
- {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
- /* format 8 */
- {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
- {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
- {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
- /* format 7 */
- {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
- {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
- /* format 1 */
- {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
- {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
- {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
- /* format 3 */
- {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
- {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
- {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
- {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
- /* format 6 */
- {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
- /* format 9 */
- {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
- {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
- {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
- {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
- /* format 10 */
- {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
- {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
- /* format 11 */
- {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
- {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
- /* format 12 */
- {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"},
- {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
- /* format 15 */
- {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
- {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
- /* format 17 */
- {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
- /* format 16 */
- {ARM_EXT_V4T, 0xDE00, 0xFE00, "undefined"},
- {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
- /* format 18 */
- {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
-
- /* The E800 .. FFFF range is unconditionally redirected to the
- 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
- are processed via that table. Thus, we can never encounter a
- bare "second half of BL/BLX(1)" instruction here. */
- {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
- {0, 0, 0, 0}
-};
-
-/* Thumb32 opcodes use the same table structure as the ARM opcodes.
- We adopt the convention that hw1 is the high 16 bits of .value and
- .mask, hw2 the low 16 bits.
-
- print_insn_thumb32 recognizes the following format control codes:
-
- %% %
-
- %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
- %M print a modified 12-bit immediate (same location)
- %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
- %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
- %S print a possibly-shifted Rm
-
- %a print the address of a plain load/store
- %w print the width and signedness of a core load/store
- %m print register mask for ldm/stm
-
- %E print the lsb and width fields of a bfc/bfi instruction
- %F print the lsb and width fields of a sbfx/ubfx instruction
- %b print a conditional branch offset
- %B print an unconditional branch offset
- %s print the shift field of an SSAT instruction
- %R print the rotation field of an SXT instruction
- %U print barrier type.
- %P print address for pli instruction.
- %c print the condition code
- %x print warning if conditional an not at end of IT block"
- %X print "\t; unpredictable <IT:code>" if conditional
-
- %<bitfield>d print bitfield in decimal
- %<bitfield>W print bitfield*4 in decimal
- %<bitfield>r print bitfield as an ARM register
- %<bitfield>c print bitfield as a condition code
-
- %<bitfield>'c print specified char iff bitfield is all ones
- %<bitfield>`c print specified char iff bitfield is all zeroes
- %<bitfield>?ab... select from array of values in big endian order
-
- With one exception at the bottom (done because BL and BLX(1) need
- to come dead last), this table was machine-sorted first in
- decreasing order of number of bits set in the mask, then in
- increasing numeric order of mask, then in increasing numeric order
- of opcode. This order is not the clearest for a human reader, but
- is guaranteed never to catch a special-case bit pattern with a more
- general mask, which is important, because this instruction encoding
- makes heavy use of special-case bit patterns. */
-static const struct opcode32 thumb32_opcodes[] =
-{
- /* V7 instructions. */
- {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
- {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
- {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
- {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
- {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
- {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
-
- /* Instructions defined in the basic V6T2 set. */
- {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
- {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
- {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
- {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
- {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"},
- {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
-
- {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
- {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
- {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
- {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
- {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
- {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
- {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
- {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
- {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
- {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
- {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
- {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
- {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
- {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
- {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
- {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
- {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
- {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
- {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
- {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
- {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
- {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
- {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
- {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
- {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
- {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
- {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
- {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
- {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
- {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
- {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
- {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
- {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
- {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
- {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
- {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
- {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
- {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
- {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
- {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
- {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
- {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
- {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
- {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
- {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
- {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
- {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
- {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
- {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
- {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
- {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
- {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
- {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
- {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
- {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
- {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
- {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
- {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
- {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
-
- /* Filter out Bcc with cond=E or F, which are used for other instructions. */
- {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
- {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
- {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
- {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
-
- /* These have been 32-bit since the invention of Thumb. */
- {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
- {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
-
- /* Fallback. */
- {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
- {0, 0, 0, 0}
-};
-
-static const char *const arm_conditional[] =
-{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
-
-static const char *const arm_fp_const[] =
-{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
-
-static const char *const arm_shift[] =
-{"lsl", "lsr", "asr", "ror"};
-
-typedef struct
-{
- const char *name;
- const char *description;
- const char *reg_names[16];
-}
-arm_regname;
-
-static const arm_regname regnames[] =
-{
- { "raw" , "Select raw register names",
- { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
- { "gcc", "Select register names used by GCC",
- { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
- { "std", "Select register names used in ARM's ISA documentation",
- { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
- { "apcs", "Select register names used in the APCS",
- { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
- { "atpcs", "Select register names used in the ATPCS",
- { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
- { "special-atpcs", "Select special register names used in the ATPCS",
- { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
-};
-
-static const char *const iwmmxt_wwnames[] =
-{"b", "h", "w", "d"};
-
-static const char *const iwmmxt_wwssnames[] =
-{"b", "bus", "bc", "bss",
- "h", "hus", "hc", "hss",
- "w", "wus", "wc", "wss",
- "d", "dus", "dc", "dss"
-};
-
-static const char *const iwmmxt_regnames[] =
-{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
- "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
-};
-
-static const char *const iwmmxt_cregnames[] =
-{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
- "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
-};
-
-/* Default to GCC register name set. */
-static unsigned int regname_selected = 1;
-
-#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
-#define arm_regnames regnames[regname_selected].reg_names
-
-static bfd_boolean force_thumb = FALSE;
-
-/* Current IT instruction state. This contains the same state as the IT
- bits in the CPSR. */
-static unsigned int ifthen_state;
-/* IT state for the next instruction. */
-static unsigned int ifthen_next_state;
-/* The address of the insn for which the IT state is valid. */
-static bfd_vma ifthen_address;
-#define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
-
-/* Cached mapping symbol state. */
-enum map_type {
- MAP_ARM,
- MAP_THUMB,
- MAP_DATA
-};
-
-enum map_type last_type;
-int last_mapping_sym = -1;
-bfd_vma last_mapping_addr = 0;
-
-
-/* Functions. */
-int
-get_arm_regname_num_options (void)
-{
- return NUM_ARM_REGNAMES;
-}
-
-int
-set_arm_regname_option (int option)
-{
- int old = regname_selected;
- regname_selected = option;
- return old;
-}
-
-int
-get_arm_regnames (int option, const char **setname, const char **setdescription,
- const char *const **register_names)
-{
- *setname = regnames[option].name;
- *setdescription = regnames[option].description;
- *register_names = regnames[option].reg_names;
- return 16;
-}
-
-/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
- Returns pointer to following character of the format string and
- fills in *VALUEP and *WIDTHP with the extracted value and number of
- bits extracted. WIDTHP can be NULL. */
-
-static const char *
-arm_decode_bitfield (const char *ptr, unsigned long insn,
- unsigned long *valuep, int *widthp)
-{
- unsigned long value = 0;
- int width = 0;
-
- do
- {
- int start, end;
- int bits;
-
- for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
- start = start * 10 + *ptr - '0';
- if (*ptr == '-')
- for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
- end = end * 10 + *ptr - '0';
- else
- end = start;
- bits = end - start;
- if (bits < 0)
- abort ();
- value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
- width += bits + 1;
- }
- while (*ptr++ == ',');
- *valuep = value;
- if (widthp)
- *widthp = width;
- return ptr - 1;
-}
-
-static void
-arm_decode_shift (long given, fprintf_ftype func, void *stream,
- int print_shift)
-{
- func (stream, "%s", arm_regnames[given & 0xf]);
-
- if ((given & 0xff0) != 0)
- {
- if ((given & 0x10) == 0)
- {
- int amount = (given & 0xf80) >> 7;
- int shift = (given & 0x60) >> 5;
-
- if (amount == 0)
- {
- if (shift == 3)
- {
- func (stream, ", rrx");
- return;
- }
-
- amount = 32;
- }
-
- if (print_shift)
- func (stream, ", %s #%d", arm_shift[shift], amount);
- else
- func (stream, ", #%d", amount);
- }
- else if (print_shift)
- func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
- arm_regnames[(given & 0xf00) >> 8]);
- else
- func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
- }
-}
-
-/* Print one coprocessor instruction on INFO->STREAM.
- Return TRUE if the instuction matched, FALSE if this is not a
- recognised coprocessor instruction. */
-
-static bfd_boolean
-print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
- bfd_boolean thumb)
-{
- const struct opcode32 *insn;
- void *stream = info->stream;
- fprintf_ftype func = info->fprintf_func;
- unsigned long mask;
- unsigned long value;
- int cond;
-
- for (insn = coprocessor_opcodes; insn->assembler; insn++)
- {
- if (insn->value == FIRST_IWMMXT_INSN
- && info->mach != bfd_mach_arm_XScale
- && info->mach != bfd_mach_arm_iWMMXt
- && info->mach != bfd_mach_arm_iWMMXt2)
- insn = insn + IWMMXT_INSN_COUNT;
-
- mask = insn->mask;
- value = insn->value;
- if (thumb)
- {
- /* The high 4 bits are 0xe for Arm conditional instructions, and
- 0xe for arm unconditional instructions. The rest of the
- encoding is the same. */
- mask |= 0xf0000000;
- value |= 0xe0000000;
- if (ifthen_state)
- cond = IFTHEN_COND;
- else
- cond = 16;
- }
- else
- {
- /* Only match unconditional instuctions against unconditional
- patterns. */
- if ((given & 0xf0000000) == 0xf0000000)
- {
- mask |= 0xf0000000;
- cond = 16;
- }
- else
- {
- cond = (given >> 28) & 0xf;
- if (cond == 0xe)
- cond = 16;
- }
- }
- if ((given & mask) == value)
- {
- const char *c;
-
- for (c = insn->assembler; *c; c++)
- {
- if (*c == '%')
- {
- switch (*++c)
- {
- case '%':
- func (stream, "%%");
- break;
-
- case 'A':
- func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
-
- if ((given & (1 << 24)) != 0)
- {
- int offset = given & 0xff;
-
- if (offset)
- func (stream, ", #%s%d]%s",
- ((given & 0x00800000) == 0 ? "-" : ""),
- offset * 4,
- ((given & 0x00200000) != 0 ? "!" : ""));
- else
- func (stream, "]");
- }
- else
- {
- int offset = given & 0xff;
-
- func (stream, "]");
-
- if (given & (1 << 21))
- {
- if (offset)
- func (stream, ", #%s%d",
- ((given & 0x00800000) == 0 ? "-" : ""),
- offset * 4);
- }
- else
- func (stream, ", {%d}", offset);
- }
- break;
-
- case 'B':
- {
- int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
- int offset = (given >> 1) & 0x3f;
-
- if (offset == 1)
- func (stream, "{d%d}", regno);
- else if (regno + offset > 32)
- func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
- else
- func (stream, "{d%d-d%d}", regno, regno + offset - 1);
- }
- break;
-
- case 'C':
- {
- int rn = (given >> 16) & 0xf;
- int offset = (given & 0xff) * 4;
- int add = (given >> 23) & 1;
-
- func (stream, "[%s", arm_regnames[rn]);
-
- if (offset)
- {
- if (!add)
- offset = -offset;
- func (stream, ", #%d", offset);
- }
- func (stream, "]");
- if (rn == 15)
- {
- func (stream, "\t; ");
- /* FIXME: Unsure if info->bytes_per_chunk is the
- right thing to use here. */
- info->print_address_func (offset + pc
- + info->bytes_per_chunk * 2, info);
- }
- }
- break;
-
- case 'c':
- func (stream, "%s", arm_conditional[cond]);
- break;
-
- case 'I':
- /* Print a Cirrus/DSP shift immediate. */
- /* Immediates are 7bit signed ints with bits 0..3 in
- bits 0..3 of opcode and bits 4..6 in bits 5..7
- of opcode. */
- {
- int imm;
-
- imm = (given & 0xf) | ((given & 0xe0) >> 1);
-
- /* Is ``imm'' a negative number? */
- if (imm & 0x40)
- imm |= (-1 << 7);
-
- func (stream, "%d", imm);
- }
-
- break;
-
- case 'F':
- switch (given & 0x00408000)
- {
- case 0:
- func (stream, "4");
- break;
- case 0x8000:
- func (stream, "1");
- break;
- case 0x00400000:
- func (stream, "2");
- break;
- default:
- func (stream, "3");
- }
- break;
-
- case 'P':
- switch (given & 0x00080080)
- {
- case 0:
- func (stream, "s");
- break;
- case 0x80:
- func (stream, "d");
- break;
- case 0x00080000:
- func (stream, "e");
- break;
- default:
- func (stream, _("<illegal precision>"));
- break;
- }
- break;
- case 'Q':
- switch (given & 0x00408000)
- {
- case 0:
- func (stream, "s");
- break;
- case 0x8000:
- func (stream, "d");
- break;
- case 0x00400000:
- func (stream, "e");
- break;
- default:
- func (stream, "p");
- break;
- }
- break;
- case 'R':
- switch (given & 0x60)
- {
- case 0:
- break;
- case 0x20:
- func (stream, "p");
- break;
- case 0x40:
- func (stream, "m");
- break;
- default:
- func (stream, "z");
- break;
- }
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- int width;
- unsigned long value;
-
- c = arm_decode_bitfield (c, given, &value, &width);
-
- switch (*c)
- {
- case 'r':
- func (stream, "%s", arm_regnames[value]);
- break;
- case 'D':
- func (stream, "d%ld", value);
- break;
- case 'Q':
- if (value & 1)
- func (stream, "<illegal reg q%ld.5>", value >> 1);
- else
- func (stream, "q%ld", value >> 1);
- break;
- case 'd':
- func (stream, "%ld", value);
- break;
- case 'k':
- {
- int from = (given & (1 << 7)) ? 32 : 16;
- func (stream, "%ld", from - value);
- }
- break;
-
- case 'f':
- if (value > 7)
- func (stream, "#%s", arm_fp_const[value & 7]);
- else
- func (stream, "f%ld", value);
- break;
-
- case 'w':
- if (width == 2)
- func (stream, "%s", iwmmxt_wwnames[value]);
- else
- func (stream, "%s", iwmmxt_wwssnames[value]);
- break;
-
- case 'g':
- func (stream, "%s", iwmmxt_regnames[value]);
- break;
- case 'G':
- func (stream, "%s", iwmmxt_cregnames[value]);
- break;
-
- case 'x':
- func (stream, "0x%lx", value);
- break;
-
- case '`':
- c++;
- if (value == 0)
- func (stream, "%c", *c);
- break;
- case '\'':
- c++;
- if (value == ((1ul << width) - 1))
- func (stream, "%c", *c);
- break;
- case '?':
- func (stream, "%c", c[(1 << width) - (int)value]);
- c += 1 << width;
- break;
- default:
- abort ();
- }
- break;
-
- case 'y':
- case 'z':
- {
- int single = *c++ == 'y';
- int regno;
-
- switch (*c)
- {
- case '4': /* Sm pair */
- func (stream, "{");
- /* Fall through. */
- case '0': /* Sm, Dm */
- regno = given & 0x0000000f;
- if (single)
- {
- regno <<= 1;
- regno += (given >> 5) & 1;
- }
- else
- regno += ((given >> 5) & 1) << 4;
- break;
-
- case '1': /* Sd, Dd */
- regno = (given >> 12) & 0x0000000f;
- if (single)
- {
- regno <<= 1;
- regno += (given >> 22) & 1;
- }
- else
- regno += ((given >> 22) & 1) << 4;
- break;
-
- case '2': /* Sn, Dn */
- regno = (given >> 16) & 0x0000000f;
- if (single)
- {
- regno <<= 1;
- regno += (given >> 7) & 1;
- }
- else
- regno += ((given >> 7) & 1) << 4;
- break;
-
- case '3': /* List */
- func (stream, "{");
- regno = (given >> 12) & 0x0000000f;
- if (single)
- {
- regno <<= 1;
- regno += (given >> 22) & 1;
- }
- else
- regno += ((given >> 22) & 1) << 4;
- break;
-
- default:
- abort ();
- }
-
- func (stream, "%c%d", single ? 's' : 'd', regno);
-
- if (*c == '3')
- {
- int count = given & 0xff;
-
- if (single == 0)
- count >>= 1;
-
- if (--count)
- {
- func (stream, "-%c%d",
- single ? 's' : 'd',
- regno + count);
- }
-
- func (stream, "}");
- }
- else if (*c == '4')
- func (stream, ", %c%d}", single ? 's' : 'd',
- regno + 1);
- }
- break;
-
- case 'L':
- switch (given & 0x00400100)
- {
- case 0x00000000: func (stream, "b"); break;
- case 0x00400000: func (stream, "h"); break;
- case 0x00000100: func (stream, "w"); break;
- case 0x00400100: func (stream, "d"); break;
- default:
- break;
- }
- break;
-
- case 'Z':
- {
- int value;
- /* given (20, 23) | given (0, 3) */
- value = ((given >> 16) & 0xf0) | (given & 0xf);
- func (stream, "%d", value);
- }
- break;
-
- case 'l':
- /* This is like the 'A' operator, except that if
- the width field "M" is zero, then the offset is
- *not* multiplied by four. */
- {
- int offset = given & 0xff;
- int multiplier = (given & 0x00000100) ? 4 : 1;
-
- func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
-
- if (offset)
- {
- if ((given & 0x01000000) != 0)
- func (stream, ", #%s%d]%s",
- ((given & 0x00800000) == 0 ? "-" : ""),
- offset * multiplier,
- ((given & 0x00200000) != 0 ? "!" : ""));
- else
- func (stream, "], #%s%d",
- ((given & 0x00800000) == 0 ? "-" : ""),
- offset * multiplier);
- }
- else
- func (stream, "]");
- }
- break;
-
- case 'r':
- {
- int imm4 = (given >> 4) & 0xf;
- int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
- int ubit = (given >> 23) & 1;
- const char *rm = arm_regnames [given & 0xf];
- const char *rn = arm_regnames [(given >> 16) & 0xf];
-
- switch (puw_bits)
- {
- case 1:
- /* fall through */
- case 3:
- func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
- if (imm4)
- func (stream, ", lsl #%d", imm4);
- break;
-
- case 4:
- /* fall through */
- case 5:
- /* fall through */
- case 6:
- /* fall through */
- case 7:
- func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
- if (imm4 > 0)
- func (stream, ", lsl #%d", imm4);
- func (stream, "]");
- if (puw_bits == 5 || puw_bits == 7)
- func (stream, "!");
- break;
-
- default:
- func (stream, "INVALID");
- }
- }
- break;
-
- case 'i':
- {
- long imm5;
- imm5 = ((given & 0x100) >> 4) | (given & 0xf);
- func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
- }
- break;
-
- default:
- abort ();
- }
- }
- }
- else
- func (stream, "%c", *c);
- }
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void
-print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
-{
- void *stream = info->stream;
- fprintf_ftype func = info->fprintf_func;
-
- if (((given & 0x000f0000) == 0x000f0000)
- && ((given & 0x02000000) == 0))
- {
- int offset = given & 0xfff;
-
- func (stream, "[pc");
-
- if (given & 0x01000000)
- {
- if ((given & 0x00800000) == 0)
- offset = - offset;
-
- /* Pre-indexed. */
- func (stream, ", #%d]", offset);
-
- offset += pc + 8;
-
- /* Cope with the possibility of write-back
- being used. Probably a very dangerous thing
- for the programmer to do, but who are we to
- argue ? */
- if (given & 0x00200000)
- func (stream, "!");
- }
- else
- {
- /* Post indexed. */
- func (stream, "], #%d", offset);
-
- /* ie ignore the offset. */
- offset = pc + 8;
- }
-
- func (stream, "\t; ");
- info->print_address_func (offset, info);
- }
- else
- {
- func (stream, "[%s",
- arm_regnames[(given >> 16) & 0xf]);
- if ((given & 0x01000000) != 0)
- {
- if ((given & 0x02000000) == 0)
- {
- int offset = given & 0xfff;
- if (offset)
- func (stream, ", #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
- }
- else
- {
- func (stream, ", %s",
- (((given & 0x00800000) == 0)
- ? "-" : ""));
- arm_decode_shift (given, func, stream, 1);
- }
-
- func (stream, "]%s",
- ((given & 0x00200000) != 0) ? "!" : "");
- }
- else
- {
- if ((given & 0x02000000) == 0)
- {
- int offset = given & 0xfff;
- if (offset)
- func (stream, "], #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
- else
- func (stream, "]");
- }
- else
- {
- func (stream, "], %s",
- (((given & 0x00800000) == 0)
- ? "-" : ""));
- arm_decode_shift (given, func, stream, 1);
- }
- }
- }
-}
-
-/* Print one neon instruction on INFO->STREAM.
- Return TRUE if the instuction matched, FALSE if this is not a
- recognised neon instruction. */
-
-static bfd_boolean
-print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
-{
- const struct opcode32 *insn;
- void *stream = info->stream;
- fprintf_ftype func = info->fprintf_func;
-
- if (thumb)
- {
- if ((given & 0xef000000) == 0xef000000)
- {
- /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
- unsigned long bit28 = given & (1 << 28);
-
- given &= 0x00ffffff;
- if (bit28)
- given |= 0xf3000000;
- else
- given |= 0xf2000000;
- }
- else if ((given & 0xff000000) == 0xf9000000)
- given ^= 0xf9000000 ^ 0xf4000000;
- else
- return FALSE;
- }
-
- for (insn = neon_opcodes; insn->assembler; insn++)
- {
- if ((given & insn->mask) == insn->value)
- {
- const char *c;
-
- for (c = insn->assembler; *c; c++)
- {
- if (*c == '%')
- {
- switch (*++c)
- {
- case '%':
- func (stream, "%%");
- break;
-
- case 'c':
- if (thumb && ifthen_state)
- func (stream, "%s", arm_conditional[IFTHEN_COND]);
- break;
-
- case 'A':
- {
- static const unsigned char enc[16] =
- {
- 0x4, 0x14, /* st4 0,1 */
- 0x4, /* st1 2 */
- 0x4, /* st2 3 */
- 0x3, /* st3 4 */
- 0x13, /* st3 5 */
- 0x3, /* st1 6 */
- 0x1, /* st1 7 */
- 0x2, /* st2 8 */
- 0x12, /* st2 9 */
- 0x2, /* st1 10 */
- 0, 0, 0, 0, 0
- };
- int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
- int rn = ((given >> 16) & 0xf);
- int rm = ((given >> 0) & 0xf);
- int align = ((given >> 4) & 0x3);
- int type = ((given >> 8) & 0xf);
- int n = enc[type] & 0xf;
- int stride = (enc[type] >> 4) + 1;
- int ix;
-
- func (stream, "{");
- if (stride > 1)
- for (ix = 0; ix != n; ix++)
- func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
- else if (n == 1)
- func (stream, "d%d", rd);
- else
- func (stream, "d%d-d%d", rd, rd + n - 1);
- func (stream, "}, [%s", arm_regnames[rn]);
- if (align)
- func (stream, ", :%d", 32 << align);
- func (stream, "]");
- if (rm == 0xd)
- func (stream, "!");
- else if (rm != 0xf)
- func (stream, ", %s", arm_regnames[rm]);
- }
- break;
-
- case 'B':
- {
- int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
- int rn = ((given >> 16) & 0xf);
- int rm = ((given >> 0) & 0xf);
- int idx_align = ((given >> 4) & 0xf);
- int align = 0;
- int size = ((given >> 10) & 0x3);
- int idx = idx_align >> (size + 1);
- int length = ((given >> 8) & 3) + 1;
- int stride = 1;
- int i;
-
- if (length > 1 && size > 0)
- stride = (idx_align & (1 << size)) ? 2 : 1;
-
- switch (length)
- {
- case 1:
- {
- int amask = (1 << size) - 1;
- if ((idx_align & (1 << size)) != 0)
- return FALSE;
- if (size > 0)
- {
- if ((idx_align & amask) == amask)
- align = 8 << size;
- else if ((idx_align & amask) != 0)
- return FALSE;
- }
- }
- break;
-
- case 2:
- if (size == 2 && (idx_align & 2) != 0)
- return FALSE;
- align = (idx_align & 1) ? 16 << size : 0;
- break;
-
- case 3:
- if ((size == 2 && (idx_align & 3) != 0)
- || (idx_align & 1) != 0)
- return FALSE;
- break;
-
- case 4:
- if (size == 2)
- {
- if ((idx_align & 3) == 3)
- return FALSE;
- align = (idx_align & 3) * 64;
- }
- else
- align = (idx_align & 1) ? 32 << size : 0;
- break;
-
- default:
- abort ();
- }
-
- func (stream, "{");
- for (i = 0; i < length; i++)
- func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
- rd + i * stride, idx);
- func (stream, "}, [%s", arm_regnames[rn]);
- if (align)
- func (stream, ", :%d", align);
- func (stream, "]");
- if (rm == 0xd)
- func (stream, "!");
- else if (rm != 0xf)
- func (stream, ", %s", arm_regnames[rm]);
- }
- break;
-
- case 'C':
- {
- int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
- int rn = ((given >> 16) & 0xf);
- int rm = ((given >> 0) & 0xf);
- int align = ((given >> 4) & 0x1);
- int size = ((given >> 6) & 0x3);
- int type = ((given >> 8) & 0x3);
- int n = type + 1;
- int stride = ((given >> 5) & 0x1);
- int ix;
-
- if (stride && (n == 1))
- n++;
- else
- stride++;
-
- func (stream, "{");
- if (stride > 1)
- for (ix = 0; ix != n; ix++)
- func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
- else if (n == 1)
- func (stream, "d%d[]", rd);
- else
- func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
- func (stream, "}, [%s", arm_regnames[rn]);
- if (align)
- {
- int align = (8 * (type + 1)) << size;
- if (type == 3)
- align = (size > 1) ? align >> 1 : align;
- if (type == 2 || (type == 0 && !size))
- func (stream, ", :<bad align %d>", align);
- else
- func (stream, ", :%d", align);
- }
- func (stream, "]");
- if (rm == 0xd)
- func (stream, "!");
- else if (rm != 0xf)
- func (stream, ", %s", arm_regnames[rm]);
- }
- break;
-
- case 'D':
- {
- int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
- int size = (given >> 20) & 3;
- int reg = raw_reg & ((4 << size) - 1);
- int ix = raw_reg >> size >> 2;
-
- func (stream, "d%d[%d]", reg, ix);
- }
- break;
-
- case 'E':
- /* Neon encoded constant for mov, mvn, vorr, vbic */
- {
- int bits = 0;
- int cmode = (given >> 8) & 0xf;
- int op = (given >> 5) & 0x1;
- unsigned long value = 0, hival = 0;
- unsigned shift;
- int size = 0;
- int isfloat = 0;
-
- bits |= ((given >> 24) & 1) << 7;
- bits |= ((given >> 16) & 7) << 4;
- bits |= ((given >> 0) & 15) << 0;
-
- if (cmode < 8)
- {
- shift = (cmode >> 1) & 3;
- value = (unsigned long)bits << (8 * shift);
- size = 32;
- }
- else if (cmode < 12)
- {
- shift = (cmode >> 1) & 1;
- value = (unsigned long)bits << (8 * shift);
- size = 16;
- }
- else if (cmode < 14)
- {
- shift = (cmode & 1) + 1;
- value = (unsigned long)bits << (8 * shift);
- value |= (1ul << (8 * shift)) - 1;
- size = 32;
- }
- else if (cmode == 14)
- {
- if (op)
- {
- /* bit replication into bytes */
- int ix;
- unsigned long mask;
-
- value = 0;
- hival = 0;
- for (ix = 7; ix >= 0; ix--)
- {
- mask = ((bits >> ix) & 1) ? 0xff : 0;
- if (ix <= 3)
- value = (value << 8) | mask;
- else
- hival = (hival << 8) | mask;
- }
- size = 64;
- }
- else
- {
- /* byte replication */
- value = (unsigned long)bits;
- size = 8;
- }
- }
- else if (!op)
- {
- /* floating point encoding */
- int tmp;
-
- value = (unsigned long)(bits & 0x7f) << 19;
- value |= (unsigned long)(bits & 0x80) << 24;
- tmp = bits & 0x40 ? 0x3c : 0x40;
- value |= (unsigned long)tmp << 24;
- size = 32;
- isfloat = 1;
- }
- else
- {
- func (stream, "<illegal constant %.8x:%x:%x>",
- bits, cmode, op);
- size = 32;
- break;
- }
- switch (size)
- {
- case 8:
- func (stream, "#%ld\t; 0x%.2lx", value, value);
- break;
-
- case 16:
- func (stream, "#%ld\t; 0x%.4lx", value, value);
- break;
-
- case 32:
- if (isfloat)
- {
- unsigned char valbytes[4];
- double fvalue;
-
- /* Do this a byte at a time so we don't have to
- worry about the host's endianness. */
- valbytes[0] = value & 0xff;
- valbytes[1] = (value >> 8) & 0xff;
- valbytes[2] = (value >> 16) & 0xff;
- valbytes[3] = (value >> 24) & 0xff;
-
- floatformat_to_double
- (&floatformat_ieee_single_little, valbytes,
- &fvalue);
-
- func (stream, "#%.7g\t; 0x%.8lx", fvalue,
- value);
- }
- else
- func (stream, "#%ld\t; 0x%.8lx",
- (long) ((value & 0x80000000)
- ? value | ~0xffffffffl : value), value);
- break;
-
- case 64:
- func (stream, "#0x%.8lx%.8lx", hival, value);
- break;
-
- default:
- abort ();
- }
- }
- break;
-
- case 'F':
- {
- int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
- int num = (given >> 8) & 0x3;
-
- if (!num)
- func (stream, "{d%d}", regno);
- else if (num + regno >= 32)
- func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
- else
- func (stream, "{d%d-d%d}", regno, regno + num);
- }
- break;
-
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- int width;
- unsigned long value;
-
- c = arm_decode_bitfield (c, given, &value, &width);
-
- switch (*c)
- {
- case 'r':
- func (stream, "%s", arm_regnames[value]);
- break;
- case 'd':
- func (stream, "%ld", value);
- break;
- case 'e':
- func (stream, "%ld", (1ul << width) - value);
- break;
-
- case 'S':
- case 'T':
- case 'U':
- /* various width encodings */
- {
- int base = 8 << (*c - 'S'); /* 8,16 or 32 */
- int limit;
- unsigned low, high;
-
- c++;
- if (*c >= '0' && *c <= '9')
- limit = *c - '0';
- else if (*c >= 'a' && *c <= 'f')
- limit = *c - 'a' + 10;
- else
- abort ();
- low = limit >> 2;
- high = limit & 3;
-
- if (value < low || value > high)
- func (stream, "<illegal width %d>", base << value);
- else
- func (stream, "%d", base << value);
- }
- break;
- case 'R':
- if (given & (1 << 6))
- goto Q;
- /* FALLTHROUGH */
- case 'D':
- func (stream, "d%ld", value);
- break;
- case 'Q':
- Q:
- if (value & 1)
- func (stream, "<illegal reg q%ld.5>", value >> 1);
- else
- func (stream, "q%ld", value >> 1);
- break;
-
- case '`':
- c++;
- if (value == 0)
- func (stream, "%c", *c);
- break;
- case '\'':
- c++;
- if (value == ((1ul << width) - 1))
- func (stream, "%c", *c);
- break;
- case '?':
- func (stream, "%c", c[(1 << width) - (int)value]);
- c += 1 << width;
- break;
- default:
- abort ();
- }
- break;
-
- default:
- abort ();
- }
- }
- }
- else
- func (stream, "%c", *c);
- }
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/* Print one ARM instruction from PC on INFO->STREAM. */
-
-static void
-print_insn_arm_internal (bfd_vma pc, struct disassemble_info *info, long given)
-{
- const struct opcode32 *insn;
- void *stream = info->stream;
- fprintf_ftype func = info->fprintf_func;
-
- if (print_insn_coprocessor (pc, info, given, FALSE))
- return;
-
- if (print_insn_neon (info, given, FALSE))
- return;
-
- for (insn = arm_opcodes; insn->assembler; insn++)
- {
- if (insn->value == FIRST_IWMMXT_INSN
- && info->mach != bfd_mach_arm_XScale
- && info->mach != bfd_mach_arm_iWMMXt)
- insn = insn + IWMMXT_INSN_COUNT;
-
- if ((given & insn->mask) == insn->value
- /* Special case: an instruction with all bits set in the condition field
- (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
- or by the catchall at the end of the table. */
- && ((given & 0xF0000000) != 0xF0000000
- || (insn->mask & 0xF0000000) == 0xF0000000
- || (insn->mask == 0 && insn->value == 0)))
- {
- const char *c;
-
- for (c = insn->assembler; *c; c++)
- {
- if (*c == '%')
- {
- switch (*++c)
- {
- case '%':
- func (stream, "%%");
- break;
-
- case 'a':
- print_arm_address (pc, info, given);
- break;
-
- case 'P':
- /* Set P address bit and use normal address
- printing routine. */
- print_arm_address (pc, info, given | (1 << 24));
- break;
-
- case 's':
- if ((given & 0x004f0000) == 0x004f0000)
- {
- /* PC relative with immediate offset. */
- int offset = ((given & 0xf00) >> 4) | (given & 0xf);
-
- if ((given & 0x00800000) == 0)
- offset = -offset;
-
- func (stream, "[pc, #%d]\t; ", offset);
- info->print_address_func (offset + pc + 8, info);
- }
- else
- {
- func (stream, "[%s",
- arm_regnames[(given >> 16) & 0xf]);
- if ((given & 0x01000000) != 0)
- {
- /* Pre-indexed. */
- if ((given & 0x00400000) == 0x00400000)
- {
- /* Immediate. */
- int offset = ((given & 0xf00) >> 4) | (given & 0xf);
- if (offset)
- func (stream, ", #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
- }
- else
- {
- /* Register. */
- func (stream, ", %s%s",
- (((given & 0x00800000) == 0)
- ? "-" : ""),
- arm_regnames[given & 0xf]);
- }
-
- func (stream, "]%s",
- ((given & 0x00200000) != 0) ? "!" : "");
- }
- else
- {
- /* Post-indexed. */
- if ((given & 0x00400000) == 0x00400000)
- {
- /* Immediate. */
- int offset = ((given & 0xf00) >> 4) | (given & 0xf);
- if (offset)
- func (stream, "], #%s%d",
- (((given & 0x00800000) == 0)
- ? "-" : ""), offset);
- else
- func (stream, "]");
- }
- else
- {
- /* Register. */
- func (stream, "], %s%s",
- (((given & 0x00800000) == 0)
- ? "-" : ""),
- arm_regnames[given & 0xf]);
- }
- }
- }
- break;
-
- case 'b':
- {
- int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
- info->print_address_func (disp*4 + pc + 8, info);
- }
- break;
-
- case 'c':
- if (((given >> 28) & 0xf) != 0xe)
- func (stream, "%s",
- arm_conditional [(given >> 28) & 0xf]);
- break;
-
- case 'm':
- {
- int started = 0;
- int reg;
-
- func (stream, "{");
- for (reg = 0; reg < 16; reg++)
- if ((given & (1 << reg)) != 0)
- {
- if (started)
- func (stream, ", ");
- started = 1;
- func (stream, "%s", arm_regnames[reg]);
- }
- func (stream, "}");
- }
- break;
-
- case 'q':
- arm_decode_shift (given, func, stream, 0);
- break;
-
- case 'o':
- if ((given & 0x02000000) != 0)
- {
- int rotate = (given & 0xf00) >> 7;
- int immed = (given & 0xff);
- immed = (((immed << (32 - rotate))
- | (immed >> rotate)) & 0xffffffff);
- func (stream, "#%d\t; 0x%x", immed, immed);
- }
- else
- arm_decode_shift (given, func, stream, 1);
- break;
-
- case 'p':
- if ((given & 0x0000f000) == 0x0000f000)
- func (stream, "p");
- break;
-
- case 't':
- if ((given & 0x01200000) == 0x00200000)
- func (stream, "t");
- break;
-
- case 'A':
- func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
-
- if ((given & (1 << 24)) != 0)
- {
- int offset = given & 0xff;
-
- if (offset)
- func (stream, ", #%s%d]%s",
- ((given & 0x00800000) == 0 ? "-" : ""),
- offset * 4,
- ((given & 0x00200000) != 0 ? "!" : ""));
- else
- func (stream, "]");
- }
- else
- {
- int offset = given & 0xff;
-
- func (stream, "]");
-
- if (given & (1 << 21))
- {
- if (offset)
- func (stream, ", #%s%d",
- ((given & 0x00800000) == 0 ? "-" : ""),
- offset * 4);
- }
- else
- func (stream, ", {%d}", offset);
- }
- break;
-
- case 'B':
- /* Print ARM V5 BLX(1) address: pc+25 bits. */
- {
- bfd_vma address;
- bfd_vma offset = 0;
-
- if (given & 0x00800000)
- /* Is signed, hi bits should be ones. */
- offset = (-1) ^ 0x00ffffff;
-
- /* Offset is (SignExtend(offset field)<<2). */
- offset += given & 0x00ffffff;
- offset <<= 2;
- address = offset + pc + 8;
-
- if (given & 0x01000000)
- /* H bit allows addressing to 2-byte boundaries. */
- address += 2;
-
- info->print_address_func (address, info);
- }
- break;
-
- case 'C':
- func (stream, "_");
- if (given & 0x80000)
- func (stream, "f");
- if (given & 0x40000)
- func (stream, "s");
- if (given & 0x20000)
- func (stream, "x");
- if (given & 0x10000)
- func (stream, "c");
- break;
-
- case 'U':
- switch (given & 0xf)
- {
- case 0xf: func(stream, "sy"); break;
- case 0x7: func(stream, "un"); break;
- case 0xe: func(stream, "st"); break;
- case 0x6: func(stream, "unst"); break;
- default:
- func(stream, "#%d", (int)given & 0xf);
- break;
- }
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- int width;
- unsigned long value;
-
- c = arm_decode_bitfield (c, given, &value, &width);
-
- switch (*c)
- {
- case 'r':
- func (stream, "%s", arm_regnames[value]);
- break;
- case 'd':
- func (stream, "%ld", value);
- break;
- case 'b':
- func (stream, "%ld", value * 8);
- break;
- case 'W':
- func (stream, "%ld", value + 1);
- break;
- case 'x':
- func (stream, "0x%08lx", value);
-
- /* Some SWI instructions have special
- meanings. */
- if ((given & 0x0fffffff) == 0x0FF00000)
- func (stream, "\t; IMB");
- else if ((given & 0x0fffffff) == 0x0FF00001)
- func (stream, "\t; IMBRange");
- break;
- case 'X':
- func (stream, "%01lx", value & 0xf);
- break;
- case '`':
- c++;
- if (value == 0)
- func (stream, "%c", *c);
- break;
- case '\'':
- c++;
- if (value == ((1ul << width) - 1))
- func (stream, "%c", *c);
- break;
- case '?':
- func (stream, "%c", c[(1 << width) - (int)value]);
- c += 1 << width;
- break;
- default:
- abort ();
- }
- break;
-
- case 'e':
- {
- int imm;
-
- imm = (given & 0xf) | ((given & 0xfff00) >> 4);
- func (stream, "%d", imm);
- }
- break;
-
- case 'E':
- /* LSB and WIDTH fields of BFI or BFC. The machine-
- language instruction encodes LSB and MSB. */
- {
- long msb = (given & 0x001f0000) >> 16;
- long lsb = (given & 0x00000f80) >> 7;
-
- long width = msb - lsb + 1;
- if (width > 0)
- func (stream, "#%lu, #%lu", lsb, width);
- else
- func (stream, "(invalid: %lu:%lu)", lsb, msb);
- }
- break;
-
- case 'V':
- /* 16-bit unsigned immediate from a MOVT or MOVW
- instruction, encoded in bits 0:11 and 15:19. */
- {
- long hi = (given & 0x000f0000) >> 4;
- long lo = (given & 0x00000fff);
- long imm16 = hi | lo;
- func (stream, "#%lu\t; 0x%lx", imm16, imm16);
- }
- break;
-
- default:
- abort ();
- }
- }
- }
- else
- func (stream, "%c", *c);
- }
- return;
- }
- }
- abort ();
-}
-
-/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
-
-static void
-print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
-{
- const struct opcode16 *insn;
- void *stream = info->stream;
- fprintf_ftype func = info->fprintf_func;
-
- for (insn = thumb_opcodes; insn->assembler; insn++)
- if ((given & insn->mask) == insn->value)
- {
- const char *c = insn->assembler;
- for (; *c; c++)
- {
- int domaskpc = 0;
- int domasklr = 0;
-
- if (*c != '%')
- {
- func (stream, "%c", *c);
- continue;
- }
-
- switch (*++c)
- {
- case '%':
- func (stream, "%%");
- break;
-
- case 'c':
- if (ifthen_state)
- func (stream, "%s", arm_conditional[IFTHEN_COND]);
- break;
-
- case 'C':
- if (ifthen_state)
- func (stream, "%s", arm_conditional[IFTHEN_COND]);
- else
- func (stream, "s");
- break;
-
- case 'I':
- {
- unsigned int tmp;
-
- ifthen_next_state = given & 0xff;
- for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
- func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
- func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
- }
- break;
-
- case 'x':
- if (ifthen_next_state)
- func (stream, "\t; unpredictable branch in IT block\n");
- break;
-
- case 'X':
- if (ifthen_state)
- func (stream, "\t; unpredictable <IT:%s>",
- arm_conditional[IFTHEN_COND]);
- break;
-
- case 'S':
- {
- long reg;
-
- reg = (given >> 3) & 0x7;
- if (given & (1 << 6))
- reg += 8;
-
- func (stream, "%s", arm_regnames[reg]);
- }
- break;
-
- case 'D':
- {
- long reg;
-
- reg = given & 0x7;
- if (given & (1 << 7))
- reg += 8;
-
- func (stream, "%s", arm_regnames[reg]);
- }
- break;
-
- case 'N':
- if (given & (1 << 8))
- domasklr = 1;
- /* Fall through. */
- case 'O':
- if (*c == 'O' && (given & (1 << 8)))
- domaskpc = 1;
- /* Fall through. */
- case 'M':
- {
- int started = 0;
- int reg;
-
- func (stream, "{");
-
- /* It would be nice if we could spot
- ranges, and generate the rS-rE format: */
- for (reg = 0; (reg < 8); reg++)
- if ((given & (1 << reg)) != 0)
- {
- if (started)
- func (stream, ", ");
- started = 1;
- func (stream, "%s", arm_regnames[reg]);
- }
-
- if (domasklr)
- {
- if (started)
- func (stream, ", ");
- started = 1;
- func (stream, arm_regnames[14] /* "lr" */);
- }
-
- if (domaskpc)
- {
- if (started)
- func (stream, ", ");
- func (stream, arm_regnames[15] /* "pc" */);
- }
-
- func (stream, "}");
- }
- break;
-
- case 'b':
- /* Print ARM V6T2 CZB address: pc+4+6 bits. */
- {
- bfd_vma address = (pc + 4
- + ((given & 0x00f8) >> 2)
- + ((given & 0x0200) >> 3));
- info->print_address_func (address, info);
- }
- break;
-
- case 's':
- /* Right shift immediate -- bits 6..10; 1-31 print
- as themselves, 0 prints as 32. */
- {
- long imm = (given & 0x07c0) >> 6;
- if (imm == 0)
- imm = 32;
- func (stream, "#%ld", imm);
- }
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- int bitstart = *c++ - '0';
- int bitend = 0;
-
- while (*c >= '0' && *c <= '9')
- bitstart = (bitstart * 10) + *c++ - '0';
-
- switch (*c)
- {
- case '-':
- {
- long reg;
-
- c++;
- while (*c >= '0' && *c <= '9')
- bitend = (bitend * 10) + *c++ - '0';
- if (!bitend)
- abort ();
- reg = given >> bitstart;
- reg &= (2 << (bitend - bitstart)) - 1;
- switch (*c)
- {
- case 'r':
- func (stream, "%s", arm_regnames[reg]);
- break;
-
- case 'd':
- func (stream, "%ld", reg);
- break;
-
- case 'H':
- func (stream, "%ld", reg << 1);
- break;
-
- case 'W':
- func (stream, "%ld", reg << 2);
- break;
-
- case 'a':
- /* PC-relative address -- the bottom two
- bits of the address are dropped
- before the calculation. */
- info->print_address_func
- (((pc + 4) & ~3) + (reg << 2), info);
- break;
-
- case 'x':
- func (stream, "0x%04lx", reg);
- break;
-
- case 'B':
- reg = ((reg ^ (1 << bitend)) - (1 << bitend));
- info->print_address_func (reg * 2 + pc + 4, info);
- break;
-
- case 'c':
- func (stream, "%s", arm_conditional [reg]);
- break;
-
- default:
- abort ();
- }
- }
- break;
-
- case '\'':
- c++;
- if ((given & (1 << bitstart)) != 0)
- func (stream, "%c", *c);
- break;
-
- case '?':
- ++c;
- if ((given & (1 << bitstart)) != 0)
- func (stream, "%c", *c++);
- else
- func (stream, "%c", *++c);
- break;
-
- default:
- abort ();
- }
- }
- break;
-
- default:
- abort ();
- }
- }
- return;
- }
-
- /* No match. */
- abort ();
-}
-
-/* Return the name of an V7M special register. */
-static const char *
-psr_name (int regno)
-{
- switch (regno)
- {
- case 0: return "APSR";
- case 1: return "IAPSR";
- case 2: return "EAPSR";
- case 3: return "PSR";
- case 5: return "IPSR";
- case 6: return "EPSR";
- case 7: return "IEPSR";
- case 8: return "MSP";
- case 9: return "PSP";
- case 16: return "PRIMASK";
- case 17: return "BASEPRI";
- case 18: return "BASEPRI_MASK";
- case 19: return "FAULTMASK";
- case 20: return "CONTROL";
- default: return "<unknown>";
- }
-}
-
-/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
-
-static void
-print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
-{
- const struct opcode32 *insn;
- void *stream = info->stream;
- fprintf_ftype func = info->fprintf_func;
-
- if (print_insn_coprocessor (pc, info, given, TRUE))
- return;
-
- if (print_insn_neon (info, given, TRUE))
- return;
-
- for (insn = thumb32_opcodes; insn->assembler; insn++)
- if ((given & insn->mask) == insn->value)
- {
- const char *c = insn->assembler;
- for (; *c; c++)
- {
- if (*c != '%')
- {
- func (stream, "%c", *c);
- continue;
- }
-
- switch (*++c)
- {
- case '%':
- func (stream, "%%");
- break;
-
- case 'c':
- if (ifthen_state)
- func (stream, "%s", arm_conditional[IFTHEN_COND]);
- break;
-
- case 'x':
- if (ifthen_next_state)
- func (stream, "\t; unpredictable branch in IT block\n");
- break;
-
- case 'X':
- if (ifthen_state)
- func (stream, "\t; unpredictable <IT:%s>",
- arm_conditional[IFTHEN_COND]);
- break;
-
- case 'I':
- {
- unsigned int imm12 = 0;
- imm12 |= (given & 0x000000ffu);
- imm12 |= (given & 0x00007000u) >> 4;
- imm12 |= (given & 0x04000000u) >> 15;
- func (stream, "#%u\t; 0x%x", imm12, imm12);
- }
- break;
-
- case 'M':
- {
- unsigned int bits = 0, imm, imm8, mod;
- bits |= (given & 0x000000ffu);
- bits |= (given & 0x00007000u) >> 4;
- bits |= (given & 0x04000000u) >> 15;
- imm8 = (bits & 0x0ff);
- mod = (bits & 0xf00) >> 8;
- switch (mod)
- {
- case 0: imm = imm8; break;
- case 1: imm = ((imm8<<16) | imm8); break;
- case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
- case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
- default:
- mod = (bits & 0xf80) >> 7;
- imm8 = (bits & 0x07f) | 0x80;
- imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
- }
- func (stream, "#%u\t; 0x%x", imm, imm);
- }
- break;
-
- case 'J':
- {
- unsigned int imm = 0;
- imm |= (given & 0x000000ffu);
- imm |= (given & 0x00007000u) >> 4;
- imm |= (given & 0x04000000u) >> 15;
- imm |= (given & 0x000f0000u) >> 4;
- func (stream, "#%u\t; 0x%x", imm, imm);
- }
- break;
-
- case 'K':
- {
- unsigned int imm = 0;
- imm |= (given & 0x000f0000u) >> 16;
- imm |= (given & 0x00000ff0u) >> 0;
- imm |= (given & 0x0000000fu) << 12;
- func (stream, "#%u\t; 0x%x", imm, imm);
- }
- break;
-
- case 'S':
- {
- unsigned int reg = (given & 0x0000000fu);
- unsigned int stp = (given & 0x00000030u) >> 4;
- unsigned int imm = 0;
- imm |= (given & 0x000000c0u) >> 6;
- imm |= (given & 0x00007000u) >> 10;
-
- func (stream, "%s", arm_regnames[reg]);
- switch (stp)
- {
- case 0:
- if (imm > 0)
- func (stream, ", lsl #%u", imm);
- break;
-
- case 1:
- if (imm == 0)
- imm = 32;
- func (stream, ", lsr #%u", imm);
- break;
-
- case 2:
- if (imm == 0)
- imm = 32;
- func (stream, ", asr #%u", imm);
- break;
-
- case 3:
- if (imm == 0)
- func (stream, ", rrx");
- else
- func (stream, ", ror #%u", imm);
- }
- }
- break;
-
- case 'a':
- {
- unsigned int Rn = (given & 0x000f0000) >> 16;
- unsigned int U = (given & 0x00800000) >> 23;
- unsigned int op = (given & 0x00000f00) >> 8;
- unsigned int i12 = (given & 0x00000fff);
- unsigned int i8 = (given & 0x000000ff);
- bfd_boolean writeback = FALSE, postind = FALSE;
- int offset = 0;
-
- func (stream, "[%s", arm_regnames[Rn]);
- if (U) /* 12-bit positive immediate offset */
- offset = i12;
- else if (Rn == 15) /* 12-bit negative immediate offset */
- offset = -(int)i12;
- else if (op == 0x0) /* shifted register offset */
- {
- unsigned int Rm = (i8 & 0x0f);
- unsigned int sh = (i8 & 0x30) >> 4;
- func (stream, ", %s", arm_regnames[Rm]);
- if (sh)
- func (stream, ", lsl #%u", sh);
- func (stream, "]");
- break;
- }
- else switch (op)
- {
- case 0xE: /* 8-bit positive immediate offset */
- offset = i8;
- break;
-
- case 0xC: /* 8-bit negative immediate offset */
- offset = -i8;
- break;
-
- case 0xF: /* 8-bit + preindex with wb */
- offset = i8;
- writeback = TRUE;
- break;
-
- case 0xD: /* 8-bit - preindex with wb */
- offset = -i8;
- writeback = TRUE;
- break;
-
- case 0xB: /* 8-bit + postindex */
- offset = i8;
- postind = TRUE;
- break;
-
- case 0x9: /* 8-bit - postindex */
- offset = -i8;
- postind = TRUE;
- break;
-
- default:
- func (stream, ", <undefined>]");
- goto skip;
- }
-
- if (postind)
- func (stream, "], #%d", offset);
- else
- {
- if (offset)
- func (stream, ", #%d", offset);
- func (stream, writeback ? "]!" : "]");
- }
-
- if (Rn == 15)
- {
- func (stream, "\t; ");
- info->print_address_func (((pc + 4) & ~3) + offset, info);
- }
- }
- skip:
- break;
-
- case 'A':
- {
- unsigned int P = (given & 0x01000000) >> 24;
- unsigned int U = (given & 0x00800000) >> 23;
- unsigned int W = (given & 0x00400000) >> 21;
- unsigned int Rn = (given & 0x000f0000) >> 16;
- unsigned int off = (given & 0x000000ff);
-
- func (stream, "[%s", arm_regnames[Rn]);
- if (P)
- {
- if (off || !U)
- func (stream, ", #%c%u", U ? '+' : '-', off * 4);
- func (stream, "]");
- if (W)
- func (stream, "!");
- }
- else
- {
- func (stream, "], ");
- if (W)
- func (stream, "#%c%u", U ? '+' : '-', off * 4);
- else
- func (stream, "{%u}", off);
- }
- }
- break;
-
- case 'w':
- {
- unsigned int Sbit = (given & 0x01000000) >> 24;
- unsigned int type = (given & 0x00600000) >> 21;
- switch (type)
- {
- case 0: func (stream, Sbit ? "sb" : "b"); break;
- case 1: func (stream, Sbit ? "sh" : "h"); break;
- case 2:
- if (Sbit)
- func (stream, "??");
- break;
- case 3:
- func (stream, "??");
- break;
- }
- }
- break;
-
- case 'm':
- {
- int started = 0;
- int reg;
-
- func (stream, "{");
- for (reg = 0; reg < 16; reg++)
- if ((given & (1 << reg)) != 0)
- {
- if (started)
- func (stream, ", ");
- started = 1;
- func (stream, "%s", arm_regnames[reg]);
- }
- func (stream, "}");
- }
- break;
-
- case 'E':
- {
- unsigned int msb = (given & 0x0000001f);
- unsigned int lsb = 0;
- lsb |= (given & 0x000000c0u) >> 6;
- lsb |= (given & 0x00007000u) >> 10;
- func (stream, "#%u, #%u", lsb, msb - lsb + 1);
- }
- break;
-
- case 'F':
- {
- unsigned int width = (given & 0x0000001f) + 1;
- unsigned int lsb = 0;
- lsb |= (given & 0x000000c0u) >> 6;
- lsb |= (given & 0x00007000u) >> 10;
- func (stream, "#%u, #%u", lsb, width);
- }
- break;
-
- case 'b':
- {
- unsigned int S = (given & 0x04000000u) >> 26;
- unsigned int J1 = (given & 0x00002000u) >> 13;
- unsigned int J2 = (given & 0x00000800u) >> 11;
- int offset = 0;
-
- offset |= !S << 20;
- offset |= J2 << 19;
- offset |= J1 << 18;
- offset |= (given & 0x003f0000) >> 4;
- offset |= (given & 0x000007ff) << 1;
- offset -= (1 << 20);
-
- info->print_address_func (pc + 4 + offset, info);
- }
- break;
-
- case 'B':
- {
- unsigned int S = (given & 0x04000000u) >> 26;
- unsigned int I1 = (given & 0x00002000u) >> 13;
- unsigned int I2 = (given & 0x00000800u) >> 11;
- int offset = 0;
-
- offset |= !S << 24;
- offset |= !(I1 ^ S) << 23;
- offset |= !(I2 ^ S) << 22;
- offset |= (given & 0x03ff0000u) >> 4;
- offset |= (given & 0x000007ffu) << 1;
- offset -= (1 << 24);
- offset += pc + 4;
-
- /* BLX target addresses are always word aligned. */
- if ((given & 0x00001000u) == 0)
- offset &= ~2u;
-
- info->print_address_func (offset, info);
- }
- break;
-
- case 's':
- {
- unsigned int shift = 0;
- shift |= (given & 0x000000c0u) >> 6;
- shift |= (given & 0x00007000u) >> 10;
- if (given & 0x00200000u)
- func (stream, ", asr #%u", shift);
- else if (shift)
- func (stream, ", lsl #%u", shift);
- /* else print nothing - lsl #0 */
- }
- break;
-
- case 'R':
- {
- unsigned int rot = (given & 0x00000030) >> 4;
- if (rot)
- func (stream, ", ror #%u", rot * 8);
- }
- break;
-
- case 'U':
- switch (given & 0xf)
- {
- case 0xf: func(stream, "sy"); break;
- case 0x7: func(stream, "un"); break;
- case 0xe: func(stream, "st"); break;
- case 0x6: func(stream, "unst"); break;
- default:
- func(stream, "#%d", (int)given & 0xf);
- break;
- }
- break;
-
- case 'C':
- if ((given & 0xff) == 0)
- {
- func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
- if (given & 0x800)
- func (stream, "f");
- if (given & 0x400)
- func (stream, "s");
- if (given & 0x200)
- func (stream, "x");
- if (given & 0x100)
- func (stream, "c");
- }
- else
- {
- func (stream, psr_name (given & 0xff));
- }
- break;
-
- case 'D':
- if ((given & 0xff) == 0)
- func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
- else
- func (stream, psr_name (given & 0xff));
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- int width;
- unsigned long val;
-
- c = arm_decode_bitfield (c, given, &val, &width);
-
- switch (*c)
- {
- case 'd': func (stream, "%lu", val); break;
- case 'W': func (stream, "%lu", val * 4); break;
- case 'r': func (stream, "%s", arm_regnames[val]); break;
-
- case 'c':
- func (stream, "%s", arm_conditional[val]);
- break;
-
- case '\'':
- c++;
- if (val == ((1ul << width) - 1))
- func (stream, "%c", *c);
- break;
-
- case '`':
- c++;
- if (val == 0)
- func (stream, "%c", *c);
- break;
-
- case '?':
- func (stream, "%c", c[(1 << width) - (int)val]);
- c += 1 << width;
- break;
-
- default:
- abort ();
- }
- }
- break;
-
- default:
- abort ();
- }
- }
- return;
- }
-
- /* No match. */
- abort ();
-}
-
-/* Print data bytes on INFO->STREAM. */
-
-static void
-print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
- long given)
-{
- switch (info->bytes_per_chunk)
- {
- case 1:
- info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
- break;
- case 2:
- info->fprintf_func (info->stream, ".short\t0x%04lx", given);
- break;
- case 4:
- info->fprintf_func (info->stream, ".word\t0x%08lx", given);
- break;
- default:
- abort ();
- }
-}
-
-/* Search back through the insn stream to determine if this instruction is
- conditionally executed. */
-static void
-find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
- bfd_boolean little)
-{
- unsigned char b[2];
- unsigned int insn;
- int status;
- /* COUNT is twice the number of instructions seen. It will be odd if we
- just crossed an instruction boundary. */
- int count;
- int it_count;
- unsigned int seen_it;
- bfd_vma addr;
-
- ifthen_address = pc;
- ifthen_state = 0;
-
- addr = pc;
- count = 1;
- it_count = 0;
- seen_it = 0;
- /* Scan backwards looking for IT instructions, keeping track of where
- instruction boundaries are. We don't know if something is actually an
- IT instruction until we find a definite instruction boundary. */
- for (;;)
- {
- if (addr == 0 || info->symbol_at_address_func(addr, info))
- {
- /* A symbol must be on an instruction boundary, and will not
- be within an IT block. */
- if (seen_it && (count & 1))
- break;
-
- return;
- }
- addr -= 2;
- status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
- if (status)
- return;
-
- if (little)
- insn = (b[0]) | (b[1] << 8);
- else
- insn = (b[1]) | (b[0] << 8);
- if (seen_it)
- {
- if ((insn & 0xf800) < 0xe800)
- {
- /* Addr + 2 is an instruction boundary. See if this matches
- the expected boundary based on the position of the last
- IT candidate. */
- if (count & 1)
- break;
- seen_it = 0;
- }
- }
- if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
- {
- /* This could be an IT instruction. */
- seen_it = insn;
- it_count = count >> 1;
- }
- if ((insn & 0xf800) >= 0xe800)
- count++;
- else
- count = (count + 2) | 1;
- /* IT blocks contain at most 4 instructions. */
- if (count >= 8 && !seen_it)
- return;
- }
- /* We found an IT instruction. */
- ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
- if ((ifthen_state & 0xf) == 0)
- ifthen_state = 0;
-}
-
-/* NOTE: There are no checks in these routines that
- the relevant number of data bytes exist. */
-
-int
-print_insn_arm (bfd_vma pc, struct disassemble_info *info)
-{
- unsigned char b[4];
- long given;
- int status;
- int is_thumb = FALSE;
- int is_data = FALSE;
- unsigned int size = 4;
- void (*printer) (bfd_vma, struct disassemble_info *, long);
-#if 0
- bfd_boolean found = FALSE;
-
- if (info->disassembler_options)
- {
- parse_disassembler_options (info->disassembler_options);
-
- /* To avoid repeated parsing of these options, we remove them here. */
- info->disassembler_options = NULL;
- }
-
- /* First check the full symtab for a mapping symbol, even if there
- are no usable non-mapping symbols for this address. */
- if (info->symtab != NULL
- && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
- {
- bfd_vma addr;
- int n;
- int last_sym = -1;
- enum map_type type = MAP_ARM;
-
- if (pc <= last_mapping_addr)
- last_mapping_sym = -1;
- is_thumb = (last_type == MAP_THUMB);
- found = FALSE;
- /* Start scanning at the start of the function, or wherever
- we finished last time. */
- n = info->symtab_pos + 1;
- if (n < last_mapping_sym)
- n = last_mapping_sym;
-
- /* Scan up to the location being disassembled. */
- for (; n < info->symtab_size; n++)
- {
- addr = bfd_asymbol_value (info->symtab[n]);
- if (addr > pc)
- break;
- if ((info->section == NULL
- || info->section == info->symtab[n]->section)
- && get_sym_code_type (info, n, &type))
- {
- last_sym = n;
- found = TRUE;
- }
- }
-
- if (!found)
- {
- n = info->symtab_pos;
- if (n < last_mapping_sym - 1)
- n = last_mapping_sym - 1;
-
- /* No mapping symbol found at this address. Look backwards
- for a preceeding one. */
- for (; n >= 0; n--)
- {
- if (get_sym_code_type (info, n, &type))
- {
- last_sym = n;
- found = TRUE;
- break;
- }
- }
- }
-
- last_mapping_sym = last_sym;
- last_type = type;
- is_thumb = (last_type == MAP_THUMB);
- is_data = (last_type == MAP_DATA);
-
- /* Look a little bit ahead to see if we should print out
- two or four bytes of data. If there's a symbol,
- mapping or otherwise, after two bytes then don't
- print more. */
- if (is_data)
- {
- size = 4 - (pc & 3);
- for (n = last_sym + 1; n < info->symtab_size; n++)
- {
- addr = bfd_asymbol_value (info->symtab[n]);
- if (addr > pc)
- {
- if (addr - pc < size)
- size = addr - pc;
- break;
- }
- }
- /* If the next symbol is after three bytes, we need to
- print only part of the data, so that we can use either
- .byte or .short. */
- if (size == 3)
- size = (pc & 1) ? 1 : 2;
- }
- }
-
- if (info->symbols != NULL)
- {
- if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
- {
- coff_symbol_type * cs;
-
- cs = coffsymbol (*info->symbols);
- is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
- || cs->native->u.syment.n_sclass == C_THUMBSTAT
- || cs->native->u.syment.n_sclass == C_THUMBLABEL
- || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
- || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
- }
- else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
- && !found)
- {
- /* If no mapping symbol has been found then fall back to the type
- of the function symbol. */
- elf_symbol_type * es;
- unsigned int type;
-
- es = *(elf_symbol_type **)(info->symbols);
- type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
-
- is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
- }
- }
-#else
- int little;
-
- little = (info->endian == BFD_ENDIAN_LITTLE);
- is_thumb |= (pc & 1);
- pc &= ~(bfd_vma)1;
-#endif
-
- if (force_thumb)
- is_thumb = TRUE;
-
- info->bytes_per_line = 4;
-
- if (is_data)
- {
- int i;
-
- /* size was already set above. */
- info->bytes_per_chunk = size;
- printer = print_insn_data;
-
- status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
- given = 0;
- if (little)
- for (i = size - 1; i >= 0; i--)
- given = b[i] | (given << 8);
- else
- for (i = 0; i < (int) size; i++)
- given = b[i] | (given << 8);
- }
- else if (!is_thumb)
- {
- /* In ARM mode endianness is a straightforward issue: the instruction
- is four bytes long and is either ordered 0123 or 3210. */
- printer = print_insn_arm_internal;
- info->bytes_per_chunk = 4;
- size = 4;
-
- status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
- if (little)
- given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
- else
- given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
- }
- else
- {
- /* In Thumb mode we have the additional wrinkle of two
- instruction lengths. Fortunately, the bits that determine
- the length of the current instruction are always to be found
- in the first two bytes. */
- printer = print_insn_thumb16;
- info->bytes_per_chunk = 2;
- size = 2;
-
- status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
- if (little)
- given = (b[0]) | (b[1] << 8);
- else
- given = (b[1]) | (b[0] << 8);
-
- if (!status)
- {
- /* These bit patterns signal a four-byte Thumb
- instruction. */
- if ((given & 0xF800) == 0xF800
- || (given & 0xF800) == 0xF000
- || (given & 0xF800) == 0xE800)
- {
- status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
- if (little)
- given = (b[0]) | (b[1] << 8) | (given << 16);
- else
- given = (b[1]) | (b[0] << 8) | (given << 16);
-
- printer = print_insn_thumb32;
- size = 4;
- }
- }
-
- if (ifthen_address != pc)
- find_ifthen_state(pc, info, little);
-
- if (ifthen_state)
- {
- if ((ifthen_state & 0xf) == 0x8)
- ifthen_next_state = 0;
- else
- ifthen_next_state = (ifthen_state & 0xe0)
- | ((ifthen_state & 0xf) << 1);
- }
- }
-
- if (status)
- {
- info->memory_error_func (status, pc, info);
- return -1;
- }
- if (info->flags & INSN_HAS_RELOC)
- /* If the instruction has a reloc associated with it, then
- the offset field in the instruction will actually be the
- addend for the reloc. (We are using REL type relocs).
- In such cases, we can ignore the pc when computing
- addresses, since the addend is not currently pc-relative. */
- pc = 0;
-
- printer (pc, info, given);
-
- if (is_thumb)
- {
- ifthen_state = ifthen_next_state;
- ifthen_address += size;
- }
- return size;
-}
-
-void
-print_arm_disassembler_options (FILE *stream)
-{
- int i;
-
- fprintf (stream, _("\n\
-The following ARM specific disassembler options are supported for use with\n\
-the -M switch:\n"));
-
- for (i = NUM_ARM_REGNAMES; i--;)
- fprintf (stream, " reg-names-%s %*c%s\n",
- regnames[i].name,
- (int)(14 - strlen (regnames[i].name)), ' ',
- regnames[i].description);
-
- fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
- fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
-}
diff --git a/arm-semi.c b/arm-semi.c
deleted file mode 100644
index cd77d1d..0000000
--- a/arm-semi.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Arm "Angel" semihosting syscalls
- *
- * Copyright (c) 2005, 2007 CodeSourcery.
- * Written by Paul Brook.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "cpu.h"
-#ifdef CONFIG_USER_ONLY
-#include "qemu.h"
-
-#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
-#else
-#include "qemu-common.h"
-#include "sysemu.h"
-#include "gdbstub.h"
-#endif
-
-#define SYS_OPEN 0x01
-#define SYS_CLOSE 0x02
-#define SYS_WRITEC 0x03
-#define SYS_WRITE0 0x04
-#define SYS_WRITE 0x05
-#define SYS_READ 0x06
-#define SYS_READC 0x07
-#define SYS_ISTTY 0x09
-#define SYS_SEEK 0x0a
-#define SYS_FLEN 0x0c
-#define SYS_TMPNAM 0x0d
-#define SYS_REMOVE 0x0e
-#define SYS_RENAME 0x0f
-#define SYS_CLOCK 0x10
-#define SYS_TIME 0x11
-#define SYS_SYSTEM 0x12
-#define SYS_ERRNO 0x13
-#define SYS_GET_CMDLINE 0x15
-#define SYS_HEAPINFO 0x16
-#define SYS_EXIT 0x18
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#define GDB_O_RDONLY 0x000
-#define GDB_O_WRONLY 0x001
-#define GDB_O_RDWR 0x002
-#define GDB_O_APPEND 0x008
-#define GDB_O_CREAT 0x200
-#define GDB_O_TRUNC 0x400
-#define GDB_O_BINARY 0
-
-static int gdb_open_modeflags[12] = {
- GDB_O_RDONLY,
- GDB_O_RDONLY | GDB_O_BINARY,
- GDB_O_RDWR,
- GDB_O_RDWR | GDB_O_BINARY,
- GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC,
- GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
- GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC,
- GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
- GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND,
- GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY,
- GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND,
- GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY
-};
-
-static int open_modeflags[12] = {
- O_RDONLY,
- O_RDONLY | O_BINARY,
- O_RDWR,
- O_RDWR | O_BINARY,
- O_WRONLY | O_CREAT | O_TRUNC,
- O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- O_RDWR | O_CREAT | O_TRUNC,
- O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
- O_WRONLY | O_CREAT | O_APPEND,
- O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
- O_RDWR | O_CREAT | O_APPEND,
- O_RDWR | O_CREAT | O_APPEND | O_BINARY
-};
-
-#ifdef CONFIG_USER_ONLY
-static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
-{
- if (code == (uint32_t)-1)
- ts->swi_errno = errno;
- return code;
-}
-#else
-static inline uint32_t set_swi_errno(CPUState *env, uint32_t code)
-{
- return code;
-}
-
-#include "softmmu-semi.h"
-#endif
-
-static target_ulong arm_semi_syscall_len;
-
-#if !defined(CONFIG_USER_ONLY)
-static target_ulong syscall_err;
-#endif
-
-static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
-{
-#ifdef CONFIG_USER_ONLY
- TaskState *ts = env->opaque;
-#endif
-
- if (ret == (target_ulong)-1) {
-#ifdef CONFIG_USER_ONLY
- ts->swi_errno = err;
-#else
- syscall_err = err;
-#endif
- env->regs[0] = ret;
- } else {
- /* Fixup syscalls that use nonstardard return conventions. */
- switch (env->regs[0]) {
- case SYS_WRITE:
- case SYS_READ:
- env->regs[0] = arm_semi_syscall_len - ret;
- break;
- case SYS_SEEK:
- env->regs[0] = 0;
- break;
- default:
- env->regs[0] = ret;
- break;
- }
- }
-}
-
-static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err)
-{
- /* The size is always stored in big-endian order, extract
- the value. We assume the size always fit in 32 bits. */
- uint32_t size;
- cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
- env->regs[0] = be32_to_cpu(size);
-#ifdef CONFIG_USER_ONLY
- ((TaskState *)env->opaque)->swi_errno = err;
-#else
- syscall_err = err;
-#endif
-}
-
-#define ARG(n) \
-({ \
- target_ulong __arg; \
- /* FIXME - handle get_user() failure */ \
- get_user_ual(__arg, args + (n) * 4); \
- __arg; \
-})
-#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
-uint32_t do_arm_semihosting(CPUState *env)
-{
- target_ulong args;
- char * s;
- int nr;
- uint32_t ret;
- uint32_t len;
-#ifdef CONFIG_USER_ONLY
- TaskState *ts = env->opaque;
-#else
- CPUState *ts = env;
-#endif
-
- nr = env->regs[0];
- args = env->regs[1];
- switch (nr) {
- case SYS_OPEN:
- if (!(s = lock_user_string(ARG(0))))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- if (ARG(1) >= 12)
- return (uint32_t)-1;
- if (strcmp(s, ":tt") == 0) {
- if (ARG(1) < 4)
- return STDIN_FILENO;
- else
- return STDOUT_FILENO;
- }
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0),
- (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
- return env->regs[0];
- } else {
- ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
- }
- unlock_user(s, ARG(0), 0);
- return ret;
- case SYS_CLOSE:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "close,%x", ARG(0));
- return env->regs[0];
- } else {
- return set_swi_errno(ts, close(ARG(0)));
- }
- case SYS_WRITEC:
- {
- char c;
-
- if (get_user_u8(c, args))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- /* Write to debug console. stderr is near enough. */
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args);
- return env->regs[0];
- } else {
- return write(STDERR_FILENO, &c, 1);
- }
- }
- case SYS_WRITE0:
- if (!(s = lock_user_string(args)))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- len = strlen(s);
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len);
- ret = env->regs[0];
- } else {
- ret = write(STDERR_FILENO, s, len);
- }
- unlock_user(s, args, 0);
- return ret;
- case SYS_WRITE:
- len = ARG(2);
- if (use_gdb_syscalls()) {
- arm_semi_syscall_len = len;
- gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len);
- return env->regs[0];
- } else {
- if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1)))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- ret = set_swi_errno(ts, write(ARG(0), s, len));
- unlock_user(s, ARG(1), 0);
- if (ret == (uint32_t)-1)
- return -1;
- return len - ret;
- }
- case SYS_READ:
- len = ARG(2);
- if (use_gdb_syscalls()) {
- arm_semi_syscall_len = len;
- gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len);
- return env->regs[0];
- } else {
- if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0)))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- do
- ret = set_swi_errno(ts, read(ARG(0), s, len));
- while (ret == -1 && errno == EINTR);
- unlock_user(s, ARG(1), len);
- if (ret == (uint32_t)-1)
- return -1;
- return len - ret;
- }
- case SYS_READC:
- /* XXX: Read from debug cosole. Not implemented. */
- return 0;
- case SYS_ISTTY:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "isatty,%x", ARG(0));
- return env->regs[0];
- } else {
- return isatty(ARG(0));
- }
- case SYS_SEEK:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1));
- return env->regs[0];
- } else {
- ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
- if (ret == (uint32_t)-1)
- return -1;
- return 0;
- }
- case SYS_FLEN:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x",
- ARG(0), env->regs[13]-64);
- return env->regs[0];
- } else {
- struct stat buf;
- ret = set_swi_errno(ts, fstat(ARG(0), &buf));
- if (ret == (uint32_t)-1)
- return -1;
- return buf.st_size;
- }
- case SYS_TMPNAM:
- /* XXX: Not implemented. */
- return -1;
- case SYS_REMOVE:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
- ret = env->regs[0];
- } else {
- if (!(s = lock_user_string(ARG(0))))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- ret = set_swi_errno(ts, remove(s));
- unlock_user(s, ARG(0), 0);
- }
- return ret;
- case SYS_RENAME:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "rename,%s,%s",
- ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1);
- return env->regs[0];
- } else {
- char *s2;
- s = lock_user_string(ARG(0));
- s2 = lock_user_string(ARG(2));
- if (!s || !s2)
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- ret = (uint32_t)-1;
- else
- ret = set_swi_errno(ts, rename(s, s2));
- if (s2)
- unlock_user(s2, ARG(2), 0);
- if (s)
- unlock_user(s, ARG(0), 0);
- return ret;
- }
- case SYS_CLOCK:
- return clock() / (CLOCKS_PER_SEC / 100);
- case SYS_TIME:
- return set_swi_errno(ts, time(NULL));
- case SYS_SYSTEM:
- if (use_gdb_syscalls()) {
- gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
- return env->regs[0];
- } else {
- if (!(s = lock_user_string(ARG(0))))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- ret = set_swi_errno(ts, system(s));
- unlock_user(s, ARG(0), 0);
- return ret;
- }
- case SYS_ERRNO:
-#ifdef CONFIG_USER_ONLY
- return ts->swi_errno;
-#else
- return syscall_err;
-#endif
- case SYS_GET_CMDLINE:
-#ifdef CONFIG_USER_ONLY
- /* Build a commandline from the original argv. */
- {
- char **arg = ts->info->host_argv;
- int len = ARG(1);
- /* lock the buffer on the ARM side */
- char *cmdline_buffer = (char*)lock_user(VERIFY_WRITE, ARG(0), len, 0);
-
- if (!cmdline_buffer)
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
-
- s = cmdline_buffer;
- while (*arg && len > 2) {
- int n = strlen(*arg);
-
- if (s != cmdline_buffer) {
- *(s++) = ' ';
- len--;
- }
- if (n >= len)
- n = len - 1;
- memcpy(s, *arg, n);
- s += n;
- len -= n;
- arg++;
- }
- /* Null terminate the string. */
- *s = 0;
- len = s - cmdline_buffer;
-
- /* Unlock the buffer on the ARM side. */
- unlock_user(cmdline_buffer, ARG(0), len);
-
- /* Adjust the commandline length argument. */
- SET_ARG(1, len);
-
- /* Return success if commandline fit into buffer. */
- return *arg ? -1 : 0;
- }
-#else
- return -1;
-#endif
- case SYS_HEAPINFO:
- {
- uint32_t *ptr;
- uint32_t limit;
-
-#ifdef CONFIG_USER_ONLY
- /* Some C libraries assume the heap immediately follows .bss, so
- allocate it using sbrk. */
- if (!ts->heap_limit) {
- long ret;
-
- ts->heap_base = do_brk(0);
- limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
- /* Try a big heap, and reduce the size if that fails. */
- for (;;) {
- ret = do_brk(limit);
- if (ret != -1)
- break;
- limit = (ts->heap_base >> 1) + (limit >> 1);
- }
- ts->heap_limit = limit;
- }
-
- if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- ptr[0] = tswap32(ts->heap_base);
- ptr[1] = tswap32(ts->heap_limit);
- ptr[2] = tswap32(ts->stack_base);
- ptr[3] = tswap32(0); /* Stack limit. */
- unlock_user(ptr, ARG(0), 16);
-#else
- limit = ram_size;
- if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
- /* FIXME - should this error code be -TARGET_EFAULT ? */
- return (uint32_t)-1;
- /* TODO: Make this use the limit of the loaded application. */
- ptr[0] = tswap32(limit / 2);
- ptr[1] = tswap32(limit);
- ptr[2] = tswap32(limit); /* Stack base */
- ptr[3] = tswap32(0); /* Stack limit. */
- unlock_user(ptr, ARG(0), 16);
-#endif
- return 0;
- }
- case SYS_EXIT:
- exit(0);
- default:
- fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
- cpu_dump_state(env, stderr, fprintf, 0);
- abort();
- }
-}
diff --git a/arm.ld b/arm.ld
deleted file mode 100644
index 93285d6..0000000
--- a/arm.ld
+++ /dev/null
@@ -1,154 +0,0 @@
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm",
- "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
- __exidx_start = .;
- .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
- __exidx_end = .;
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.gen_code)
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .data1 : { *(.data1) }
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- }
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- PROVIDE_HIDDEN (__init_array_end = .);
- }
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- PROVIDE_HIDDEN (__fini_array_end = .);
- }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
deleted file mode 100644
index 1cc4d6e..0000000
--- a/audio/alsaaudio.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-/*
- * QEMU ALSA audio driver
- *
- * Copyright (c) 2008 The Android Open Source Project
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <alsa/asoundlib.h>
-#include "audio.h"
-
-#define AUDIO_CAP "alsa"
-#include "audio_int.h"
-#include <dlfcn.h>
-#include <pthread.h>
-#include "qemu_debug.h"
-
-#define DEBUG 1
-
-#if DEBUG
-# include <stdio.h>
-# define D(...) VERBOSE_PRINT(audio,__VA_ARGS__)
-# define D_ACTIVE VERBOSE_CHECK(audio)
-# define O(...) VERBOSE_PRINT(audioout,__VA_ARGS__)
-# define I(...) VERBOSE_PRINT(audioin,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-# define D_ACTIVE 0
-# define O(...) ((void)0)
-# define I(...) ((void)0)
-#endif
-
-
-#define STRINGIFY_(x) #x
-#define STRINGIFY(x) STRINGIFY_(x)
-
-#define DYNLINK_FUNCTIONS \
- DYNLINK_FUNC(size_t,snd_pcm_sw_params_sizeof,(void)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_current,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \
- DYNLINK_FUNC(int,snd_pcm_sw_params_set_start_threshold,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)) \
- DYNLINK_FUNC(int,snd_pcm_sw_params,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)) \
- DYNLINK_FUNC(int,snd_pcm_sw_params_current,(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)) \
- DYNLINK_FUNC(size_t,snd_pcm_hw_params_sizeof,(void)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_any,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_access,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_get_format,(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_format,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_rate_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_channels_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_buffer_time_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_get_buffer_size,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \
- DYNLINK_FUNC(int,snd_pcm_prepare,(snd_pcm_t *pcm)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_get_period_size,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_get_period_size_min,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_period_size,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_get_buffer_size_min,(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_buffer_size,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_period_time_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)) \
- DYNLINK_FUNC(snd_pcm_sframes_t,snd_pcm_avail_update,(snd_pcm_t *pcm)) \
- DYNLINK_FUNC(int,snd_pcm_drop,(snd_pcm_t *pcm)) \
- DYNLINK_FUNC(snd_pcm_sframes_t,snd_pcm_writei,(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)) \
- DYNLINK_FUNC(snd_pcm_sframes_t,snd_pcm_readi,(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)) \
- DYNLINK_FUNC(snd_pcm_state_t,snd_pcm_state,(snd_pcm_t *pcm)) \
- DYNLINK_FUNC(const char*,snd_strerror,(int errnum)) \
- DYNLINK_FUNC(int,snd_pcm_open,(snd_pcm_t **pcm, const char *name,snd_pcm_stream_t stream, int mode)) \
- DYNLINK_FUNC(int,snd_pcm_close,(snd_pcm_t *pcm)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_buffer_size_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_set_period_size_near,(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir)) \
- DYNLINK_FUNC(int,snd_pcm_hw_params_get_format,(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val)) \
-
-#define DYNLINK_FUNCTIONS_INIT \
- alsa_dynlink_init
-
-#include "dynlink.h"
-
-/* these are inlined functions in the original headers */
-#define FF_snd_pcm_hw_params_alloca(ptr) \
- do { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(FF(snd_pcm_hw_params_sizeof)()); memset(*ptr, 0, FF(snd_pcm_hw_params_sizeof)()); } while (0)
-
-#define FF_snd_pcm_sw_params_alloca(ptr) \
- do { assert(ptr); *ptr = (snd_pcm_sw_params_t *) alloca(FF(snd_pcm_sw_params_sizeof)()); memset(*ptr, 0, FF(snd_pcm_sw_params_sizeof)()); } while (0)
-
-static void* alsa_lib;
-
-typedef struct ALSAVoiceOut {
- HWVoiceOut hw;
- void *pcm_buf;
- snd_pcm_t *handle;
-} ALSAVoiceOut;
-
-typedef struct ALSAVoiceIn {
- HWVoiceIn hw;
- snd_pcm_t *handle;
- void *pcm_buf;
-} ALSAVoiceIn;
-
-static struct {
- int size_in_usec_in;
- int size_in_usec_out;
- const char *pcm_name_in;
- const char *pcm_name_out;
- unsigned int buffer_size_in;
- unsigned int period_size_in;
- unsigned int buffer_size_out;
- unsigned int period_size_out;
- unsigned int threshold;
-
- int buffer_size_in_overridden;
- int period_size_in_overridden;
-
- int buffer_size_out_overridden;
- int period_size_out_overridden;
- int verbose;
-} conf = {
- .buffer_size_out = 1024,
- .pcm_name_out = "default",
- .pcm_name_in = "default",
-};
-
-struct alsa_params_req {
- int freq;
- snd_pcm_format_t fmt;
- int nchannels;
- int size_in_usec;
- int override_mask;
- unsigned int buffer_size;
- unsigned int period_size;
-};
-
-struct alsa_params_obt {
- int freq;
- audfmt_e fmt;
- int endianness;
- int nchannels;
- snd_pcm_uframes_t samples;
-};
-
-static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", FF(snd_strerror) (err));
-}
-
-static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
- int err,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", FF(snd_strerror) (err));
-}
-
-static void alsa_anal_close (snd_pcm_t **handlep)
-{
- int err = FF(snd_pcm_close) (*handlep);
- if (err) {
- alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
- }
- *handlep = NULL;
-}
-
-static int alsa_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static snd_pcm_format_t aud_to_alsafmt (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- return SND_PCM_FORMAT_S8;
-
- case AUD_FMT_U8:
- return SND_PCM_FORMAT_U8;
-
- case AUD_FMT_S16:
- return SND_PCM_FORMAT_S16_LE;
-
- case AUD_FMT_U16:
- return SND_PCM_FORMAT_U16_LE;
-
- case AUD_FMT_S32:
- return SND_PCM_FORMAT_S32_LE;
-
- case AUD_FMT_U32:
- return SND_PCM_FORMAT_U32_LE;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return SND_PCM_FORMAT_U8;
- }
-}
-
-static int alsa_to_audfmt (snd_pcm_format_t alsafmt, audfmt_e *fmt,
- int *endianness)
-{
- switch (alsafmt) {
- case SND_PCM_FORMAT_S8:
- *endianness = 0;
- *fmt = AUD_FMT_S8;
- break;
-
- case SND_PCM_FORMAT_U8:
- *endianness = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case SND_PCM_FORMAT_S16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case SND_PCM_FORMAT_U16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case SND_PCM_FORMAT_S16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case SND_PCM_FORMAT_U16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- case SND_PCM_FORMAT_S32_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S32;
- break;
-
- case SND_PCM_FORMAT_U32_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U32;
- break;
-
- case SND_PCM_FORMAT_S32_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S32;
- break;
-
- case SND_PCM_FORMAT_U32_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U32;
- break;
-
- default:
- dolog ("Unrecognized audio format %d\n", alsafmt);
- return -1;
- }
-
- return 0;
-}
-
-static void alsa_dump_info (struct alsa_params_req *req,
- struct alsa_params_obt *obt)
-{
- dolog ("parameter | requested value | obtained value\n");
- dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
- dolog ("channels | %10d | %10d\n",
- req->nchannels, obt->nchannels);
- dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
- dolog ("============================================\n");
- dolog ("requested: buffer size %d period size %d\n",
- req->buffer_size, req->period_size);
- dolog ("obtained: samples %ld\n", obt->samples);
-}
-
-static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
-{
- int err;
- snd_pcm_sw_params_t *sw_params;
-
- FF_snd_pcm_sw_params_alloca (&sw_params);
-
- err = FF(snd_pcm_sw_params_current) (handle, sw_params);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to get current software parameters\n");
- return;
- }
-
- err = FF(snd_pcm_sw_params_set_start_threshold) (handle, sw_params, threshold);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to set software threshold to %ld\n",
- threshold);
- return;
- }
-
- err = FF(snd_pcm_sw_params) (handle, sw_params);
- if (err < 0) {
- dolog ("Could not fully initialize DAC\n");
- alsa_logerr (err, "Failed to set software parameters\n");
- return;
- }
-}
-
-static int alsa_open (int in, struct alsa_params_req *req,
- struct alsa_params_obt *obt, snd_pcm_t **handlep)
-{
- snd_pcm_t *handle;
- snd_pcm_hw_params_t *hw_params;
- int err;
- int size_in_usec;
- unsigned int freq, nchannels;
- const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
- snd_pcm_uframes_t obt_buffer_size;
- const char *typ = in ? "ADC" : "DAC";
- snd_pcm_format_t obtfmt;
-
- freq = req->freq;
- nchannels = req->nchannels;
- size_in_usec = req->size_in_usec;
-
- FF_snd_pcm_hw_params_alloca (&hw_params);
-
- err = FF(snd_pcm_open) (
- &handle,
- pcm_name,
- in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
- SND_PCM_NONBLOCK
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
- return -1;
- }
-
- err = FF(snd_pcm_hw_params_any) (handle, hw_params);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
- goto err;
- }
-
- err = FF(snd_pcm_hw_params_set_access) (
- handle,
- hw_params,
- SND_PCM_ACCESS_RW_INTERLEAVED
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set access type\n");
- goto err;
- }
-
- err = FF(snd_pcm_hw_params_set_format) (handle, hw_params, req->fmt);
- if (err < 0 && conf.verbose) {
- alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
- goto err;
- }
-
- err = FF(snd_pcm_hw_params_set_rate_near) (handle, hw_params, &freq, 0);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
- goto err;
- }
-
- err = FF(snd_pcm_hw_params_set_channels_near) (
- handle,
- hw_params,
- &nchannels
- );
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
- req->nchannels);
- goto err;
- }
-
- if (nchannels != 1 && nchannels != 2) {
- alsa_logerr2 (err, typ,
- "Can not handle obtained number of channels %d\n",
- nchannels);
- goto err;
- }
-
- if (req->buffer_size) {
- unsigned long obt;
-
- if (size_in_usec) {
- int dir = 0;
- unsigned int btime = req->buffer_size;
-
- err = FF(snd_pcm_hw_params_set_buffer_time_near) (
- handle,
- hw_params,
- &btime,
- &dir
- );
- obt = btime;
- }
- else {
- snd_pcm_uframes_t bsize = req->buffer_size;
-
- err = FF(snd_pcm_hw_params_set_buffer_size_near) (
- handle,
- hw_params,
- &bsize
- );
- obt = bsize;
- }
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n",
- size_in_usec ? "time" : "size", req->buffer_size);
- goto err;
- }
-
- if ((req->override_mask & 2) && (obt - req->buffer_size))
- dolog ("Requested buffer %s %u was rejected, using %lu\n",
- size_in_usec ? "time" : "size", req->buffer_size, obt);
- }
-
- if (req->period_size) {
- unsigned long obt;
-
- if (size_in_usec) {
- int dir = 0;
- unsigned int ptime = req->period_size;
-
- err = FF(snd_pcm_hw_params_set_period_time_near) (
- handle,
- hw_params,
- &ptime,
- &dir
- );
- obt = ptime;
- }
- else {
- int dir = 0;
- snd_pcm_uframes_t psize = req->period_size;
-
- err = FF(snd_pcm_hw_params_set_period_size_near) (
- handle,
- hw_params,
- &psize,
- &dir
- );
- obt = psize;
- }
-
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to set period %s to %d\n",
- size_in_usec ? "time" : "size", req->period_size);
- goto err;
- }
-
- if ((req->override_mask & 1) && (obt - req->period_size))
- dolog ("Requested period %s %u was rejected, using %lu\n",
- size_in_usec ? "time" : "size", req->period_size, obt);
- }
-
- err = FF(snd_pcm_hw_params) (handle, hw_params);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
- goto err;
- }
-
- err = FF(snd_pcm_hw_params_get_buffer_size) (hw_params, &obt_buffer_size);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to get buffer size\n");
- goto err;
- }
-
- err = FF(snd_pcm_hw_params_get_format)(hw_params, &obtfmt);
- err = FF(snd_pcm_hw_params_get_format) (hw_params, &obtfmt);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Failed to get format\n");
- goto err;
- }
-
- if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
- dolog ("Invalid format was returned %d\n", obtfmt);
- goto err;
- }
-
- err = FF(snd_pcm_prepare) (handle);
- if (err < 0) {
- alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
- goto err;
- }
-
- if (!in && conf.threshold) {
- snd_pcm_uframes_t threshold;
- int bytes_per_sec;
-
- bytes_per_sec = freq << (nchannels == 2);
-
- switch (obt->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- bytes_per_sec <<= 1;
- break;
-
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- bytes_per_sec <<= 2;
- break;
- }
-
- threshold = (conf.threshold * bytes_per_sec) / 1000;
- alsa_set_threshold (handle, threshold);
- }
-
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->samples = obt_buffer_size;
-
- *handlep = handle;
-
- if (conf.verbose &&
- (obt->fmt != req->fmt ||
- obt->nchannels != req->nchannels ||
- obt->freq != req->freq)) {
- dolog ("Audio paramters for %s\n", typ);
- alsa_dump_info (req, obt);
- }
-
-#ifdef DEBUG
- alsa_dump_info (req, obt);
-#endif
- return 0;
-
- err:
- alsa_anal_close (&handle);
- return -1;
-}
-
-static int alsa_recover (snd_pcm_t *handle)
-{
- int err = FF(snd_pcm_prepare) (handle);
- if (err < 0) {
- alsa_logerr (err, "Failed to prepare handle %p\n", handle);
- return -1;
- }
- return 0;
-}
-
-static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
-{
- snd_pcm_sframes_t avail;
-
- avail = FF(snd_pcm_avail_update) (handle);
- if (avail < 0) {
- if (avail == -EPIPE) {
- if (!alsa_recover (handle)) {
- avail = FF(snd_pcm_avail_update) (handle);
- }
- }
-
- if (avail < 0) {
- alsa_logerr (avail,
- "Could not obtain number of available frames\n");
- return -1;
- }
- }
-
- return avail;
-}
-
-static int alsa_run_out (HWVoiceOut *hw)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
- int rpos, live, decr;
- int samples;
- uint8_t *dst;
- st_sample_t *src;
- snd_pcm_sframes_t avail;
-
- live = audio_pcm_hw_get_live_out (hw);
- if (!live) {
- return 0;
- }
-
- avail = alsa_get_avail (alsa->handle);
- if (avail < 0) {
- dolog ("Could not get number of available playback frames\n");
- return 0;
- }
-
- decr = audio_MIN (live, avail);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int len = audio_MIN (samples, left_till_end_samples);
- snd_pcm_sframes_t written;
-
- src = hw->mix_buf + rpos;
- dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
-
- hw->clip (dst, src, len);
-
- while (len) {
- written = FF(snd_pcm_writei) (alsa->handle, dst, len);
-
- if (written <= 0) {
- switch (written) {
- case 0:
- if (conf.verbose) {
- dolog ("Failed to write %d frames (wrote zero)\n", len);
- }
- goto exit;
-
- case -EPIPE:
- if (alsa_recover (alsa->handle)) {
- alsa_logerr (written, "Failed to write %d frames\n",
- len);
- goto exit;
- }
- if (conf.verbose) {
- dolog ("Recovering from playback xrun\n");
- }
- continue;
-
- case -EAGAIN:
- goto exit;
-
- default:
- alsa_logerr (written, "Failed to write %d frames to %p\n",
- len, dst);
- goto exit;
- }
- }
-
- rpos = (rpos + written) % hw->samples;
- samples -= written;
- len -= written;
- dst = advance (dst, written << hw->info.shift);
- src += written;
- }
- }
-
- exit:
- hw->rpos = rpos;
- return decr;
-}
-
-static void alsa_fini_out (HWVoiceOut *hw)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- ldebug ("alsa_fini\n");
- alsa_anal_close (&alsa->handle);
-
- if (alsa->pcm_buf) {
- qemu_free (alsa->pcm_buf);
- alsa->pcm_buf = NULL;
- }
-}
-
-static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
- struct alsa_params_req req;
- struct alsa_params_obt obt;
- snd_pcm_t *handle;
- audsettings_t obt_as;
- int result = -1;
-
- /* shut alsa debug spew */
- if (!D_ACTIVE)
- stdio_disable();
-
- req.fmt = aud_to_alsafmt (as->fmt);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.period_size = conf.period_size_out;
- req.buffer_size = conf.buffer_size_out;
- req.size_in_usec = conf.size_in_usec_out;
- req.override_mask = !!conf.period_size_out_overridden
- | (!!conf.buffer_size_out_overridden << 1);
-
- if (alsa_open (0, &req, &obt, &handle)) {
- goto Exit;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = obt.fmt;
- obt_as.endianness = obt.endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);
- if (!alsa->pcm_buf) {
- dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- alsa_anal_close (&handle);
- goto Exit;
- }
-
- alsa->handle = handle;
- result = 0; /* success */
-
-Exit:
- if (!D_ACTIVE)
- stdio_enable();
-
- return result;
-}
-
-static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
-{
- int err;
-
- if (pause) {
- err = FF(snd_pcm_drop) (handle);
- if (err < 0) {
- alsa_logerr (err, "Could not stop %s\n", typ);
- return -1;
- }
- }
- else {
- err = FF(snd_pcm_prepare) (handle);
- if (err < 0) {
- alsa_logerr (err, "Could not prepare handle for %s\n", typ);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- return alsa_voice_ctl (alsa->handle, "playback", 0);
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- return alsa_voice_ctl (alsa->handle, "playback", 1);
- }
-
- return -1;
-}
-
-static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
- struct alsa_params_req req;
- struct alsa_params_obt obt;
- snd_pcm_t *handle;
- audsettings_t obt_as;
- int result = -1;
-
- /* shut alsa debug spew */
- if (!D_ACTIVE)
- stdio_disable();
-
- req.fmt = aud_to_alsafmt (as->fmt);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.period_size = conf.period_size_in;
- req.buffer_size = conf.buffer_size_in;
- req.size_in_usec = conf.size_in_usec_in;
- req.override_mask = !!conf.period_size_in_overridden
- | (!!conf.buffer_size_in_overridden << 1);
-
- if (alsa_open (1, &req, &obt, &handle)) {
- goto Exit;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = obt.fmt;
- obt_as.endianness = obt.endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
- alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!alsa->pcm_buf) {
- dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- alsa_anal_close (&handle);
- goto Exit;
- }
-
- alsa->handle = handle;
- result = 0; /* success */
-
-Exit:
- if (!D_ACTIVE)
- stdio_enable();
-
- return result;
-}
-
-static void alsa_fini_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- alsa_anal_close (&alsa->handle);
-
- if (alsa->pcm_buf) {
- qemu_free (alsa->pcm_buf);
- alsa->pcm_buf = NULL;
- }
-}
-
-static int alsa_run_in (HWVoiceIn *hw)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int i;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- int decr;
- struct {
- int add;
- int len;
- } bufs[2] = {
- { hw->wpos, 0 },
- { 0, 0 }
- };
- snd_pcm_sframes_t avail;
- snd_pcm_uframes_t read_samples = 0;
-
- if (!dead) {
- return 0;
- }
-
- avail = alsa_get_avail (alsa->handle);
- if (avail < 0) {
- dolog ("Could not get number of captured frames\n");
- return 0;
- }
-
- if (!avail && (FF(snd_pcm_state) (alsa->handle) == SND_PCM_STATE_PREPARED)) {
- avail = hw->samples;
- }
-
- decr = audio_MIN (dead, avail);
- if (!decr) {
- return 0;
- }
-
- if (hw->wpos + decr > hw->samples) {
- bufs[0].len = (hw->samples - hw->wpos);
- bufs[1].len = (decr - (hw->samples - hw->wpos));
- }
- else {
- bufs[0].len = decr;
- }
-
- for (i = 0; i < 2; ++i) {
- void *src;
- st_sample_t *dst;
- snd_pcm_sframes_t nread;
- snd_pcm_uframes_t len;
-
- len = bufs[i].len;
-
- src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
- dst = hw->conv_buf + bufs[i].add;
-
- while (len) {
- nread = FF(snd_pcm_readi) (alsa->handle, src, len);
-
- if (nread <= 0) {
- switch (nread) {
- case 0:
- if (conf.verbose) {
- dolog ("Failed to read %ld frames (read zero)\n", len);
- }
- goto exit;
-
- case -EPIPE:
- if (alsa_recover (alsa->handle)) {
- alsa_logerr (nread, "Failed to read %ld frames\n", len);
- goto exit;
- }
- if (conf.verbose) {
- dolog ("Recovering from capture xrun\n");
- }
- continue;
-
- case -EAGAIN:
- goto exit;
-
- default:
- alsa_logerr (
- nread,
- "Failed to read %ld frames from %p\n",
- len,
- src
- );
- goto exit;
- }
- }
-
- hw->conv (dst, src, nread, &nominal_volume);
-
- src = advance (src, nread << hwshift);
- dst += nread;
-
- read_samples += nread;
- len -= nread;
- }
- }
-
- exit:
- hw->wpos = (hw->wpos + read_samples) % hw->samples;
- return read_samples;
-}
-
-static int alsa_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- return alsa_voice_ctl (alsa->handle, "capture", 0);
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- return alsa_voice_ctl (alsa->handle, "capture", 1);
- }
-
- return -1;
-}
-
-static void *alsa_audio_init (void)
-{
- void* result = NULL;
-
- alsa_lib = dlopen( "libasound.so", RTLD_NOW );
- if (alsa_lib == NULL)
- alsa_lib = dlopen( "libasound.so.2", RTLD_NOW );
-
- if (alsa_lib == NULL) {
- ldebug("could not find libasound on this system\n");
- goto Exit;
- }
-
- if (alsa_dynlink_init(alsa_lib) < 0)
- goto Fail;
-
- result = &conf;
- goto Exit;
-
-Fail:
- ldebug("%s: failed to open library\n", __FUNCTION__);
- dlclose(alsa_lib);
-
-Exit:
- return result;
-}
-
-static void alsa_audio_fini (void *opaque)
-{
- if (alsa_lib != NULL) {
- dlclose(alsa_lib);
- alsa_lib = NULL;
- }
- (void) opaque;
-}
-
-static struct audio_option alsa_options[] = {
- {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out,
- "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
- {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out,
- "DAC period size (0 to go with system default)",
- &conf.period_size_out_overridden, 0},
- {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out,
- "DAC buffer size (0 to go with system default)",
- &conf.buffer_size_out_overridden, 0},
-
- {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in,
- "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
- {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in,
- "ADC period size (0 to go with system default)",
- &conf.period_size_in_overridden, 0},
- {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in,
- "ADC buffer size (0 to go with system default)",
- &conf.buffer_size_in_overridden, 0},
-
- {"THRESHOLD", AUD_OPT_INT, &conf.threshold,
- "(undocumented)", NULL, 0},
-
- {"DAC_DEV", AUD_OPT_STR, &conf.pcm_name_out,
- "DAC device name (for instance dmix)", NULL, 0},
-
- {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in,
- "ADC device name", NULL, 0},
-
- {"VERBOSE", AUD_OPT_BOOL, &conf.verbose,
- "Behave in a more verbose way", NULL, 0},
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops alsa_pcm_ops = {
- alsa_init_out,
- alsa_fini_out,
- alsa_run_out,
- alsa_write,
- alsa_ctl_out,
-
- alsa_init_in,
- alsa_fini_in,
- alsa_run_in,
- alsa_read,
- alsa_ctl_in
-};
-
-struct audio_driver alsa_audio_driver = {
- INIT_FIELD (name = ) "alsa",
- INIT_FIELD (descr = ) "ALSA audio (www.alsa-project.org)",
- INIT_FIELD (options = ) alsa_options,
- INIT_FIELD (init = ) alsa_audio_init,
- INIT_FIELD (fini = ) alsa_audio_fini,
- INIT_FIELD (pcm_ops = ) &alsa_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) INT_MAX,
- INIT_FIELD (voice_size_out = ) sizeof (ALSAVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (ALSAVoiceIn)
-};
diff --git a/audio/audio.c b/audio/audio.c
deleted file mode 100644
index 5a77dac..0000000
--- a/audio/audio.c
+++ /dev/null
@@ -1,2172 +0,0 @@
-/*
- * QEMU Audio subsystem
- *
- * Copyright (c) 2007-2008 The Android Open Source Project
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw/hw.h"
-#include "audio.h"
-#include "console.h"
-#include "qemu-timer.h"
-#include "sysemu.h"
-
-#define AUDIO_CAP "audio"
-#include "audio_int.h"
-#include "android/utils/system.h"
-#include "qemu_debug.h"
-#include "android/android.h"
-
-/* #define DEBUG_PLIVE */
-/* #define DEBUG_LIVE */
-/* #define DEBUG_OUT */
-/* #define DEBUG_CAPTURE */
-
-#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
-
-static struct audio_driver *drvtab[] = {
-#ifdef CONFIG_ESD
- &esd_audio_driver,
-#endif
-#ifdef CONFIG_ALSA
- &alsa_audio_driver,
-#endif
-#ifdef CONFIG_COREAUDIO
- &coreaudio_audio_driver,
-#endif
-#ifdef CONFIG_DSOUND
- &dsound_audio_driver,
-#endif
-#ifdef CONFIG_FMOD
- &fmod_audio_driver,
-#endif
-#ifdef CONFIG_WINAUDIO
- &win_audio_driver,
-#endif
-#ifdef CONFIG_SDL
- &sdl_audio_driver,
-#endif
-#ifdef CONFIG_OSS
- &oss_audio_driver,
-#endif
- &no_audio_driver,
-#if 0 /* disabled WAV audio for now - until we find a user-friendly way to use it */
- &wav_audio_driver
-#endif
-};
-
-
-int
-audio_get_backend_count( int is_input )
-{
- int nn, count = 0;
-
- for (nn = 0; nn < sizeof(drvtab)/sizeof(drvtab[0]); nn++)
- {
- if (is_input) {
- if ( drvtab[nn]->max_voices_in > 0 )
- count += 1;
- } else {
- if ( drvtab[nn]->max_voices_out > 0 )
- count += 1;
- }
- }
- return count;
-}
-
-const char*
-audio_get_backend_name( int is_input, int index, const char* *pinfo )
-{
- int nn;
-
- index += 1;
- for (nn = 0; nn < sizeof(drvtab)/sizeof(drvtab[0]); nn++)
- {
- if (is_input) {
- if ( drvtab[nn]->max_voices_in > 0 ) {
- if ( --index == 0 ) {
- *pinfo = drvtab[nn]->descr;
- return drvtab[nn]->name;
- }
- }
- } else {
- if ( drvtab[nn]->max_voices_out > 0 ) {
- if ( --index == 0 ) {
- *pinfo = drvtab[nn]->descr;
- return drvtab[nn]->name;
- }
- }
- }
- }
- *pinfo = NULL;
- return NULL;
-}
-
-
-int
-audio_check_backend_name( int is_input, const char* name )
-{
- int nn;
-
- for (nn = 0; nn < sizeof(drvtab)/sizeof(drvtab[0]); nn++)
- {
- if ( !strcmp(drvtab[nn]->name, name) ) {
- if (is_input) {
- if (drvtab[nn]->max_voices_in > 0)
- return 1;
- } else {
- if (drvtab[nn]->max_voices_out > 0)
- return 1;
- }
- break;
- }
- }
- return 0;
-}
-
-
-struct fixed_settings {
- int enabled;
- int nb_voices;
- int greedy;
- audsettings_t settings;
-};
-
-static struct {
- struct fixed_settings fixed_out;
- struct fixed_settings fixed_in;
- union {
- int hz;
- int64_t ticks;
- } period;
- int plive;
- int log_to_monitor;
-} conf = {
- { /* DAC fixed settings */
- 1, /* enabled */
- 1, /* nb_voices */
- 1, /* greedy */
- {
- 44100, /* freq */
- 2, /* nchannels */
- AUD_FMT_S16, /* fmt */
- AUDIO_HOST_ENDIANNESS
- }
- },
-
- { /* ADC fixed settings */
- 1, /* enabled */
- 1, /* nb_voices */
- 1, /* greedy */
- {
- 44100, /* freq */
- 2, /* nchannels */
- AUD_FMT_S16, /* fmt */
- AUDIO_HOST_ENDIANNESS
- }
- },
-
- { 0 }, /* period */
- 0, /* plive */
- 0 /* log_to_monitor */
-};
-
-AudioState glob_audio_state;
-
-volume_t nominal_volume = {
- 0,
-#ifdef FLOAT_MIXENG
- 1.0,
- 1.0
-#else
- 1ULL << 32,
- 1ULL << 32
-#endif
-};
-
-/* http://www.df.lth.se/~john_e/gems/gem002d.html */
-/* http://www.multi-platforms.com/Tips/PopCount.htm */
-uint32_t popcount (uint32_t u)
-{
- u = ((u&0x55555555) + ((u>>1)&0x55555555));
- u = ((u&0x33333333) + ((u>>2)&0x33333333));
- u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
- u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
- u = ( u&0x0000ffff) + (u>>16);
- return u;
-}
-
-inline uint32_t lsbindex (uint32_t u)
-{
- return popcount ((u&-u)-1);
-}
-
-#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
-#error No its not
-#else
-int audio_bug (const char *funcname, int cond)
-{
- if (cond) {
- static int shown;
-
- AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
- if (!shown) {
- shown = 1;
- AUD_log (NULL, "Save all your work and restart without audio\n");
- AUD_log (NULL, "Please send bug report to malc@pulsesoft.com\n");
- AUD_log (NULL, "I am sorry\n");
- }
- AUD_log (NULL, "Context:\n");
-
-#if defined AUDIO_BREAKPOINT_ON_BUG
-# if defined HOST_I386
-# if defined __GNUC__
- __asm__ ("int3");
-# elif defined _MSC_VER
- _asm _emit 0xcc;
-# else
- abort ();
-# endif
-# else
- abort ();
-# endif
-#endif
- }
-
- return cond;
-}
-#endif
-
-static inline int audio_bits_to_index (int bits)
-{
- switch (bits) {
- case 8:
- return 0;
-
- case 16:
- return 1;
-
- case 32:
- return 2;
-
- default:
- audio_bug ("bits_to_index", 1);
- AUD_log (NULL, "invalid bits %d\n", bits);
- return 0;
- }
-}
-
-void *audio_calloc (const char *funcname, int nmemb, size_t size)
-{
- int cond;
- size_t len;
-
- len = nmemb * size;
- cond = !nmemb || !size;
- cond |= nmemb < 0;
- cond |= len < size;
-
- if (audio_bug ("audio_calloc", cond)) {
- AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
- funcname);
- AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
- return NULL;
- }
-
- return qemu_mallocz (len);
-}
-
-static char *audio_alloc_prefix (const char *s)
-{
- const char qemu_prefix[] = "QEMU_";
- size_t len;
- char *r;
-
- if (!s) {
- return NULL;
- }
-
- len = strlen (s);
- r = qemu_malloc (len + sizeof (qemu_prefix));
-
- if (r) {
- size_t i;
- char *u = r + sizeof (qemu_prefix) - 1;
-
- strcpy (r, qemu_prefix);
- strcat (r, s);
-
- for (i = 0; i < len; ++i) {
- u[i] = toupper (u[i]);
- }
- }
- return r;
-}
-
-static const char *audio_audfmt_to_string (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_U8:
- return "U8";
-
- case AUD_FMT_U16:
- return "U16";
-
- case AUD_FMT_S8:
- return "S8";
-
- case AUD_FMT_S16:
- return "S16";
-
- case AUD_FMT_U32:
- return "U32";
-
- case AUD_FMT_S32:
- return "S32";
- }
-
- dolog ("Bogus audfmt %d returning S16\n", fmt);
- return "S16";
-}
-
-static audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval,
- int *defaultp)
-{
- if (!strcasecmp (s, "u8")) {
- *defaultp = 0;
- return AUD_FMT_U8;
- }
- else if (!strcasecmp (s, "u16")) {
- *defaultp = 0;
- return AUD_FMT_U16;
- }
- else if (!strcasecmp (s, "u32")) {
- *defaultp = 0;
- return AUD_FMT_U32;
- }
- else if (!strcasecmp (s, "s8")) {
- *defaultp = 0;
- return AUD_FMT_S8;
- }
- else if (!strcasecmp (s, "s16")) {
- *defaultp = 0;
- return AUD_FMT_S16;
- }
- else if (!strcasecmp (s, "s32")) {
- *defaultp = 0;
- return AUD_FMT_S32;
- }
- else {
- dolog ("Bogus audio format `%s' using %s\n",
- s, audio_audfmt_to_string (defval));
- *defaultp = 1;
- return defval;
- }
-}
-
-static audfmt_e audio_get_conf_fmt (const char *envname,
- audfmt_e defval,
- int *defaultp)
-{
- const char *var = getenv (envname);
- if (!var) {
- *defaultp = 1;
- return defval;
- }
- return audio_string_to_audfmt (var, defval, defaultp);
-}
-
-static int audio_get_conf_int (const char *key, int defval, int *defaultp)
-{
- int val;
- char *strval;
-
- strval = getenv (key);
- if (strval) {
- *defaultp = 0;
- val = atoi (strval);
- return val;
- }
- else {
- *defaultp = 1;
- return defval;
- }
-}
-
-static const char *audio_get_conf_str (const char *key,
- const char *defval,
- int *defaultp)
-{
- const char *val = getenv (key);
- if (!val) {
- *defaultp = 1;
- return defval;
- }
- else {
- *defaultp = 0;
- return val;
- }
-}
-
-/* defined in android_sdl.c */
-extern void dprintn(const char* fmt, ...);
-extern void dprintnv(const char* fmt, va_list args);
-
-void AUD_vlog (const char *cap, const char *fmt, va_list ap)
-{
- if (conf.log_to_monitor) {
- if (cap) {
- term_printf ("%s: ", cap);
- }
-
- term_vprintf (fmt, ap);
- }
- else {
- if (!VERBOSE_CHECK(audio))
- return;
-
- if (cap) {
- dprintn("%s: ", cap);
- }
-
- dprintnv(fmt, ap);
- }
-}
-
-void AUD_log (const char *cap, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (cap, fmt, ap);
- va_end (ap);
-}
-
-static void audio_print_options (const char *prefix,
- struct audio_option *opt)
-{
- char *uprefix;
-
- if (!prefix) {
- dolog ("No prefix specified\n");
- return;
- }
-
- if (!opt) {
- dolog ("No options\n");
- return;
- }
-
- uprefix = audio_alloc_prefix (prefix);
-
- for (; opt->name; opt++) {
- const char *state = "default";
- printf (" %s_%s: ", uprefix, opt->name);
-
- if (opt->overriddenp && *opt->overriddenp) {
- state = "current";
- }
-
- switch (opt->tag) {
- case AUD_OPT_BOOL:
- {
- int *intp = opt->valp;
- printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
- }
- break;
-
- case AUD_OPT_INT:
- {
- int *intp = opt->valp;
- printf ("integer, %s = %d\n", state, *intp);
- }
- break;
-
- case AUD_OPT_FMT:
- {
- audfmt_e *fmtp = opt->valp;
- printf (
- "format, %s = %s, (one of: U8 S8 U16 S16 U32 S32)\n",
- state,
- audio_audfmt_to_string (*fmtp)
- );
- }
- break;
-
- case AUD_OPT_STR:
- {
- const char **strp = opt->valp;
- printf ("string, %s = %s\n",
- state,
- *strp ? *strp : "(not set)");
- }
- break;
-
- default:
- printf ("???\n");
- dolog ("Bad value tag for option %s_%s %d\n",
- uprefix, opt->name, opt->tag);
- break;
- }
- printf (" %s\n", opt->descr);
- }
-
- qemu_free (uprefix);
-}
-
-static void audio_process_options (const char *prefix,
- struct audio_option *opt)
-{
- char *optname;
- const char qemu_prefix[] = "QEMU_";
- size_t preflen;
-
- if (audio_bug (AUDIO_FUNC, !prefix)) {
- dolog ("prefix = NULL\n");
- return;
- }
-
- if (audio_bug (AUDIO_FUNC, !opt)) {
- dolog ("opt = NULL\n");
- return;
- }
-
- preflen = strlen (prefix);
-
- for (; opt->name; opt++) {
- size_t len, i;
- int def;
-
- if (!opt->valp) {
- dolog ("Option value pointer for `%s' is not set\n",
- opt->name);
- continue;
- }
-
- len = strlen (opt->name);
- /* len of opt->name + len of prefix + size of qemu_prefix
- * (includes trailing zero) + zero + underscore (on behalf of
- * sizeof) */
- optname = qemu_malloc (len + preflen + sizeof (qemu_prefix) + 1);
- if (!optname) {
- dolog ("Could not allocate memory for option name `%s'\n",
- opt->name);
- continue;
- }
-
- strcpy (optname, qemu_prefix);
-
- /* copy while upper-casing, including trailing zero */
- for (i = 0; i <= preflen; ++i) {
- optname[i + sizeof (qemu_prefix) - 1] = toupper (prefix[i]);
- }
- strcat (optname, "_");
- strcat (optname, opt->name);
-
- def = 1;
- switch (opt->tag) {
- case AUD_OPT_BOOL:
- case AUD_OPT_INT:
- {
- int *intp = opt->valp;
- *intp = audio_get_conf_int (optname, *intp, &def);
- }
- break;
-
- case AUD_OPT_FMT:
- {
- audfmt_e *fmtp = opt->valp;
- *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
- }
- break;
-
- case AUD_OPT_STR:
- {
- const char **strp = opt->valp;
- *strp = audio_get_conf_str (optname, *strp, &def);
- }
- break;
-
- default:
- dolog ("Bad value tag for option `%s' - %d\n",
- optname, opt->tag);
- break;
- }
-
- if (!opt->overriddenp) {
- opt->overriddenp = &opt->overridden;
- }
- *opt->overriddenp = !def;
- qemu_free (optname);
- }
-}
-
-static void audio_print_settings (audsettings_t *as)
-{
- dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- AUD_log (NULL, "S8");
- break;
- case AUD_FMT_U8:
- AUD_log (NULL, "U8");
- break;
- case AUD_FMT_S16:
- AUD_log (NULL, "S16");
- break;
- case AUD_FMT_U16:
- AUD_log (NULL, "U16");
- break;
- default:
- AUD_log (NULL, "invalid(%d)", as->fmt);
- break;
- }
-
- AUD_log (NULL, " endianness=");
- switch (as->endianness) {
- case 0:
- AUD_log (NULL, "little");
- break;
- case 1:
- AUD_log (NULL, "big");
- break;
- default:
- AUD_log (NULL, "invalid");
- break;
- }
- AUD_log (NULL, "\n");
-}
-
-static int audio_validate_settings (audsettings_t *as)
-{
- int invalid;
-
- invalid = as->nchannels != 1 && as->nchannels != 2;
- invalid |= as->endianness != 0 && as->endianness != 1;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- break;
- default:
- invalid = 1;
- break;
- }
-
- invalid |= as->freq <= 0;
- return invalid ? -1 : 0;
-}
-
-static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
-{
- int bits = 8, sign = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- sign = 1;
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- case AUD_FMT_U16:
- bits = 16;
- break;
- case AUD_FMT_S32:
- sign = 1;
- case AUD_FMT_U32:
- bits = 32;
- break;
- }
- return info->freq == as->freq
- && info->nchannels == as->nchannels
- && info->sign == sign
- && info->bits == bits
- && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
-}
-
-void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)
-{
- int bits = 8, sign = 0, shift = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- sign = 1;
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- case AUD_FMT_U16:
- bits = 16;
- shift = 1;
- break;
-
- case AUD_FMT_S32:
- sign = 1;
- case AUD_FMT_U32:
- bits = 32;
- shift = 2;
- break;
- }
-
- info->freq = as->freq;
- info->bits = bits;
- info->sign = sign;
- info->nchannels = as->nchannels;
- info->shift = (as->nchannels == 2) + shift;
- info->align = (1 << info->shift) - 1;
- info->bytes_per_second = info->freq << info->shift;
- info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
-}
-
-void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
-{
- if (!len) {
- return;
- }
-
- if (info->sign) {
- memset (buf, 0x00, len << info->shift);
- }
- else {
- switch (info->bits) {
- case 8:
- memset (buf, 0x80, len << info->shift);
- break;
-
- case 16:
- {
- int i;
- uint16_t *p = buf;
- int shift = info->nchannels - 1;
- short s = INT16_MAX;
-
- if (info->swap_endianness) {
- s = bswap16 (s);
- }
-
- for (i = 0; i < len << shift; i++) {
- p[i] = s;
- }
- }
- break;
-
- case 32:
- {
- int i;
- uint32_t *p = buf;
- int shift = info->nchannels - 1;
- int32_t s = INT32_MAX;
-
- if (info->swap_endianness) {
- s = bswap32 (s);
- }
-
- for (i = 0; i < len << shift; i++) {
- p[i] = s;
- }
- }
- break;
-
- default:
- AUD_log (NULL, "audio_pcm_info_clear_buf: invalid bits %d\n",
- info->bits);
- break;
- }
- }
-}
-
-/*
- * Capture
- */
-static void noop_conv (st_sample_t *dst, const void *src,
- int samples, volume_t *vol)
-{
- (void) src;
- (void) dst;
- (void) samples;
- (void) vol;
-}
-
-static CaptureVoiceOut *audio_pcm_capture_find_specific (
- AudioState *s,
- audsettings_t *as
- )
-{
- CaptureVoiceOut *cap;
-
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- if (audio_pcm_info_eq (&cap->hw.info, as)) {
- return cap;
- }
- }
- return NULL;
-}
-
-static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
-{
- struct capture_callback *cb;
-
-#ifdef DEBUG_CAPTURE
- dolog ("notification %d sent\n", cmd);
-#endif
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.notify (cb->opaque, cmd);
- }
-}
-
-static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
-{
- if (cap->hw.enabled != enabled) {
- audcnotification_e cmd;
- cap->hw.enabled = enabled;
- cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
- audio_notify_capture (cap, cmd);
- }
-}
-
-static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
-{
- HWVoiceOut *hw = &cap->hw;
- SWVoiceOut *sw;
- int enabled = 0;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- enabled = 1;
- break;
- }
- }
- audio_capture_maybe_changed (cap, enabled);
-}
-
-static void audio_detach_capture (HWVoiceOut *hw)
-{
- SWVoiceCap *sc = hw->cap_head.lh_first;
-
- while (sc) {
- SWVoiceCap *sc1 = sc->entries.le_next;
- SWVoiceOut *sw = &sc->sw;
- CaptureVoiceOut *cap = sc->cap;
- int was_active = sw->active;
-
- if (sw->rate) {
- st_rate_stop (sw->rate);
- sw->rate = NULL;
- }
-
- LIST_REMOVE (sw, entries);
- LIST_REMOVE (sc, entries);
- qemu_free (sc);
- if (was_active) {
- /* We have removed soft voice from the capture:
- this might have changed the overall status of the capture
- since this might have been the only active voice */
- audio_recalc_and_notify_capture (cap);
- }
- sc = sc1;
- }
-}
-
-static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
-{
- CaptureVoiceOut *cap;
-
- audio_detach_capture (hw);
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- SWVoiceCap *sc;
- SWVoiceOut *sw;
- HWVoiceOut *hw_cap = &cap->hw;
-
- sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
- if (!sc) {
- dolog ("Could not allocate soft capture voice (%zu bytes)\n",
- sizeof (*sc));
- return -1;
- }
-
- sc->cap = cap;
- sw = &sc->sw;
- sw->hw = hw_cap;
- sw->info = hw->info;
- sw->empty = 1;
- sw->active = hw->enabled;
- sw->conv = noop_conv;
- sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
- sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
- if (!sw->rate) {
- dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
- qemu_free (sw);
- return -1;
- }
- LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
- LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
-#ifdef DEBUG_CAPTURE
- asprintf (&sw->name, "for %p %d,%d,%d",
- hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
- dolog ("Added %s active = %d\n", sw->name, sw->active);
-#endif
- if (sw->active) {
- audio_capture_maybe_changed (cap, 1);
- }
- }
- return 0;
-}
-
-/*
- * Hard voice (capture)
- */
-static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
-{
- SWVoiceIn *sw;
- int m = hw->total_samples_captured;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- m = audio_MIN (m, sw->total_hw_samples_acquired);
- }
- }
- return m;
-}
-
-int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
-{
- int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
- return live;
-}
-
-/*
- * Soft voice (capture)
- */
-static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
-{
- HWVoiceIn *hw = sw->hw;
- int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
- int rpos;
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
-
- rpos = hw->wpos - live;
- if (rpos >= 0) {
- return rpos;
- }
- else {
- return hw->samples + rpos;
- }
-}
-
-int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
-{
- HWVoiceIn *hw = sw->hw;
- int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
- st_sample_t *src, *dst = sw->buf;
-
- rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
-
- live = hw->total_samples_captured - sw->total_hw_samples_acquired;
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
-
- samples = size >> sw->info.shift;
- if (!live) {
- return 0;
- }
-
- swlim = (live * sw->ratio) >> 32;
- swlim = audio_MIN (swlim, samples);
-
- while (swlim) {
- src = hw->conv_buf + rpos;
- isamp = hw->wpos - rpos;
- /* XXX: <= ? */
- if (isamp <= 0) {
- isamp = hw->samples - rpos;
- }
-
- if (!isamp) {
- break;
- }
- osamp = swlim;
-
- if (audio_bug (AUDIO_FUNC, osamp < 0)) {
- dolog ("osamp=%d\n", osamp);
- return 0;
- }
-
- st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
- swlim -= osamp;
- rpos = (rpos + isamp) % hw->samples;
- dst += osamp;
- ret += osamp;
- total += isamp;
- }
-
- sw->clip (buf, sw->buf, ret);
- sw->total_hw_samples_acquired += total;
- return ret << sw->info.shift;
-}
-
-/*
- * Hard voice (playback)
- */
-static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
-{
- SWVoiceOut *sw;
- int m = INT_MAX;
- int nb_live = 0;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active || !sw->empty) {
- m = audio_MIN (m, sw->total_hw_samples_mixed);
- nb_live += 1;
- }
- }
-
- *nb_livep = nb_live;
- return m;
-}
-
-int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live)
-{
- int smin;
-
- smin = audio_pcm_hw_find_min_out (hw, nb_live);
-
- if (!*nb_live) {
- return 0;
- }
- else {
- int live = smin;
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
- return live;
- }
-}
-
-int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
-{
- int nb_live;
- int live;
-
- live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- return 0;
- }
- return live;
-}
-
-/*
- * Soft voice (playback)
- */
-int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
-{
- int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
- int ret = 0, pos = 0, total = 0;
-
- if (!sw) {
- return size;
- }
-
- hwsamples = sw->hw->samples;
-
- live = sw->total_hw_samples_mixed;
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
- dolog ("live=%d hw->samples=%d\n", live, hwsamples);
- return 0;
- }
-
- if (live == hwsamples) {
-#ifdef DEBUG_OUT
- dolog ("%s is full %d\n", sw->name, live);
-#endif
- return 0;
- }
-
- wpos = (sw->hw->rpos + live) % hwsamples;
- samples = size >> sw->info.shift;
-
- dead = hwsamples - live;
- swlim = ((int64_t) dead << 32) / sw->ratio;
- swlim = audio_MIN (swlim, samples);
- if (swlim) {
- sw->conv (sw->buf, buf, swlim, &sw->vol);
- }
-
- while (swlim) {
- dead = hwsamples - live;
- left = hwsamples - wpos;
- blck = audio_MIN (dead, left);
- if (!blck) {
- break;
- }
- isamp = swlim;
- osamp = blck;
- st_rate_flow_mix (
- sw->rate,
- sw->buf + pos,
- sw->hw->mix_buf + wpos,
- &isamp,
- &osamp
- );
- ret += isamp;
- swlim -= isamp;
- pos += isamp;
- live += osamp;
- wpos = (wpos + osamp) % hwsamples;
- total += osamp;
- }
-
- sw->total_hw_samples_mixed += total;
- sw->empty = sw->total_hw_samples_mixed == 0;
-
-#ifdef DEBUG_OUT
- dolog (
- "%s: write size %d ret %d total sw %d\n",
- SW_NAME (sw),
- size >> sw->info.shift,
- ret,
- sw->total_hw_samples_mixed
- );
-#endif
-
- return ret << sw->info.shift;
-}
-
-#ifdef DEBUG_AUDIO
-static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
-{
- dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
- cap, info->bits, info->sign, info->freq, info->nchannels);
-}
-#endif
-
-#define DAC
-#include "audio_template.h"
-#undef DAC
-#include "audio_template.h"
-
-int AUD_write (SWVoiceOut *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw) {
- /* XXX: Consider options */
- return size;
- }
-
- if (!sw->hw->enabled) {
- dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
- return 0;
- }
-
- BEGIN_NOSIGALRM
- bytes = sw->hw->pcm_ops->write (sw, buf, size);
- END_NOSIGALRM
- return bytes;
-}
-
-int AUD_read (SWVoiceIn *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw) {
- /* XXX: Consider options */
- return size;
- }
-
- if (!sw->hw->enabled) {
- dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
- return 0;
- }
-
- BEGIN_NOSIGALRM
- bytes = sw->hw->pcm_ops->read (sw, buf, size);
- END_NOSIGALRM
- return bytes;
-}
-
-int AUD_get_buffer_size_out (SWVoiceOut *sw)
-{
- return sw->hw->samples << sw->hw->info.shift;
-}
-
-void AUD_set_active_out (SWVoiceOut *sw, int on)
-{
- HWVoiceOut *hw;
-
- if (!sw) {
- return;
- }
-
- hw = sw->hw;
- if (sw->active != on) {
- SWVoiceOut *temp_sw;
- SWVoiceCap *sc;
-
- if (on) {
- hw->pending_disable = 0;
- if (!hw->enabled) {
- hw->enabled = 1;
- BEGIN_NOSIGALRM
- hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
- END_NOSIGALRM
- }
- }
- else {
- if (hw->enabled) {
- int nb_active = 0;
-
- for (temp_sw = hw->sw_head.lh_first; temp_sw;
- temp_sw = temp_sw->entries.le_next) {
- nb_active += temp_sw->active != 0;
- }
-
- hw->pending_disable = nb_active == 1;
- }
- }
-
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- sc->sw.active = hw->enabled;
- if (hw->enabled) {
- audio_capture_maybe_changed (sc->cap, 1);
- }
- }
- sw->active = on;
- }
-}
-
-void AUD_set_active_in (SWVoiceIn *sw, int on)
-{
- HWVoiceIn *hw;
-
- if (!sw) {
- return;
- }
-
- hw = sw->hw;
- if (sw->active != on) {
- SWVoiceIn *temp_sw;
-
- if (on) {
- if (!hw->enabled) {
- hw->enabled = 1;
- BEGIN_NOSIGALRM
- hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);
- END_NOSIGALRM
- }
- sw->total_hw_samples_acquired = hw->total_samples_captured;
- }
- else {
- if (hw->enabled) {
- int nb_active = 0;
-
- for (temp_sw = hw->sw_head.lh_first; temp_sw;
- temp_sw = temp_sw->entries.le_next) {
- nb_active += temp_sw->active != 0;
- }
-
- if (nb_active == 1) {
- hw->enabled = 0;
- BEGIN_NOSIGALRM
- hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
- END_NOSIGALRM
- }
- }
- }
- sw->active = on;
- }
-}
-
-static int audio_get_avail (SWVoiceIn *sw)
-{
- int live;
-
- if (!sw) {
- return 0;
- }
-
- live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
- if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
- dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
- return 0;
- }
-
- ldebug (
- "%s: get_avail live %d ret %" PRId64 "\n",
- SW_NAME (sw),
- live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
- );
-
- return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
-}
-
-static int audio_get_free (SWVoiceOut *sw)
-{
- int live, dead;
-
- if (!sw) {
- return 0;
- }
-
- live = sw->total_hw_samples_mixed;
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
- dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
- return 0;
- }
-
- dead = sw->hw->samples - live;
-
-#ifdef DEBUG_OUT
- dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
- SW_NAME (sw),
- live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
-#endif
-
- return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
-}
-
-static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
-{
- int n;
-
- if (hw->enabled) {
- SWVoiceCap *sc;
-
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- SWVoiceOut *sw = &sc->sw;
- int rpos2 = rpos;
-
- n = samples;
- while (n) {
- int till_end_of_hw = hw->samples - rpos2;
- int to_write = audio_MIN (till_end_of_hw, n);
- int bytes = to_write << hw->info.shift;
- int written;
-
- sw->buf = hw->mix_buf + rpos2;
- written = audio_pcm_sw_write (sw, NULL, bytes);
- if (written - bytes) {
- dolog ("Could not mix %d bytes into a capture "
- "buffer, mixed %d\n",
- bytes, written);
- break;
- }
- n -= to_write;
- rpos2 = (rpos2 + to_write) % hw->samples;
- }
- }
- }
-
- n = audio_MIN (samples, hw->samples - rpos);
- mixeng_clear (hw->mix_buf + rpos, n);
- mixeng_clear (hw->mix_buf, samples - n);
-}
-
-static void audio_run_out (AudioState *s)
-{
- HWVoiceOut *hw = NULL;
- SWVoiceOut *sw;
-
- while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
- int played;
- int live, free, nb_live, cleanup_required, prev_rpos;
-
- live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
- if (!nb_live) {
- live = 0;
- }
-
- if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
- dolog ("live=%d hw->samples=%d\n", live, hw->samples);
- continue;
- }
-
- if (hw->pending_disable && !nb_live) {
- SWVoiceCap *sc;
-#ifdef DEBUG_OUT
- dolog ("Disabling voice\n");
-#endif
- hw->enabled = 0;
- hw->pending_disable = 0;
- BEGIN_NOSIGALRM
- hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
- END_NOSIGALRM
- for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- sc->sw.active = 0;
- audio_recalc_and_notify_capture (sc->cap);
- }
- continue;
- }
-
- if (!live) {
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (sw->active) {
- free = audio_get_free (sw);
- if (free > 0) {
- sw->callback.fn (sw->callback.opaque, free);
- }
- }
- }
- continue;
- }
-
- prev_rpos = hw->rpos;
- BEGIN_NOSIGALRM
- played = hw->pcm_ops->run_out (hw);
- END_NOSIGALRM
- if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
- dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
- hw->rpos, hw->samples, played);
- hw->rpos = 0;
- }
-
-#ifdef DEBUG_OUT
- dolog ("played=%d\n", played);
-#endif
-
- if (played) {
- hw->ts_helper += played;
- audio_capture_mix_and_clear (hw, prev_rpos, played);
- }
-
- cleanup_required = 0;
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (!sw->active && sw->empty) {
- continue;
- }
-
- if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
- dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
- played, sw->total_hw_samples_mixed);
- played = sw->total_hw_samples_mixed;
- }
-
- sw->total_hw_samples_mixed -= played;
-
- if (!sw->total_hw_samples_mixed) {
- sw->empty = 1;
- cleanup_required |= !sw->active && !sw->callback.fn;
- }
-
- if (sw->active) {
- free = audio_get_free (sw);
- if (free > 0) {
- sw->callback.fn (sw->callback.opaque, free);
- }
- }
- }
-
- if (cleanup_required) {
- SWVoiceOut *sw1;
-
- sw = hw->sw_head.lh_first;
- while (sw) {
- sw1 = sw->entries.le_next;
- if (!sw->active && !sw->callback.fn) {
-#ifdef DEBUG_PLIVE
- dolog ("Finishing with old voice\n");
-#endif
- audio_close_out (s, sw);
- }
- sw = sw1;
- }
- }
- }
-}
-
-static void audio_run_in (AudioState *s)
-{
- HWVoiceIn *hw = NULL;
-
- while ((hw = audio_pcm_hw_find_any_enabled_in (s, hw))) {
- SWVoiceIn *sw;
- int captured, min;
-
- BEGIN_NOSIGALRM
- captured = hw->pcm_ops->run_in (hw);
- END_NOSIGALRM
-
- min = audio_pcm_hw_find_min_in (hw);
- hw->total_samples_captured += captured - min;
- hw->ts_helper += captured;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- sw->total_hw_samples_acquired -= min;
-
- if (sw->active) {
- int avail;
-
- avail = audio_get_avail (sw);
- if (avail > 0) {
- sw->callback.fn (sw->callback.opaque, avail);
- }
- }
- }
- }
-}
-
-static void audio_run_capture (AudioState *s)
-{
- CaptureVoiceOut *cap;
-
- for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
- int live, rpos, captured;
- HWVoiceOut *hw = &cap->hw;
- SWVoiceOut *sw;
-
- captured = live = audio_pcm_hw_get_live_out (hw);
- rpos = hw->rpos;
- while (live) {
- int left = hw->samples - rpos;
- int to_capture = audio_MIN (live, left);
- st_sample_t *src;
- struct capture_callback *cb;
-
- src = hw->mix_buf + rpos;
- hw->clip (cap->buf, src, to_capture);
- mixeng_clear (src, to_capture);
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.capture (cb->opaque, cap->buf,
- to_capture << hw->info.shift);
- }
- rpos = (rpos + to_capture) % hw->samples;
- live -= to_capture;
- }
- hw->rpos = rpos;
-
- for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
- if (!sw->active && sw->empty) {
- continue;
- }
-
- if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) {
- dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
- captured, sw->total_hw_samples_mixed);
- captured = sw->total_hw_samples_mixed;
- }
-
- sw->total_hw_samples_mixed -= captured;
- sw->empty = sw->total_hw_samples_mixed == 0;
- }
- }
-}
-
-static void audio_timer (void *opaque)
-{
- AudioState* s = opaque;
-#if 0
-#define MAX_DIFFS 1000
- int64_t now = qemu_get_clock(vm_clock);
- static int64_t last = 0;
- static float diffs[MAX_DIFFS];
- static int num_diffs;
-
- if (last == 0)
- last = now;
- else {
- diffs[num_diffs] = (float)((now-last)/1e6); /* last diff in ms */
- if (++num_diffs == MAX_DIFFS) {
- double min_diff = 1e6, max_diff = -1e6;
- double all_diff = 0.;
- int nn;
-
- for (nn = 0; nn < num_diffs; nn++) {
- if (diffs[nn] < min_diff) min_diff = diffs[nn];
- if (diffs[nn] > max_diff) max_diff = diffs[nn];
- all_diff += diffs[nn];
- }
- all_diff *= 1.0/num_diffs;
- printf("audio timer: min_diff=%6.2g max_diff=%6.2g avg_diff=%6.2g samples=%d\n",
- min_diff, max_diff, all_diff, num_diffs);
- num_diffs = 0;
- }
- }
- last = now;
-#endif
- audio_run_out (s);
- audio_run_in (s);
- audio_run_capture (s);
-
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
-}
-
-static struct audio_option audio_options[] = {
- /* DAC */
- {"DAC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_out.enabled,
- "Use fixed settings for host DAC", NULL, 0},
-
- {"DAC_FIXED_FREQ", AUD_OPT_INT, &conf.fixed_out.settings.freq,
- "Frequency for fixed host DAC", NULL, 0},
-
- {"DAC_FIXED_FMT", AUD_OPT_FMT, &conf.fixed_out.settings.fmt,
- "Format for fixed host DAC", NULL, 0},
-
- {"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf.fixed_out.settings.nchannels,
- "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},
-
- {"DAC_VOICES", AUD_OPT_INT, &conf.fixed_out.nb_voices,
- "Number of voices for DAC", NULL, 0},
-
- /* ADC */
- {"ADC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_in.enabled,
- "Use fixed settings for host ADC", NULL, 0},
-
- {"ADC_FIXED_FREQ", AUD_OPT_INT, &conf.fixed_in.settings.freq,
- "Frequency for fixed host ADC", NULL, 0},
-
- {"ADC_FIXED_FMT", AUD_OPT_FMT, &conf.fixed_in.settings.fmt,
- "Format for fixed host ADC", NULL, 0},
-
- {"ADC_FIXED_CHANNELS", AUD_OPT_INT, &conf.fixed_in.settings.nchannels,
- "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},
-
- {"ADC_VOICES", AUD_OPT_INT, &conf.fixed_in.nb_voices,
- "Number of voices for ADC", NULL, 0},
-
- /* Misc */
- {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hz,
- "Timer period in HZ (0 - use lowest possible)", NULL, 0},
-
- {"PLIVE", AUD_OPT_BOOL, &conf.plive,
- "(undocumented)", NULL, 0},
-
- {"LOG_TO_MONITOR", AUD_OPT_BOOL, &conf.log_to_monitor,
- "print logging messages to monitor instead of stderr", NULL, 0},
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static void audio_pp_nb_voices (const char *typ, int nb)
-{
- switch (nb) {
- case 0:
- printf ("Does not support %s\n", typ);
- break;
- case 1:
- printf ("One %s voice\n", typ);
- break;
- case INT_MAX:
- printf ("Theoretically supports many %s voices\n", typ);
- break;
- default:
- printf ("Theoretically supports upto %d %s voices\n", nb, typ);
- break;
- }
-
-}
-
-void AUD_help (void)
-{
- size_t i;
-
- audio_process_options ("AUDIO", audio_options);
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- struct audio_driver *d = drvtab[i];
- if (d->options) {
- audio_process_options (d->name, d->options);
- }
- }
-
- printf ("Audio options:\n");
- audio_print_options ("AUDIO", audio_options);
- printf ("\n");
-
- printf ("Available drivers:\n");
-
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- struct audio_driver *d = drvtab[i];
-
- printf ("Name: %s\n", d->name);
- printf ("Description: %s\n", d->descr);
-
- audio_pp_nb_voices ("playback", d->max_voices_out);
- audio_pp_nb_voices ("capture", d->max_voices_in);
-
- if (d->options) {
- printf ("Options:\n");
- audio_print_options (d->name, d->options);
- }
- else {
- printf ("No options\n");
- }
- printf ("\n");
- }
-
- printf (
- "Options are settable through environment variables.\n"
- "Example:\n"
-#ifdef _WIN32
- " set QEMU_AUDIO_DRV=wav\n"
- " set QEMU_WAV_PATH=c:\\tune.wav\n"
-#else
- " export QEMU_AUDIO_DRV=wav\n"
- " export QEMU_WAV_PATH=$HOME/tune.wav\n"
- "(for csh replace export with setenv in the above)\n"
-#endif
- " qemu ...\n\n"
- );
-}
-
-static int audio_driver_init (AudioState *s, struct audio_driver *drv, int out)
-{
- void* opaque;
-
- if (drv->options) {
- audio_process_options (drv->name, drv->options);
- }
-
- /* is the driver already initialized ? */
- if (out) {
- if (drv == s->drv_in) {
- s->drv_out = drv;
- s->drv_out_opaque = s->drv_in_opaque;
- return 0;
- }
- } else {
- if (drv == s->drv_out) {
- s->drv_in = drv;
- s->drv_in_opaque = s->drv_out_opaque;
- return 0;
- }
- }
-
- BEGIN_NOSIGALRM
- opaque = drv->init();
- END_NOSIGALRM
-
- if (opaque != NULL) {
- audio_init_nb_voices_out (s, drv);
- audio_init_nb_voices_in (s, drv);
- if (out) {
- s->drv_out = drv;
- s->drv_out_opaque = opaque;
- } else {
- s->drv_in = drv;
- s->drv_in_opaque = opaque;
- }
- return 0;
- }
- else {
- dolog ("Could not init `%s' audio driver\n", drv->name);
- return -1;
- }
-}
-
-static void audio_vm_change_state_handler (void *opaque, int running)
-{
- AudioState *s = opaque;
- HWVoiceOut *hwo = NULL;
- HWVoiceIn *hwi = NULL;
- int op = running ? VOICE_ENABLE : VOICE_DISABLE;
-
- BEGIN_NOSIGALRM
- while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
- hwo->pcm_ops->ctl_out (hwo, op);
- }
-
- while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
- hwi->pcm_ops->ctl_in (hwi, op);
- }
- END_NOSIGALRM
-}
-
-// to make sure audio_atexit() is only called once
-static int initialized = 0;
-
-static void audio_atexit (void)
-{
- AudioState *s = &glob_audio_state;
- HWVoiceOut *hwo = NULL;
- HWVoiceIn *hwi = NULL;
-
- if (!initialized) return;
- initialized = 0;
-
- BEGIN_NOSIGALRM
- while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
- SWVoiceCap *sc;
-
- hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
- hwo->pcm_ops->fini_out (hwo);
-
- for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
- CaptureVoiceOut *cap = sc->cap;
- struct capture_callback *cb;
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- cb->ops.destroy (cb->opaque);
- }
- }
- }
-
- while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
- hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
- hwi->pcm_ops->fini_in (hwi);
- }
-
- if (s->drv_in) {
- s->drv_in->fini (s->drv_in_opaque);
- }
- if (s->drv_out) {
- s->drv_out->fini (s->drv_out_opaque);
- }
- END_NOSIGALRM
-}
-
-static void audio_save (QEMUFile *f, void *opaque)
-{
- (void) f;
- (void) opaque;
-}
-
-static int audio_load (QEMUFile *f, void *opaque, int version_id)
-{
- (void) f;
- (void) opaque;
-
- if (version_id != 1) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card)
-{
- card->audio = s;
- card->name = qemu_strdup (name);
- memset (&card->entries, 0, sizeof (card->entries));
- LIST_INSERT_HEAD (&s->card_head, card, entries);
-}
-
-void AUD_remove_card (QEMUSoundCard *card)
-{
- LIST_REMOVE (card, entries);
- card->audio = NULL;
- qemu_free (card->name);
-}
-
-static int
-find_audio_driver( AudioState* s, int out )
-{
- int i, done = 0, def;
- const char* envname;
- const char* drvname;
- struct audio_driver* drv = NULL;
- const char* drvtype = out ? "output" : "input";
-
- envname = out ? "QEMU_AUDIO_OUT_DRV" : "QEMU_AUDIO_IN_DRV";
- drvname = audio_get_conf_str(envname, NULL, &def);
- if (drvname == NULL) {
- drvname = audio_get_conf_str("QEMU_AUDIO_DRV", NULL, &def);
- }
-
- if (drvname != NULL) { /* look for a specific driver */
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (!strcmp (drvname, drvtab[i]->name)) {
- drv = drvtab[i];
- break;
- }
- }
- }
-
- if (drv != NULL) {
- done = !audio_driver_init (s, drv, out);
- if (!done) {
- dolog ("Could not initialize '%s' %s audio backend, trying default one.\n",
- drvname, drvtype);
- dolog ("Run with -qemu -audio-help to list available backends\n");
- drv = NULL;
- }
- }
-
- if (!drv) {
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (drvtab[i]->can_be_default) {
- drv = drvtab[i];
- done = !audio_driver_init (s, drv, out);
- if (done)
- break;
- }
- }
- }
-
- if (!done) {
- drv = &no_audio_driver;
- done = !audio_driver_init (s, drv, out);
- if (!done) {
- /* this should never happen */
- dolog ("Could not initialize audio subsystem\n");
- return -1;
- }
- dolog ("warning: Could not find suitable audio %s backend\n", drvtype);
- }
-
- if (VERBOSE_CHECK(init))
- dprint("using '%s' audio %s backend", drv->name, drvtype );
- return 0;
-}
-
-
-AudioState *AUD_init (void)
-{
- AudioState *s = &glob_audio_state;
-
- LIST_INIT (&s->hw_head_out);
- LIST_INIT (&s->hw_head_in);
- LIST_INIT (&s->cap_head);
- atexit (audio_atexit);
-
- s->ts = qemu_new_timer (vm_clock, audio_timer, s);
- if (!s->ts) {
- dolog ("Could not create audio timer\n");
- return NULL;
- }
-
- audio_process_options ("AUDIO", audio_options);
-
- s->nb_hw_voices_out = conf.fixed_out.nb_voices;
- s->nb_hw_voices_in = conf.fixed_in.nb_voices;
-
- if (s->nb_hw_voices_out <= 0) {
- dolog ("Bogus number of playback voices %d, setting to 1\n",
- s->nb_hw_voices_out);
- s->nb_hw_voices_out = 1;
- }
-
- if (s->nb_hw_voices_in <= 0) {
- dolog ("Bogus number of capture voices %d, setting to 0\n",
- s->nb_hw_voices_in);
- s->nb_hw_voices_in = 0;
- }
-
- if ( find_audio_driver (s, 0) == 0 &&
- find_audio_driver (s, 1) == 0 )
- {
- VMChangeStateEntry *e;
-
- if (conf.period.hz <= 0) {
- if (conf.period.hz < 0) {
- dolog ("warning: Timer period is negative - %d "
- "treating as zero\n",
- conf.period.hz);
- }
- conf.period.ticks = 1;
- }
- else {
- conf.period.ticks = ticks_per_sec / conf.period.hz;
- }
-
- e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
- if (!e) {
- dolog ("warning: Could not register change state handler\n"
- "(Audio can continue looping even after stopping the VM)\n");
- }
- }
- else {
- qemu_del_timer (s->ts);
- return NULL;
- }
-
- initialized = 1;
-
- LIST_INIT (&s->card_head);
- register_savevm ("audio", 0, 1, audio_save, audio_load, s);
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
- return s;
-}
-
-// this was added to work around a deadlock in SDL when quitting
-void AUD_cleanup()
-{
- audio_atexit();
-}
-
-CaptureVoiceOut *AUD_add_capture (
- AudioState *s,
- audsettings_t *as,
- struct audio_capture_ops *ops,
- void *cb_opaque
- )
-{
- CaptureVoiceOut *cap;
- struct capture_callback *cb;
-
- if (!s) {
- /* XXX suppress */
- s = &glob_audio_state;
- }
-
- if (audio_validate_settings (as)) {
- dolog ("Invalid settings were passed when trying to add capture\n");
- audio_print_settings (as);
- goto err0;
- }
-
- cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
- if (!cb) {
- dolog ("Could not allocate capture callback information, size %zu\n",
- sizeof (*cb));
- goto err0;
- }
- cb->ops = *ops;
- cb->opaque = cb_opaque;
-
- cap = audio_pcm_capture_find_specific (s, as);
- if (cap) {
- LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
- return cap;
- }
- else {
- HWVoiceOut *hw;
- CaptureVoiceOut *cap;
-
- cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
- if (!cap) {
- dolog ("Could not allocate capture voice, size %zu\n",
- sizeof (*cap));
- goto err1;
- }
-
- hw = &cap->hw;
- LIST_INIT (&hw->sw_head);
- LIST_INIT (&cap->cb_head);
-
- /* XXX find a more elegant way */
- hw->samples = 4096 * 4;
- hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
- sizeof (st_sample_t));
- if (!hw->mix_buf) {
- dolog ("Could not allocate capture mix buffer (%d samples)\n",
- hw->samples);
- goto err2;
- }
-
- audio_pcm_init_info (&hw->info, as);
-
- cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!cap->buf) {
- dolog ("Could not allocate capture buffer "
- "(%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- goto err3;
- }
-
- hw->clip = mixeng_clip
- [hw->info.nchannels == 2]
- [hw->info.sign]
- [hw->info.swap_endianness]
- [audio_bits_to_index (hw->info.bits)];
-
- LIST_INSERT_HEAD (&s->cap_head, cap, entries);
- LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
-
- hw = NULL;
- while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
- audio_attach_capture (s, hw);
- }
- return cap;
-
- err3:
- qemu_free (cap->hw.mix_buf);
- err2:
- qemu_free (cap);
- err1:
- qemu_free (cb);
- err0:
- return NULL;
- }
-}
-
-void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
-{
- struct capture_callback *cb;
-
- for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
- if (cb->opaque == cb_opaque) {
- cb->ops.destroy (cb_opaque);
- LIST_REMOVE (cb, entries);
- qemu_free (cb);
-
- if (!cap->cb_head.lh_first) {
- SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
-
- while (sw) {
- SWVoiceCap *sc = (SWVoiceCap *) sw;
-#ifdef DEBUG_CAPTURE
- dolog ("freeing %s\n", sw->name);
-#endif
-
- sw1 = sw->entries.le_next;
- if (sw->rate) {
- st_rate_stop (sw->rate);
- sw->rate = NULL;
- }
- LIST_REMOVE (sw, entries);
- LIST_REMOVE (sc, entries);
- qemu_free (sc);
- sw = sw1;
- }
- LIST_REMOVE (cap, entries);
- qemu_free (cap);
- }
- return;
- }
- }
-}
-
-void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
-{
- if (sw) {
- sw->vol.mute = mute;
- sw->vol.l = nominal_volume.l * lvol / 255;
- sw->vol.r = nominal_volume.r * rvol / 255;
- }
-}
-
-void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
-{
- if (sw) {
- sw->vol.mute = mute;
- sw->vol.l = nominal_volume.l * lvol / 255;
- sw->vol.r = nominal_volume.r * rvol / 255;
- }
-}
diff --git a/audio/audio.h b/audio/audio.h
deleted file mode 100644
index 2c347bf..0000000
--- a/audio/audio.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_AUDIO_H
-#define QEMU_AUDIO_H
-
-#include "config.h"
-#include "qemu-common.h"
-#include "sys-queue.h"
-
-typedef void (*audio_callback_fn_t) (void *opaque, int avail);
-
-typedef enum {
- AUD_FMT_U8,
- AUD_FMT_S8,
- AUD_FMT_U16,
- AUD_FMT_S16,
- AUD_FMT_U32,
- AUD_FMT_S32
-} audfmt_e;
-
-#ifdef WORDS_BIGENDIAN
-#define AUDIO_HOST_ENDIANNESS 1
-#else
-#define AUDIO_HOST_ENDIANNESS 0
-#endif
-
-typedef struct {
- int freq;
- int nchannels;
- audfmt_e fmt;
- int endianness;
-} audsettings_t;
-
-typedef enum {
- AUD_CNOTIFY_ENABLE,
- AUD_CNOTIFY_DISABLE
-} audcnotification_e;
-
-struct audio_capture_ops {
- void (*notify) (void *opaque, audcnotification_e cmd);
- void (*capture) (void *opaque, void *buf, int size);
- void (*destroy) (void *opaque);
-};
-
-struct capture_ops {
- void (*info) (void *opaque);
- void (*destroy) (void *opaque);
-};
-
-typedef struct CaptureState {
- void *opaque;
- struct capture_ops ops;
- LIST_ENTRY (CaptureState) entries;
-} CaptureState;
-
-typedef struct SWVoiceOut SWVoiceOut;
-typedef struct CaptureVoiceOut CaptureVoiceOut;
-typedef struct SWVoiceIn SWVoiceIn;
-
-typedef struct QEMUSoundCard {
- AudioState *audio;
- char *name;
- LIST_ENTRY (QEMUSoundCard) entries;
-} QEMUSoundCard;
-
-typedef struct QEMUAudioTimeStamp {
- uint64_t old_ts;
-} QEMUAudioTimeStamp;
-
-void AUD_vlog (const char *cap, const char *fmt, va_list ap);
-void AUD_log (const char *cap, const char *fmt, ...)
-#ifdef __GNUC__
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
- ;
-
-extern AudioState glob_audio_state;
-
-AudioState *AUD_init (void);
-void AUD_help (void);
-void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card);
-void AUD_remove_card (QEMUSoundCard *card);
-CaptureVoiceOut *AUD_add_capture (
- AudioState *s,
- audsettings_t *as,
- struct audio_capture_ops *ops,
- void *opaque
- );
-void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque);
-
-SWVoiceOut *AUD_open_out (
- QEMUSoundCard *card,
- SWVoiceOut *sw,
- const char *name,
- void *callback_opaque,
- audio_callback_fn_t callback_fn,
- audsettings_t *settings
- );
-
-void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
-int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
-int AUD_get_buffer_size_out (SWVoiceOut *sw);
-void AUD_set_active_out (SWVoiceOut *sw, int on);
-int AUD_is_active_out (SWVoiceOut *sw);
-
-void AUD_init_time_stamp_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
-uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
-
-void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol);
-void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol);
-
-SWVoiceIn *AUD_open_in (
- QEMUSoundCard *card,
- SWVoiceIn *sw,
- const char *name,
- void *callback_opaque,
- audio_callback_fn_t callback_fn,
- audsettings_t *settings
- );
-
-void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
-int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
-void AUD_set_active_in (SWVoiceIn *sw, int on);
-int AUD_is_active_in (SWVoiceIn *sw);
-
-void AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
-uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
-
-static inline void *advance (void *p, int incr)
-{
- uint8_t *d = p;
- return (d + incr);
-}
-
-uint32_t popcount (uint32_t u);
-uint32_t lsbindex (uint32_t u);
-
-#ifdef __GNUC__
-#define audio_MIN(a, b) ( __extension__ ({ \
- __typeof (a) ta = a; \
- __typeof (b) tb = b; \
- ((ta)>(tb)?(tb):(ta)); \
-}))
-
-#define audio_MAX(a, b) ( __extension__ ({ \
- __typeof (a) ta = a; \
- __typeof (b) tb = b; \
- ((ta)<(tb)?(tb):(ta)); \
-}))
-#else
-#define audio_MIN(a, b) ((a)>(b)?(b):(a))
-#define audio_MAX(a, b) ((a)<(b)?(b):(a))
-#endif
-
-extern int
-audio_get_backend_count( int is_input );
-
-extern const char*
-audio_get_backend_name( int is_input, int index, const char* *pinfo );
-
-extern int
-audio_check_backend_name( int is_input, const char* name );
-
-#endif /* audio.h */
diff --git a/audio/audio_int.h b/audio/audio_int.h
deleted file mode 100644
index 6677ec1..0000000
--- a/audio/audio_int.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_AUDIO_INT_H
-#define QEMU_AUDIO_INT_H
-
-#include "audio/audio.h"
-
-#ifdef CONFIG_COREAUDIO
-#define FLOAT_MIXENG
-/* #define RECIPROCAL */
-#endif
-#include "mixeng.h"
-
-struct audio_pcm_ops;
-
-typedef enum {
- AUD_OPT_INT,
- AUD_OPT_FMT,
- AUD_OPT_STR,
- AUD_OPT_BOOL
-} audio_option_tag_e;
-
-struct audio_option {
- const char *name;
- audio_option_tag_e tag;
- void *valp;
- const char *descr;
- int *overriddenp;
- int overridden;
-};
-
-struct audio_callback {
- void *opaque;
- audio_callback_fn_t fn;
-};
-
-struct audio_pcm_info {
- int bits;
- int sign;
- int freq;
- int nchannels;
- int align;
- int shift;
- int bytes_per_second;
- int swap_endianness;
-};
-
-typedef struct SWVoiceCap SWVoiceCap;
-
-typedef struct HWVoiceOut {
- int enabled;
- int pending_disable;
- struct audio_pcm_info info;
-
- f_sample *clip;
-
- int rpos;
- uint64_t ts_helper;
-
- st_sample_t *mix_buf;
-
- int samples;
- LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
- LIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
- struct audio_pcm_ops *pcm_ops;
- LIST_ENTRY (HWVoiceOut) entries;
-} HWVoiceOut;
-
-typedef struct HWVoiceIn {
- int enabled;
- struct audio_pcm_info info;
-
- t_sample *conv;
-
- int wpos;
- int total_samples_captured;
- uint64_t ts_helper;
-
- st_sample_t *conv_buf;
-
- int samples;
- LIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
- struct audio_pcm_ops *pcm_ops;
- LIST_ENTRY (HWVoiceIn) entries;
-} HWVoiceIn;
-
-struct SWVoiceOut {
- struct audio_pcm_info info;
- t_sample *conv;
- int64_t ratio;
- st_sample_t *buf;
- void *rate;
- int total_hw_samples_mixed;
- int active;
- int empty;
- HWVoiceOut *hw;
- char *name;
- volume_t vol;
- struct audio_callback callback;
- LIST_ENTRY (SWVoiceOut) entries;
-};
-
-struct SWVoiceIn {
- int active;
- struct audio_pcm_info info;
- int64_t ratio;
- void *rate;
- int total_hw_samples_acquired;
- st_sample_t *buf;
- f_sample *clip;
- HWVoiceIn *hw;
- char *name;
- volume_t vol;
- struct audio_callback callback;
- LIST_ENTRY (SWVoiceIn) entries;
-};
-
-struct audio_driver {
- const char *name;
- const char *descr;
- struct audio_option *options;
- void *(*init) (void);
- void (*fini) (void *);
- struct audio_pcm_ops *pcm_ops;
- int can_be_default;
- int max_voices_out;
- int max_voices_in;
- int voice_size_out;
- int voice_size_in;
-};
-
-struct audio_pcm_ops {
- int (*init_out)(HWVoiceOut *hw, audsettings_t *as);
- void (*fini_out)(HWVoiceOut *hw);
- int (*run_out) (HWVoiceOut *hw);
- int (*write) (SWVoiceOut *sw, void *buf, int size);
- int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
-
- int (*init_in) (HWVoiceIn *hw, audsettings_t *as);
- void (*fini_in) (HWVoiceIn *hw);
- int (*run_in) (HWVoiceIn *hw);
- int (*read) (SWVoiceIn *sw, void *buf, int size);
- int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
-};
-
-struct capture_callback {
- struct audio_capture_ops ops;
- void *opaque;
- LIST_ENTRY (capture_callback) entries;
-};
-
-struct CaptureVoiceOut {
- HWVoiceOut hw;
- void *buf;
- LIST_HEAD (cb_listhead, capture_callback) cb_head;
- LIST_ENTRY (CaptureVoiceOut) entries;
-};
-
-struct SWVoiceCap {
- SWVoiceOut sw;
- CaptureVoiceOut *cap;
- LIST_ENTRY (SWVoiceCap) entries;
-};
-
-struct AudioState {
- struct audio_driver* drv_in;
- void* drv_in_opaque;
- struct audio_driver* drv_out;
- void* drv_out_opaque;
-
- QEMUTimer *ts;
- LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
- LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
- LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
- LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
- int nb_hw_voices_out;
- int nb_hw_voices_in;
-};
-
-extern struct audio_driver no_audio_driver;
-extern struct audio_driver oss_audio_driver;
-extern struct audio_driver sdl_audio_driver;
-extern struct audio_driver win_audio_driver;
-extern struct audio_driver wav_audio_driver;
-extern struct audio_driver fmod_audio_driver;
-extern struct audio_driver esd_audio_driver;
-extern struct audio_driver alsa_audio_driver;
-extern struct audio_driver coreaudio_audio_driver;
-extern struct audio_driver dsound_audio_driver;
-extern struct audio_driver esd_audio_driver;
-extern volume_t nominal_volume;
-
-void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as);
-void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
-
-int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
-int audio_pcm_hw_get_live_in (HWVoiceIn *hw);
-
-int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
-int audio_pcm_hw_get_live_out (HWVoiceOut *hw);
-int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live);
-
-int audio_bug (const char *funcname, int cond);
-void *audio_calloc (const char *funcname, int nmemb, size_t size);
-
-#define VOICE_ENABLE 1
-#define VOICE_DISABLE 2
-
-static inline int audio_ring_dist (int dst, int src, int len)
-{
- return (dst >= src) ? (dst - src) : (len - src + dst);
-}
-
-#if defined __GNUC__
-#define GCC_ATTR __attribute__ ((__unused__, __format__ (__printf__, 1, 2)))
-#define INIT_FIELD(f) . f
-#define GCC_FMT_ATTR(n, m) __attribute__ ((__format__ (__printf__, n, m)))
-#else
-#define GCC_ATTR /**/
-#define INIT_FIELD(f) /**/
-#define GCC_FMT_ATTR(n, m)
-#endif
-
-static void GCC_ATTR dolog (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-}
-
-#ifdef DEBUG
-static void GCC_ATTR ldebug (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-}
-#else
-#if defined NDEBUG && defined __GNUC__
-#define ldebug(...)
-#elif defined NDEBUG && defined _MSC_VER
-#define ldebug __noop
-#else
-static void GCC_ATTR ldebug (const char *fmt, ...)
-{
- (void) fmt;
-}
-#endif
-#endif
-
-#undef GCC_ATTR
-
-#define AUDIO_STRINGIFY_(n) #n
-#define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n)
-
-#if defined _MSC_VER || defined __GNUC__
-#define AUDIO_FUNC __FUNCTION__
-#else
-#define AUDIO_FUNC __FILE__ ":" AUDIO_STRINGIFY (__LINE__)
-#endif
-
-#endif /* audio_int.h */
diff --git a/audio/audio_pt_int.c b/audio/audio_pt_int.c
deleted file mode 100644
index c753774..0000000
--- a/audio/audio_pt_int.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "audio.h"
-
-#define AUDIO_CAP "audio-pt"
-
-#include "audio_int.h"
-#include "audio_pt_int.h"
-
-static void logerr (struct audio_pt *pt, int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (pt->drv, fmt, ap);
- va_end (ap);
-
- AUD_log (NULL, "\n");
- AUD_log (pt->drv, "Reason: %s\n", strerror (err));
-}
-
-int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
- void *opaque, const char *drv, const char *cap)
-{
- int err, err2;
- const char *efunc;
-
- p->drv = drv;
-
- err = pthread_mutex_init (&p->mutex, NULL);
- if (err) {
- efunc = "pthread_mutex_init";
- goto err0;
- }
-
- err = pthread_cond_init (&p->cond, NULL);
- if (err) {
- efunc = "pthread_cond_init";
- goto err1;
- }
-
- err = pthread_create (&p->thread, NULL, func, opaque);
- if (err) {
- efunc = "pthread_create";
- goto err2;
- }
-
- return 0;
-
- err2:
- err2 = pthread_cond_destroy (&p->cond);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
- }
-
- err1:
- err2 = pthread_mutex_destroy (&p->mutex);
- if (err2) {
- logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
- }
-
- err0:
- logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
- return -1;
-}
-
-int audio_pt_fini (struct audio_pt *p, const char *cap)
-{
- int err, ret = 0;
-
- err = pthread_cond_destroy (&p->cond);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
- ret = -1;
- }
-
- err = pthread_mutex_destroy (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
- ret = -1;
- }
- return ret;
-}
-
-int audio_pt_lock (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_lock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_unlock (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_unlock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_wait (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_cond_wait (&p->cond, &p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
-{
- int err;
-
- err = pthread_mutex_unlock (&p->mutex);
- if (err) {
- logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
- return -1;
- }
- err = pthread_cond_signal (&p->cond);
- if (err) {
- logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
- return -1;
- }
- return 0;
-}
-
-int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
-{
- int err;
- void *ret;
-
- err = pthread_join (p->thread, &ret);
- if (err) {
- logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
- return -1;
- }
- *arg = ret;
- return 0;
-}
diff --git a/audio/audio_pt_int.h b/audio/audio_pt_int.h
deleted file mode 100644
index 0dfff76..0000000
--- a/audio/audio_pt_int.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef QEMU_AUDIO_PT_INT_H
-#define QEMU_AUDIO_PT_INT_H
-
-#include <pthread.h>
-
-struct audio_pt {
- const char *drv;
- pthread_t thread;
- pthread_cond_t cond;
- pthread_mutex_t mutex;
-};
-
-int audio_pt_init (struct audio_pt *, void *(*) (void *), void *,
- const char *, const char *);
-int audio_pt_fini (struct audio_pt *, const char *);
-int audio_pt_lock (struct audio_pt *, const char *);
-int audio_pt_unlock (struct audio_pt *, const char *);
-int audio_pt_wait (struct audio_pt *, const char *);
-int audio_pt_unlock_and_signal (struct audio_pt *, const char *);
-int audio_pt_join (struct audio_pt *, void **, const char *);
-
-#endif /* audio_pt_int.h */
diff --git a/audio/audio_template.h b/audio/audio_template.h
deleted file mode 100644
index 6f8e166..0000000
--- a/audio/audio_template.h
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifdef DAC
-#define NAME "playback"
-#define HWBUF hw->mix_buf
-#define TYPE out
-#define HW HWVoiceOut
-#define SW SWVoiceOut
-#else
-#define NAME "capture"
-#define TYPE in
-#define HW HWVoiceIn
-#define SW SWVoiceIn
-#define HWBUF hw->conv_buf
-#endif
-
-static void glue (audio_init_nb_voices_, TYPE) (
- AudioState *s,
- struct audio_driver *drv
- )
-{
- int max_voices = glue (drv->max_voices_, TYPE);
- int voice_size = glue (drv->voice_size_, TYPE);
-
- if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
- if (!max_voices) {
-#ifdef DAC
- dolog ("Driver `%s' does not support " NAME "\n", drv->name);
-#endif
- }
- else {
- dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
- drv->name,
- glue (s->nb_hw_voices_, TYPE),
- max_voices);
- }
- glue (s->nb_hw_voices_, TYPE) = max_voices;
- }
-
- if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
- dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
- drv->name, max_voices);
- glue (s->nb_hw_voices_, TYPE) = 0;
- }
-
- if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
- dolog ("drv=`%s' voice_size=%d max_voices=0\n",
- drv->name, voice_size);
- }
-}
-
-static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
-{
- if (HWBUF) {
- qemu_free (HWBUF);
- }
-
- HWBUF = NULL;
-}
-
-static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
-{
- HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
- if (!HWBUF) {
- dolog ("Could not allocate " NAME " buffer (%d samples)\n",
- hw->samples);
- return -1;
- }
-
- return 0;
-}
-
-static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
-{
- if (sw->buf) {
- qemu_free (sw->buf);
- }
-
- if (sw->rate) {
- st_rate_stop (sw->rate);
- }
-
- sw->buf = NULL;
- sw->rate = NULL;
-}
-
-static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
-{
- int samples;
-
-#ifdef DAC
- samples = sw->hw->samples;
-#else
- samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
-#endif
-
- sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
- if (!sw->buf) {
- dolog ("Could not allocate buffer for `%s' (%d samples)\n",
- SW_NAME (sw), samples);
- return -1;
- }
-
-#ifdef DAC
- sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
-#else
- sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
-#endif
- if (!sw->rate) {
- qemu_free (sw->buf);
- sw->buf = NULL;
- return -1;
- }
- return 0;
-}
-
-static int glue (audio_pcm_sw_init_, TYPE) (
- SW *sw,
- HW *hw,
- const char *name,
- audsettings_t *as
- )
-{
- int err;
-
- audio_pcm_init_info (&sw->info, as);
- sw->hw = hw;
- sw->active = 0;
-#ifdef DAC
- sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
- sw->total_hw_samples_mixed = 0;
- sw->empty = 1;
-#else
- sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
-#endif
-
-#ifdef DAC
- sw->conv = mixeng_conv
-#else
- sw->clip = mixeng_clip
-#endif
- [sw->info.nchannels == 2]
- [sw->info.sign]
- [sw->info.swap_endianness]
- [audio_bits_to_index (sw->info.bits)];
-
- sw->name = qemu_strdup (name);
- err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
- if (err) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- return err;
-}
-
-static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
-{
- glue (audio_pcm_sw_free_resources_, TYPE) (sw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
-}
-
-static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
-{
- LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
-}
-
-static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
-{
- LIST_REMOVE (sw, entries);
-}
-
-static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
-{
- HW *hw = *hwp;
-
- if (!hw->sw_head.lh_first) {
-#ifdef DAC
- audio_detach_capture (hw);
-#endif
- LIST_REMOVE (hw, entries);
- glue (s->nb_hw_voices_, TYPE) += 1;
- glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
- BEGIN_NOSIGALRM
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- END_NOSIGALRM
- qemu_free (hw);
- *hwp = NULL;
- }
-}
-
-static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
-{
- return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
-}
-
-static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
-{
- while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
- if (hw->enabled) {
- return hw;
- }
- }
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
- AudioState *s,
- HW *hw,
- audsettings_t *as
- )
-{
- while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
- if (audio_pcm_info_eq (&hw->info, as)) {
- return hw;
- }
- }
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t *as)
-{
- HW *hw;
- struct audio_driver *drv = glue(s->drv_, TYPE);
- int err;
-
- if (!glue (s->nb_hw_voices_, TYPE)) {
- return NULL;
- }
-
- if (audio_bug (AUDIO_FUNC, !drv)) {
- dolog ("No host audio driver\n");
- return NULL;
- }
-
- if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
- dolog ("Host audio driver without pcm_ops\n");
- return NULL;
- }
-
- hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
- if (!hw) {
- dolog ("Can not allocate voice `%s' size %d\n",
- drv->name, glue (drv->voice_size_, TYPE));
- return NULL;
- }
-
- hw->pcm_ops = drv->pcm_ops;
- LIST_INIT (&hw->sw_head);
-#ifdef DAC
- LIST_INIT (&hw->cap_head);
-#endif
- BEGIN_NOSIGALRM
- err = glue (hw->pcm_ops->init_, TYPE) (hw, as);
- END_NOSIGALRM
- if (err)
- goto err0;
-
- if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
- dolog ("hw->samples=%d\n", hw->samples);
- goto err1;
- }
-
-#ifdef DAC
- hw->clip = mixeng_clip
-#else
- hw->conv = mixeng_conv
-#endif
- [hw->info.nchannels == 2]
- [hw->info.sign]
- [hw->info.swap_endianness]
- [audio_bits_to_index (hw->info.bits)];
-
- if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
- goto err1;
- }
-
- LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
- glue (s->nb_hw_voices_, TYPE) -= 1;
-#ifdef DAC
- audio_attach_capture (s, hw);
-#endif
- return hw;
-
- err1:
- BEGIN_NOSIGALRM
- glue (hw->pcm_ops->fini_, TYPE) (hw);
- END_NOSIGALRM
- err0:
- qemu_free (hw);
- return NULL;
-}
-
-static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
-{
- HW *hw;
-
- if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
- hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
- if (hw) {
- return hw;
- }
- }
-
- hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
- if (hw) {
- return hw;
- }
-
- hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
- if (hw) {
- return hw;
- }
-
- return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
-}
-
-static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
- AudioState *s,
- const char *sw_name,
- audsettings_t *as
- )
-{
- SW *sw;
- HW *hw;
- audsettings_t hw_as;
-
- if (glue (conf.fixed_, TYPE).enabled) {
- hw_as = glue (conf.fixed_, TYPE).settings;
- }
- else {
- hw_as = *as;
- }
-
- sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
- if (!sw) {
- dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
- sw_name ? sw_name : "unknown", sizeof (*sw));
- goto err1;
- }
-
- hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
- if (!hw) {
- goto err2;
- }
-
- glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
-
- if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
- goto err3;
- }
-
- return sw;
-
-err3:
- glue (audio_pcm_hw_del_sw_, TYPE) (sw);
- glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
-err2:
- qemu_free (sw);
-err1:
- return NULL;
-}
-
-static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
-{
- glue (audio_pcm_sw_fini_, TYPE) (sw);
- glue (audio_pcm_hw_del_sw_, TYPE) (sw);
- glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
- qemu_free (sw);
-}
-
-void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
-{
- if (sw) {
- if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
- dolog ("card=%p card->audio=%p\n",
- card, card ? card->audio : NULL);
- return;
- }
-
- glue (audio_close_, TYPE) (card->audio, sw);
- }
-}
-
-SW *glue (AUD_open_, TYPE) (
- QEMUSoundCard *card,
- SW *sw,
- const char *name,
- void *callback_opaque ,
- audio_callback_fn_t callback_fn,
- audsettings_t *as
- )
-{
- AudioState *s;
-#ifdef DAC
- int live = 0;
- SW *old_sw = NULL;
-#endif
-
- ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
- name, as->freq, as->nchannels, as->fmt);
-
- if (audio_bug (AUDIO_FUNC,
- !card || !card->audio || !name || !callback_fn || !as)) {
- dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
- card, card ? card->audio : NULL, name, callback_fn, as);
- goto fail;
- }
-
- s = card->audio;
-
- if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
- audio_print_settings (as);
- goto fail;
- }
-
- if (audio_bug (AUDIO_FUNC, !glue (s->drv_, TYPE))) {
- dolog ("Can not open `%s' (no host audio driver)\n", name);
- goto fail;
- }
-
- if (sw && audio_pcm_info_eq (&sw->info, as)) {
- return sw;
- }
-
-#ifdef DAC
- if (conf.plive && sw && (!sw->active && !sw->empty)) {
- live = sw->total_hw_samples_mixed;
-
-#ifdef DEBUG_PLIVE
- dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live);
- dolog ("Old %s freq %d, bits %d, channels %d\n",
- SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
- dolog ("New %s freq %d, bits %d, channels %d\n",
- name,
- freq,
- (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
- nchannels);
-#endif
-
- if (live) {
- old_sw = sw;
- old_sw->callback.fn = NULL;
- sw = NULL;
- }
- }
-#endif
-
- if (!glue (conf.fixed_, TYPE).enabled && sw) {
- glue (AUD_close_, TYPE) (card, sw);
- sw = NULL;
- }
-
- if (sw) {
- HW *hw = sw->hw;
-
- if (!hw) {
- dolog ("Internal logic error voice `%s' has no hardware store\n",
- SW_NAME (sw));
- goto fail;
- }
-
- glue (audio_pcm_sw_fini_, TYPE) (sw);
- if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
- goto fail;
- }
- }
- else {
- sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
- if (!sw) {
- dolog ("Failed to create voice `%s'\n", name);
- return NULL;
- }
- }
-
- if (sw) {
- sw->vol = nominal_volume;
- sw->callback.fn = callback_fn;
- sw->callback.opaque = callback_opaque;
-
-#ifdef DAC
- if (live) {
- int mixed =
- (live << old_sw->info.shift)
- * old_sw->info.bytes_per_second
- / sw->info.bytes_per_second;
-
-#ifdef DEBUG_PLIVE
- dolog ("Silence will be mixed %d\n", mixed);
-#endif
- sw->total_hw_samples_mixed += mixed;
- }
-#endif
-
-#ifdef DEBUG_AUDIO
- dolog ("%s\n", name);
- audio_pcm_print_info ("hw", &sw->hw->info);
- audio_pcm_print_info ("sw", &sw->info);
-#endif
- }
-
- return sw;
-
- fail:
- glue (AUD_close_, TYPE) (card, sw);
- return NULL;
-}
-
-int glue (AUD_is_active_, TYPE) (SW *sw)
-{
- return sw ? sw->active : 0;
-}
-
-void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
-{
- if (!sw) {
- return;
- }
-
- ts->old_ts = sw->hw->ts_helper;
-}
-
-uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
-{
- uint64_t delta, cur_ts, old_ts;
-
- if (!sw) {
- return 0;
- }
-
- cur_ts = sw->hw->ts_helper;
- old_ts = ts->old_ts;
- /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
-
- if (cur_ts >= old_ts) {
- delta = cur_ts - old_ts;
- }
- else {
- delta = UINT64_MAX - old_ts + cur_ts;
- }
-
- if (!delta) {
- return 0;
- }
-
- return (delta * sw->hw->info.freq) / 1000000;
-}
-
-#undef TYPE
-#undef HW
-#undef SW
-#undef HWBUF
-#undef NAME
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
deleted file mode 100644
index f23ebee..0000000
--- a/audio/coreaudio.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- * QEMU OS X CoreAudio audio driver
- *
- * Copyright (c) 2008 The Android Open Source Project
- * Copyright (c) 2005 Mike Kronenberg
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <CoreAudio/CoreAudio.h>
-#include <string.h> /* strerror */
-#include <pthread.h> /* pthread_X */
-
-#include "audio.h"
-
-#define AUDIO_CAP "coreaudio"
-#include "audio_int.h"
-
-#define ENABLE_IN 1
-
-#if 0
-# define D(...) fprintf(stderr, __VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-struct {
- int out_buffer_frames;
- int out_nbuffers;
- int in_buffer_frames;
- int in_nbuffers;
- int isAtexit;
-} conf = {
- .out_buffer_frames = 512,
- .out_nbuffers = 4,
- .in_buffer_frames = 512,
- .in_nbuffers = 4,
- .isAtexit = 0
-};
-
-/***************************************************************************************/
-/***************************************************************************************/
-/*** ***/
-/*** U T I L I T Y R O U T I N E S ***/
-/*** ***/
-/***************************************************************************************/
-/***************************************************************************************/
-
-static void coreaudio_logstatus (OSStatus status)
-{
- char *str = "BUG";
-
- switch(status) {
- case kAudioHardwareNoError:
- str = "kAudioHardwareNoError";
- break;
-
- case kAudioHardwareNotRunningError:
- str = "kAudioHardwareNotRunningError";
- break;
-
- case kAudioHardwareUnspecifiedError:
- str = "kAudioHardwareUnspecifiedError";
- break;
-
- case kAudioHardwareUnknownPropertyError:
- str = "kAudioHardwareUnknownPropertyError";
- break;
-
- case kAudioHardwareBadPropertySizeError:
- str = "kAudioHardwareBadPropertySizeError";
- break;
-
- case kAudioHardwareIllegalOperationError:
- str = "kAudioHardwareIllegalOperationError";
- break;
-
- case kAudioHardwareBadDeviceError:
- str = "kAudioHardwareBadDeviceError";
- break;
-
- case kAudioHardwareBadStreamError:
- str = "kAudioHardwareBadStreamError";
- break;
-
- case kAudioHardwareUnsupportedOperationError:
- str = "kAudioHardwareUnsupportedOperationError";
- break;
-
- case kAudioDeviceUnsupportedFormatError:
- str = "kAudioDeviceUnsupportedFormatError";
- break;
-
- case kAudioDevicePermissionsError:
- str = "kAudioDevicePermissionsError";
- break;
-
- default:
- AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
- return;
- }
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
- OSStatus status,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_log (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- coreaudio_logstatus (status);
-}
-
-static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
- OSStatus status,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- coreaudio_logstatus (status);
-}
-
-static void coreaudio_atexit (void)
-{
- conf.isAtexit = 1;
-}
-
-/***************************************************************************************/
-/***************************************************************************************/
-/*** ***/
-/*** S H A R E D I N / O U T V O I C E ***/
-/*** ***/
-/***************************************************************************************/
-/***************************************************************************************/
-
-typedef struct coreAudioVoice {
- pthread_mutex_t mutex;
- AudioDeviceID deviceID;
- Boolean isInput;
- UInt32 bufferFrameSize;
- AudioStreamBasicDescription streamBasicDescription;
- AudioDeviceIOProc ioproc;
- int live;
- int decr;
- int pos;
-} coreaudioVoice;
-
-
-static inline UInt32
-coreaudio_voice_isPlaying (coreaudioVoice* core)
-{
- OSStatus status;
- UInt32 result = 0;
- UInt32 propertySize = sizeof(core->deviceID);
- status = AudioDeviceGetProperty(
- core->deviceID, 0, core->isInput,
- kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr(status,
- "Could not determine whether Device is playing\n");
- }
- return result;
-}
-
-static int
-coreaudio_voice_lock (coreaudioVoice* core, const char *fn_name)
-{
- int err;
-
- err = pthread_mutex_lock (&core->mutex);
- if (err) {
- dolog ("Could not lock voice for %s\nReason: %s\n",
- fn_name, strerror (err));
- return -1;
- }
- return 0;
-}
-
-static int
-coreaudio_voice_unlock (coreaudioVoice* core, const char *fn_name)
-{
- int err;
-
- err = pthread_mutex_unlock (&core->mutex);
- if (err) {
- dolog ("Could not unlock voice for %s\nReason: %s\n",
- fn_name, strerror (err));
- return -1;
- }
- return 0;
-}
-
-static int
-coreaudio_voice_ctl (coreaudioVoice* core, int cmd)
-{
- OSStatus status;
-
- switch (cmd) {
- case VOICE_ENABLE:
- /* start playback */
- D("%s: %s started\n", __FUNCTION__, core->isInput ? "input" : "output");
- if (!coreaudio_voice_isPlaying(core)) {
- status = AudioDeviceStart(core->deviceID, core->ioproc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not resume playback\n");
- }
- }
- break;
-
- case VOICE_DISABLE:
- /* stop playback */
- D("%s: %s stopped\n", __FUNCTION__, core->isInput ? "input" : "output");
- if (!conf.isAtexit) {
- if (coreaudio_voice_isPlaying(core)) {
- status = AudioDeviceStop(core->deviceID, core->ioproc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not pause playback\n");
- }
- }
- }
- break;
- }
- return 0;
-}
-
-static void
-coreaudio_voice_fini (coreaudioVoice* core)
-{
- OSStatus status;
- int err;
-
- if (!conf.isAtexit) {
- /* stop playback */
- coreaudio_voice_ctl(core, VOICE_DISABLE);
-
- /* remove callback */
- status = AudioDeviceRemoveIOProc(core->deviceID, core->ioproc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr (status, "Could not remove IOProc\n");
- }
- }
- core->deviceID = kAudioDeviceUnknown;
-
- /* destroy mutex */
- err = pthread_mutex_destroy(&core->mutex);
- if (err) {
- dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
- }
-}
-
-
-static int
-coreaudio_voice_init (coreaudioVoice* core,
- audsettings_t* as,
- int frameSize,
- AudioDeviceIOProc ioproc,
- void* hw,
- int input)
-{
- OSStatus status;
- UInt32 propertySize;
- int err;
- int bits = 8;
- AudioValueRange frameRange;
- const char* typ = input ? "input" : "playback";
-
- core->isInput = input ? true : false;
-
- /* create mutex */
- err = pthread_mutex_init(&core->mutex, NULL);
- if (err) {
- dolog("Could not create mutex\nReason: %s\n", strerror (err));
- return -1;
- }
-
- if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) {
- bits = 16;
- }
-
- // TODO: audio_pcm_init_info (&hw->info, as);
- /* open default output device */
- /* note: we use DefaultSystemOutputDevice because DefaultOutputDevice seems to
- * always link to the internal speakers, and not the ones selected through system properties
- * go figure...
- */
- propertySize = sizeof(core->deviceID);
- status = AudioHardwareGetProperty(
- input ? kAudioHardwarePropertyDefaultInputDevice :
- kAudioHardwarePropertyDefaultSystemOutputDevice,
- &propertySize,
- &core->deviceID);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get default %s device\n", typ);
- return -1;
- }
- if (core->deviceID == kAudioDeviceUnknown) {
- dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
- return -1;
- }
-
- /* get minimum and maximum buffer frame sizes */
- propertySize = sizeof(frameRange);
- status = AudioDeviceGetProperty(
- core->deviceID,
- 0,
- core->isInput,
- kAudioDevicePropertyBufferFrameSizeRange,
- &propertySize,
- &frameRange);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame range\n");
- return -1;
- }
-
- if (frameRange.mMinimum > frameSize) {
- core->bufferFrameSize = (UInt32) frameRange.mMinimum;
- dolog ("warning: Upsizing Output Buffer Frames to %f\n", frameRange.mMinimum);
- }
- else if (frameRange.mMaximum < frameSize) {
- core->bufferFrameSize = (UInt32) frameRange.mMaximum;
- dolog ("warning: Downsizing Output Buffer Frames to %f\n", frameRange.mMaximum);
- }
- else {
- core->bufferFrameSize = frameSize;
- }
-
- /* set Buffer Frame Size */
- propertySize = sizeof(core->bufferFrameSize);
- status = AudioDeviceSetProperty(
- core->deviceID,
- NULL,
- 0,
- core->isInput,
- kAudioDevicePropertyBufferFrameSize,
- propertySize,
- &core->bufferFrameSize);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not set device buffer frame size %ld\n",
- core->bufferFrameSize);
- return -1;
- }
-
- /* get Buffer Frame Size */
- propertySize = sizeof(core->bufferFrameSize);
- status = AudioDeviceGetProperty(
- core->deviceID,
- 0,
- core->isInput,
- kAudioDevicePropertyBufferFrameSize,
- &propertySize,
- &core->bufferFrameSize);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get device buffer frame size\n");
- return -1;
- }
- // TODO: hw->samples = *pNBuffers * core->bufferFrameSize;
-
- /* get StreamFormat */
- propertySize = sizeof(core->streamBasicDescription);
- status = AudioDeviceGetProperty(
- core->deviceID,
- 0,
- core->isInput,
- kAudioDevicePropertyStreamFormat,
- &propertySize,
- &core->streamBasicDescription);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ,
- "Could not get Device Stream properties\n");
- core->deviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* set Samplerate */
- core->streamBasicDescription.mSampleRate = (Float64) as->freq;
- propertySize = sizeof(core->streamBasicDescription);
- status = AudioDeviceSetProperty(
- core->deviceID,
- 0,
- 0,
- core->isInput,
- kAudioDevicePropertyStreamFormat,
- propertySize,
- &core->streamBasicDescription);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
- as->freq);
- core->deviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* set Callback */
- core->ioproc = ioproc;
- status = AudioDeviceAddIOProc(core->deviceID, ioproc, hw);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
- core->deviceID = kAudioDeviceUnknown;
- return -1;
- }
-
- /* start Playback */
- if (!input && !coreaudio_voice_isPlaying(core)) {
- status = AudioDeviceStart(core->deviceID, core->ioproc);
- if (status != kAudioHardwareNoError) {
- coreaudio_logerr2 (status, typ, "Could not start playback\n");
- AudioDeviceRemoveIOProc(core->deviceID, core->ioproc);
- core->deviceID = kAudioDeviceUnknown;
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/***************************************************************************************/
-/***************************************************************************************/
-/*** ***/
-/*** O U T P U T V O I C E ***/
-/*** ***/
-/***************************************************************************************/
-/***************************************************************************************/
-
-typedef struct coreaudioVoiceOut {
- HWVoiceOut hw;
- coreaudioVoice core[1];
-} coreaudioVoiceOut;
-
-#define CORE_OUT(hw) ((coreaudioVoiceOut*)(hw))->core
-
-
-static int
-coreaudio_run_out (HWVoiceOut *hw)
-{
- int live, decr;
- coreaudioVoice *core = CORE_OUT(hw);
-
- if (coreaudio_voice_lock (core, "coreaudio_run_out")) {
- return 0;
- }
-
- live = audio_pcm_hw_get_live_out (hw);
-
- if (core->decr > live) {
- ldebug ("core->decr %d live %d core->live %d\n",
- core->decr,
- live,
- core->live);
- }
-
- decr = audio_MIN (core->decr, live);
- core->decr -= decr;
- core->live = live - decr;
- hw->rpos = core->pos;
-
- coreaudio_voice_unlock (core, "coreaudio_run_out");
- return decr;
-}
-
-
-/* callback to feed audiooutput buffer */
-static OSStatus
-audioOutDeviceIOProc(
- AudioDeviceID inDevice,
- const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData,
- const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData,
- const AudioTimeStamp* inOutputTime,
- void* hwptr)
-{
- UInt32 frame, frameCount;
- float *out = outOutputData->mBuffers[0].mData;
- HWVoiceOut *hw = hwptr;
- coreaudioVoice *core = CORE_OUT(hw);
- int rpos, live;
- st_sample_t *src;
-#ifndef FLOAT_MIXENG
-#ifdef RECIPROCAL
- const float scale = 1.f / UINT_MAX;
-#else
- const float scale = UINT_MAX;
-#endif
-#endif
-
- if (coreaudio_voice_lock (core, "audioDeviceIOProc")) {
- inInputTime = 0;
- return 0;
- }
-
- frameCount = core->bufferFrameSize;
- live = core->live;
-
- /* if there are not enough samples, set signal and return */
- if (live < frameCount) {
- inInputTime = 0;
- coreaudio_voice_unlock (core, "audioDeviceIOProc(empty)");
- return 0;
- }
-
- rpos = core->pos;
- src = hw->mix_buf + rpos;
-
- /* fill buffer */
- for (frame = 0; frame < frameCount; frame++) {
-#ifdef FLOAT_MIXENG
- *out++ = src[frame].l; /* left channel */
- *out++ = src[frame].r; /* right channel */
-#else
-#ifdef RECIPROCAL
- *out++ = src[frame].l * scale; /* left channel */
- *out++ = src[frame].r * scale; /* right channel */
-#else
- *out++ = src[frame].l / scale; /* left channel */
- *out++ = src[frame].r / scale; /* right channel */
-#endif
-#endif
- }
-
- rpos = (rpos + frameCount) % hw->samples;
- core->decr += frameCount;
- core->pos = rpos;
-
- coreaudio_voice_unlock (core, "audioDeviceIOProc");
- return 0;
-}
-
-static int
-coreaudio_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int
-coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- coreaudioVoice* core = CORE_OUT(hw);
- int err;
-
- audio_pcm_init_info (&hw->info, as);
-
- err = coreaudio_voice_init( core, as, conf.out_buffer_frames, audioOutDeviceIOProc, hw, 0 );
- if (err < 0)
- return err;
-
- hw->samples = core->bufferFrameSize * conf.out_nbuffers;
- return 0;
-}
-
-static void
-coreaudio_fini_out (HWVoiceOut *hw)
-{
-
- coreaudioVoice* core = CORE_OUT(hw);
-
- coreaudio_voice_fini(core);
-}
-
-static int
-coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- coreaudioVoice* core = CORE_OUT(hw);
-
- return coreaudio_voice_ctl(core, cmd);
-}
-
-/***************************************************************************************/
-/***************************************************************************************/
-/*** ***/
-/*** I N P U T V O I C E ***/
-/*** ***/
-/***************************************************************************************/
-/***************************************************************************************/
-
-
-
-typedef struct coreaudioVoiceIn {
- HWVoiceIn hw;
- coreaudioVoice core[1];
-} coreaudioVoiceIn;
-
-#define CORE_IN(hw) ((coreaudioVoiceIn*)(hw))->core
-
-
-static int
-coreaudio_run_in (HWVoiceIn *hw)
-{
- int decr;
-
- coreaudioVoice *core = CORE_IN(hw);
-
- if (coreaudio_voice_lock (core, "coreaudio_run_in")) {
- return 0;
- }
- D("%s: core.decr=%d core.pos=%d\n", __FUNCTION__, core->decr, core->pos);
- decr = core->decr;
- core->decr -= decr;
- hw->wpos = core->pos;
-
- coreaudio_voice_unlock (core, "coreaudio_run_in");
- return decr;
-}
-
-
-/* callback to feed audiooutput buffer */
-static OSStatus
-audioInDeviceIOProc(
- AudioDeviceID inDevice,
- const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData,
- const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData,
- const AudioTimeStamp* inOutputTime,
- void* hwptr)
-{
- UInt32 frame, frameCount;
- float *in = inInputData->mBuffers[0].mData;
- HWVoiceIn *hw = hwptr;
- coreaudioVoice *core = CORE_IN(hw);
- int wpos, avail;
- st_sample_t *dst;
-#ifndef FLOAT_MIXENG
-#ifdef RECIPROCAL
- const float scale = 1.f / UINT_MAX;
-#else
- const float scale = UINT_MAX;
-#endif
-#endif
-
- if (coreaudio_voice_lock (core, "audioDeviceIOProc")) {
- inInputTime = 0;
- return 0;
- }
-
- frameCount = core->bufferFrameSize;
- avail = hw->samples - hw->total_samples_captured - core->decr;
-
- D("%s: enter avail=%d core.decr=%d core.pos=%d hw.samples=%d hw.total_samples_captured=%d frameCount=%d\n",
- __FUNCTION__, avail, core->decr, core->pos, hw->samples, hw->total_samples_captured, (int)frameCount);
-
- /* if there are not enough samples, set signal and return */
- if (avail < frameCount) {
- inInputTime = 0;
- coreaudio_voice_unlock (core, "audioDeviceIOProc(empty)");
- return 0;
- }
-
- wpos = core->pos;
- dst = hw->conv_buf + wpos;
-
- /* fill buffer */
- for (frame = 0; frame < frameCount; frame++) {
-#ifdef FLOAT_MIXENG
- dst[frame].l = *in++; /* left channel */
- dst[frame].r = *in++; /* right channel */
-#else
-#ifdef RECIPROCAL
- dst[frame].l = *in++ * scale; /* left channel */
- dst[frame].r = *in++ * scale; /* right channel */
-#else
- dst[frame].l = *in++ / scale; /* left channel */
- dst[frame].r = *in++ / scale; /* right channel */
-#endif
-#endif
- }
-
- wpos = (wpos + frameCount) % hw->samples;
- core->decr += frameCount;
- core->pos = wpos;
-
- D("exit: core.decr=%d core.pos=%d\n", core->decr, core->pos);
- coreaudio_voice_unlock (core, "audioDeviceIOProc");
- return 0;
-}
-
-static int
-coreaudio_read (SWVoiceIn *sw, void *buf, int len)
-{
- int result = audio_pcm_sw_read(sw, buf, len);
- D("%s: audio_pcm_sw_read(%d) returned %d\n", __FUNCTION__, len, result);
- return result;
-}
-
-static int
-coreaudio_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- coreaudioVoice* core = CORE_IN(hw);
- int err;
-
- audio_pcm_init_info (&hw->info, as);
-
- err = coreaudio_voice_init( core, as, conf.in_buffer_frames, audioInDeviceIOProc, hw, 1 );
- if (err < 0) {
- return err;
- }
-
- hw->samples = core->bufferFrameSize * conf.in_nbuffers;
- return 0;
-}
-
-static void
-coreaudio_fini_in (HWVoiceIn *hw)
-{
-
- coreaudioVoice* core = CORE_IN(hw);
-
- coreaudio_voice_fini(core);
-}
-
-static int
-coreaudio_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- coreaudioVoice* core = CORE_IN(hw);
-
- return coreaudio_voice_ctl(core, cmd);
-}
-
-static void*
-coreaudio_audio_init (void)
-{
- atexit(coreaudio_atexit);
- return &coreaudio_audio_init;
-}
-
-static void
-coreaudio_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-static struct audio_option coreaudio_options[] = {
- {"OUT_BUFFER_SIZE", AUD_OPT_INT, &conf.out_buffer_frames,
- "Size of the output buffer in frames", NULL, 0},
- {"OUT_BUFFER_COUNT", AUD_OPT_INT, &conf.out_nbuffers,
- "Number of output buffers", NULL, 0},
- {"IN_BUFFER_SIZE", AUD_OPT_INT, &conf.in_buffer_frames,
- "Size of the input buffer in frames", NULL, 0},
- {"IN_BUFFER_COUNT", AUD_OPT_INT, &conf.in_nbuffers,
- "Number of input buffers", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops coreaudio_pcm_ops = {
- coreaudio_init_out,
- coreaudio_fini_out,
- coreaudio_run_out,
- coreaudio_write,
- coreaudio_ctl_out,
-
-#if ENABLE_IN
- coreaudio_init_in,
- coreaudio_fini_in,
- coreaudio_run_in,
- coreaudio_read,
- coreaudio_ctl_in
-#else
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-#endif
-};
-
-struct audio_driver coreaudio_audio_driver = {
- INIT_FIELD (name = ) "coreaudio",
- INIT_FIELD (descr = )
- "CoreAudio (developer.apple.com/audio/coreaudio.html)",
- INIT_FIELD (options = ) coreaudio_options,
- INIT_FIELD (init = ) coreaudio_audio_init,
- INIT_FIELD (fini = ) coreaudio_audio_fini,
- INIT_FIELD (pcm_ops = ) &coreaudio_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
-#if ENABLE_IN
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (max_voices_in = ) 1,
- INIT_FIELD (voice_size_out = ) sizeof (coreaudioVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (coreaudioVoiceIn),
-#else
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (max_voices_in = ) 0,
- INIT_FIELD (voice_size_out = ) sizeof (coreaudioVoiceOut),
- INIT_FIELD (voice_size_in = ) 0,
-#endif
-};
diff --git a/audio/dsound_template.h b/audio/dsound_template.h
deleted file mode 100644
index 9cc0b9d..0000000
--- a/audio/dsound_template.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * QEMU DirectSound audio driver header
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef DSBTYPE_IN
-#define NAME "capture buffer"
-#define NAME2 "DirectSoundCapture"
-#define TYPE in
-#define IFACE IDirectSoundCaptureBuffer
-#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
-#define FIELD dsound_capture_buffer
-#define FIELD2 dsound_capture
-#else
-#define NAME "playback buffer"
-#define NAME2 "DirectSound"
-#define TYPE out
-#define IFACE IDirectSoundBuffer
-#define BUFPTR LPDIRECTSOUNDBUFFER
-#define FIELD dsound_buffer
-#define FIELD2 dsound
-#endif
-
-static int glue (dsound_unlock_, TYPE) (
- BUFPTR buf,
- LPVOID p1,
- LPVOID p2,
- DWORD blen1,
- DWORD blen2
- )
-{
- HRESULT hr;
-
- hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not unlock " NAME "\n");
- return -1;
- }
-
- return 0;
-}
-
-static int glue (dsound_lock_, TYPE) (
- BUFPTR buf,
- struct audio_pcm_info *info,
- DWORD pos,
- DWORD len,
- LPVOID *p1p,
- LPVOID *p2p,
- DWORD *blen1p,
- DWORD *blen2p,
- int entire
- )
-{
- HRESULT hr;
- int i;
- LPVOID p1 = NULL, p2 = NULL;
- DWORD blen1 = 0, blen2 = 0;
- DWORD flag;
-
-#ifdef DSBTYPE_IN
- flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
-#else
- flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
-#endif
- for (i = 0; i < conf.lock_retries; ++i) {
- hr = glue (IFACE, _Lock) (
- buf,
- pos,
- len,
- &p1,
- &blen1,
- &p2,
- &blen2,
- flag
- );
-
- if (FAILED (hr)) {
-#ifndef DSBTYPE_IN
- if (hr == DSERR_BUFFERLOST) {
- if (glue (dsound_restore_, TYPE) (buf)) {
- dsound_logerr (hr, "Could not lock " NAME "\n");
- goto fail;
- }
- continue;
- }
-#endif
- dsound_logerr (hr, "Could not lock " NAME "\n");
- goto fail;
- }
-
- break;
- }
-
- if (i == conf.lock_retries) {
- dolog ("%d attempts to lock " NAME " failed\n", i);
- goto fail;
- }
-
- if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
- dolog ("DirectSound returned misaligned buffer %ld %ld\n",
- blen1, blen2);
- glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
- goto fail;
- }
-
- if (!p1 && blen1) {
- dolog ("warning: !p1 && blen1=%ld\n", blen1);
- blen1 = 0;
- }
-
- if (!p2 && blen2) {
- dolog ("warning: !p2 && blen2=%ld\n", blen2);
- blen2 = 0;
- }
-
- *p1p = p1;
- *p2p = p2;
- *blen1p = blen1;
- *blen2p = blen2;
- return 0;
-
- fail:
- *p1p = NULL - 1;
- *p2p = NULL - 1;
- *blen1p = -1;
- *blen2p = -1;
- return -1;
-}
-
-#ifdef DSBTYPE_IN
-static void dsound_fini_in (HWVoiceIn *hw)
-#else
-static void dsound_fini_out (HWVoiceOut *hw)
-#endif
-{
- HRESULT hr;
-#ifdef DSBTYPE_IN
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
-#else
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
-#endif
-
- if (ds->FIELD) {
- hr = glue (IFACE, _Stop) (ds->FIELD);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop " NAME "\n");
- }
-
- hr = glue (IFACE, _Release) (ds->FIELD);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release " NAME "\n");
- }
- ds->FIELD = NULL;
- }
-}
-
-#ifdef DSBTYPE_IN
-static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
-#else
-static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
-#endif
-{
- int err;
- HRESULT hr;
- dsound *s = &glob_dsound;
- WAVEFORMATEX wfx;
- audsettings_t obt_as;
-#ifdef DSBTYPE_IN
- const char *typ = "ADC";
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- DSCBUFFERDESC bd;
- DSCBCAPS bc;
-#else
- const char *typ = "DAC";
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- DSBUFFERDESC bd;
- DSBCAPS bc;
-#endif
-
- if (!s->FIELD2) {
- dolog ("Attempt to initialize voice without " NAME2 " object\n");
- return -1;
- }
-
- err = waveformat_from_audio_settings (&wfx, as);
- if (err) {
- return -1;
- }
-
- memset (&bd, 0, sizeof (bd));
- bd.dwSize = sizeof (bd);
- bd.lpwfxFormat = &wfx;
-#ifdef DSBTYPE_IN
- bd.dwBufferBytes = conf.bufsize_in;
- hr = IDirectSoundCapture_CreateCaptureBuffer (
- s->dsound_capture,
- &bd,
- &ds->dsound_capture_buffer,
- NULL
- );
-#else
- bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
- bd.dwBufferBytes = conf.bufsize_out;
- hr = IDirectSound_CreateSoundBuffer (
- s->dsound,
- &bd,
- &ds->dsound_buffer,
- NULL
- );
-#endif
-
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
- return -1;
- }
-
- hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
- goto fail0;
- }
-
-#ifdef DEBUG_DSOUND
- dolog (NAME "\n");
- print_wave_format (&wfx);
-#endif
-
- memset (&bc, 0, sizeof (bc));
- bc.dwSize = sizeof (bc);
-
- hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
- if (FAILED (hr)) {
- dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
- goto fail0;
- }
-
- err = waveformat_to_audio_settings (&wfx, &obt_as);
- if (err) {
- goto fail0;
- }
-
- ds->first_time = 1;
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
-
- if (bc.dwBufferBytes & hw->info.align) {
- dolog (
- "GetCaps returned misaligned buffer size %ld, alignment %d\n",
- bc.dwBufferBytes, hw->info.align + 1
- );
- }
- hw->samples = bc.dwBufferBytes >> hw->info.shift;
-
-#ifdef DEBUG_DSOUND
- dolog ("caps %ld, desc %ld\n",
- bc.dwBufferBytes, bd.dwBufferBytes);
-
- dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
- hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
-#endif
- return 0;
-
- fail0:
- glue (dsound_fini_, TYPE) (hw);
- return -1;
-}
-
-#undef NAME
-#undef TYPE
-#undef IFACE
-#undef BUFPTR
-#undef FIELD
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
deleted file mode 100644
index 8284067..0000000
--- a/audio/dsoundaudio.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * QEMU DirectSound audio driver
- *
- * Copyright (c) 2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * SEAL 1.07 by Carlos 'pel' Hasan was used as documentation
- */
-
-#include "audio.h"
-
-#define AUDIO_CAP "dsound"
-#include "audio_int.h"
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <mmsystem.h>
-#include <objbase.h>
-#include <dsound.h>
-
-/* #define DEBUG_DSOUND */
-
-static struct {
- int lock_retries;
- int restore_retries;
- int getstatus_retries;
- int set_primary;
- int bufsize_in;
- int bufsize_out;
- audsettings_t settings;
- int latency_millis;
-} conf = {
- 1,
- 1,
- 1,
- 0,
- 16384,
- 16384,
- {
- 44100,
- 2,
- AUD_FMT_S16
- },
- 10
-};
-
-typedef struct {
- LPDIRECTSOUND dsound;
- LPDIRECTSOUNDCAPTURE dsound_capture;
- LPDIRECTSOUNDBUFFER dsound_primary_buffer;
- audsettings_t settings;
-} dsound;
-
-static dsound glob_dsound;
-
-typedef struct {
- HWVoiceOut hw;
- LPDIRECTSOUNDBUFFER dsound_buffer;
- DWORD old_pos;
- int first_time;
-#ifdef DEBUG_DSOUND
- DWORD old_ppos;
- DWORD played;
- DWORD mixed;
-#endif
-} DSoundVoiceOut;
-
-typedef struct {
- HWVoiceIn hw;
- int first_time;
- LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
-} DSoundVoiceIn;
-
-static void dsound_log_hresult (HRESULT hr)
-{
- const char *str = "BUG";
-
- switch (hr) {
- case DS_OK:
- str = "The method succeeded";
- break;
-#ifdef DS_NO_VIRTUALIZATION
- case DS_NO_VIRTUALIZATION:
- str = "The buffer was created, but another 3D algorithm was substituted";
- break;
-#endif
-#ifdef DS_INCOMPLETE
- case DS_INCOMPLETE:
- str = "The method succeeded, but not all the optional effects were obtained";
- break;
-#endif
-#ifdef DSERR_ACCESSDENIED
- case DSERR_ACCESSDENIED:
- str = "The request failed because access was denied";
- break;
-#endif
-#ifdef DSERR_ALLOCATED
- case DSERR_ALLOCATED:
- str = "The request failed because resources, such as a priority level, were already in use by another caller";
- break;
-#endif
-#ifdef DSERR_ALREADYINITIALIZED
- case DSERR_ALREADYINITIALIZED:
- str = "The object is already initialized";
- break;
-#endif
-#ifdef DSERR_BADFORMAT
- case DSERR_BADFORMAT:
- str = "The specified wave format is not supported";
- break;
-#endif
-#ifdef DSERR_BADSENDBUFFERGUID
- case DSERR_BADSENDBUFFERGUID:
- str = "The GUID specified in an audiopath file does not match a valid mix-in buffer";
- break;
-#endif
-#ifdef DSERR_BUFFERLOST
- case DSERR_BUFFERLOST:
- str = "The buffer memory has been lost and must be restored";
- break;
-#endif
-#ifdef DSERR_BUFFERTOOSMALL
- case DSERR_BUFFERTOOSMALL:
- str = "The buffer size is not great enough to enable effects processing";
- break;
-#endif
-#ifdef DSERR_CONTROLUNAVAIL
- case DSERR_CONTROLUNAVAIL:
- str = "The buffer control (volume, pan, and so on) requested by the caller is not available. Controls must be specified when the buffer is created, using the dwFlags member of DSBUFFERDESC";
- break;
-#endif
-#ifdef DSERR_DS8_REQUIRED
- case DSERR_DS8_REQUIRED:
- str = "A DirectSound object of class CLSID_DirectSound8 or later is required for the requested functionality. For more information, see IDirectSound8 Interface";
- break;
-#endif
-#ifdef DSERR_FXUNAVAILABLE
- case DSERR_FXUNAVAILABLE:
- str = "The effects requested could not be found on the system, or they are in the wrong order or in the wrong location; for example, an effect expected in hardware was found in software";
- break;
-#endif
-#ifdef DSERR_GENERIC
- case DSERR_GENERIC :
- str = "An undetermined error occurred inside the DirectSound subsystem";
- break;
-#endif
-#ifdef DSERR_INVALIDCALL
- case DSERR_INVALIDCALL:
- str = "This function is not valid for the current state of this object";
- break;
-#endif
-#ifdef DSERR_INVALIDPARAM
- case DSERR_INVALIDPARAM:
- str = "An invalid parameter was passed to the returning function";
- break;
-#endif
-#ifdef DSERR_NOAGGREGATION
- case DSERR_NOAGGREGATION:
- str = "The object does not support aggregation";
- break;
-#endif
-#ifdef DSERR_NODRIVER
- case DSERR_NODRIVER:
- str = "No sound driver is available for use, or the given GUID is not a valid DirectSound device ID";
- break;
-#endif
-#ifdef DSERR_NOINTERFACE
- case DSERR_NOINTERFACE:
- str = "The requested COM interface is not available";
- break;
-#endif
-#ifdef DSERR_OBJECTNOTFOUND
- case DSERR_OBJECTNOTFOUND:
- str = "The requested object was not found";
- break;
-#endif
-#ifdef DSERR_OTHERAPPHASPRIO
- case DSERR_OTHERAPPHASPRIO:
- str = "Another application has a higher priority level, preventing this call from succeeding";
- break;
-#endif
-#ifdef DSERR_OUTOFMEMORY
- case DSERR_OUTOFMEMORY:
- str = "The DirectSound subsystem could not allocate sufficient memory to complete the caller's request";
- break;
-#endif
-#ifdef DSERR_PRIOLEVELNEEDED
- case DSERR_PRIOLEVELNEEDED:
- str = "A cooperative level of DSSCL_PRIORITY or higher is required";
- break;
-#endif
-#ifdef DSERR_SENDLOOP
- case DSERR_SENDLOOP:
- str = "A circular loop of send effects was detected";
- break;
-#endif
-#ifdef DSERR_UNINITIALIZED
- case DSERR_UNINITIALIZED:
- str = "The Initialize method has not been called or has not been called successfully before other methods were called";
- break;
-#endif
-#ifdef DSERR_UNSUPPORTED
- case DSERR_UNSUPPORTED:
- str = "The function called is not supported at this time";
- break;
-#endif
- default:
- AUD_log (AUDIO_CAP, "Reason: Unknown (HRESULT %#lx)\n", hr);
- return;
- }
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", str);
-}
-
-static void GCC_FMT_ATTR (2, 3) dsound_logerr (
- HRESULT hr,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- dsound_log_hresult (hr);
-}
-
-static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
- HRESULT hr,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- dsound_log_hresult (hr);
-}
-
-static DWORD millis_to_bytes (struct audio_pcm_info *info, DWORD millis)
-{
- return (millis * info->bytes_per_second) / 1000;
-}
-
-#ifdef DEBUG_DSOUND
-static void print_wave_format (WAVEFORMATEX *wfx)
-{
- dolog ("tag = %d\n", wfx->wFormatTag);
- dolog ("nChannels = %d\n", wfx->nChannels);
- dolog ("nSamplesPerSec = %ld\n", wfx->nSamplesPerSec);
- dolog ("nAvgBytesPerSec = %ld\n", wfx->nAvgBytesPerSec);
- dolog ("nBlockAlign = %d\n", wfx->nBlockAlign);
- dolog ("wBitsPerSample = %d\n", wfx->wBitsPerSample);
- dolog ("cbSize = %d\n", wfx->cbSize);
-}
-#endif
-
-static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
-{
- HRESULT hr;
- int i;
-
- for (i = 0; i < conf.restore_retries; ++i) {
- hr = IDirectSoundBuffer_Restore (dsb);
-
- switch (hr) {
- case DS_OK:
- return 0;
-
- case DSERR_BUFFERLOST:
- continue;
-
- default:
- dsound_logerr (hr, "Could not restore playback buffer\n");
- return -1;
- }
- }
-
- dolog ("%d attempts to restore playback buffer failed\n", i);
- return -1;
-}
-
-static int waveformat_from_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
-{
- memset (wfx, 0, sizeof (*wfx));
-
- wfx->wFormatTag = WAVE_FORMAT_PCM;
- wfx->nChannels = as->nchannels;
- wfx->nSamplesPerSec = as->freq;
- wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
- wfx->nBlockAlign = 1 << (as->nchannels == 2);
- wfx->cbSize = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- wfx->wBitsPerSample = 8;
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- wfx->wBitsPerSample = 16;
- wfx->nAvgBytesPerSec <<= 1;
- wfx->nBlockAlign <<= 1;
- break;
-
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- wfx->wBitsPerSample = 32;
- wfx->nAvgBytesPerSec <<= 2;
- wfx->nBlockAlign <<= 2;
- break;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", as->freq);
- return -1;
- }
-
- return 0;
-}
-
-static int waveformat_to_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
-{
- if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
- dolog ("Invalid wave format, tag is not PCM, but %d\n",
- wfx->wFormatTag);
- return -1;
- }
-
- if (!wfx->nSamplesPerSec) {
- dolog ("Invalid wave format, frequency is zero\n");
- return -1;
- }
- as->freq = wfx->nSamplesPerSec;
-
- switch (wfx->nChannels) {
- case 1:
- as->nchannels = 1;
- break;
-
- case 2:
- as->nchannels = 2;
- break;
-
- default:
- dolog (
- "Invalid wave format, number of channels is not 1 or 2, but %d\n",
- wfx->nChannels
- );
- return -1;
- }
-
- switch (wfx->wBitsPerSample) {
- case 8:
- as->fmt = AUD_FMT_U8;
- break;
-
- case 16:
- as->fmt = AUD_FMT_S16;
- break;
-
- case 32:
- as->fmt = AUD_FMT_S32;
- break;
-
- default:
- dolog ("Invalid wave format, bits per sample is not "
- "8, 16 or 32, but %d\n",
- wfx->wBitsPerSample);
- return -1;
- }
-
- return 0;
-}
-
-#include "dsound_template.h"
-#define DSBTYPE_IN
-#include "dsound_template.h"
-#undef DSBTYPE_IN
-
-static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
-{
- HRESULT hr;
- int i;
-
- for (i = 0; i < conf.getstatus_retries; ++i) {
- hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer status\n");
- return -1;
- }
-
- if (*statusp & DSERR_BUFFERLOST) {
- if (dsound_restore_out (dsb)) {
- return -1;
- }
- continue;
- }
- break;
- }
-
- return 0;
-}
-
-static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
- DWORD *statusp)
-{
- HRESULT hr;
-
- hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer status\n");
- return -1;
- }
-
- return 0;
-}
-
-static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
-{
- int src_len1 = dst_len;
- int src_len2 = 0;
- int pos = hw->rpos + dst_len;
- st_sample_t *src1 = hw->mix_buf + hw->rpos;
- st_sample_t *src2 = NULL;
-
- if (pos > hw->samples) {
- src_len1 = hw->samples - hw->rpos;
- src2 = hw->mix_buf;
- src_len2 = dst_len - src_len1;
- pos = src_len2;
- }
-
- if (src_len1) {
- hw->clip (dst, src1, src_len1);
- }
-
- if (src_len2) {
- dst = advance (dst, src_len1 << hw->info.shift);
- hw->clip (dst, src2, src_len2);
- }
-
- hw->rpos = pos % hw->samples;
-}
-
-static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
-{
- int err;
- LPVOID p1, p2;
- DWORD blen1, blen2, len1, len2;
-
- err = dsound_lock_out (
- dsb,
- &hw->info,
- 0,
- hw->samples << hw->info.shift,
- &p1, &p2,
- &blen1, &blen2,
- 1
- );
- if (err) {
- return;
- }
-
- len1 = blen1 >> hw->info.shift;
- len2 = blen2 >> hw->info.shift;
-
-#ifdef DEBUG_DSOUND
- dolog ("clear %p,%ld,%ld %p,%ld,%ld\n",
- p1, blen1, len1,
- p2, blen2, len2);
-#endif
-
- if (p1 && len1) {
- audio_pcm_info_clear_buf (&hw->info, p1, len1);
- }
-
- if (p2 && len2) {
- audio_pcm_info_clear_buf (&hw->info, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
-}
-
-static void dsound_close (dsound *s)
-{
- HRESULT hr;
-
- if (s->dsound_primary_buffer) {
- hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release primary buffer\n");
- }
- s->dsound_primary_buffer = NULL;
- }
-}
-
-static int dsound_open (dsound *s)
-{
- int err;
- HRESULT hr;
- WAVEFORMATEX wfx;
- DSBUFFERDESC dsbd;
- HWND hwnd;
-
- hwnd = GetForegroundWindow ();
- hr = IDirectSound_SetCooperativeLevel (
- s->dsound,
- hwnd,
- DSSCL_PRIORITY
- );
-
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not set cooperative level for window %p\n",
- hwnd);
- return -1;
- }
-
- if (!conf.set_primary) {
- return 0;
- }
-
- err = waveformat_from_audio_settings (&wfx, &conf.settings);
- if (err) {
- return -1;
- }
-
- memset (&dsbd, 0, sizeof (dsbd));
- dsbd.dwSize = sizeof (dsbd);
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
- dsbd.dwBufferBytes = 0;
- dsbd.lpwfxFormat = NULL;
-
- hr = IDirectSound_CreateSoundBuffer (
- s->dsound,
- &dsbd,
- &s->dsound_primary_buffer,
- NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create primary playback buffer\n");
- return -1;
- }
-
- hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not set primary playback buffer format\n");
- }
-
- hr = IDirectSoundBuffer_GetFormat (
- s->dsound_primary_buffer,
- &wfx,
- sizeof (wfx),
- NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get primary playback buffer format\n");
- goto fail0;
- }
-
-#ifdef DEBUG_DSOUND
- dolog ("Primary\n");
- print_wave_format (&wfx);
-#endif
-
- err = waveformat_to_audio_settings (&wfx, &s->settings);
- if (err) {
- goto fail0;
- }
-
- return 0;
-
- fail0:
- dsound_close (s);
- return -1;
-}
-
-static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- HRESULT hr;
- DWORD status;
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
-
- if (!dsb) {
- dolog ("Attempt to control voice without a buffer\n");
- return 0;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (dsound_get_status_out (dsb, &status)) {
- return -1;
- }
-
- if (status & DSBSTATUS_PLAYING) {
- dolog ("warning: Voice is already playing\n");
- return 0;
- }
-
- dsound_clear_sample (hw, dsb);
-
- hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start playing buffer\n");
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- if (dsound_get_status_out (dsb, &status)) {
- return -1;
- }
-
- if (status & DSBSTATUS_PLAYING) {
- hr = IDirectSoundBuffer_Stop (dsb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop playing buffer\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not playing\n");
- }
- break;
- }
- return 0;
-}
-
-static int dsound_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int dsound_run_out (HWVoiceOut *hw)
-{
- int err;
- HRESULT hr;
- DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
- LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
- int live, len, hwshift;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD wpos, ppos, old_pos;
- LPVOID p1, p2;
- int bufsize;
-
- if (!dsb) {
- dolog ("Attempt to run empty with playback buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
- bufsize = hw->samples << hwshift;
-
- live = audio_pcm_hw_get_live_out (hw);
-
- hr = IDirectSoundBuffer_GetCurrentPosition (
- dsb,
- &ppos,
- ds->first_time ? &wpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer position\n");
- return 0;
- }
-
- len = live << hwshift;
-
- if (ds->first_time) {
- if (conf.latency_millis) {
- DWORD cur_blat;
-
- cur_blat = audio_ring_dist (wpos, ppos, bufsize);
- ds->first_time = 0;
- old_pos = wpos;
- old_pos +=
- millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat;
- old_pos %= bufsize;
- old_pos &= ~hw->info.align;
- }
- else {
- old_pos = wpos;
- }
-#ifdef DEBUG_DSOUND
- ds->played = 0;
- ds->mixed = 0;
-#endif
- }
- else {
- if (ds->old_pos == ppos) {
-#ifdef DEBUG_DSOUND
- dolog ("old_pos == ppos\n");
-#endif
- return 0;
- }
-
-#ifdef DEBUG_DSOUND
- ds->played += audio_ring_dist (ds->old_pos, ppos, hw->bufsize);
-#endif
- old_pos = ds->old_pos;
- }
-
- if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
- len = ppos - old_pos;
- }
- else {
- if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
- len = bufsize - old_pos + ppos;
- }
- }
-
- if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
- dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
- len, bufsize, old_pos, ppos);
- return 0;
- }
-
- len &= ~hw->info.align;
- if (!len) {
- return 0;
- }
-
-#ifdef DEBUG_DSOUND
- ds->old_ppos = ppos;
-#endif
- err = dsound_lock_out (
- dsb,
- &hw->info,
- old_pos,
- len,
- &p1, &p2,
- &blen1, &blen2,
- 0
- );
- if (err) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- dsound_write_sample (hw, p1, len1);
- }
-
- if (p2 && len2) {
- dsound_write_sample (hw, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
- ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
-
-#ifdef DEBUG_DSOUND
- ds->mixed += decr << hwshift;
-
- dolog ("played %lu mixed %lu diff %ld sec %f\n",
- ds->played,
- ds->mixed,
- ds->mixed - ds->played,
- abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second);
-#endif
- return decr;
-}
-
-static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- HRESULT hr;
- DWORD status;
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
-
- if (!dscb) {
- dolog ("Attempt to control capture voice without a buffer\n");
- return -1;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- dolog ("warning: Voice is already capturing\n");
- return 0;
- }
-
- /* clear ?? */
-
- hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start capturing\n");
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- hr = IDirectSoundCaptureBuffer_Stop (dscb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop capturing\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not capturing\n");
- }
- break;
- }
- return 0;
-}
-
-static int dsound_read (SWVoiceIn *sw, void *buf, int len)
-{
- return audio_pcm_sw_read (sw, buf, len);
-}
-
-static int dsound_run_in (HWVoiceIn *hw)
-{
- int err;
- HRESULT hr;
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
- int live, len, dead;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD cpos, rpos;
- LPVOID p1, p2;
- int hwshift;
-
- if (!dscb) {
- dolog ("Attempt to run without capture buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- if (!dead) {
- return 0;
- }
-
- hr = IDirectSoundCaptureBuffer_GetCurrentPosition (
- dscb,
- &cpos,
- ds->first_time ? &rpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer position\n");
- return 0;
- }
-
- if (ds->first_time) {
- ds->first_time = 0;
- if (rpos & hw->info.align) {
- ldebug ("warning: Misaligned capture read position %ld(%d)\n",
- rpos, hw->info.align);
- }
- hw->wpos = rpos >> hwshift;
- }
-
- if (cpos & hw->info.align) {
- ldebug ("warning: Misaligned capture position %ld(%d)\n",
- cpos, hw->info.align);
- }
- cpos >>= hwshift;
-
- len = audio_ring_dist (cpos, hw->wpos, hw->samples);
- if (!len) {
- return 0;
- }
- len = audio_MIN (len, dead);
-
- err = dsound_lock_in (
- dscb,
- &hw->info,
- hw->wpos << hwshift,
- len << hwshift,
- &p1,
- &p2,
- &blen1,
- &blen2,
- 0
- );
- if (err) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
- }
-
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
- }
-
- dsound_unlock_in (dscb, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
- return decr;
-}
-
-static void dsound_audio_fini (void *opaque)
-{
- HRESULT hr;
- dsound *s = opaque;
-
- if (!s->dsound) {
- return;
- }
-
- hr = IDirectSound_Release (s->dsound);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSound\n");
- }
- s->dsound = NULL;
-
- if (!s->dsound_capture) {
- return;
- }
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
-}
-
-static void *dsound_audio_init (void)
-{
- int err;
- HRESULT hr;
- dsound *s = &glob_dsound;
-
- hr = CoInitialize (NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize COM\n");
- return NULL;
- }
-
- hr = CoCreateInstance (
- &CLSID_DirectSound,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSound,
- (void **) &s->dsound
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create DirectSound instance\n");
- return NULL;
- }
-
- hr = IDirectSound_Initialize (s->dsound, NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize DirectSound\n");
-
- hr = IDirectSound_Release (s->dsound);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSound\n");
- }
- s->dsound = NULL;
- return NULL;
- }
-
- hr = CoCreateInstance (
- &CLSID_DirectSoundCapture,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSoundCapture,
- (void **) &s->dsound_capture
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
- }
- else {
- hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
- }
- }
-
- err = dsound_open (s);
- if (err) {
- dsound_audio_fini (s);
- return NULL;
- }
-
- return s;
-}
-
-static struct audio_option dsound_options[] = {
- {"LOCK_RETRIES", AUD_OPT_INT, &conf.lock_retries,
- "Number of times to attempt locking the buffer", NULL, 0},
- {"RESTOURE_RETRIES", AUD_OPT_INT, &conf.restore_retries,
- "Number of times to attempt restoring the buffer", NULL, 0},
- {"GETSTATUS_RETRIES", AUD_OPT_INT, &conf.getstatus_retries,
- "Number of times to attempt getting status of the buffer", NULL, 0},
- {"SET_PRIMARY", AUD_OPT_BOOL, &conf.set_primary,
- "Set the parameters of primary buffer", NULL, 0},
- {"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis,
- "(undocumented)", NULL, 0},
- {"PRIMARY_FREQ", AUD_OPT_INT, &conf.settings.freq,
- "Primary buffer frequency", NULL, 0},
- {"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,
- "Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0},
- {"PRIMARY_FMT", AUD_OPT_FMT, &conf.settings.fmt,
- "Primary buffer format", NULL, 0},
- {"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out,
- "(undocumented)", NULL, 0},
- {"BUFSIZE_IN", AUD_OPT_INT, &conf.bufsize_in,
- "(undocumented)", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops dsound_pcm_ops = {
- dsound_init_out,
- dsound_fini_out,
- dsound_run_out,
- dsound_write,
- dsound_ctl_out,
-
- dsound_init_in,
- dsound_fini_in,
- dsound_run_in,
- dsound_read,
- dsound_ctl_in
-};
-
-struct audio_driver dsound_audio_driver = {
- INIT_FIELD (name = ) "dsound",
- INIT_FIELD (descr = )
- "DirectSound audio (www.wikipedia.org/wiki/DirectSound)",
- INIT_FIELD (options = ) dsound_options,
- INIT_FIELD (init = ) dsound_audio_init,
- INIT_FIELD (fini = ) dsound_audio_fini,
- INIT_FIELD (pcm_ops = ) &dsound_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) 1,
- INIT_FIELD (voice_size_out = ) sizeof (DSoundVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (DSoundVoiceIn)
-};
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
deleted file mode 100644
index 05c030f..0000000
--- a/audio/esdaudio.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * QEMU ESD audio driver
- *
- * Copyright (c) 2008 The Android Open Source Project
- * Copyright (c) 2006 Frederick Reeve (brushed up by malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <esd.h>
-#include "audio.h"
-#include <signal.h>
-
-#define AUDIO_CAP "esd"
-#include "audio_int.h"
-#include "audio_pt_int.h"
-#include <dlfcn.h>
-
-#include "qemu_debug.h"
-
-#define DEBUG 1
-
-#if DEBUG
-# include <stdio.h>
-# define D(...) VERBOSE_PRINT(audio,__VA_ARGS__)
-# define D_ACTIVE VERBOSE_CHECK(audio)
-# define O(...) VERBOSE_PRINT(audioout,__VA_ARGS__)
-# define I(...) VERBOSE_PRINT(audioin,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-# define D_ACTIVE 0
-# define O(...) ((void)0)
-# define I(...) ((void)0)
-#endif
-
-#define STRINGIFY_(x) #x
-#define STRINGIFY(x) STRINGIFY_(x)
-
-typedef struct {
- HWVoiceOut hw;
- int done;
- int live;
- int decr;
- int rpos;
- void *pcm_buf;
- int fd;
- struct audio_pt pt;
-} ESDVoiceOut;
-
-typedef struct {
- HWVoiceIn hw;
- int done;
- int dead;
- int incr;
- int wpos;
- void *pcm_buf;
- int fd;
- struct audio_pt pt;
-} ESDVoiceIn;
-
-static struct {
- int samples;
- int divisor;
- char *dac_host;
- char *adc_host;
-} conf = {
- 1024,
- 2,
- NULL,
- NULL
-};
-
-/* link dynamically to the libesd.so */
-
-#define DYNLINK_FUNCTIONS \
- DYNLINK_FUNC(int,esd_play_stream,(esd_format_t,int,const char*,const char*)) \
- DYNLINK_FUNC(int,esd_record_stream,(esd_format_t,int,const char*,const char*)) \
- DYNLINK_FUNC(int,esd_open_sound,( const char *host )) \
- DYNLINK_FUNC(int,esd_close,(int)) \
-
-#define DYNLINK_FUNCTIONS_INIT \
- esd_dynlink_init
-
-#include "dynlink.h"
-
-static void* esd_lib;
-
-static void GCC_FMT_ATTR (2, 3) qesd_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
-}
-
-/* playback */
-static void *qesd_thread_out (void *arg)
-{
- ESDVoiceOut* esd = arg;
- HWVoiceOut* hw = &esd->hw;
- int threshold;
- sigset_t set;
-
- threshold = conf.divisor ? hw->samples / conf.divisor : 0;
-
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- /* ignore SIGALRM in this thread */
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
-
- pthread_sigmask( SIG_BLOCK, &set, NULL);
-
- O("EsounD output thread starting, threshold is %d samples", threshold);
- for (;;) {
- int decr, to_mix, rpos;
-
- for (;;) {
- if (esd->done) {
- goto exit;
- }
-
- if (esd->live > threshold) {
- break;
- }
-
- if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) {
- O("EsounD output thread aborting on wait error");
- goto exit;
- }
- }
-
- decr = to_mix = esd->live;
- rpos = hw->rpos;
-
- if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) {
- O("EsounD output thread aborting on unlock error");
- return NULL;
- }
-
- while (to_mix) {
- ssize_t written;
- int chunk = audio_MIN (to_mix, hw->samples - rpos);
- st_sample_t *src = hw->mix_buf + rpos;
-
- hw->clip (esd->pcm_buf, src, chunk);
-
- again:
- written = write (esd->fd, esd->pcm_buf, chunk << hw->info.shift);
- if (written == -1) {
- if (errno == EINTR || errno == EAGAIN) {
- goto again;
- }
- qesd_logerr (errno, "write failed\n");
- O("EsounD output thread aborting on write error: %s", strerror(errno));
- return NULL;
- }
-
- if (written != chunk << hw->info.shift) {
- int wsamples = written >> hw->info.shift;
- int wbytes = wsamples << hw->info.shift;
- if (wbytes != written) {
- dolog ("warning: Misaligned write %d (requested %d), "
- "alignment %d\n",
- wbytes, written, hw->info.align + 1);
- }
- to_mix -= wsamples;
- rpos = (rpos + wsamples) % hw->samples;
- break;
- }
-
- rpos = (rpos + chunk) % hw->samples;
- to_mix -= chunk;
- }
-
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- O("EsounD output thread aborting on lock error\n");
- return NULL;
- }
-
- esd->rpos = rpos;
- esd->live -= decr;
- esd->decr += decr;
- }
- O("EsounD output thread exiting");
-
- exit:
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
- return NULL;
-}
-
-static int qesd_run_out (HWVoiceOut *hw)
-{
- int live, decr;
- ESDVoiceOut *esd = (ESDVoiceOut *) hw;
-
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- O("%s: exiting on lock error", __FUNCTION__);
- return 0;
- }
-
- live = audio_pcm_hw_get_live_out (hw);
- decr = audio_MIN (live, esd->decr);
- esd->decr -= decr;
- esd->live = live - decr;
- hw->rpos = esd->rpos;
- if (esd->live > 0) {
- O("%s: signaling %d samples\n", esd->live);
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
- }
- else {
- O(".");
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
- }
- return decr;
-}
-
-static int qesd_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int qesd_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- ESDVoiceOut *esd = (ESDVoiceOut *) hw;
- audsettings_t obt_as = *as;
- int esdfmt = ESD_STREAM | ESD_PLAY;
- int result = -1;
-
- /* shut down verbose debug spew */
- if (!D_ACTIVE)
- stdio_disable();
-
- O("initializing EsoundD audio output");
- esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- esdfmt |= ESD_BITS8;
- obt_as.fmt = AUD_FMT_U8;
- break;
-#if 0
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- dolog ("Will use 16 instead of 32 bit samples\n");
-#endif
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- deffmt:
- esdfmt |= ESD_BITS16;
- obt_as.fmt = AUD_FMT_S16;
- break;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", as->fmt);
- goto deffmt;
-
- }
- obt_as.endianness = AUDIO_HOST_ENDIANNESS;
-
- audio_pcm_init_info (&hw->info, &obt_as);
-
- hw->samples = conf.samples;
- esd->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!esd->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- goto exit;
- }
-
- esd->fd = FF(esd_play_stream) (esdfmt, as->freq, conf.dac_host, NULL);
- if (esd->fd < 0) {
- if (conf.dac_host == NULL) {
- esd->fd = FF(esd_play_stream) (esdfmt, as->freq, "localhost", NULL);
- }
- if (esd->fd < 0) {
- qesd_logerr (errno, "esd_play_stream failed\n");
- goto fail2;
- }
- }
-
- if (audio_pt_init (&esd->pt, qesd_thread_out, esd, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
-
- result = 0; /* success */
- goto exit;
-
- fail3:
- if (close (esd->fd)) {
- qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
- AUDIO_FUNC, esd->fd);
- }
- esd->fd = -1;
-
- fail2:
- qemu_free (esd->pcm_buf);
- esd->pcm_buf = NULL;
-
- exit:
- if (!D_ACTIVE)
- stdio_enable();
-
- return result;
-}
-
-static void qesd_fini_out (HWVoiceOut *hw)
-{
- void *ret;
- ESDVoiceOut *esd = (ESDVoiceOut *) hw;
-
- audio_pt_lock (&esd->pt, AUDIO_FUNC);
- esd->done = 1;
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
- audio_pt_join (&esd->pt, &ret, AUDIO_FUNC);
-
- if (esd->fd >= 0) {
- if (close (esd->fd)) {
- qesd_logerr (errno, "failed to close esd socket\n");
- }
- esd->fd = -1;
- }
-
- audio_pt_fini (&esd->pt, AUDIO_FUNC);
-
- qemu_free (esd->pcm_buf);
- esd->pcm_buf = NULL;
-}
-
-static int qesd_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-/* capture */
-static void *qesd_thread_in (void *arg)
-{
- ESDVoiceIn *esd = arg;
- HWVoiceIn *hw = &esd->hw;
- int threshold;
-
- threshold = conf.divisor ? hw->samples / conf.divisor : 0;
-
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- for (;;) {
- int incr, to_grab, wpos;
-
- for (;;) {
- if (esd->done) {
- goto exit;
- }
-
- if (esd->dead > threshold) {
- break;
- }
-
- if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) {
- goto exit;
- }
- }
-
- incr = to_grab = esd->dead;
- wpos = hw->wpos;
-
- if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- while (to_grab) {
- ssize_t nread;
- int chunk = audio_MIN (to_grab, hw->samples - wpos);
- void *buf = advance (esd->pcm_buf, wpos);
-
- again:
- nread = read (esd->fd, buf, chunk << hw->info.shift);
- if (nread == -1) {
- if (errno == EINTR || errno == EAGAIN) {
- goto again;
- }
- qesd_logerr (errno, "read failed\n");
- return NULL;
- }
-
- if (nread != chunk << hw->info.shift) {
- int rsamples = nread >> hw->info.shift;
- int rbytes = rsamples << hw->info.shift;
- if (rbytes != nread) {
- dolog ("warning: Misaligned write %d (requested %d), "
- "alignment %d\n",
- rbytes, nread, hw->info.align + 1);
- }
- to_grab -= rsamples;
- wpos = (wpos + rsamples) % hw->samples;
- break;
- }
-
- hw->conv (hw->conv_buf + wpos, buf, nread >> hw->info.shift,
- &nominal_volume);
- wpos = (wpos + chunk) % hw->samples;
- to_grab -= chunk;
- }
-
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return NULL;
- }
-
- esd->wpos = wpos;
- esd->dead -= incr;
- esd->incr += incr;
- }
-
- exit:
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
- return NULL;
-}
-
-static int qesd_run_in (HWVoiceIn *hw)
-{
- int live, incr, dead;
- ESDVoiceIn *esd = (ESDVoiceIn *) hw;
-
- if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) {
- return 0;
- }
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- incr = audio_MIN (dead, esd->incr);
- esd->incr -= incr;
- esd->dead = dead - incr;
- hw->wpos = esd->wpos;
- if (esd->dead > 0) {
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
- }
- else {
- audio_pt_unlock (&esd->pt, AUDIO_FUNC);
- }
- return incr;
-}
-
-static int qesd_read (SWVoiceIn *sw, void *buf, int len)
-{
- return audio_pcm_sw_read (sw, buf, len);
-}
-
-static int qesd_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- ESDVoiceIn *esd = (ESDVoiceIn *) hw;
- audsettings_t obt_as = *as;
- int esdfmt = ESD_STREAM | ESD_RECORD;
- int result = -1;
-
- /* shut down verbose debug spew */
- if (!D_ACTIVE)
- stdio_disable();
-
- esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;
- switch (as->fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- esdfmt |= ESD_BITS8;
- obt_as.fmt = AUD_FMT_U8;
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- esdfmt |= ESD_BITS16;
- obt_as.fmt = AUD_FMT_S16;
- break;
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- dolog ("Will use 16 instead of 32 bit samples\n");
- esdfmt |= ESD_BITS16;
- obt_as.fmt = AUD_FMT_S16;
- break;
- }
- obt_as.endianness = AUDIO_HOST_ENDIANNESS;
-
- audio_pcm_init_info (&hw->info, &obt_as);
-
- hw->samples = conf.samples;
- esd->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!esd->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- goto exit;
- }
-
- esd->fd = FF(esd_record_stream) (esdfmt, as->freq, conf.adc_host, NULL);
- if (esd->fd < 0) {
- if (conf.adc_host == NULL) {
- esd->fd = FF(esd_record_stream) (esdfmt, as->freq, "localhost", NULL);
- }
- if (esd->fd < 0) {
- qesd_logerr (errno, "esd_record_stream failed\n");
- goto fail2;
- }
- }
-
- if (audio_pt_init (&esd->pt, qesd_thread_in, esd, AUDIO_CAP, AUDIO_FUNC)) {
- goto fail3;
- }
-
- result = 0; /* success */
- goto exit;
-
- fail3:
- if (close (esd->fd)) {
- qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",
- AUDIO_FUNC, esd->fd);
- }
- esd->fd = -1;
-
- fail2:
- qemu_free (esd->pcm_buf);
- esd->pcm_buf = NULL;
-
- exit:
- if (!D_ACTIVE)
- stdio_enable();
-
- return result;
-}
-
-static void qesd_fini_in (HWVoiceIn *hw)
-{
- void *ret;
- ESDVoiceIn *esd = (ESDVoiceIn *) hw;
-
- audio_pt_lock (&esd->pt, AUDIO_FUNC);
- esd->done = 1;
- audio_pt_unlock_and_signal (&esd->pt, AUDIO_FUNC);
- audio_pt_join (&esd->pt, &ret, AUDIO_FUNC);
-
- if (esd->fd >= 0) {
- if (close (esd->fd)) {
- qesd_logerr (errno, "failed to close esd socket\n");
- }
- esd->fd = -1;
- }
-
- audio_pt_fini (&esd->pt, AUDIO_FUNC);
-
- qemu_free (esd->pcm_buf);
- esd->pcm_buf = NULL;
-}
-
-static int qesd_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-/* common */
-static void *qesd_audio_init (void)
-{
- void* result = NULL;
-
- D("%s: entering", __FUNCTION__);
-
- if (esd_lib == NULL) {
- int fd;
-
- esd_lib = dlopen( "libesd.so", RTLD_NOW );
- if (esd_lib == NULL)
- esd_lib = dlopen( "libesd.so.0", RTLD_NOW );
-
- if (esd_lib == NULL) {
- D("could not find libesd on this system");
- goto Exit;
- }
-
- if (esd_dynlink_init(esd_lib) < 0)
- goto Fail;
-
- fd = FF(esd_open_sound)(conf.dac_host);
- if (fd < 0) {
- D("%s: could not open direct sound server connection, trying localhost",
- __FUNCTION__);
- fd = FF(esd_open_sound)("localhost");
- if (fd < 0) {
- D("%s: could not open localhost sound server connection", __FUNCTION__);
- goto Fail;
- }
- }
-
- D("%s: EsounD server connection succeeded", __FUNCTION__);
- /* FF(esd_close)(fd); */
- }
- result = &conf;
- goto Exit;
-
-Fail:
- D("%s: failed to open library", __FUNCTION__);
- dlclose(esd_lib);
- esd_lib = NULL;
-
-Exit:
- return result;
-}
-
-static void qesd_audio_fini (void *opaque)
-{
- (void) opaque;
- if (esd_lib != NULL) {
- dlclose(esd_lib);
- esd_lib = NULL;
- }
- ldebug ("esd_fini");
-}
-
-struct audio_option qesd_options[] = {
- {"SAMPLES", AUD_OPT_INT, &conf.samples,
- "buffer size in samples", NULL, 0},
-
- {"DIVISOR", AUD_OPT_INT, &conf.divisor,
- "threshold divisor", NULL, 0},
-
- {"DAC_HOST", AUD_OPT_STR, &conf.dac_host,
- "playback host", NULL, 0},
-
- {"ADC_HOST", AUD_OPT_STR, &conf.adc_host,
- "capture host", NULL, 0},
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-struct audio_pcm_ops qesd_pcm_ops = {
- qesd_init_out,
- qesd_fini_out,
- qesd_run_out,
- qesd_write,
- qesd_ctl_out,
-
- qesd_init_in,
- qesd_fini_in,
- qesd_run_in,
- qesd_read,
- qesd_ctl_in,
-};
-
-struct audio_driver esd_audio_driver = {
- INIT_FIELD (name = ) "esd",
- INIT_FIELD (descr = )
- "EsounD audio (en.wikipedia.org/wiki/Esound)",
- INIT_FIELD (options = ) qesd_options,
- INIT_FIELD (init = ) qesd_audio_init,
- INIT_FIELD (fini = ) qesd_audio_fini,
- INIT_FIELD (pcm_ops = ) &qesd_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) 1,
- INIT_FIELD (voice_size_out = ) sizeof (ESDVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (ESDVoiceIn)
-};
diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c
deleted file mode 100644
index e230e8b..0000000
--- a/audio/fmodaudio.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * QEMU FMOD audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <fmod.h>
-#include <fmod_errors.h>
-#include "audio.h"
-
-#define AUDIO_CAP "fmod"
-#include "audio_int.h"
-
-typedef struct FMODVoiceOut {
- HWVoiceOut hw;
- unsigned int old_pos;
- FSOUND_SAMPLE *fmod_sample;
- int channel;
-} FMODVoiceOut;
-
-typedef struct FMODVoiceIn {
- HWVoiceIn hw;
- FSOUND_SAMPLE *fmod_sample;
-} FMODVoiceIn;
-
-static struct {
- const char *drvname;
- int nb_samples;
- int freq;
- int nb_channels;
- int bufsize;
- int threshold;
- int broken_adc;
-} conf = {
- NULL,
- 2048 * 2,
- 44100,
- 2,
- 0,
- 0,
- 0
-};
-
-static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n",
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n",
- FMOD_ErrorString (FSOUND_GetError ()));
-}
-
-static int fmod_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void fmod_clear_sample (FMODVoiceOut *fmd)
-{
- HWVoiceOut *hw = &fmd->hw;
- int status;
- void *p1 = 0, *p2 = 0;
- unsigned int len1 = 0, len2 = 0;
-
- status = FSOUND_Sample_Lock (
- fmd->fmod_sample,
- 0,
- hw->samples << hw->info.shift,
- &p1,
- &p2,
- &len1,
- &len2
- );
-
- if (!status) {
- fmod_logerr ("Failed to lock sample\n");
- return;
- }
-
- if ((len1 & hw->info.align) || (len2 & hw->info.align)) {
- dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
- len1, len2, hw->info.align + 1);
- goto fail;
- }
-
- if ((len1 + len2) - (hw->samples << hw->info.shift)) {
- dolog ("Lock returned incomplete length %d, %d\n",
- len1 + len2, hw->samples << hw->info.shift);
- goto fail;
- }
-
- audio_pcm_info_clear_buf (&hw->info, p1, hw->samples);
-
- fail:
- status = FSOUND_Sample_Unlock (fmd->fmod_sample, p1, p2, len1, len2);
- if (!status) {
- fmod_logerr ("Failed to unlock sample\n");
- }
-}
-
-static void fmod_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
-{
- int src_len1 = dst_len;
- int src_len2 = 0;
- int pos = hw->rpos + dst_len;
- st_sample_t *src1 = hw->mix_buf + hw->rpos;
- st_sample_t *src2 = NULL;
-
- if (pos > hw->samples) {
- src_len1 = hw->samples - hw->rpos;
- src2 = hw->mix_buf;
- src_len2 = dst_len - src_len1;
- pos = src_len2;
- }
-
- if (src_len1) {
- hw->clip (dst, src1, src_len1);
- }
-
- if (src_len2) {
- dst = advance (dst, src_len1 << hw->info.shift);
- hw->clip (dst, src2, src_len2);
- }
-
- hw->rpos = pos % hw->samples;
-}
-
-static int fmod_unlock_sample (FSOUND_SAMPLE *sample, void *p1, void *p2,
- unsigned int blen1, unsigned int blen2)
-{
- int status = FSOUND_Sample_Unlock (sample, p1, p2, blen1, blen2);
- if (!status) {
- fmod_logerr ("Failed to unlock sample\n");
- return -1;
- }
- return 0;
-}
-
-static int fmod_lock_sample (
- FSOUND_SAMPLE *sample,
- struct audio_pcm_info *info,
- int pos,
- int len,
- void **p1,
- void **p2,
- unsigned int *blen1,
- unsigned int *blen2
- )
-{
- int status;
-
- status = FSOUND_Sample_Lock (
- sample,
- pos << info->shift,
- len << info->shift,
- p1,
- p2,
- blen1,
- blen2
- );
-
- if (!status) {
- fmod_logerr ("Failed to lock sample\n");
- return -1;
- }
-
- if ((*blen1 & info->align) || (*blen2 & info->align)) {
- dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
- *blen1, *blen2, info->align + 1);
-
- fmod_unlock_sample (sample, *p1, *p2, *blen1, *blen2);
-
- *p1 = NULL - 1;
- *p2 = NULL - 1;
- *blen1 = ~0U;
- *blen2 = ~0U;
- return -1;
- }
-
- if (!*p1 && *blen1) {
- dolog ("warning: !p1 && blen1=%d\n", *blen1);
- *blen1 = 0;
- }
-
- if (!p2 && *blen2) {
- dolog ("warning: !p2 && blen2=%d\n", *blen2);
- *blen2 = 0;
- }
-
- return 0;
-}
-
-static int fmod_run_out (HWVoiceOut *hw)
-{
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
- int live, decr;
- void *p1 = 0, *p2 = 0;
- unsigned int blen1 = 0, blen2 = 0;
- unsigned int len1 = 0, len2 = 0;
- int nb_live;
-
- live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
- if (!live) {
- return 0;
- }
-
- if (!hw->pending_disable
- && nb_live
- && (conf.threshold && live <= conf.threshold)) {
- ldebug ("live=%d nb_live=%d\n", live, nb_live);
- return 0;
- }
-
- decr = live;
-
- if (fmd->channel >= 0) {
- int len = decr;
- int old_pos = fmd->old_pos;
- int ppos = FSOUND_GetCurrentPosition (fmd->channel);
-
- if (ppos == old_pos || !ppos) {
- return 0;
- }
-
- if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
- len = ppos - old_pos;
- }
- else {
- if ((old_pos > ppos) && ((old_pos + len) > (ppos + hw->samples))) {
- len = hw->samples - old_pos + ppos;
- }
- }
- decr = len;
-
- if (audio_bug (AUDIO_FUNC, decr < 0)) {
- dolog ("decr=%d live=%d ppos=%d old_pos=%d len=%d\n",
- decr, live, ppos, old_pos, len);
- return 0;
- }
- }
-
-
- if (!decr) {
- return 0;
- }
-
- if (fmod_lock_sample (fmd->fmod_sample, &fmd->hw.info,
- fmd->old_pos, decr,
- &p1, &p2,
- &blen1, &blen2)) {
- return 0;
- }
-
- len1 = blen1 >> hw->info.shift;
- len2 = blen2 >> hw->info.shift;
- ldebug ("%p %p %d %d %d %d\n", p1, p2, len1, len2, blen1, blen2);
- decr = len1 + len2;
-
- if (p1 && len1) {
- fmod_write_sample (hw, p1, len1);
- }
-
- if (p2 && len2) {
- fmod_write_sample (hw, p2, len2);
- }
-
- fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
-
- fmd->old_pos = (fmd->old_pos + decr) % hw->samples;
- return decr;
-}
-
-static int aud_to_fmodfmt (audfmt_e fmt, int stereo)
-{
- int mode = FSOUND_LOOP_NORMAL;
-
- switch (fmt) {
- case AUD_FMT_S8:
- mode |= FSOUND_SIGNED | FSOUND_8BITS;
- break;
-
- case AUD_FMT_U8:
- mode |= FSOUND_UNSIGNED | FSOUND_8BITS;
- break;
-
- case AUD_FMT_S16:
- mode |= FSOUND_SIGNED | FSOUND_16BITS;
- break;
-
- case AUD_FMT_U16:
- mode |= FSOUND_UNSIGNED | FSOUND_16BITS;
- break;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_FMOD
- abort ();
-#endif
- mode |= FSOUND_8BITS;
- }
- mode |= stereo ? FSOUND_STEREO : FSOUND_MONO;
- return mode;
-}
-
-static void fmod_fini_out (HWVoiceOut *hw)
-{
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-
- if (fmd->fmod_sample) {
- FSOUND_Sample_Free (fmd->fmod_sample);
- fmd->fmod_sample = 0;
-
- if (fmd->channel >= 0) {
- FSOUND_StopSound (fmd->channel);
- }
- }
-}
-
-static int fmod_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- int bits16, mode, channel;
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
- audsettings_t obt_as = *as;
-
- mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
- fmd->fmod_sample = FSOUND_Sample_Alloc (
- FSOUND_FREE, /* index */
- conf.nb_samples, /* length */
- mode, /* mode */
- as->freq, /* freq */
- 255, /* volume */
- 128, /* pan */
- 255 /* priority */
- );
-
- if (!fmd->fmod_sample) {
- fmod_logerr2 ("DAC", "Failed to allocate FMOD sample\n");
- return -1;
- }
-
- channel = FSOUND_PlaySoundEx (FSOUND_FREE, fmd->fmod_sample, 0, 1);
- if (channel < 0) {
- fmod_logerr2 ("DAC", "Failed to start playing sound\n");
- FSOUND_Sample_Free (fmd->fmod_sample);
- return -1;
- }
- fmd->channel = channel;
-
- /* FMOD always operates on little endian frames? */
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
- bits16 = (mode & FSOUND_16BITS) != 0;
- hw->samples = conf.nb_samples;
- return 0;
-}
-
-static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- int status;
- FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- fmod_clear_sample (fmd);
- status = FSOUND_SetPaused (fmd->channel, 0);
- if (!status) {
- fmod_logerr ("Failed to resume channel %d\n", fmd->channel);
- }
- break;
-
- case VOICE_DISABLE:
- status = FSOUND_SetPaused (fmd->channel, 1);
- if (!status) {
- fmod_logerr ("Failed to pause channel %d\n", fmd->channel);
- }
- break;
- }
- return 0;
-}
-
-static int fmod_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- int bits16, mode;
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
- audsettings_t obt_as = *as;
-
- if (conf.broken_adc) {
- return -1;
- }
-
- mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
- fmd->fmod_sample = FSOUND_Sample_Alloc (
- FSOUND_FREE, /* index */
- conf.nb_samples, /* length */
- mode, /* mode */
- as->freq, /* freq */
- 255, /* volume */
- 128, /* pan */
- 255 /* priority */
- );
-
- if (!fmd->fmod_sample) {
- fmod_logerr2 ("ADC", "Failed to allocate FMOD sample\n");
- return -1;
- }
-
- /* FMOD always operates on little endian frames? */
- obt_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &obt_as);
- bits16 = (mode & FSOUND_16BITS) != 0;
- hw->samples = conf.nb_samples;
- return 0;
-}
-
-static void fmod_fini_in (HWVoiceIn *hw)
-{
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-
- if (fmd->fmod_sample) {
- FSOUND_Record_Stop ();
- FSOUND_Sample_Free (fmd->fmod_sample);
- fmd->fmod_sample = 0;
- }
-}
-
-static int fmod_run_in (HWVoiceIn *hw)
-{
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int live, dead, new_pos, len;
- unsigned int blen1 = 0, blen2 = 0;
- unsigned int len1, len2;
- unsigned int decr;
- void *p1, *p2;
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- if (!dead) {
- return 0;
- }
-
- new_pos = FSOUND_Record_GetPosition ();
- if (new_pos < 0) {
- fmod_logerr ("Could not get recording position\n");
- return 0;
- }
-
- len = audio_ring_dist (new_pos, hw->wpos, hw->samples);
- if (!len) {
- return 0;
- }
- len = audio_MIN (len, dead);
-
- if (fmod_lock_sample (fmd->fmod_sample, &fmd->hw.info,
- hw->wpos, len,
- &p1, &p2,
- &blen1, &blen2)) {
- return 0;
- }
-
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && blen1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
- }
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
- }
-
- fmod_unlock_sample (fmd->fmod_sample, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
- return decr;
-}
-
-static struct {
- const char *name;
- int type;
-} drvtab[] = {
- {"none", FSOUND_OUTPUT_NOSOUND},
-#ifdef _WIN32
- {"winmm", FSOUND_OUTPUT_WINMM},
- {"dsound", FSOUND_OUTPUT_DSOUND},
- {"a3d", FSOUND_OUTPUT_A3D},
- {"asio", FSOUND_OUTPUT_ASIO},
-#endif
-#ifdef __linux__
- {"oss", FSOUND_OUTPUT_OSS},
- {"alsa", FSOUND_OUTPUT_ALSA},
- {"esd", FSOUND_OUTPUT_ESD},
-#endif
-#ifdef __APPLE__
- {"mac", FSOUND_OUTPUT_MAC},
-#endif
-#if 0
- {"xbox", FSOUND_OUTPUT_XBOX},
- {"ps2", FSOUND_OUTPUT_PS2},
- {"gcube", FSOUND_OUTPUT_GC},
-#endif
- {"none-realtime", FSOUND_OUTPUT_NOSOUND_NONREALTIME}
-};
-
-static void *fmod_audio_init (void)
-{
- size_t i;
- double ver;
- int status;
- int output_type = -1;
- const char *drv = conf.drvname;
-
- ver = FSOUND_GetVersion ();
- if (ver < FMOD_VERSION) {
- dolog ("Wrong FMOD version %f, need at least %f\n", ver, FMOD_VERSION);
- return NULL;
- }
-
-#ifdef __linux__
- if (ver < 3.75) {
- dolog ("FMOD before 3.75 has bug preventing ADC from working\n"
- "ADC will be disabled.\n");
- conf.broken_adc = 1;
- }
-#endif
-
- if (drv) {
- int found = 0;
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (!strcmp (drv, drvtab[i].name)) {
- output_type = drvtab[i].type;
- found = 1;
- break;
- }
- }
- if (!found) {
- dolog ("Unknown FMOD driver `%s'\n", drv);
- dolog ("Valid drivers:\n");
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- dolog (" %s\n", drvtab[i].name);
- }
- }
- }
-
- if (output_type != -1) {
- status = FSOUND_SetOutput (output_type);
- if (!status) {
- fmod_logerr ("FSOUND_SetOutput(%d) failed\n", output_type);
- return NULL;
- }
- }
-
- if (conf.bufsize) {
- status = FSOUND_SetBufferSize (conf.bufsize);
- if (!status) {
- fmod_logerr ("FSOUND_SetBufferSize (%d) failed\n", conf.bufsize);
- }
- }
-
- status = FSOUND_Init (conf.freq, conf.nb_channels, 0);
- if (!status) {
- fmod_logerr ("FSOUND_Init failed\n");
- return NULL;
- }
-
- return &conf;
-}
-
-static int fmod_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int fmod_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- int status;
- FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- status = FSOUND_Record_StartSample (fmd->fmod_sample, 1);
- if (!status) {
- fmod_logerr ("Failed to start recording\n");
- }
- break;
-
- case VOICE_DISABLE:
- status = FSOUND_Record_Stop ();
- if (!status) {
- fmod_logerr ("Failed to stop recording\n");
- }
- break;
- }
- return 0;
-}
-
-static void fmod_audio_fini (void *opaque)
-{
- (void) opaque;
- FSOUND_Close ();
-}
-
-static struct audio_option fmod_options[] = {
- {"DRV", AUD_OPT_STR, &conf.drvname,
- "FMOD driver", NULL, 0},
- {"FREQ", AUD_OPT_INT, &conf.freq,
- "Default frequency", NULL, 0},
- {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
- "Buffer size in samples", NULL, 0},
- {"CHANNELS", AUD_OPT_INT, &conf.nb_channels,
- "Number of default channels (1 - mono, 2 - stereo)", NULL, 0},
- {"BUFSIZE", AUD_OPT_INT, &conf.bufsize,
- "(undocumented)", NULL, 0},
-#if 0
- {"THRESHOLD", AUD_OPT_INT, &conf.threshold,
- "(undocumented)"},
-#endif
-
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops fmod_pcm_ops = {
- fmod_init_out,
- fmod_fini_out,
- fmod_run_out,
- fmod_write,
- fmod_ctl_out,
-
- fmod_init_in,
- fmod_fini_in,
- fmod_run_in,
- fmod_read,
- fmod_ctl_in
-};
-
-struct audio_driver fmod_audio_driver = {
- INIT_FIELD (name = ) "fmod",
- INIT_FIELD (descr = ) "FMOD 3.xx http://www.fmod.org",
- INIT_FIELD (options = ) fmod_options,
- INIT_FIELD (init = ) fmod_audio_init,
- INIT_FIELD (fini = ) fmod_audio_fini,
- INIT_FIELD (pcm_ops = ) &fmod_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) INT_MAX,
- INIT_FIELD (voice_size_out = ) sizeof (FMODVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (FMODVoiceIn)
-};
diff --git a/audio/mixeng.c b/audio/mixeng.c
deleted file mode 100644
index 34fc6df..0000000
--- a/audio/mixeng.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- * Copyright (c) 1998 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "audio.h"
-
-#define AUDIO_CAP "mixeng"
-#include "audio_int.h"
-
-#define NOVOL
-
-/* 8 bit */
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-
-/* Signed 8 bit */
-#define IN_T int8_t
-#define IN_MIN SCHAR_MIN
-#define IN_MAX SCHAR_MAX
-#define SIGNED
-#define SHIFT 8
-#include "mixeng_template.h"
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-#undef SHIFT
-
-/* Unsigned 8 bit */
-#define IN_T uint8_t
-#define IN_MIN 0
-#define IN_MAX UCHAR_MAX
-#define SHIFT 8
-#include "mixeng_template.h"
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-#undef SHIFT
-
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-
-/* Signed 16 bit */
-#define IN_T int16_t
-#define IN_MIN SHRT_MIN
-#define IN_MAX SHRT_MAX
-#define SIGNED
-#define SHIFT 16
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap16 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-#undef SHIFT
-
-/* Unsigned 16 bit */
-#define IN_T uint16_t
-#define IN_MIN 0
-#define IN_MAX USHRT_MAX
-#define SHIFT 16
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap16 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-#undef SHIFT
-
-/* Signed 32 bit */
-#define IN_T int32_t
-#define IN_MIN INT32_MIN
-#define IN_MAX INT32_MAX
-#define SIGNED
-#define SHIFT 32
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap32 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-#undef SHIFT
-
-/* Unsigned 16 bit */
-#define IN_T uint32_t
-#define IN_MIN 0
-#define IN_MAX UINT32_MAX
-#define SHIFT 32
-#define ENDIAN_CONVERSION natural
-#define ENDIAN_CONVERT(v) (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#define ENDIAN_CONVERSION swap
-#define ENDIAN_CONVERT(v) bswap32 (v)
-#include "mixeng_template.h"
-#undef ENDIAN_CONVERT
-#undef ENDIAN_CONVERSION
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-#undef SHIFT
-
-t_sample *mixeng_conv[2][2][2][3] = {
- {
- {
- {
- conv_natural_uint8_t_to_mono,
- conv_natural_uint16_t_to_mono,
- conv_natural_uint32_t_to_mono
- },
- {
- conv_natural_uint8_t_to_mono,
- conv_swap_uint16_t_to_mono,
- conv_swap_uint32_t_to_mono,
- }
- },
- {
- {
- conv_natural_int8_t_to_mono,
- conv_natural_int16_t_to_mono,
- conv_natural_int32_t_to_mono
- },
- {
- conv_natural_int8_t_to_mono,
- conv_swap_int16_t_to_mono,
- conv_swap_int32_t_to_mono
- }
- }
- },
- {
- {
- {
- conv_natural_uint8_t_to_stereo,
- conv_natural_uint16_t_to_stereo,
- conv_natural_uint32_t_to_stereo
- },
- {
- conv_natural_uint8_t_to_stereo,
- conv_swap_uint16_t_to_stereo,
- conv_swap_uint32_t_to_stereo
- }
- },
- {
- {
- conv_natural_int8_t_to_stereo,
- conv_natural_int16_t_to_stereo,
- conv_natural_int32_t_to_stereo
- },
- {
- conv_natural_int8_t_to_stereo,
- conv_swap_int16_t_to_stereo,
- conv_swap_int32_t_to_stereo,
- }
- }
- }
-};
-
-f_sample *mixeng_clip[2][2][2][3] = {
- {
- {
- {
- clip_natural_uint8_t_from_mono,
- clip_natural_uint16_t_from_mono,
- clip_natural_uint32_t_from_mono
- },
- {
- clip_natural_uint8_t_from_mono,
- clip_swap_uint16_t_from_mono,
- clip_swap_uint32_t_from_mono
- }
- },
- {
- {
- clip_natural_int8_t_from_mono,
- clip_natural_int16_t_from_mono,
- clip_natural_int32_t_from_mono
- },
- {
- clip_natural_int8_t_from_mono,
- clip_swap_int16_t_from_mono,
- clip_swap_int32_t_from_mono
- }
- }
- },
- {
- {
- {
- clip_natural_uint8_t_from_stereo,
- clip_natural_uint16_t_from_stereo,
- clip_natural_uint32_t_from_stereo
- },
- {
- clip_natural_uint8_t_from_stereo,
- clip_swap_uint16_t_from_stereo,
- clip_swap_uint32_t_from_stereo
- }
- },
- {
- {
- clip_natural_int8_t_from_stereo,
- clip_natural_int16_t_from_stereo,
- clip_natural_int32_t_from_stereo
- },
- {
- clip_natural_int8_t_from_stereo,
- clip_swap_int16_t_from_stereo,
- clip_swap_int32_t_from_stereo
- }
- }
- }
-};
-
-/*
- * August 21, 1998
- * Copyright 1998 Fabrice Bellard.
- *
- * [Rewrote completly the code of Lance Norskog And Sundry
- * Contributors with a more efficient algorithm.]
- *
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
- */
-
-/*
- * Sound Tools rate change effect file.
- */
-/*
- * Linear Interpolation.
- *
- * The use of fractional increment allows us to use no buffer. It
- * avoid the problems at the end of the buffer we had with the old
- * method which stored a possibly big buffer of size
- * lcm(in_rate,out_rate).
- *
- * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
- * the input & output frequencies are equal, a delay of one sample is
- * introduced. Limited to processing 32-bit count worth of samples.
- *
- * 1 << FRAC_BITS evaluating to zero in several places. Changed with
- * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
- */
-
-/* Private data */
-struct rate {
- uint64_t opos;
- uint64_t opos_inc;
- uint32_t ipos; /* position in the input stream (integer) */
- st_sample_t ilast; /* last sample in the input stream */
-};
-
-/*
- * Prepare processing.
- */
-void *st_rate_start (int inrate, int outrate)
-{
- struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
-
- if (!rate) {
- dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
- return NULL;
- }
-
- rate->opos = 0;
-
- /* increment */
- rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
-
- rate->ipos = 0;
- rate->ilast.l = 0;
- rate->ilast.r = 0;
- return rate;
-}
-
-#define NAME st_rate_flow_mix
-#define OP(a, b) a += b
-#include "rate_template.h"
-
-#define NAME st_rate_flow
-#define OP(a, b) a = b
-#include "rate_template.h"
-
-void st_rate_stop (void *opaque)
-{
- qemu_free (opaque);
-}
-
-void mixeng_clear (st_sample_t *buf, int len)
-{
- memset (buf, 0, len * sizeof (st_sample_t));
-}
diff --git a/audio/mixeng.h b/audio/mixeng.h
deleted file mode 100644
index 95b68df..0000000
--- a/audio/mixeng.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * QEMU Mixing engine header
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_MIXENG_H
-#define QEMU_MIXENG_H
-
-#ifdef FLOAT_MIXENG
-typedef float real_t;
-typedef struct { int mute; real_t r; real_t l; } volume_t;
-typedef struct { real_t l; real_t r; } st_sample_t;
-#else
-typedef struct { int mute; int64_t r; int64_t l; } volume_t;
-typedef struct { int64_t l; int64_t r; } st_sample_t;
-#endif
-
-typedef void (t_sample) (st_sample_t *dst, const void *src,
- int samples, volume_t *vol);
-typedef void (f_sample) (void *dst, const st_sample_t *src, int samples);
-
-extern t_sample *mixeng_conv[2][2][2][3];
-extern f_sample *mixeng_clip[2][2][2][3];
-
-void *st_rate_start (int inrate, int outrate);
-void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp);
-void st_rate_flow_mix (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp);
-void st_rate_stop (void *opaque);
-void mixeng_clear (st_sample_t *buf, int len);
-
-#endif /* mixeng.h */
diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h
deleted file mode 100644
index d726441..0000000
--- a/audio/mixeng_template.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Tusen tack till Mike Nordell
- * dec++'ified by Dscho
- */
-
-#ifndef SIGNED
-#define HALF (IN_MAX >> 1)
-#endif
-
-#ifdef NOVOL
-#define VOL(a, b) a
-#else
-#ifdef FLOAT_MIXENG
-#define VOL(a, b) ((a) * (b))
-#else
-#define VOL(a, b) ((a) * (b)) >> 32
-#endif
-#endif
-
-#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
-
-#ifdef FLOAT_MIXENG
-static real_t inline glue (conv_, ET) (IN_T v)
-{
- IN_T nv = ENDIAN_CONVERT (v);
-
-#ifdef RECIPROCAL
-#ifdef SIGNED
- return nv * (1.f / (real_t) (IN_MAX - IN_MIN));
-#else
- return (nv - HALF) * (1.f / (real_t) IN_MAX);
-#endif
-#else /* !RECIPROCAL */
-#ifdef SIGNED
- return nv / (real_t) (IN_MAX - IN_MIN);
-#else
- return (nv - HALF) / (real_t) IN_MAX;
-#endif
-#endif
-}
-
-static IN_T inline glue (clip_, ET) (real_t v)
-{
- if (v >= 0.5) {
- return IN_MAX;
- }
- else if (v < -0.5) {
- return IN_MIN;
- }
-
-#ifdef SIGNED
- return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
-#else
- return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
-#endif
-}
-
-#else /* !FLOAT_MIXENG */
-
-static inline int64_t glue (conv_, ET) (IN_T v)
-{
- IN_T nv = ENDIAN_CONVERT (v);
-#ifdef SIGNED
- return ((int64_t) nv) << (32 - SHIFT);
-#else
- return ((int64_t) nv - HALF) << (32 - SHIFT);
-#endif
-}
-
-static inline IN_T glue (clip_, ET) (int64_t v)
-{
- if (v >= 0x7f000000) {
- return IN_MAX;
- }
- else if (v < -2147483648LL) {
- return IN_MIN;
- }
-
-#ifdef SIGNED
- return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
-#else
- return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
-#endif
-}
-#endif
-
-static void glue (glue (conv_, ET), _to_stereo)
- (st_sample_t *dst, const void *src, int samples, volume_t *vol)
-{
- st_sample_t *out = dst;
- IN_T *in = (IN_T *) src;
-#ifndef NOVOL
- if (vol->mute) {
- mixeng_clear (dst, samples);
- return;
- }
-#else
- (void) vol;
-#endif
- while (samples--) {
- out->l = VOL (glue (conv_, ET) (*in++), vol->l);
- out->r = VOL (glue (conv_, ET) (*in++), vol->r);
- out += 1;
- }
-}
-
-static void glue (glue (conv_, ET), _to_mono)
- (st_sample_t *dst, const void *src, int samples, volume_t *vol)
-{
- st_sample_t *out = dst;
- IN_T *in = (IN_T *) src;
-#ifndef NOVOL
- if (vol->mute) {
- mixeng_clear (dst, samples);
- return;
- }
-#else
- (void) vol;
-#endif
- while (samples--) {
- out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
- out->r = out->l;
- out += 1;
- in += 1;
- }
-}
-
-static void glue (glue (clip_, ET), _from_stereo)
- (void *dst, const st_sample_t *src, int samples)
-{
- const st_sample_t *in = src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue (clip_, ET) (in->l);
- *out++ = glue (clip_, ET) (in->r);
- in += 1;
- }
-}
-
-static void glue (glue (clip_, ET), _from_mono)
- (void *dst, const st_sample_t *src, int samples)
-{
- const st_sample_t *in = src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue (clip_, ET) (in->l + in->r);
- in += 1;
- }
-}
-
-#undef ET
-#undef HALF
-#undef VOL
diff --git a/audio/noaudio.c b/audio/noaudio.c
deleted file mode 100644
index 8788a41..0000000
--- a/audio/noaudio.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * QEMU Timer based audio emulation
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-timer.h"
-
-#define AUDIO_CAP "noaudio"
-#include "audio_int.h"
-
-typedef struct NoVoiceOut {
- HWVoiceOut hw;
- int64_t old_ticks;
-} NoVoiceOut;
-
-typedef struct NoVoiceIn {
- HWVoiceIn hw;
- int64_t old_ticks;
-} NoVoiceIn;
-
-static int no_run_out (HWVoiceOut *hw)
-{
- NoVoiceOut *no = (NoVoiceOut *) hw;
- int live, decr, samples;
- int64_t now;
- int64_t ticks;
- int64_t bytes;
-
- live = audio_pcm_hw_get_live_out (&no->hw);
- if (!live) {
- return 0;
- }
-
- now = qemu_get_clock (vm_clock);
- ticks = now - no->old_ticks;
- bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
- bytes = audio_MIN (bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
-
- no->old_ticks = now;
- decr = audio_MIN (live, samples);
- hw->rpos = (hw->rpos + decr) % hw->samples;
- return decr;
-}
-
-static int no_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int no_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
- return 0;
-}
-
-static void no_fini_out (HWVoiceOut *hw)
-{
- (void) hw;
-}
-
-static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static int no_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- audio_pcm_init_info (&hw->info, as);
- hw->samples = 1024;
- return 0;
-}
-
-static void no_fini_in (HWVoiceIn *hw)
-{
- (void) hw;
-}
-
-static int no_run_in (HWVoiceIn *hw)
-{
- NoVoiceIn *no = (NoVoiceIn *) hw;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- int samples = 0;
-
- if (dead) {
- int64_t now = qemu_get_clock (vm_clock);
- int64_t ticks = now - no->old_ticks;
- int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
-
- no->old_ticks = now;
- bytes = audio_MIN (bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
- samples = audio_MIN (samples, dead);
- }
- return samples;
-}
-
-static int no_read (SWVoiceIn *sw, void *buf, int size)
-{
- int samples = size >> sw->info.shift;
- int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
- int to_clear = audio_MIN (samples, total);
- audio_pcm_info_clear_buf (&sw->info, buf, to_clear);
- return to_clear;
-}
-
-static int no_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static void *no_audio_init (void)
-{
- return &no_audio_init;
-}
-
-static void no_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-static struct audio_pcm_ops no_pcm_ops = {
- no_init_out,
- no_fini_out,
- no_run_out,
- no_write,
- no_ctl_out,
-
- no_init_in,
- no_fini_in,
- no_run_in,
- no_read,
- no_ctl_in
-};
-
-struct audio_driver no_audio_driver = {
- INIT_FIELD (name = ) "none",
- INIT_FIELD (descr = ) "disabled audio",
- INIT_FIELD (options = ) NULL,
- INIT_FIELD (init = ) no_audio_init,
- INIT_FIELD (fini = ) no_audio_fini,
- INIT_FIELD (pcm_ops = ) &no_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) INT_MAX,
- INIT_FIELD (voice_size_out = ) sizeof (NoVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (NoVoiceIn)
-};
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
deleted file mode 100644
index 2ccaade..0000000
--- a/audio/ossaudio.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * QEMU OSS audio driver
- *
- * Copyright (c) 2003-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-
-#define AUDIO_CAP "oss"
-#include "audio_int.h"
-
-typedef struct OSSVoiceOut {
- HWVoiceOut hw;
- void *pcm_buf;
- int fd;
- int nfrags;
- int fragsize;
- int mmapped;
- int old_optr;
-} OSSVoiceOut;
-
-typedef struct OSSVoiceIn {
- HWVoiceIn hw;
- void *pcm_buf;
- int fd;
- int nfrags;
- int fragsize;
- int old_optr;
-} OSSVoiceIn;
-
-static struct {
- int try_mmap;
- int nfrags;
- int fragsize;
- const char *devpath_out;
- const char *devpath_in;
- int debug;
-} conf = {
- .try_mmap = 0,
- .nfrags = 4,
- .fragsize = 4096,
- .devpath_out = "/dev/dsp",
- .devpath_in = "/dev/dsp",
- .debug = 0
-};
-
-struct oss_params {
- int freq;
- audfmt_e fmt;
- int nchannels;
- int nfrags;
- int fragsize;
-};
-
-static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
-}
-
-static void GCC_FMT_ATTR (3, 4) oss_logerr2 (
- int err,
- const char *typ,
- const char *fmt,
- ...
- )
-{
- va_list ap;
-
- AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
-}
-
-static void oss_anal_close (int *fdp)
-{
- int err = close (*fdp);
- if (err) {
- oss_logerr (errno, "Failed to close file(fd=%d)\n", *fdp);
- }
- *fdp = -1;
-}
-
-static int oss_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static int aud_to_ossfmt (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- return AFMT_S8;
-
- case AUD_FMT_U8:
- return AFMT_U8;
-
- case AUD_FMT_S16:
- return AFMT_S16_LE;
-
- case AUD_FMT_U16:
- return AFMT_U16_LE;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return AFMT_U8;
- }
-}
-
-static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness)
-{
- switch (ossfmt) {
- case AFMT_S8:
- *endianness =0;
- *fmt = AUD_FMT_S8;
- break;
-
- case AFMT_U8:
- *endianness = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case AFMT_S16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case AFMT_U16_LE:
- *endianness = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case AFMT_S16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case AFMT_U16_BE:
- *endianness = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- default:
- dolog ("Unrecognized audio format %d\n", ossfmt);
- return -1;
- }
-
- return 0;
-}
-
-#if defined DEBUG_MISMATCHES || defined DEBUG
-static void oss_dump_info (struct oss_params *req, struct oss_params *obt)
-{
- dolog ("parameter | requested value | obtained value\n");
- dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
- dolog ("channels | %10d | %10d\n",
- req->nchannels, obt->nchannels);
- dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
- dolog ("nfrags | %10d | %10d\n", req->nfrags, obt->nfrags);
- dolog ("fragsize | %10d | %10d\n",
- req->fragsize, obt->fragsize);
-}
-#endif
-
-static int oss_open (int in, struct oss_params *req,
- struct oss_params *obt, int *pfd)
-{
- int fd;
- int mmmmssss;
- audio_buf_info abinfo;
- int fmt, freq, nchannels;
- const char *dspname = in ? conf.devpath_in : conf.devpath_out;
- const char *typ = in ? "ADC" : "DAC";
-
- fd = open (dspname, (in ? O_RDONLY : O_WRONLY) | O_NONBLOCK);
- if (-1 == fd) {
- oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname);
- return -1;
- }
-
- freq = req->freq;
- nchannels = req->nchannels;
- fmt = req->fmt;
-
- if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
- oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
- oss_logerr2 (errno, typ, "Failed to set number of channels %d\n",
- req->nchannels);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
- oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq);
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_NONBLOCK, NULL)) {
- oss_logerr2 (errno, typ, "Failed to set non-blocking mode\n");
- goto err;
- }
-
- mmmmssss = (req->nfrags << 16) | lsbindex (req->fragsize);
- if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
- oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n",
- req->nfrags, req->fragsize);
- goto err;
- }
-
- if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) {
- oss_logerr2 (errno, typ, "Failed to get buffer length\n");
- goto err;
- }
-
- if (!abinfo.fragstotal || !abinfo.fragsize) {
- AUD_log(AUDIO_CAP, "Returned bogus buffer information(%d, %d) for %s\n",
- abinfo.fragstotal, abinfo.fragsize, typ);
- goto err;
- }
-
- obt->fmt = fmt;
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->nfrags = abinfo.fragstotal;
- obt->fragsize = abinfo.fragsize;
- *pfd = fd;
-
-#ifdef DEBUG_MISMATCHES
- if ((req->fmt != obt->fmt) ||
- (req->nchannels != obt->nchannels) ||
- (req->freq != obt->freq) ||
- (req->fragsize != obt->fragsize) ||
- (req->nfrags != obt->nfrags)) {
- dolog ("Audio parameters mismatch\n");
- oss_dump_info (req, obt);
- }
-#endif
-
-#ifdef DEBUG
- oss_dump_info (req, obt);
-#endif
- return 0;
-
- err:
- oss_anal_close (&fd);
- return -1;
-}
-
-static int oss_run_out (HWVoiceOut *hw)
-{
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
- int err, rpos, live, decr;
- int samples;
- uint8_t *dst;
- st_sample_t *src;
- struct audio_buf_info abinfo;
- struct count_info cntinfo;
- int bufsize;
-
- live = audio_pcm_hw_get_live_out (hw);
- if (!live) {
- return 0;
- }
-
- bufsize = hw->samples << hw->info.shift;
-
- if (oss->mmapped) {
- int bytes;
-
- err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
- if (err < 0) {
- oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
- return 0;
- }
-
- if (cntinfo.ptr == oss->old_optr) {
- if (abs (hw->samples - live) < 64) {
- dolog ("warning: Overrun\n");
- }
- return 0;
- }
-
- if (cntinfo.ptr > oss->old_optr) {
- bytes = cntinfo.ptr - oss->old_optr;
- }
- else {
- bytes = bufsize + cntinfo.ptr - oss->old_optr;
- }
-
- decr = audio_MIN (bytes >> hw->info.shift, live);
- }
- else {
- err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
- if (err < 0) {
- oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
- return 0;
- }
-
- if (abinfo.bytes > bufsize) {
- if (conf.debug) {
- dolog ("warning: Invalid available size, size=%d bufsize=%d\n"
- "please report your OS/audio hw to malc@pulsesoft.com\n",
- abinfo.bytes, bufsize);
- }
- abinfo.bytes = bufsize;
- }
-
- if (abinfo.bytes < 0) {
- if (conf.debug) {
- dolog ("warning: Invalid available size, size=%d bufsize=%d\n",
- abinfo.bytes, bufsize);
- }
- return 0;
- }
-
- decr = audio_MIN (abinfo.bytes >> hw->info.shift, live);
- if (!decr) {
- return 0;
- }
- }
-
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = hw->mix_buf + rpos;
- dst = advance (oss->pcm_buf, rpos << hw->info.shift);
-
- hw->clip (dst, src, convert_samples);
- if (!oss->mmapped) {
- int written;
-
- written = write (oss->fd, dst, convert_samples << hw->info.shift);
- /* XXX: follow errno recommendations ? */
- if (written == -1) {
- oss_logerr (
- errno,
- "Failed to write %d bytes of audio data from %p\n",
- convert_samples << hw->info.shift,
- dst
- );
- continue;
- }
-
- if (written != convert_samples << hw->info.shift) {
- int wsamples = written >> hw->info.shift;
- int wbytes = wsamples << hw->info.shift;
- if (wbytes != written) {
- dolog ("warning: Misaligned write %d (requested %d), "
- "alignment %d\n",
- wbytes, written, hw->info.align + 1);
- }
- decr -= wsamples;
- rpos = (rpos + wsamples) % hw->samples;
- break;
- }
- }
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- }
- if (oss->mmapped) {
- oss->old_optr = cntinfo.ptr;
- }
-
- hw->rpos = rpos;
- return decr;
-}
-
-static void oss_fini_out (HWVoiceOut *hw)
-{
- int err;
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
-
- ldebug ("oss_fini\n");
- oss_anal_close (&oss->fd);
-
- if (oss->pcm_buf) {
- if (oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
- if (err) {
- oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
- oss->pcm_buf, hw->samples << hw->info.shift);
- }
- }
- else {
- qemu_free (oss->pcm_buf);
- }
- oss->pcm_buf = NULL;
- }
-}
-
-static int oss_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
- struct oss_params req, obt;
- int endianness;
- int err;
- int fd;
- audfmt_e effective_fmt;
- audsettings_t obt_as;
-
- oss->fd = -1;
-
- req.fmt = aud_to_ossfmt (as->fmt);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.fragsize = conf.fragsize;
- req.nfrags = conf.nfrags;
-
- if (oss_open (0, &req, &obt, &fd)) {
- return -1;
- }
-
- err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
- if (err) {
- oss_anal_close (&fd);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- oss->nfrags = obt.nfrags;
- oss->fragsize = obt.fragsize;
-
- if (obt.nfrags * obt.fragsize & hw->info.align) {
- dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",
- obt.nfrags * obt.fragsize, hw->info.align + 1);
- }
-
- hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
-
- oss->mmapped = 0;
- if (conf.try_mmap) {
- oss->pcm_buf = mmap (
- 0,
- hw->samples << hw->info.shift,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fd,
- 0
- );
- if (oss->pcm_buf == MAP_FAILED) {
- oss_logerr (errno, "Failed to map %d bytes of DAC\n",
- hw->samples << hw->info.shift);
- } else {
- int err;
- int trig = 0;
- if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
- }
- else {
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (
- errno,
- "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- );
- }
- else {
- oss->mmapped = 1;
- }
- }
-
- if (!oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
- if (err) {
- oss_logerr (errno, "Failed to unmap buffer %p size %d\n",
- oss->pcm_buf, hw->samples << hw->info.shift);
- }
- }
- }
- }
-
- if (!oss->mmapped) {
- oss->pcm_buf = audio_calloc (
- AUDIO_FUNC,
- hw->samples,
- 1 << hw->info.shift
- );
- if (!oss->pcm_buf) {
- dolog (
- "Could not allocate DAC buffer (%d samples, each %d bytes)\n",
- hw->samples,
- 1 << hw->info.shift
- );
- oss_anal_close (&fd);
- return -1;
- }
- }
-
- oss->fd = fd;
- return 0;
-}
-
-static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- int trig;
- OSSVoiceOut *oss = (OSSVoiceOut *) hw;
-
- if (!oss->mmapped) {
- return 0;
- }
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (
- errno,
- "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- );
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- trig = 0;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
- return -1;
- }
- break;
- }
- return 0;
-}
-
-static int oss_init_in (HWVoiceIn *hw, audsettings_t *as)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
- struct oss_params req, obt;
- int endianness;
- int err;
- int fd;
- audfmt_e effective_fmt;
- audsettings_t obt_as;
-
- oss->fd = -1;
-
- req.fmt = aud_to_ossfmt (as->fmt);
- req.freq = as->freq;
- req.nchannels = as->nchannels;
- req.fragsize = conf.fragsize;
- req.nfrags = conf.nfrags;
- if (oss_open (1, &req, &obt, &fd)) {
- return -1;
- }
-
- err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
- if (err) {
- oss_anal_close (&fd);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.nchannels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianness;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- oss->nfrags = obt.nfrags;
- oss->fragsize = obt.fragsize;
-
- if (obt.nfrags * obt.fragsize & hw->info.align) {
- dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",
- obt.nfrags * obt.fragsize, hw->info.align + 1);
- }
-
- hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
- oss->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!oss->pcm_buf) {
- dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
- hw->samples, 1 << hw->info.shift);
- oss_anal_close (&fd);
- return -1;
- }
-
- oss->fd = fd;
- return 0;
-}
-
-static void oss_fini_in (HWVoiceIn *hw)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
-
- oss_anal_close (&oss->fd);
-
- if (oss->pcm_buf) {
- qemu_free (oss->pcm_buf);
- oss->pcm_buf = NULL;
- }
-}
-
-static int oss_run_in (HWVoiceIn *hw)
-{
- OSSVoiceIn *oss = (OSSVoiceIn *) hw;
- int hwshift = hw->info.shift;
- int i;
- int live = audio_pcm_hw_get_live_in (hw);
- int dead = hw->samples - live;
- size_t read_samples = 0;
- struct {
- int add;
- int len;
- } bufs[2] = {
- { hw->wpos, 0 },
- { 0, 0 }
- };
-
- if (!dead) {
- return 0;
- }
-
- if (hw->wpos + dead > hw->samples) {
- bufs[0].len = (hw->samples - hw->wpos) << hwshift;
- bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift;
- }
- else {
- bufs[0].len = dead << hwshift;
- }
-
-
- for (i = 0; i < 2; ++i) {
- ssize_t nread;
-
- if (bufs[i].len) {
- void *p = advance (oss->pcm_buf, bufs[i].add << hwshift);
- nread = read (oss->fd, p, bufs[i].len);
-
- if (nread > 0) {
- if (nread & hw->info.align) {
- dolog ("warning: Misaligned read %zd (requested %d), "
- "alignment %d\n", nread, bufs[i].add << hwshift,
- hw->info.align + 1);
- }
- read_samples += nread >> hwshift;
- hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift,
- &nominal_volume);
- }
-
- if (bufs[i].len - nread) {
- if (nread == -1) {
- switch (errno) {
- case EINTR:
- case EAGAIN:
- break;
- default:
- oss_logerr (
- errno,
- "Failed to read %d bytes of audio (to %p)\n",
- bufs[i].len, p
- );
- break;
- }
- }
- break;
- }
- }
- }
-
- hw->wpos = (hw->wpos + read_samples) % hw->samples;
- return read_samples;
-}
-
-static int oss_read (SWVoiceIn *sw, void *buf, int size)
-{
- return audio_pcm_sw_read (sw, buf, size);
-}
-
-static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static void *oss_audio_init (void)
-{
- return &conf;
-}
-
-static void oss_audio_fini (void *opaque)
-{
- (void) opaque;
-}
-
-static struct audio_option oss_options[] = {
- {"FRAGSIZE", AUD_OPT_INT, &conf.fragsize,
- "Fragment size in bytes", NULL, 0},
- {"NFRAGS", AUD_OPT_INT, &conf.nfrags,
- "Number of fragments", NULL, 0},
- {"MMAP", AUD_OPT_BOOL, &conf.try_mmap,
- "Try using memory mapped access", NULL, 0},
- {"DAC_DEV", AUD_OPT_STR, &conf.devpath_out,
- "Path to DAC device", NULL, 0},
- {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in,
- "Path to ADC device", NULL, 0},
- {"DEBUG", AUD_OPT_BOOL, &conf.debug,
- "Turn on some debugging messages", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops oss_pcm_ops = {
- oss_init_out,
- oss_fini_out,
- oss_run_out,
- oss_write,
- oss_ctl_out,
-
- oss_init_in,
- oss_fini_in,
- oss_run_in,
- oss_read,
- oss_ctl_in
-};
-
-struct audio_driver oss_audio_driver = {
- INIT_FIELD (name = ) "oss",
- INIT_FIELD (descr = ) "OSS audio (www.opensound.com)",
- INIT_FIELD (options = ) oss_options,
- INIT_FIELD (init = ) oss_audio_init,
- INIT_FIELD (fini = ) oss_audio_fini,
- INIT_FIELD (pcm_ops = ) &oss_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) INT_MAX,
- INIT_FIELD (max_voices_in = ) INT_MAX,
- INIT_FIELD (voice_size_out = ) sizeof (OSSVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (OSSVoiceIn)
-};
diff --git a/audio/rate_template.h b/audio/rate_template.h
deleted file mode 100644
index 398d305..0000000
--- a/audio/rate_template.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- * Copyright (c) 1998 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-void NAME (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp)
-{
- struct rate *rate = opaque;
- st_sample_t *istart, *iend;
- st_sample_t *ostart, *oend;
- st_sample_t ilast, icur, out;
-#ifdef FLOAT_MIXENG
- real_t t;
-#else
- int64_t t;
-#endif
-
- ilast = rate->ilast;
-
- istart = ibuf;
- iend = ibuf + *isamp;
-
- ostart = obuf;
- oend = obuf + *osamp;
-
- if (rate->opos_inc == (1ULL + UINT_MAX)) {
- int i, n = *isamp > *osamp ? *osamp : *isamp;
- for (i = 0; i < n; i++) {
- OP (obuf[i].l, ibuf[i].l);
- OP (obuf[i].r, ibuf[i].r);
- }
- *isamp = n;
- *osamp = n;
- return;
- }
-
- while (obuf < oend) {
-
- /* Safety catch to make sure we have input samples. */
- if (ibuf >= iend) {
- break;
- }
-
- /* read as many input samples so that ipos > opos */
-
- while (rate->ipos <= (rate->opos >> 32)) {
- ilast = *ibuf++;
- rate->ipos++;
- /* See if we finished the input buffer yet */
- if (ibuf >= iend) {
- goto the_end;
- }
- }
-
- icur = *ibuf;
-
- /* interpolate */
-#ifdef FLOAT_MIXENG
-#ifdef RECIPROCAL
- t = (rate->opos & UINT_MAX) * (1.f / UINT_MAX);
-#else
- t = (rate->opos & UINT_MAX) / (real_t) UINT_MAX;
-#endif
- out.l = (ilast.l * (1.0 - t)) + icur.l * t;
- out.r = (ilast.r * (1.0 - t)) + icur.r * t;
-#else
- t = rate->opos & 0xffffffff;
- out.l = (ilast.l * ((int64_t) UINT_MAX - t) + icur.l * t) >> 32;
- out.r = (ilast.r * ((int64_t) UINT_MAX - t) + icur.r * t) >> 32;
-#endif
-
- /* output sample & increment position */
- OP (obuf->l, out.l);
- OP (obuf->r, out.r);
- obuf += 1;
- rate->opos += rate->opos_inc;
- }
-
-the_end:
- *isamp = ibuf - istart;
- *osamp = obuf - ostart;
- rate->ilast = ilast;
-}
-
-#undef NAME
-#undef OP
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
deleted file mode 100644
index ea5bccd..0000000
--- a/audio/sdlaudio.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * QEMU SDL audio driver
- *
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <SDL.h>
-#include <SDL_thread.h>
-
-#ifndef _WIN32
-#ifdef __sun__
-#define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-#include <signal.h>
-#endif
-
-#define AUDIO_CAP "sdl"
-#include "audio_int.h"
-
-/* define DEBUG to 1 to dump audio debugging info at runtime to stderr */
-#define DEBUG 0
-
-/* define NEW_AUDIO to 1 to activate the new audio thread callback */
-#define NEW_AUDIO 1
-
-#if DEBUG
-# define D(...) fprintf(stderr, __VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-static struct {
- int nb_samples;
-} conf = {
- 1024
-};
-
-#if DEBUG
-int64_t start_time;
-#endif
-
-#if NEW_AUDIO
-
-#define AUDIO_BUFFER_SIZE (8192)
-
-typedef HWVoiceOut SDLVoiceOut;
-
-struct SDLAudioState {
- int exit;
- SDL_mutex* mutex;
- int initialized;
- uint8_t data[ AUDIO_BUFFER_SIZE ];
- int pos, count;
-} glob_sdl;
-#else /* !NEW_AUDIO */
-
-typedef struct SDLVoiceOut {
- HWVoiceOut hw;
- int live;
- int rpos;
- int decr;
-} SDLVoiceOut;
-
-struct SDLAudioState {
- int exit;
- SDL_mutex *mutex;
- SDL_sem *sem;
- int initialized;
-} glob_sdl;
-
-#endif /* !NEW_AUDIO */
-
-typedef struct SDLAudioState SDLAudioState;
-
-static void GCC_FMT_ATTR (1, 2) sdl_logerr (const char *fmt, ...)
-{
- va_list ap;
-
- va_start (ap, fmt);
- AUD_vlog (AUDIO_CAP, fmt, ap);
- va_end (ap);
-
- AUD_log (AUDIO_CAP, "Reason: %s\n", SDL_GetError ());
-}
-
-static int sdl_lock (SDLAudioState *s, const char *forfn)
-{
- if (SDL_LockMutex (s->mutex)) {
- sdl_logerr ("SDL_LockMutex for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock (SDLAudioState *s, const char *forfn)
-{
- if (SDL_UnlockMutex (s->mutex)) {
- sdl_logerr ("SDL_UnlockMutex for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-#if !NEW_AUDIO
-static int sdl_post (SDLAudioState *s, const char *forfn)
-{
- if (SDL_SemPost (s->sem)) {
- sdl_logerr ("SDL_SemPost for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_wait (SDLAudioState *s, const char *forfn)
-{
- if (SDL_SemWait (s->sem)) {
- sdl_logerr ("SDL_SemWait for %s failed\n", forfn);
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)
-{
- if (sdl_unlock (s, forfn)) {
- return -1;
- }
-
- return sdl_post (s, forfn);
-}
-#endif
-
-static int aud_to_sdlfmt (audfmt_e fmt, int *shift)
-{
- switch (fmt) {
- case AUD_FMT_S8:
- *shift = 0;
- return AUDIO_S8;
-
- case AUD_FMT_U8:
- *shift = 0;
- return AUDIO_U8;
-
- case AUD_FMT_S16:
- *shift = 1;
- return AUDIO_S16LSB;
-
- case AUD_FMT_U16:
- *shift = 1;
- return AUDIO_U16LSB;
-
- default:
- dolog ("Internal logic error: Bad audio format %d\n", fmt);
-#ifdef DEBUG_AUDIO
- abort ();
-#endif
- return AUDIO_U8;
- }
-}
-
-static int sdl_to_audfmt (int sdlfmt, audfmt_e *fmt, int *endianess)
-{
- switch (sdlfmt) {
- case AUDIO_S8:
- *endianess = 0;
- *fmt = AUD_FMT_S8;
- break;
-
- case AUDIO_U8:
- *endianess = 0;
- *fmt = AUD_FMT_U8;
- break;
-
- case AUDIO_S16LSB:
- *endianess = 0;
- *fmt = AUD_FMT_S16;
- break;
-
- case AUDIO_U16LSB:
- *endianess = 0;
- *fmt = AUD_FMT_U16;
- break;
-
- case AUDIO_S16MSB:
- *endianess = 1;
- *fmt = AUD_FMT_S16;
- break;
-
- case AUDIO_U16MSB:
- *endianess = 1;
- *fmt = AUD_FMT_U16;
- break;
-
- default:
- dolog ("Unrecognized SDL audio format %d\n", sdlfmt);
- return -1;
- }
-
- return 0;
-}
-
-static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
-{
- int status;
-#ifndef _WIN32
- sigset_t new, old;
-
- /* Make sure potential threads created by SDL don't hog signals. */
- sigfillset (&new);
- pthread_sigmask (SIG_BLOCK, &new, &old);
-#endif
-
- status = SDL_OpenAudio (req, obt);
- if (status) {
- sdl_logerr ("SDL_OpenAudio failed\n");
- }
-#ifndef _WIN32
- pthread_sigmask (SIG_SETMASK, &old, 0);
-#endif
- return status;
-}
-
-static void sdl_close (SDLAudioState *s)
-{
- if (s->initialized) {
- sdl_lock (s, "sdl_close");
- s->exit = 1;
-#if NEW_AUDIO
- sdl_unlock (s, "sdl_close");
-#else
- sdl_unlock_and_post (s, "sdl_close");
-#endif
- SDL_PauseAudio (1);
- SDL_CloseAudio ();
- s->initialized = 0;
- }
-}
-
-#if NEW_AUDIO
-
-static void sdl_callback (void *opaque, Uint8 *buf, int len)
-{
-#if DEBUG
- int64_t now;
-#endif
- SDLAudioState *s = &glob_sdl;
-
- if (s->exit) {
- return;
- }
-
- sdl_lock (s, "sdl_callback");
-#if DEBUG
- if (s->count > 0) {
- now = qemu_get_clock(vm_clock);
- if (start_time == 0)
- start_time = now;
- now = now - start_time;
- D( "R %6.3f: pos:%5d count:%5d len:%5d\n", now/1e9, s->pos, s->count, len );
- }
-#endif
- while (len > 0) {
- int avail = audio_MIN( AUDIO_BUFFER_SIZE - s->pos, s->count );
-
- if (avail == 0)
- break;
-
- if (avail > len)
- avail = len;
-
- memcpy( buf, s->data + s->pos, avail );
- buf += avail;
- len -= avail;
-
- s->count -= avail;
- s->pos += avail;
- if (s->pos == AUDIO_BUFFER_SIZE)
- s->pos = 0;
- }
- sdl_unlock (s, "sdl_callback");
-}
-
-#else /* !NEW_AUDIO */
-static void sdl_callback (void *opaque, Uint8 *buf, int len)
-{
- SDLVoiceOut *sdl = opaque;
- SDLAudioState *s = &glob_sdl;
- HWVoiceOut *hw = &sdl->hw;
- int samples = len >> hw->info.shift;
-
- if (s->exit) {
- return;
- }
-
- while (samples) {
- int to_mix, decr;
-
- /* dolog ("in callback samples=%d\n", samples); */
- sdl_wait (s, "sdl_callback");
- if (s->exit) {
- return;
- }
-
- if (sdl_lock (s, "sdl_callback")) {
- return;
- }
-
- if (audio_bug (AUDIO_FUNC, sdl->live < 0 || sdl->live > hw->samples)) {
- dolog ("sdl->live=%d hw->samples=%d\n",
- sdl->live, hw->samples);
- return;
- }
-
- if (!sdl->live) {
- goto again;
- }
-
- /* dolog ("in callback live=%d\n", live); */
- to_mix = audio_MIN (samples, sdl->live);
- decr = to_mix;
- while (to_mix) {
- int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
- st_sample_t *src = hw->mix_buf + hw->rpos;
-
- /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
- hw->clip (buf, src, chunk);
- sdl->rpos = (sdl->rpos + chunk) % hw->samples;
- to_mix -= chunk;
- buf += chunk << hw->info.shift;
- }
- samples -= decr;
- sdl->live -= decr;
- sdl->decr += decr;
-
- again:
- if (sdl_unlock (s, "sdl_callback")) {
- return;
- }
- }
- /* dolog ("done len=%d\n", len); */
-}
-#endif /* !NEW_AUDIO */
-
-static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-#if NEW_AUDIO
-
-static int sdl_run_out (HWVoiceOut *hw)
-{
- SDLAudioState *s = &glob_sdl;
- int live, avail, end, total;
-
- if (sdl_lock (s, "sdl_run_out")) {
- return 0;
- }
- avail = AUDIO_BUFFER_SIZE - s->count;
- end = s->pos + s->count;
- if (end >= AUDIO_BUFFER_SIZE)
- end -= AUDIO_BUFFER_SIZE;
- sdl_unlock (s, "sdl_run_out");
-
- live = audio_pcm_hw_get_live_out (hw);
-
- total = 0;
- while (live > 0) {
- int bytes = audio_MIN(AUDIO_BUFFER_SIZE - end, avail);
- int samples = bytes >> hw->info.shift;
- int hwsamples = audio_MIN(hw->samples - hw->rpos, live);
- uint8_t* dst = s->data + end;
- st_sample_t* src = hw->mix_buf + hw->rpos;
-
- if (samples == 0)
- break;
-
- if (samples > hwsamples) {
- samples = hwsamples;
- bytes = hwsamples << hw->info.shift;
- }
-
- hw->clip (dst, src, samples);
- hw->rpos += samples;
- if (hw->rpos == hw->samples)
- hw->rpos = 0;
-
- live -= samples;
- avail -= bytes;
- end += bytes;
- if (end == AUDIO_BUFFER_SIZE)
- end = 0;
-
- total += bytes;
- }
-
- sdl_lock (s, "sdl_run_out");
- s->count += total;
- sdl_unlock (s, "sdl_run_out");
-
- return total >> hw->info.shift;
-}
-
-#else /* !NEW_AUDIO */
-static int sdl_run_out (HWVoiceOut *hw)
-{
- int decr, live;
- SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
- SDLAudioState *s = &glob_sdl;
-
- if (sdl_lock (s, "sdl_callback")) {
- return 0;
- }
-
- live = audio_pcm_hw_get_live_out (hw);
-
- if (sdl->decr > live) {
- ldebug ("sdl->decr %d live %d sdl->live %d\n",
- sdl->decr,
- live,
- sdl->live);
- }
-
- decr = audio_MIN (sdl->decr, live);
- sdl->decr -= decr;
-
- sdl->live = live - decr;
- hw->rpos = sdl->rpos;
-
- if (sdl->live > 0) {
- sdl_unlock_and_post (s, "sdl_callback");
- }
- else {
- sdl_unlock (s, "sdl_callback");
- }
- return decr;
-}
-#endif /* !NEW_AUDIO */
-
-static void sdl_fini_out (HWVoiceOut *hw)
-{
- (void) hw;
-
- sdl_close (&glob_sdl);
-}
-
-#if DEBUG
-
-typedef struct { int value; const char* name; } MatchRec;
-typedef const MatchRec* Match;
-
-static const char*
-match_find( Match matches, int value, char* temp )
-{
- int nn;
- for ( nn = 0; matches[nn].name != NULL; nn++ ) {
- if ( matches[nn].value == value )
- return matches[nn].name;
- }
- sprintf( temp, "(%d?)", value );
- return temp;
-}
-
-static const MatchRec sdl_audio_format_matches[] = {
- { AUDIO_U8, "AUDIO_U8" },
- { AUDIO_S8, "AUDIO_S8" },
- { AUDIO_U16, "AUDIO_U16LE" },
- { AUDIO_S16, "AUDIO_S16LE" },
- { AUDIO_U16MSB, "AUDIO_U16BE" },
- { AUDIO_S16MSB, "AUDIO_S16BE" },
- { 0, NULL }
-};
-
-static void
-print_sdl_audiospec( SDL_AudioSpec* spec, const char* prefix )
-{
- char temp[64];
- const char* fmt;
-
- if (!prefix)
- prefix = "";
-
- printf( "%s audiospec [freq:%d format:%s channels:%d samples:%d bytes:%d",
- prefix,
- spec->freq,
- match_find( sdl_audio_format_matches, spec->format, temp ),
- spec->channels,
- spec->samples,
- spec->size
- );
- printf( "]\n" );
-}
-#endif
-
-static int sdl_init_out (HWVoiceOut *hw, audsettings_t *as)
-{
- SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
- SDLAudioState *s = &glob_sdl;
- SDL_AudioSpec req, obt;
- int shift;
- int endianess;
- int err;
- audfmt_e effective_fmt;
- audsettings_t obt_as;
-
- shift <<= as->nchannels == 2;
-
- req.freq = as->freq;
- req.format = aud_to_sdlfmt (as->fmt, &shift);
- req.channels = as->nchannels;
- req.samples = conf.nb_samples;
- req.callback = sdl_callback;
- req.userdata = sdl;
-
-#if DEBUG
- print_sdl_audiospec( &req, "wanted" );
-#endif
-
- if (sdl_open (&req, &obt)) {
- return -1;
- }
-
-#if DEBUG
- print_sdl_audiospec( &req, "obtained" );
-#endif
-
- err = sdl_to_audfmt (obt.format, &effective_fmt, &endianess);
- if (err) {
- sdl_close (s);
- return -1;
- }
-
- obt_as.freq = obt.freq;
- obt_as.nchannels = obt.channels;
- obt_as.fmt = effective_fmt;
- obt_as.endianness = endianess;
-
- audio_pcm_init_info (&hw->info, &obt_as);
- hw->samples = obt.samples;
-
-#if DEBUG
- start_time = qemu_get_clock(vm_clock);
-#endif
-
- s->initialized = 1;
- s->exit = 0;
- SDL_PauseAudio (0);
- return 0;
-}
-
-static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- SDL_PauseAudio (0);
- break;
-
- case VOICE_DISABLE:
- SDL_PauseAudio (1);
- break;
- }
- return 0;
-}
-
-static void *sdl_audio_init (void)
-{
- SDLAudioState *s = &glob_sdl;
-
- if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
- sdl_logerr ("SDL failed to initialize audio subsystem\n");
- return NULL;
- }
-
- s->mutex = SDL_CreateMutex ();
- if (!s->mutex) {
- sdl_logerr ("Failed to create SDL mutex\n");
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-#if !NEW_AUDIO
- s->sem = SDL_CreateSemaphore (0);
- if (!s->sem) {
- sdl_logerr ("Failed to create SDL semaphore\n");
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-#endif
- return s;
-}
-
-static void sdl_audio_fini (void *opaque)
-{
- SDLAudioState *s = opaque;
- sdl_close (s);
-#if !NEW_AUDIO
- if (s->sem) {
- SDL_DestroySemaphore (s->sem);
- s->sem = NULL;
- }
-#endif
- if (s->mutex) {
- SDL_DestroyMutex (s->mutex);
- s->mutex = NULL;
- }
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
-}
-
-static struct audio_option sdl_options[] = {
- {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
- "Size of SDL buffer in samples", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops sdl_pcm_ops = {
- sdl_init_out,
- sdl_fini_out,
- sdl_run_out,
- sdl_write_out,
- sdl_ctl_out,
-
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-struct audio_driver sdl_audio_driver = {
- INIT_FIELD (name = ) "sdl",
- INIT_FIELD (descr = ) "SDL audio (www.libsdl.org)",
- INIT_FIELD (options = ) sdl_options,
- INIT_FIELD (init = ) sdl_audio_init,
- INIT_FIELD (fini = ) sdl_audio_fini,
- INIT_FIELD (pcm_ops = ) &sdl_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (max_voices_in = ) 0,
- INIT_FIELD (voice_size_out = ) sizeof (SDLVoiceOut),
- INIT_FIELD (voice_size_in = ) 0
-};
diff --git a/audio/sys-queue.h b/audio/sys-queue.h
deleted file mode 100644
index 5b6e2a0..0000000
--- a/audio/sys-queue.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)queue.h 8.3 (Berkeley) 12/13/93
- */
-
-#ifndef _SYS_QUEUE_H
-#define _SYS_QUEUE_H 1
-
-/*
- * This file defines three types of data structures: lists, tail queues,
- * and circular queues.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list after
- * an existing element or at the head of the list. A list may only be
- * traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list after
- * an existing element, at the head of the list, or at the end of the
- * list. A tail queue may only be traversed in the forward direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) { \
- (head)->lh_first = NULL; \
-}
-
-#define LIST_INSERT_AFTER(listelm, elm, field) { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-}
-
-#define LIST_INSERT_HEAD(head, elm, field) { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-}
-
-#define LIST_REMOVE(elm, field) { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-}
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-}
-
-#define TAILQ_INSERT_HEAD(head, elm, field) { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-}
-
-#define TAILQ_INSERT_TAIL(head, elm, field) { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-}
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-}
-
-#define TAILQ_REMOVE(head, elm, field) { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-}
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-}
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-}
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-}
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-}
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-}
-
-#define CIRCLEQ_REMOVE(head, elm, field) { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-}
-#endif /* sys/queue.h */
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
deleted file mode 100644
index 8a500b9..0000000
--- a/audio/wavaudio.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * QEMU WAV audio driver
- *
- * Copyright (c) 2007 The Android Open Source Project
- * Copyright (c) 2004-2005 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define AUDIO_CAP "wav"
-#include "qemu-timer.h"
-#include "audio_int.h"
-#include "qemu_file.h"
-
-#define WAV_AUDIO_IN 1
-
-/** VOICE OUT (Saving to a .WAV file)
- **/
-typedef struct WAVVoiceOut {
- HWVoiceOut hw;
- QEMUFile *f;
- int64_t old_ticks;
- void *pcm_buf;
- int total_samples;
-} WAVVoiceOut;
-
-static struct {
- audsettings_t settings;
- const char *wav_path;
-} conf_out = {
- {
- 44100,
- 2,
- AUD_FMT_S16,
- 0
- },
- "qemu.wav"
-};
-
-static int wav_out_run (HWVoiceOut *hw)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- int rpos, live, decr, samples;
- uint8_t *dst;
- st_sample_t *src;
- int64_t now = qemu_get_clock (vm_clock);
- int64_t ticks = now - wav->old_ticks;
- int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
-
- if (bytes > INT_MAX) {
- samples = INT_MAX >> hw->info.shift;
- }
- else {
- samples = bytes >> hw->info.shift;
- }
-
- live = audio_pcm_hw_get_live_out (hw);
- if (!live) {
- return 0;
- }
-
- wav->old_ticks = now;
- decr = audio_MIN (live, samples);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = hw->mix_buf + rpos;
- dst = advance (wav->pcm_buf, rpos << hw->info.shift);
-
- hw->clip (dst, src, convert_samples);
- qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- wav->total_samples += convert_samples;
- }
-
- hw->rpos = rpos;
- return decr;
-}
-
-static int wav_out_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-/* VICE code: Store number as little endian. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-static int wav_out_init (HWVoiceOut *hw, audsettings_t *as)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- int bits16 = 0, stereo = 0;
- uint8_t hdr[] = {
- 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
- 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
- 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
- };
- audsettings_t wav_as = conf_out.settings;
-
- (void) as;
-
- stereo = wav_as.nchannels == 2;
- switch (wav_as.fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- bits16 = 0;
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- bits16 = 1;
- break;
-
- case AUD_FMT_S32:
- case AUD_FMT_U32:
- dolog ("WAVE files can not handle 32bit formats\n");
- return -1;
- }
-
- hdr[34] = bits16 ? 0x10 : 0x08;
-
- wav_as.endianness = 0;
- audio_pcm_init_info (&hw->info, &wav_as);
-
- hw->samples = 1024;
- wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!wav->pcm_buf) {
- dolog ("Could not allocate buffer (%d bytes)\n",
- hw->samples << hw->info.shift);
- return -1;
- }
-
- le_store (hdr + 22, hw->info.nchannels, 2);
- le_store (hdr + 24, hw->info.freq, 4);
- le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
- le_store (hdr + 32, 1 << (bits16 + stereo), 2);
-
- wav->f = qemu_fopen (conf_out.wav_path, "wb");
- if (!wav->f) {
- dolog ("Failed to open wave file `%s'\nReason: %s\n",
- conf_out.wav_path, strerror (errno));
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
- return -1;
- }
-
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
- return 0;
-}
-
-static void wav_out_fini (HWVoiceOut *hw)
-{
- WAVVoiceOut *wav = (WAVVoiceOut *) hw;
- uint8_t rlen[4];
- uint8_t dlen[4];
- uint32_t datalen = wav->total_samples << hw->info.shift;
- uint32_t rifflen = datalen + 36;
-
- if (!wav->f) {
- return;
- }
-
- le_store (rlen, rifflen, 4);
- le_store (dlen, datalen, 4);
-
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
-
- qemu_fclose (wav->f);
- wav->f = NULL;
-
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
-}
-
-static int wav_out_ctl (HWVoiceOut *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-
-#if WAV_AUDIO_IN
-
-/** WAV IN (Reading from a .WAV file)
- **/
-
- static struct {
- const char *wav_path;
-} conf_in = {
- "qemu.wav"
-};
-
-typedef struct WAVVoiceIn {
- HWVoiceIn hw;
- QEMUFile* f;
- int64_t old_ticks;
- void* pcm_buf;
- int total_samples;
- int total_size;
-} WAVVoiceIn;
-
-
-static int
-le_read( const uint8_t* p, int size ) {
- int shift = 0;
- int result = 0;
- for ( ; size > 0; size-- ) {
- result = result | (p[0] << shift);
- p += 1;
- shift += 8;
- }
- return result;
-}
-
-static int
-wav_in_init (HWVoiceIn *hw, audsettings_t *as)
-{
- WAVVoiceIn* wav = (WAVVoiceIn *) hw;
- const char* path = conf_in.wav_path;
- uint8_t hdr[44];
- audsettings_t wav_as = *as;
- int nchannels, freq, format, bits;
-
- wav->f = qemu_fopen (path, "rb");
- if (wav->f == NULL) {
- dolog("Failed to open wave file '%s'\nReason: %s\n", path,
- strerror(errno));
- return -1;
- }
-
- if (qemu_get_buffer (wav->f, hdr, sizeof(hdr)) != (int)sizeof(hdr)) {
- dolog("File '%s' to be a .wav file\n", path);
- goto Fail;
- }
-
- /* check that this is a wave file */
- if ( hdr[0] != 'R' || hdr[1] != 'I' || hdr[2] != 'F' || hdr[3] != 'F' ||
- hdr[8] != 'W' || hdr[9] != 'A' || hdr[10]!= 'V' || hdr[11]!= 'E' ||
- hdr[12]!= 'f' || hdr[13]!= 'm' || hdr[14]!= 't' || hdr[15]!= ' ' ||
- hdr[40]!= 'd' || hdr[41]!= 'a' || hdr[42]!= 't' || hdr[43]!= 'a') {
- dolog("File '%s' is not a valid .wav file\n", path);
- goto Fail;
- }
-
- nchannels = le_read( hdr+22, 2 );
- freq = le_read( hdr+24, 4 );
- format = le_read( hdr+32, 2 );
- bits = le_read( hdr+34, 2 );
-
- wav->total_size = le_read( hdr+40, 4 );
-
- /* perform some sainty checks */
- switch (nchannels) {
- case 1:
- case 2: break;
- default:
- dolog("unsupported number of channels (%d) in '%s'\n",
- nchannels, path);
- goto Fail;
- }
-
- switch (format) {
- case 1:
- case 2:
- case 4: break;
- default:
- dolog("unsupported bytes per sample (%d) in '%s'\n",
- format, path);
- goto Fail;
- }
-
- if (format*8/nchannels != bits) {
- dolog("invalid bits per sample (%d, expected %d) in '%s'\n",
- bits, format*8/nchannels, path);
- goto Fail;
- }
-
- wav_as.nchannels = nchannels;
- wav_as.fmt = (bits == 8) ? AUD_FMT_U8 : AUD_FMT_S16;
- wav_as.freq = freq;
- wav_as.endianness = 0; /* always little endian */
-
- audio_pcm_init_info (&hw->info, &wav_as);
-
- hw->samples = 1024;
- wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
- if (!wav->pcm_buf) {
- goto Fail;
- }
- return 0;
-
-Fail:
- qemu_fclose (wav->f);
- wav->f = NULL;
- return -1;
-}
-
-
-static void wav_in_fini (HWVoiceIn *hw)
-{
- WAVVoiceIn *wav = (WAVVoiceIn *) hw;
-
- if (!wav->f) {
- return;
- }
-
- qemu_fclose (wav->f);
- wav->f = NULL;
-
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
-}
-
-static int wav_in_run (HWVoiceIn *hw)
-{
- WAVVoiceIn* wav = (WAVVoiceIn *) hw;
- int wpos, live, decr, samples;
- uint8_t* src;
- st_sample_t* dst;
-
- int64_t now = qemu_get_clock (vm_clock);
- int64_t ticks = now - wav->old_ticks;
- int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
-
- if (bytes > INT_MAX) {
- samples = INT_MAX >> hw->info.shift;
- }
- else {
- samples = bytes >> hw->info.shift;
- }
-
- live = audio_pcm_hw_get_live_in (hw);
- if (!live) {
- return 0;
- }
-
- wav->old_ticks = now;
-
- decr = audio_MIN (live, samples);
- samples = decr;
- wpos = hw->wpos;
- while (samples) {
- int left_till_end_samples = hw->samples - wpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- dst = hw->conv_buf + wpos;
- src = advance (wav->pcm_buf, wpos << hw->info.shift);
-
- qemu_get_buffer (wav->f, src, convert_samples << hw->info.shift);
- memcpy (dst, src, convert_samples << hw->info.shift);
-
- wpos = (wpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- wav->total_samples += convert_samples;
- }
-
- hw->wpos = wpos;
- return decr;
-}
-
-static int wav_in_read (SWVoiceIn *sw, void *buf, int len)
-{
- return audio_pcm_sw_read (sw, buf, len);
-}
-
-static int wav_in_ctl (HWVoiceIn *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-#endif /* WAV_AUDIO_IN */
-
-/** COMMON CODE
- **/
-static void *wav_audio_init (void)
-{
- return &conf_out;
-}
-
-static void wav_audio_fini (void *opaque)
-{
- (void) opaque;
- ldebug ("wav_fini");
-}
-
-struct audio_option wav_options[] = {
- {"FREQUENCY", AUD_OPT_INT, &conf_out.settings.freq,
- "Frequency", NULL, 0},
-
- {"FORMAT", AUD_OPT_FMT, &conf_out.settings.fmt,
- "Format", NULL, 0},
-
- {"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf_out.settings.nchannels,
- "Number of channels (1 - mono, 2 - stereo)", NULL, 0},
-
- {"PATH", AUD_OPT_STR, &conf_out.wav_path,
- "Path to output .wav file", NULL, 0},
-
-#if WAV_AUDIO_IN
- {"IN_PATH", AUD_OPT_STR, &conf_in.wav_path,
- "Path to input .wav file", NULL, 0},
-#endif
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-struct audio_pcm_ops wav_pcm_ops = {
- wav_out_init,
- wav_out_fini,
- wav_out_run,
- wav_out_write,
- wav_out_ctl,
-
-#if WAV_AUDIO_IN
- wav_in_init,
- wav_in_fini,
- wav_in_run,
- wav_in_read,
- wav_in_ctl
-#else
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-#endif
-};
-
-struct audio_driver wav_audio_driver = {
- INIT_FIELD (name = ) "wav",
- INIT_FIELD (descr = )
- "WAV file read/write (www.wikipedia.org/wiki/WAV)",
- INIT_FIELD (options = ) wav_options,
- INIT_FIELD (init = ) wav_audio_init,
- INIT_FIELD (fini = ) wav_audio_fini,
- INIT_FIELD (pcm_ops = ) &wav_pcm_ops,
- INIT_FIELD (can_be_default = ) 0,
-#if WAV_AUDIO_IN
- INIT_FIELD (max_voices_in = ) 1,
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (voice_size_out = ) sizeof (WAVVoiceOut),
- INIT_FIELD (voice_size_in = ) sizeof (WAVVoiceIn)
-#else
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (max_voices_in = ) 0,
- INIT_FIELD (voice_size_out = ) sizeof (WAVVoiceOut),
- INIT_FIELD (voice_size_in = ) 0
-#endif
-};
diff --git a/audio/wavcapture.c b/audio/wavcapture.c
deleted file mode 100644
index d6f733e..0000000
--- a/audio/wavcapture.c
+++ /dev/null
@@ -1,166 +0,0 @@
-#include "audio/audio.h"
-#include "qemu_file.h"
-#include "console.h"
-
-typedef struct {
- QEMUFile *f;
- int bytes;
- char *path;
- int freq;
- int bits;
- int nchannels;
- CaptureVoiceOut *cap;
-} WAVState;
-
-/* VICE code: Store number as little endian. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-static void wav_notify (void *opaque, audcnotification_e cmd)
-{
- (void) opaque;
- (void) cmd;
-}
-
-static void wav_destroy (void *opaque)
-{
- WAVState *wav = opaque;
- uint8_t rlen[4];
- uint8_t dlen[4];
- uint32_t datalen = wav->bytes;
- uint32_t rifflen = datalen + 36;
-
- if (!wav->f) {
- return;
- }
-
- le_store (rlen, rifflen, 4);
- le_store (dlen, datalen, 4);
-
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
- qemu_fclose (wav->f);
- if (wav->path) {
- qemu_free (wav->path);
- }
-}
-
-static void wav_capture (void *opaque, void *buf, int size)
-{
- WAVState *wav = opaque;
-
- qemu_put_buffer (wav->f, buf, size);
- wav->bytes += size;
-}
-
-static void wav_capture_destroy (void *opaque)
-{
- WAVState *wav = opaque;
-
- AUD_del_capture (wav->cap, wav);
-}
-
-static void wav_capture_info (void *opaque)
-{
- WAVState *wav = opaque;
- char *path = wav->path;
-
- term_printf ("Capturing audio(%d,%d,%d) to %s: %d bytes\n",
- wav->freq, wav->bits, wav->nchannels,
- path ? path : "<not available>", wav->bytes);
-}
-
-static struct capture_ops wav_capture_ops = {
- .destroy = wav_capture_destroy,
- .info = wav_capture_info
-};
-
-int wav_start_capture (CaptureState *s, const char *path, int freq,
- int bits, int nchannels)
-{
- WAVState *wav;
- uint8_t hdr[] = {
- 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
- 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
- 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
- };
- audsettings_t as;
- struct audio_capture_ops ops;
- int stereo, bits16, shift;
- CaptureVoiceOut *cap;
-
- if (bits != 8 && bits != 16) {
- term_printf ("incorrect bit count %d, must be 8 or 16\n", bits);
- return -1;
- }
-
- if (nchannels != 1 && nchannels != 2) {
- term_printf ("incorrect channel count %d, must be 1 or 2\n", bits);
- return -1;
- }
-
- stereo = nchannels == 2;
- bits16 = bits == 16;
-
- as.freq = freq;
- as.nchannels = 1 << stereo;
- as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
- as.endianness = 0;
-
- ops.notify = wav_notify;
- ops.capture = wav_capture;
- ops.destroy = wav_destroy;
-
- wav = qemu_mallocz (sizeof (*wav));
- if (!wav) {
- AUD_log ("wav", "Could not allocate memory (%zu bytes)", sizeof (*wav));
- return -1;
- }
-
- shift = bits16 + stereo;
- hdr[34] = bits16 ? 0x10 : 0x08;
-
- le_store (hdr + 22, as.nchannels, 2);
- le_store (hdr + 24, freq, 4);
- le_store (hdr + 28, freq << shift, 4);
- le_store (hdr + 32, 1 << shift, 2);
-
- wav->f = qemu_fopen (path, "wb");
- if (!wav->f) {
- term_printf ("Failed to open wave file `%s'\nReason: %s\n",
- path, strerror (errno));
- qemu_free (wav);
- return -1;
- }
-
- wav->path = qemu_strdup (path);
- wav->bits = bits;
- wav->nchannels = nchannels;
- wav->freq = freq;
-
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
-
- cap = AUD_add_capture (NULL, &as, &ops, wav);
- if (!cap) {
- term_printf ("Failed to add audio capture\n");
- qemu_free (wav->path);
- qemu_fclose (wav->f);
- qemu_free (wav);
- return -1;
- }
-
- wav->cap = cap;
- s->opaque = wav;
- s->ops = wav_capture_ops;
- return 0;
-}
diff --git a/audio/winaudio.c b/audio/winaudio.c
deleted file mode 100644
index 6e8daef..0000000
--- a/audio/winaudio.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * QEMU "simple" Windows audio driver
- *
- * Copyright (c) 2007 The Android Open Source Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <mmsystem.h>
-
-#define AUDIO_CAP "winaudio"
-#include "audio_int.h"
-
-/* define DEBUG to 1 to dump audio debugging info at runtime to stderr */
-#define DEBUG 0
-
-#if 1
-# define D_ACTIVE 1
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) do{ if (D_ACTIVE) printf(__VA_ARGS__); } while(0)
-#else
-# define D(...) ((void)0)
-#endif
-
-static struct {
- int nb_samples;
-} conf = {
- 1024
-};
-
-#if DEBUG
-int64_t start_time;
-int64_t last_time;
-#endif
-
-#define NUM_OUT_BUFFERS 8 /* must be at least 2 */
-
-/** COMMON UTILITIES
- **/
-
-#if DEBUG
-static void
-dump_mmerror( const char* func, MMRESULT error )
-{
- const char* reason = NULL;
-
- fprintf(stderr, "%s returned error: ", func);
- switch (error) {
- case MMSYSERR_ALLOCATED: reason="specified resource is already allocated"; break;
- case MMSYSERR_BADDEVICEID: reason="bad device id"; break;
- case MMSYSERR_NODRIVER: reason="no driver is present"; break;
- case MMSYSERR_NOMEM: reason="unable to allocate or lock memory"; break;
- case WAVERR_BADFORMAT: reason="unsupported waveform-audio format"; break;
- case WAVERR_SYNC: reason="device is synchronous"; break;
- default:
- fprintf(stderr, "unknown(%d)\n", error);
- }
- if (reason)
- fprintf(stderr, "%s\n", reason);
-}
-#else
-# define dump_mmerror(func,error) ((void)0)
-#endif
-
-
-/** AUDIO OUT
- **/
-
-typedef struct WinAudioOut {
- HWVoiceOut hw;
- HWAVEOUT waveout;
- int silence;
- CRITICAL_SECTION lock;
- unsigned char* buffer_bytes;
- WAVEHDR buffers[ NUM_OUT_BUFFERS ];
- int write_index; /* starting first writable buffer */
- int write_count; /* available writable buffers count */
- int write_pos; /* position in current writable buffer */
- int write_size; /* size in bytes of each buffer */
-} WinAudioOut;
-
-/* The Win32 callback that is called when a buffer has finished playing */
-static void CALLBACK
-winaudio_out_buffer_done (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
- DWORD dwParam1, DWORD dwParam2)
-{
- WinAudioOut* s = (WinAudioOut*) dwInstance;
-
- /* Only service "buffer done playing" messages */
- if ( uMsg != WOM_DONE )
- return;
-
- /* Signal that we are done playing a buffer */
- EnterCriticalSection( &s->lock );
- if (s->write_count < NUM_OUT_BUFFERS)
- s->write_count += 1;
- LeaveCriticalSection( &s->lock );
-}
-
-static int
-winaudio_out_write (SWVoiceOut *sw, void *buf, int len)
-{
- return audio_pcm_sw_write (sw, buf, len);
-}
-
-static void
-winaudio_out_fini (HWVoiceOut *hw)
-{
- WinAudioOut* s = (WinAudioOut*) hw;
- int i;
-
- if (s->waveout) {
- waveOutReset(s->waveout);
- s->waveout = 0;
- }
-
- for ( i=0; i<NUM_OUT_BUFFERS; ++i ) {
- if ( s->buffers[i].dwUser != 0xFFFF ) {
- waveOutUnprepareHeader(
- s->waveout, &s->buffers[i], sizeof(s->buffers[i]) );
- s->buffers[i].dwUser = 0xFFFF;
- }
- }
-
- if (s->buffer_bytes != NULL) {
- qemu_free(s->buffer_bytes);
- s->buffer_bytes = NULL;
- }
-
- if (s->waveout) {
- waveOutClose(s->waveout);
- s->waveout = NULL;
- }
-}
-
-
-static int
-winaudio_out_init (HWVoiceOut *hw, audsettings_t *as)
-{
- WinAudioOut* s = (WinAudioOut*) hw;
- MMRESULT result;
- WAVEFORMATEX format;
- int shift, i, samples_size;
-
- s->waveout = NULL;
- InitializeCriticalSection( &s->lock );
- for (i = 0; i < NUM_OUT_BUFFERS; i++) {
- s->buffers[i].dwUser = 0xFFFF;
- }
- s->buffer_bytes = NULL;
-
- /* compute desired wave output format */
- format.wFormatTag = WAVE_FORMAT_PCM;
- format.nChannels = as->nchannels;
- format.nSamplesPerSec = as->freq;
- format.nAvgBytesPerSec = as->freq*as->nchannels;
-
- s->silence = 0;
-
- switch (as->fmt) {
- case AUD_FMT_S8: shift = 0; break;
- case AUD_FMT_U8: shift = 0; s->silence = 0x80; break;
- case AUD_FMT_S16: shift = 1; break;
- case AUD_FMT_U16: shift = 1; s->silence = 0x8000; break;
- default:
- fprintf(stderr, "qemu: winaudio: Bad output audio format: %d\n",
- as->fmt);
- return -1;
- }
-
- format.nAvgBytesPerSec = (format.nSamplesPerSec & format.nChannels) << shift;
- format.nBlockAlign = format.nChannels << shift;
- format.wBitsPerSample = 8 << shift;
- format.cbSize = 0;
-
- /* open the wave out device */
- result = waveOutOpen( &s->waveout, WAVE_MAPPER, &format,
- (DWORD_PTR)winaudio_out_buffer_done, (DWORD_PTR) hw,
- CALLBACK_FUNCTION);
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror( "qemu: winaudio: waveOutOpen()", result);
- return -1;
- }
-
- samples_size = format.nBlockAlign * conf.nb_samples;
- s->buffer_bytes = qemu_malloc( NUM_OUT_BUFFERS * samples_size );
- if (s->buffer_bytes == NULL) {
- waveOutClose( s->waveout );
- s->waveout = NULL;
- fprintf(stderr, "not enough memory for Windows audio buffers\n");
- return -1;
- }
-
- for (i = 0; i < NUM_OUT_BUFFERS; i++) {
- memset( &s->buffers[i], 0, sizeof(s->buffers[i]) );
- s->buffers[i].lpData = (LPSTR)(s->buffer_bytes + i*samples_size);
- s->buffers[i].dwBufferLength = samples_size;
- s->buffers[i].dwFlags = WHDR_DONE;
-
- result = waveOutPrepareHeader( s->waveout, &s->buffers[i],
- sizeof(s->buffers[i]) );
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror("waveOutPrepareHeader()", result);
- return -1;
- }
- }
-
-#if DEBUG
- /* Check the sound device we retrieved */
- {
- WAVEOUTCAPS caps;
-
- result = waveOutGetDevCaps((UINT) s->waveout, &caps, sizeof(caps));
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror("waveOutGetDevCaps()", result);
- } else
- printf("Audio out device: %s\n", caps.szPname);
- }
-#endif
-
- audio_pcm_init_info (&hw->info, as);
- hw->samples = conf.nb_samples*2;
-
- s->write_index = 0;
- s->write_count = NUM_OUT_BUFFERS;
- s->write_pos = 0;
- s->write_size = samples_size;
- return 0;
-}
-
-
-static int
-winaudio_out_run (HWVoiceOut *hw)
-{
- WinAudioOut* s = (WinAudioOut*) hw;
- int played = 0;
- int has_buffer;
- int live = audio_pcm_hw_get_live_out (hw);
-
- if (!live) {
- return 0;
- }
-
- EnterCriticalSection( &s->lock );
- has_buffer = (s->write_count > 0);
- LeaveCriticalSection( &s->lock );
-
- if (has_buffer) {
- while (live > 0) {
- WAVEHDR* wav_buffer = s->buffers + s->write_index;
- int wav_bytes = (s->write_size - s->write_pos);
- int wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
- int hw_samples = audio_MIN(hw->samples - hw->rpos, live);
- st_sample_t* src = hw->mix_buf + hw->rpos;
- uint8_t* dst = (uint8_t*)wav_buffer->lpData + s->write_pos;
-
- if (wav_samples > hw_samples) {
- wav_samples = hw_samples;
- }
-
- wav_bytes = wav_samples << hw->info.shift;
-
- //D("run_out: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d rpos:%d hwsamples:%d\n", s->write_index,
- // s->write_pos, s->write_size, wav_samples, wav_bytes, live, hw->rpos, hw->samples);
- hw->clip (dst, src, wav_samples);
- hw->rpos += wav_samples;
- if (hw->rpos >= hw->samples)
- hw->rpos -= hw->samples;
-
- live -= wav_samples;
- played += wav_samples;
- s->write_pos += wav_bytes;
- if (s->write_pos == s->write_size) {
-#if xxDEBUG
- int64_t now = qemu_get_clock(vm_clock) - start_time;
- int64_t diff = now - last_time;
-
- D("run_out: (%7.3f:%7d):waveOutWrite buffer:%d\n",
- now/1e9, (now-last_time)/1e9, s->write_index);
- last_time = now;
-#endif
- waveOutWrite( s->waveout, wav_buffer, sizeof(*wav_buffer) );
- s->write_pos = 0;
- s->write_index += 1;
- if (s->write_index == NUM_OUT_BUFFERS)
- s->write_index = 0;
-
- EnterCriticalSection( &s->lock );
- if (--s->write_count == 0) {
- live = 0;
- }
- LeaveCriticalSection( &s->lock );
- }
- }
-
- }
- return played;
-}
-
-static int
-winaudio_out_ctl (HWVoiceOut *hw, int cmd, ...)
-{
- WinAudioOut* s = (WinAudioOut*) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- waveOutRestart( s->waveout );
- break;
-
- case VOICE_DISABLE:
- waveOutPause( s->waveout );
- break;
- }
- return 0;
-}
-
-/** AUDIO IN
- **/
-
-#define NUM_IN_BUFFERS 2
-
-typedef struct WinAudioIn {
- HWVoiceIn hw;
- HWAVEIN wavein;
- CRITICAL_SECTION lock;
- unsigned char* buffer_bytes;
- WAVEHDR buffers[ NUM_IN_BUFFERS ];
- int read_index;
- int read_count;
- int read_pos;
- int read_size;
-} WinAudioIn;
-
-/* The Win32 callback that is called when a buffer has finished playing */
-static void CALLBACK
-winaudio_in_buffer_done (HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
- DWORD dwParam1, DWORD dwParam2)
-{
- WinAudioIn* s = (WinAudioIn*) dwInstance;
-
- /* Only service "buffer done playing" messages */
- if ( uMsg != WIM_DATA )
- return;
-
- /* Signal that we are done playing a buffer */
- EnterCriticalSection( &s->lock );
- if (s->read_count < NUM_IN_BUFFERS)
- s->read_count += 1;
- //D(".%c",s->read_count + '0'); fflush(stdout);
- LeaveCriticalSection( &s->lock );
-}
-
-static void
-winaudio_in_fini (HWVoiceIn *hw)
-{
- WinAudioIn* s = (WinAudioIn*) hw;
- int i;
-
- if (s->wavein) {
- waveInReset(s->wavein);
- s->wavein = 0;
- }
-
- for ( i=0; i<NUM_OUT_BUFFERS; ++i ) {
- if ( s->buffers[i].dwUser != 0xFFFF ) {
- waveInUnprepareHeader(
- s->wavein, &s->buffers[i], sizeof(s->buffers[i]) );
- s->buffers[i].dwUser = 0xFFFF;
- }
- }
-
- if (s->buffer_bytes != NULL) {
- qemu_free(s->buffer_bytes);
- s->buffer_bytes = NULL;
- }
-
- if (s->wavein) {
- waveInClose(s->wavein);
- s->wavein = NULL;
- }
-}
-
-
-static int
-winaudio_in_init (HWVoiceIn *hw, audsettings_t *as)
-{
- WinAudioIn* s = (WinAudioIn*) hw;
- MMRESULT result;
- WAVEFORMATEX format;
- int shift, i, samples_size;
-
- s->wavein = NULL;
- InitializeCriticalSection( &s->lock );
- for (i = 0; i < NUM_OUT_BUFFERS; i++) {
- s->buffers[i].dwUser = 0xFFFF;
- }
- s->buffer_bytes = NULL;
-
- /* compute desired wave input format */
- format.wFormatTag = WAVE_FORMAT_PCM;
- format.nChannels = as->nchannels;
- format.nSamplesPerSec = as->freq;
- format.nAvgBytesPerSec = as->freq*as->nchannels;
-
- switch (as->fmt) {
- case AUD_FMT_S8: shift = 0; break;
- case AUD_FMT_U8: shift = 0; break;
- case AUD_FMT_S16: shift = 1; break;
- case AUD_FMT_U16: shift = 1; break;
- default:
- fprintf(stderr, "qemu: winaudio: Bad input audio format: %d\n",
- as->fmt);
- return -1;
- }
-
- format.nAvgBytesPerSec = (format.nSamplesPerSec * format.nChannels) << shift;
- format.nBlockAlign = format.nChannels << shift;
- format.wBitsPerSample = 8 << shift;
- format.cbSize = 0;
-
- /* open the wave in device */
- result = waveInOpen( &s->wavein, WAVE_MAPPER, &format,
- (DWORD_PTR)winaudio_in_buffer_done, (DWORD_PTR) hw,
- CALLBACK_FUNCTION);
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror( "qemu: winaudio: waveInOpen()", result);
- return -1;
- }
-
- samples_size = format.nBlockAlign * conf.nb_samples;
- s->buffer_bytes = qemu_malloc( NUM_IN_BUFFERS * samples_size );
- if (s->buffer_bytes == NULL) {
- waveInClose( s->wavein );
- s->wavein = NULL;
- fprintf(stderr, "not enough memory for Windows audio buffers\n");
- return -1;
- }
-
- for (i = 0; i < NUM_IN_BUFFERS; i++) {
- memset( &s->buffers[i], 0, sizeof(s->buffers[i]) );
- s->buffers[i].lpData = (LPSTR)(s->buffer_bytes + i*samples_size);
- s->buffers[i].dwBufferLength = samples_size;
- s->buffers[i].dwFlags = WHDR_DONE;
-
- result = waveInPrepareHeader( s->wavein, &s->buffers[i],
- sizeof(s->buffers[i]) );
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror("waveInPrepareHeader()", result);
- return -1;
- }
-
- result = waveInAddBuffer( s->wavein, &s->buffers[i],
- sizeof(s->buffers[i]) );
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror("waveInAddBuffer()", result);
- return -1;
- }
- }
-
-#if DEBUG
- /* Check the sound device we retrieved */
- {
- WAVEINCAPS caps;
-
- result = waveInGetDevCaps((UINT) s->wavein, &caps, sizeof(caps));
- if ( result != MMSYSERR_NOERROR ) {
- dump_mmerror("waveInGetDevCaps()", result);
- } else
- printf("Audio in device: %s\n", caps.szPname);
- }
-#endif
-
- audio_pcm_init_info (&hw->info, as);
- hw->samples = conf.nb_samples*2;
-
- s->read_index = 0;
- s->read_count = 0;
- s->read_pos = 0;
- s->read_size = samples_size;
- return 0;
-}
-
-
-/* report the number of captured samples to the audio subsystem */
-static int
-winaudio_in_run (HWVoiceIn *hw)
-{
- WinAudioIn* s = (WinAudioIn*) hw;
- int captured = 0;
- int has_buffer;
- int live = hw->samples - hw->total_samples_captured;
-
- if (!live) {
-#if 0
- static int counter;
- if (++counter == 100) {
- D("0"); fflush(stdout);
- counter = 0;
- }
-#endif
- return 0;
- }
-
- EnterCriticalSection( &s->lock );
- has_buffer = (s->read_count > 0);
- LeaveCriticalSection( &s->lock );
-
- if (has_buffer > 0) {
- while (live > 0) {
- WAVEHDR* wav_buffer = s->buffers + s->read_index;
- int wav_bytes = (s->read_size - s->read_pos);
- int wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
- int hw_samples = audio_MIN(hw->samples - hw->wpos, live);
- st_sample_t* dst = hw->conv_buf + hw->wpos;
- uint8_t* src = (uint8_t*)wav_buffer->lpData + s->read_pos;
-
- if (wav_samples > hw_samples) {
- wav_samples = hw_samples;
- }
-
- wav_bytes = wav_samples << hw->info.shift;
-
- D("%s: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d wpos:%d hwsamples:%d\n",
- __FUNCTION__, s->read_index, s->read_pos, s->read_size, wav_samples, wav_bytes, live,
- hw->wpos, hw->samples);
-
- hw->conv(dst, src, wav_samples, &nominal_volume);
-
- hw->wpos += wav_samples;
- if (hw->wpos >= hw->samples)
- hw->wpos -= hw->samples;
-
- live -= wav_samples;
- captured += wav_samples;
- s->read_pos += wav_bytes;
- if (s->read_pos == s->read_size) {
- s->read_pos = 0;
- s->read_index += 1;
- if (s->read_index == NUM_IN_BUFFERS)
- s->read_index = 0;
-
- waveInAddBuffer( s->wavein, wav_buffer, sizeof(*wav_buffer) );
-
- EnterCriticalSection( &s->lock );
- if (--s->read_count == 0) {
- live = 0;
- }
- LeaveCriticalSection( &s->lock );
- }
- }
- }
- return captured;
-}
-
-
-static int
-winaudio_in_read (SWVoiceIn *sw, void *buf, int len)
-{
- int ret = audio_pcm_sw_read (sw, buf, len);
- if (ret > 0)
- D("%s: (%d) returned %d\n", __FUNCTION__, len, ret);
- return ret;
-}
-
-
-static int
-winaudio_in_ctl (HWVoiceIn *hw, int cmd, ...)
-{
- WinAudioIn* s = (WinAudioIn*) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- D("%s: enable audio in\n", __FUNCTION__);
- waveInStart( s->wavein );
- break;
-
- case VOICE_DISABLE:
- D("%s: disable audio in\n", __FUNCTION__);
- waveInStop( s->wavein );
- break;
- }
- return 0;
-}
-
-/** AUDIO STATE
- **/
-
-typedef struct WinAudioState {
- int dummy;
-} WinAudioState;
-
-static WinAudioState g_winaudio;
-
-static void*
-winaudio_init(void)
-{
- WinAudioState* s = &g_winaudio;
-
-#if DEBUG
- start_time = qemu_get_clock(vm_clock);
- last_time = 0;
-#endif
-
- return s;
-}
-
-
-static void
-winaudio_fini (void *opaque)
-{
-}
-
-static struct audio_option winaudio_options[] = {
- {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
- "Size of Windows audio buffer in samples", NULL, 0},
- {NULL, 0, NULL, NULL, NULL, 0}
-};
-
-static struct audio_pcm_ops winaudio_pcm_ops = {
- winaudio_out_init,
- winaudio_out_fini,
- winaudio_out_run,
- winaudio_out_write,
- winaudio_out_ctl,
-
- winaudio_in_init,
- winaudio_in_fini,
- winaudio_in_run,
- winaudio_in_read,
- winaudio_in_ctl
-};
-
-struct audio_driver win_audio_driver = {
- INIT_FIELD (name = ) "winaudio",
- INIT_FIELD (descr = ) "Windows wave audio",
- INIT_FIELD (options = ) winaudio_options,
- INIT_FIELD (init = ) winaudio_init,
- INIT_FIELD (fini = ) winaudio_fini,
- INIT_FIELD (pcm_ops = ) &winaudio_pcm_ops,
- INIT_FIELD (can_be_default = ) 1,
- INIT_FIELD (max_voices_out = ) 1,
- INIT_FIELD (max_voices_in = ) 1,
- INIT_FIELD (voice_size_out = ) sizeof (WinAudioOut),
- INIT_FIELD (voice_size_in = ) sizeof (WinAudioIn)
-};
diff --git a/block-bochs.c b/block-bochs.c
deleted file mode 100644
index b167e0b..0000000
--- a/block-bochs.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Block driver for the various disk image formats used by Bochs
- * Currently only for "growing" type in read-only mode
- *
- * Copyright (c) 2005 Alex Beregszaszi
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-
-/**************************************************************/
-
-#define HEADER_MAGIC "Bochs Virtual HD Image"
-#define HEADER_VERSION 0x00020000
-#define HEADER_V1 0x00010000
-#define HEADER_SIZE 512
-
-#define REDOLOG_TYPE "Redolog"
-#define GROWING_TYPE "Growing"
-
-// not allocated: 0xffffffff
-
-// always little-endian
-struct bochs_header_v1 {
- char magic[32]; // "Bochs Virtual HD Image"
- char type[16]; // "Redolog"
- char subtype[16]; // "Undoable" / "Volatile" / "Growing"
- uint32_t version;
- uint32_t header; // size of header
-
- union {
- struct {
- uint32_t catalog; // num of entries
- uint32_t bitmap; // bitmap size
- uint32_t extent; // extent size
- uint64_t disk; // disk size
- char padding[HEADER_SIZE - 64 - 8 - 20];
- } redolog;
- char padding[HEADER_SIZE - 64 - 8];
- } extra;
-};
-
-// always little-endian
-struct bochs_header {
- char magic[32]; // "Bochs Virtual HD Image"
- char type[16]; // "Redolog"
- char subtype[16]; // "Undoable" / "Volatile" / "Growing"
- uint32_t version;
- uint32_t header; // size of header
-
- union {
- struct {
- uint32_t catalog; // num of entries
- uint32_t bitmap; // bitmap size
- uint32_t extent; // extent size
- uint32_t reserved; // for ???
- uint64_t disk; // disk size
- char padding[HEADER_SIZE - 64 - 8 - 24];
- } redolog;
- char padding[HEADER_SIZE - 64 - 8];
- } extra;
-};
-
-typedef struct BDRVBochsState {
- int fd;
-
- uint32_t *catalog_bitmap;
- int catalog_size;
-
- int data_offset;
-
- int bitmap_blocks;
- int extent_blocks;
- int extent_size;
-} BDRVBochsState;
-
-static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const struct bochs_header *bochs = (const void *)buf;
-
- if (buf_size < HEADER_SIZE)
- return 0;
-
- if (!strcmp(bochs->magic, HEADER_MAGIC) &&
- !strcmp(bochs->type, REDOLOG_TYPE) &&
- !strcmp(bochs->subtype, GROWING_TYPE) &&
- ((le32_to_cpu(bochs->version) == HEADER_VERSION) ||
- (le32_to_cpu(bochs->version) == HEADER_V1)))
- return 100;
-
- return 0;
-}
-
-static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVBochsState *s = bs->opaque;
- int fd, i;
- struct bochs_header bochs;
- struct bochs_header_v1 header_v1;
-
- fd = open(filename, O_RDWR | O_BINARY);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- }
-
- bs->read_only = 1; // no write support yet
-
- s->fd = fd;
-
- if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) {
- goto fail;
- }
-
- if (strcmp(bochs.magic, HEADER_MAGIC) ||
- strcmp(bochs.type, REDOLOG_TYPE) ||
- strcmp(bochs.subtype, GROWING_TYPE) ||
- ((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
- (le32_to_cpu(bochs.version) != HEADER_V1))) {
- goto fail;
- }
-
- if (le32_to_cpu(bochs.version) == HEADER_V1) {
- memcpy(&header_v1, &bochs, sizeof(bochs));
- bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;
- } else {
- bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
- }
-
- lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);
-
- s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
- s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
- if (!s->catalog_bitmap)
- goto fail;
- if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) !=
- s->catalog_size * 4)
- goto fail;
- for (i = 0; i < s->catalog_size; i++)
- le32_to_cpus(&s->catalog_bitmap[i]);
-
- s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
-
- s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
- s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
-
- s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
-
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
- BDRVBochsState *s = bs->opaque;
- int64_t offset = sector_num * 512;
- int64_t extent_index, extent_offset, bitmap_offset, block_offset;
- char bitmap_entry;
-
- // seek to sector
- extent_index = offset / s->extent_size;
- extent_offset = (offset % s->extent_size) / 512;
-
- if (s->catalog_bitmap[extent_index] == 0xffffffff)
- {
-// fprintf(stderr, "page not allocated [%x - %x:%x]\n",
-// sector_num, extent_index, extent_offset);
- return -1; // not allocated
- }
-
- bitmap_offset = s->data_offset + (512 * s->catalog_bitmap[extent_index] *
- (s->extent_blocks + s->bitmap_blocks));
- block_offset = bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
-
-// fprintf(stderr, "sect: %x [ext i: %x o: %x] -> %x bitmap: %x block: %x\n",
-// sector_num, extent_index, extent_offset,
-// le32_to_cpu(s->catalog_bitmap[extent_index]),
-// bitmap_offset, block_offset);
-
- // read in bitmap for current extent
- lseek(s->fd, bitmap_offset + (extent_offset / 8), SEEK_SET);
-
- read(s->fd, &bitmap_entry, 1);
-
- if (!((bitmap_entry >> (extent_offset % 8)) & 1))
- {
-// fprintf(stderr, "sector (%x) in bitmap not allocated\n",
-// sector_num);
- return -1; // not allocated
- }
-
- lseek(s->fd, block_offset, SEEK_SET);
-
- return 0;
-}
-
-static int bochs_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVBochsState *s = bs->opaque;
- int ret;
-
- while (nb_sectors > 0) {
- if (!seek_to_sector(bs, sector_num))
- {
- ret = read(s->fd, buf, 512);
- if (ret != 512)
- return -1;
- }
- else
- memset(buf, 0, 512);
- nb_sectors--;
- sector_num++;
- buf += 512;
- }
- return 0;
-}
-
-static void bochs_close(BlockDriverState *bs)
-{
- BDRVBochsState *s = bs->opaque;
- qemu_free(s->catalog_bitmap);
- close(s->fd);
-}
-
-BlockDriver bdrv_bochs = {
- "bochs",
- sizeof(BDRVBochsState),
- bochs_probe,
- bochs_open,
- bochs_read,
- NULL,
- bochs_close,
-};
diff --git a/block-cloop.c b/block-cloop.c
deleted file mode 100644
index 43d3801..0000000
--- a/block-cloop.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * QEMU Block driver for CLOOP images
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-#include <zlib.h>
-
-typedef struct BDRVCloopState {
- int fd;
- uint32_t block_size;
- uint32_t n_blocks;
- uint64_t* offsets;
- uint32_t sectors_per_block;
- uint32_t current_block;
- uint8_t *compressed_block;
- uint8_t *uncompressed_block;
- z_stream zstream;
-} BDRVCloopState;
-
-static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const char* magic_version_2_0="#!/bin/sh\n"
- "#V2.0 Format\n"
- "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
- int length=strlen(magic_version_2_0);
- if(length>buf_size)
- length=buf_size;
- if(!memcmp(magic_version_2_0,buf,length))
- return 2;
- return 0;
-}
-
-static int cloop_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVCloopState *s = bs->opaque;
- uint32_t offsets_size,max_compressed_block_size=1,i;
-
- s->fd = open(filename, O_RDONLY | O_BINARY);
- if (s->fd < 0)
- return -errno;
- bs->read_only = 1;
-
- /* read header */
- if(lseek(s->fd,128,SEEK_SET)<0) {
-cloop_close:
- close(s->fd);
- return -1;
- }
- if(read(s->fd,&s->block_size,4)<4)
- goto cloop_close;
- s->block_size=be32_to_cpu(s->block_size);
- if(read(s->fd,&s->n_blocks,4)<4)
- goto cloop_close;
- s->n_blocks=be32_to_cpu(s->n_blocks);
-
- /* read offsets */
- offsets_size=s->n_blocks*sizeof(uint64_t);
- if(!(s->offsets=(uint64_t*)malloc(offsets_size)))
- goto cloop_close;
- if(read(s->fd,s->offsets,offsets_size)<offsets_size)
- goto cloop_close;
- for(i=0;i<s->n_blocks;i++) {
- s->offsets[i]=be64_to_cpu(s->offsets[i]);
- if(i>0) {
- uint32_t size=s->offsets[i]-s->offsets[i-1];
- if(size>max_compressed_block_size)
- max_compressed_block_size=size;
- }
- }
-
- /* initialize zlib engine */
- if(!(s->compressed_block = malloc(max_compressed_block_size+1)))
- goto cloop_close;
- if(!(s->uncompressed_block = malloc(s->block_size)))
- goto cloop_close;
- if(inflateInit(&s->zstream) != Z_OK)
- goto cloop_close;
- s->current_block=s->n_blocks;
-
- s->sectors_per_block = s->block_size/512;
- bs->total_sectors = s->n_blocks*s->sectors_per_block;
- return 0;
-}
-
-static inline int cloop_read_block(BDRVCloopState *s,int block_num)
-{
- if(s->current_block != block_num) {
- int ret;
- uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
-
- lseek(s->fd, s->offsets[block_num], SEEK_SET);
- ret = read(s->fd, s->compressed_block, bytes);
- if (ret != bytes)
- return -1;
-
- s->zstream.next_in = s->compressed_block;
- s->zstream.avail_in = bytes;
- s->zstream.next_out = s->uncompressed_block;
- s->zstream.avail_out = s->block_size;
- ret = inflateReset(&s->zstream);
- if(ret != Z_OK)
- return -1;
- ret = inflate(&s->zstream, Z_FINISH);
- if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
- return -1;
-
- s->current_block = block_num;
- }
- return 0;
-}
-
-static int cloop_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVCloopState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++) {
- uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
- block_num=(sector_num+i)/s->sectors_per_block;
- if(cloop_read_block(s, block_num) != 0)
- return -1;
- memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
- }
- return 0;
-}
-
-static void cloop_close(BlockDriverState *bs)
-{
- BDRVCloopState *s = bs->opaque;
- close(s->fd);
- if(s->n_blocks>0)
- free(s->offsets);
- free(s->compressed_block);
- free(s->uncompressed_block);
- inflateEnd(&s->zstream);
-}
-
-BlockDriver bdrv_cloop = {
- "cloop",
- sizeof(BDRVCloopState),
- cloop_probe,
- cloop_open,
- cloop_read,
- NULL,
- cloop_close,
-};
-
-
diff --git a/block-cow.c b/block-cow.c
deleted file mode 100644
index 9e7b646..0000000
--- a/block-cow.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Block driver for the COW format
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef _WIN32
-#include "qemu-common.h"
-#include "block_int.h"
-#include <sys/mman.h>
-
-/**************************************************************/
-/* COW block driver using file system holes */
-
-/* user mode linux compatible COW file */
-#define COW_MAGIC 0x4f4f4f4d /* MOOO */
-#define COW_VERSION 2
-
-struct cow_header_v2 {
- uint32_t magic;
- uint32_t version;
- char backing_file[1024];
- int32_t mtime;
- uint64_t size;
- uint32_t sectorsize;
-};
-
-typedef struct BDRVCowState {
- int fd;
- uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
- uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
- int cow_bitmap_size;
- int64_t cow_sectors_offset;
-} BDRVCowState;
-
-static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const struct cow_header_v2 *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(struct cow_header_v2) &&
- be32_to_cpu(cow_header->magic) == COW_MAGIC &&
- be32_to_cpu(cow_header->version) == COW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int cow_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVCowState *s = bs->opaque;
- int fd;
- struct cow_header_v2 cow_header;
- int64_t size;
-
- fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
- }
- s->fd = fd;
- /* see if it is a cow image */
- if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
- goto fail;
- }
-
- if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
- be32_to_cpu(cow_header.version) != COW_VERSION) {
- goto fail;
- }
-
- /* cow image found */
- size = be64_to_cpu(cow_header.size);
- bs->total_sectors = size / 512;
-
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
- cow_header.backing_file);
-
- /* mmap the bitmap */
- s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
- s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
- s->cow_bitmap_size,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, s->fd, 0);
- if (s->cow_bitmap_addr == MAP_FAILED)
- goto fail;
- s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header);
- s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511;
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline void cow_set_bit(uint8_t *bitmap, int64_t bitnum)
-{
- bitmap[bitnum / 8] |= (1 << (bitnum%8));
-}
-
-static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
-{
- return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
-}
-
-
-/* Return true if first block has been changed (ie. current version is
- * in COW file). Set the number of continuous blocks for which that
- * is true. */
-static inline int is_changed(uint8_t *bitmap,
- int64_t sector_num, int nb_sectors,
- int *num_same)
-{
- int changed;
-
- if (!bitmap || nb_sectors == 0) {
- *num_same = nb_sectors;
- return 0;
- }
-
- changed = is_bit_set(bitmap, sector_num);
- for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
- if (is_bit_set(bitmap, sector_num + *num_same) != changed)
- break;
- }
-
- return changed;
-}
-
-static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVCowState *s = bs->opaque;
- return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
-}
-
-static int cow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVCowState *s = bs->opaque;
- int ret, n;
-
- while (nb_sectors > 0) {
- if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
- lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
- ret = read(s->fd, buf, n * 512);
- if (ret != n * 512)
- return -1;
- } else {
- if (bs->backing_hd) {
- /* read from the base image */
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- memset(buf, 0, n * 512);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int cow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVCowState *s = bs->opaque;
- int ret, i;
-
- lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
- ret = write(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
- return -1;
- for (i = 0; i < nb_sectors; i++)
- cow_set_bit(s->cow_bitmap, sector_num + i);
- return 0;
-}
-
-static void cow_close(BlockDriverState *bs)
-{
- BDRVCowState *s = bs->opaque;
- munmap(s->cow_bitmap_addr, s->cow_bitmap_size);
- close(s->fd);
-}
-
-static int cow_create(const char *filename, int64_t image_sectors,
- const char *image_filename, int flags)
-{
- int fd, cow_fd;
- struct cow_header_v2 cow_header;
- struct stat st;
-
- if (flags)
- return -ENOTSUP;
-
- cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- 0644);
- if (cow_fd < 0)
- return -1;
- memset(&cow_header, 0, sizeof(cow_header));
- cow_header.magic = cpu_to_be32(COW_MAGIC);
- cow_header.version = cpu_to_be32(COW_VERSION);
- if (image_filename) {
- /* Note: if no file, we put a dummy mtime */
- cow_header.mtime = cpu_to_be32(0);
-
- fd = open(image_filename, O_RDONLY | O_BINARY);
- if (fd < 0) {
- close(cow_fd);
- goto mtime_fail;
- }
- if (fstat(fd, &st) != 0) {
- close(fd);
- goto mtime_fail;
- }
- close(fd);
- cow_header.mtime = cpu_to_be32(st.st_mtime);
- mtime_fail:
- pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
- image_filename);
- }
- cow_header.sectorsize = cpu_to_be32(512);
- cow_header.size = cpu_to_be64(image_sectors * 512);
- write(cow_fd, &cow_header, sizeof(cow_header));
- /* resize to include at least all the bitmap */
- ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
- close(cow_fd);
- return 0;
-}
-
-static void cow_flush(BlockDriverState *bs)
-{
- BDRVCowState *s = bs->opaque;
- fsync(s->fd);
-}
-
-BlockDriver bdrv_cow = {
- "cow",
- sizeof(BDRVCowState),
- cow_probe,
- cow_open,
- cow_read,
- cow_write,
- cow_close,
- cow_create,
- cow_flush,
- cow_is_allocated,
-};
-#endif
diff --git a/block-dmg.c b/block-dmg.c
deleted file mode 100644
index 8c9d0da..0000000
--- a/block-dmg.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * QEMU Block driver for DMG images
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-#include "bswap.h"
-#include <zlib.h>
-
-typedef struct BDRVDMGState {
- int fd;
-
- /* each chunk contains a certain number of sectors,
- * offsets[i] is the offset in the .dmg file,
- * lengths[i] is the length of the compressed chunk,
- * sectors[i] is the sector beginning at offsets[i],
- * sectorcounts[i] is the number of sectors in that chunk,
- * the sectors array is ordered
- * 0<=i<n_chunks */
-
- uint32_t n_chunks;
- uint32_t* types;
- uint64_t* offsets;
- uint64_t* lengths;
- uint64_t* sectors;
- uint64_t* sectorcounts;
- uint32_t current_chunk;
- uint8_t *compressed_chunk;
- uint8_t *uncompressed_chunk;
- z_stream zstream;
-} BDRVDMGState;
-
-static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- int len=strlen(filename);
- if(len>4 && !strcmp(filename+len-4,".dmg"))
- return 2;
- return 0;
-}
-
-static off_t read_off(int fd)
-{
- uint64_t buffer;
- if(read(fd,&buffer,8)<8)
- return 0;
- return be64_to_cpu(buffer);
-}
-
-static off_t read_uint32(int fd)
-{
- uint32_t buffer;
- if(read(fd,&buffer,4)<4)
- return 0;
- return be32_to_cpu(buffer);
-}
-
-static int dmg_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVDMGState *s = bs->opaque;
- off_t info_begin,info_end,last_in_offset,last_out_offset;
- uint32_t count;
- uint32_t max_compressed_size=1,max_sectors_per_chunk=1,i;
-
- s->fd = open(filename, O_RDONLY | O_BINARY);
- if (s->fd < 0)
- return -errno;
- bs->read_only = 1;
- s->n_chunks = 0;
- s->offsets = s->lengths = s->sectors = s->sectorcounts = 0;
-
- /* read offset of info blocks */
- if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
-dmg_close:
- close(s->fd);
- /* open raw instead */
- bs->drv=&bdrv_raw;
- return bs->drv->bdrv_open(bs, filename, flags);
- }
- info_begin=read_off(s->fd);
- if(info_begin==0)
- goto dmg_close;
- if(lseek(s->fd,info_begin,SEEK_SET)<0)
- goto dmg_close;
- if(read_uint32(s->fd)!=0x100)
- goto dmg_close;
- if((count = read_uint32(s->fd))==0)
- goto dmg_close;
- info_end = info_begin+count;
- if(lseek(s->fd,0xf8,SEEK_CUR)<0)
- goto dmg_close;
-
- /* read offsets */
- last_in_offset = last_out_offset = 0;
- while(lseek(s->fd,0,SEEK_CUR)<info_end) {
- uint32_t type;
-
- count = read_uint32(s->fd);
- if(count==0)
- goto dmg_close;
- type = read_uint32(s->fd);
- if(type!=0x6d697368 || count<244)
- lseek(s->fd,count-4,SEEK_CUR);
- else {
- int new_size, chunk_count;
- if(lseek(s->fd,200,SEEK_CUR)<0)
- goto dmg_close;
- chunk_count = (count-204)/40;
- new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
- s->types = qemu_realloc(s->types, new_size/2);
- s->offsets = qemu_realloc(s->offsets, new_size);
- s->lengths = qemu_realloc(s->lengths, new_size);
- s->sectors = qemu_realloc(s->sectors, new_size);
- s->sectorcounts = qemu_realloc(s->sectorcounts, new_size);
-
- for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {
- s->types[i] = read_uint32(s->fd);
- if(s->types[i]!=0x80000005 && s->types[i]!=1 && s->types[i]!=2) {
- if(s->types[i]==0xffffffff) {
- last_in_offset = s->offsets[i-1]+s->lengths[i-1];
- last_out_offset = s->sectors[i-1]+s->sectorcounts[i-1];
- }
- chunk_count--;
- i--;
- if(lseek(s->fd,36,SEEK_CUR)<0)
- goto dmg_close;
- continue;
- }
- read_uint32(s->fd);
- s->sectors[i] = last_out_offset+read_off(s->fd);
- s->sectorcounts[i] = read_off(s->fd);
- s->offsets[i] = last_in_offset+read_off(s->fd);
- s->lengths[i] = read_off(s->fd);
- if(s->lengths[i]>max_compressed_size)
- max_compressed_size = s->lengths[i];
- if(s->sectorcounts[i]>max_sectors_per_chunk)
- max_sectors_per_chunk = s->sectorcounts[i];
- }
- s->n_chunks+=chunk_count;
- }
- }
-
- /* initialize zlib engine */
- if(!(s->compressed_chunk = malloc(max_compressed_size+1)))
- goto dmg_close;
- if(!(s->uncompressed_chunk = malloc(512*max_sectors_per_chunk)))
- goto dmg_close;
- if(inflateInit(&s->zstream) != Z_OK)
- goto dmg_close;
-
- s->current_chunk = s->n_chunks;
-
- return 0;
-}
-
-static inline int is_sector_in_chunk(BDRVDMGState* s,
- uint32_t chunk_num,int sector_num)
-{
- if(chunk_num>=s->n_chunks || s->sectors[chunk_num]>sector_num ||
- s->sectors[chunk_num]+s->sectorcounts[chunk_num]<=sector_num)
- return 0;
- else
- return -1;
-}
-
-static inline uint32_t search_chunk(BDRVDMGState* s,int sector_num)
-{
- /* binary search */
- uint32_t chunk1=0,chunk2=s->n_chunks,chunk3;
- while(chunk1!=chunk2) {
- chunk3 = (chunk1+chunk2)/2;
- if(s->sectors[chunk3]>sector_num)
- chunk2 = chunk3;
- else if(s->sectors[chunk3]+s->sectorcounts[chunk3]>sector_num)
- return chunk3;
- else
- chunk1 = chunk3;
- }
- return s->n_chunks; /* error */
-}
-
-static inline int dmg_read_chunk(BDRVDMGState *s,int sector_num)
-{
- if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
- int ret;
- uint32_t chunk = search_chunk(s,sector_num);
-
- if(chunk>=s->n_chunks)
- return -1;
-
- s->current_chunk = s->n_chunks;
- switch(s->types[chunk]) {
- case 0x80000005: { /* zlib compressed */
- int i;
-
- ret = lseek(s->fd, s->offsets[chunk], SEEK_SET);
- if(ret<0)
- return -1;
-
- /* we need to buffer, because only the chunk as whole can be
- * inflated. */
- i=0;
- do {
- ret = read(s->fd, s->compressed_chunk+i, s->lengths[chunk]-i);
- if(ret<0 && errno==EINTR)
- ret=0;
- i+=ret;
- } while(ret>=0 && ret+i<s->lengths[chunk]);
-
- if (ret != s->lengths[chunk])
- return -1;
-
- s->zstream.next_in = s->compressed_chunk;
- s->zstream.avail_in = s->lengths[chunk];
- s->zstream.next_out = s->uncompressed_chunk;
- s->zstream.avail_out = 512*s->sectorcounts[chunk];
- ret = inflateReset(&s->zstream);
- if(ret != Z_OK)
- return -1;
- ret = inflate(&s->zstream, Z_FINISH);
- if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
- return -1;
- break; }
- case 1: /* copy */
- ret = read(s->fd, s->uncompressed_chunk, s->lengths[chunk]);
- if (ret != s->lengths[chunk])
- return -1;
- break;
- case 2: /* zero */
- memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
- break;
- }
- s->current_chunk = chunk;
- }
- return 0;
-}
-
-static int dmg_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVDMGState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++) {
- uint32_t sector_offset_in_chunk;
- if(dmg_read_chunk(s, sector_num+i) != 0)
- return -1;
- sector_offset_in_chunk = sector_num+i-s->sectors[s->current_chunk];
- memcpy(buf+i*512,s->uncompressed_chunk+sector_offset_in_chunk*512,512);
- }
- return 0;
-}
-
-static void dmg_close(BlockDriverState *bs)
-{
- BDRVDMGState *s = bs->opaque;
- close(s->fd);
- if(s->n_chunks>0) {
- free(s->types);
- free(s->offsets);
- free(s->lengths);
- free(s->sectors);
- free(s->sectorcounts);
- }
- free(s->compressed_chunk);
- free(s->uncompressed_chunk);
- inflateEnd(&s->zstream);
-}
-
-BlockDriver bdrv_dmg = {
- "dmg",
- sizeof(BDRVDMGState),
- dmg_probe,
- dmg_open,
- dmg_read,
- NULL,
- dmg_close,
-};
-
diff --git a/block-nbd.c b/block-nbd.c
deleted file mode 100644
index 5b6cc4f..0000000
--- a/block-nbd.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * QEMU Block driver for NBD
- *
- * Copyright (C) 2008 Bull S.A.S.
- * Author: Laurent Vivier <Laurent.Vivier@bull.net>
- *
- * Some parts:
- * Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "nbd.h"
-
-#include <sys/types.h>
-#include <unistd.h>
-
-typedef struct BDRVNBDState {
- int sock;
- off_t size;
- size_t blocksize;
-} BDRVNBDState;
-
-static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
-{
- BDRVNBDState *s = bs->opaque;
- const char *host;
- const char *unixpath;
- int sock;
- off_t size;
- size_t blocksize;
- int ret;
-
- if ((flags & BDRV_O_CREAT))
- return -EINVAL;
-
- if (!strstart(filename, "nbd:", &host))
- return -EINVAL;
-
- if (strstart(host, "unix:", &unixpath)) {
-
- if (unixpath[0] != '/')
- return -EINVAL;
-
- sock = unix_socket_outgoing(unixpath);
-
- } else {
- uint16_t port;
- char *p, *r;
- char hostname[128];
-
- pstrcpy(hostname, 128, host);
-
- p = strchr(hostname, ':');
- if (p == NULL)
- return -EINVAL;
-
- *p = '\0';
- p++;
-
- port = strtol(p, &r, 0);
- if (r == p)
- return -EINVAL;
- sock = tcp_socket_outgoing(hostname, port);
- }
-
- if (sock == -1)
- return -errno;
-
- ret = nbd_receive_negotiate(sock, &size, &blocksize);
- if (ret == -1)
- return -errno;
-
- s->sock = sock;
- s->size = size;
- s->blocksize = blocksize;
-
- return 0;
-}
-
-static int nbd_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVNBDState *s = bs->opaque;
- struct nbd_request request;
- struct nbd_reply reply;
-
- request.type = NBD_CMD_READ;
- request.handle = (uint64_t)(intptr_t)bs;
- request.from = sector_num * 512;;
- request.len = nb_sectors * 512;
-
- if (nbd_send_request(s->sock, &request) == -1)
- return -errno;
-
- if (nbd_receive_reply(s->sock, &reply) == -1)
- return -errno;
-
- if (reply.error !=0)
- return -reply.error;
-
- if (reply.handle != request.handle)
- return -EIO;
-
- if (nbd_wr_sync(s->sock, buf, request.len, 1) != request.len)
- return -EIO;
-
- return 0;
-}
-
-static int nbd_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVNBDState *s = bs->opaque;
- struct nbd_request request;
- struct nbd_reply reply;
-
- request.type = NBD_CMD_WRITE;
- request.handle = (uint64_t)(intptr_t)bs;
- request.from = sector_num * 512;;
- request.len = nb_sectors * 512;
-
- if (nbd_send_request(s->sock, &request) == -1)
- return -errno;
-
- if (nbd_wr_sync(s->sock, (uint8_t*)buf, request.len, 0) != request.len)
- return -EIO;
-
- if (nbd_receive_reply(s->sock, &reply) == -1)
- return -errno;
-
- if (reply.error !=0)
- return -reply.error;
-
- if (reply.handle != request.handle)
- return -EIO;
-
- return 0;
-}
-
-static void nbd_close(BlockDriverState *bs)
-{
- BDRVNBDState *s = bs->opaque;
- struct nbd_request request;
-
- request.type = NBD_CMD_DISC;
- request.handle = (uint64_t)(intptr_t)bs;
- request.from = 0;
- request.len = 0;
- nbd_send_request(s->sock, &request);
-
- close(s->sock);
-}
-
-static int64_t nbd_getlength(BlockDriverState *bs)
-{
- BDRVNBDState *s = bs->opaque;
-
- return s->size;
-}
-
-BlockDriver bdrv_nbd = {
- "nbd",
- sizeof(BDRVNBDState),
- NULL, /* no probe for protocols */
- nbd_open,
- nbd_read,
- nbd_write,
- nbd_close,
- .bdrv_getlength = nbd_getlength,
- .protocol_name = "nbd",
-};
diff --git a/block-parallels.c b/block-parallels.c
deleted file mode 100644
index 4654b07..0000000
--- a/block-parallels.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Block driver for Parallels disk image format
- *
- * Copyright (c) 2007 Alex Beregszaszi
- *
- * This code is based on comparing different disk images created by Parallels.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-
-/**************************************************************/
-
-#define HEADER_MAGIC "WithoutFreeSpace"
-#define HEADER_VERSION 2
-#define HEADER_SIZE 64
-
-// always little-endian
-struct parallels_header {
- char magic[16]; // "WithoutFreeSpace"
- uint32_t version;
- uint32_t heads;
- uint32_t cylinders;
- uint32_t tracks;
- uint32_t catalog_entries;
- uint32_t nb_sectors;
- char padding[24];
-} __attribute__((packed));
-
-typedef struct BDRVParallelsState {
- int fd;
-
- uint32_t *catalog_bitmap;
- int catalog_size;
-
- int tracks;
-} BDRVParallelsState;
-
-static int parallels_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const struct parallels_header *ph = (const void *)buf;
-
- if (buf_size < HEADER_SIZE)
- return 0;
-
- if (!memcmp(ph->magic, HEADER_MAGIC, 16) &&
- (le32_to_cpu(ph->version) == HEADER_VERSION))
- return 100;
-
- return 0;
-}
-
-static int parallels_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVParallelsState *s = bs->opaque;
- int fd, i;
- struct parallels_header ph;
-
- fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
- }
-
- bs->read_only = 1; // no write support yet
-
- s->fd = fd;
-
- if (read(fd, &ph, sizeof(ph)) != sizeof(ph))
- goto fail;
-
- if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
- (le32_to_cpu(ph.version) != HEADER_VERSION)) {
- goto fail;
- }
-
- bs->total_sectors = le32_to_cpu(ph.nb_sectors);
-
- if (lseek(s->fd, 64, SEEK_SET) != 64)
- goto fail;
-
- s->tracks = le32_to_cpu(ph.tracks);
-
- s->catalog_size = le32_to_cpu(ph.catalog_entries);
- s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
- if (!s->catalog_bitmap)
- goto fail;
- if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) !=
- s->catalog_size * 4)
- goto fail;
- for (i = 0; i < s->catalog_size; i++)
- le32_to_cpus(&s->catalog_bitmap[i]);
-
- return 0;
-fail:
- if (s->catalog_bitmap)
- qemu_free(s->catalog_bitmap);
- close(fd);
- return -1;
-}
-
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
- BDRVParallelsState *s = bs->opaque;
- uint32_t index, offset, position;
-
- index = sector_num / s->tracks;
- offset = sector_num % s->tracks;
-
- // not allocated
- if ((index > s->catalog_size) || (s->catalog_bitmap[index] == 0))
- return -1;
-
- position = (s->catalog_bitmap[index] + offset) * 512;
-
-// fprintf(stderr, "sector: %llx index=%x offset=%x pointer=%x position=%x\n",
-// sector_num, index, offset, s->catalog_bitmap[index], position);
-
- if (lseek(s->fd, position, SEEK_SET) != position)
- return -1;
-
- return 0;
-}
-
-static int parallels_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVParallelsState *s = bs->opaque;
-
- while (nb_sectors > 0) {
- if (!seek_to_sector(bs, sector_num)) {
- if (read(s->fd, buf, 512) != 512)
- return -1;
- } else
- memset(buf, 0, 512);
- nb_sectors--;
- sector_num++;
- buf += 512;
- }
- return 0;
-}
-
-static void parallels_close(BlockDriverState *bs)
-{
- BDRVParallelsState *s = bs->opaque;
- qemu_free(s->catalog_bitmap);
- close(s->fd);
-}
-
-BlockDriver bdrv_parallels = {
- "parallels",
- sizeof(BDRVParallelsState),
- parallels_probe,
- parallels_open,
- parallels_read,
- NULL,
- parallels_close,
-};
diff --git a/block-qcow.c b/block-qcow.c
deleted file mode 100644
index 1fecf30..0000000
--- a/block-qcow.c
+++ /dev/null
@@ -1,904 +0,0 @@
-/*
- * Block driver for the QCOW format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-#include <zlib.h>
-#include "aes.h"
-
-/**************************************************************/
-/* QEMU COW block driver with compression and encryption support */
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW_VERSION 1
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-#define QCOW_OFLAG_COMPRESSED (1LL << 63)
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t mtime;
- uint64_t size; /* in bytes */
- uint8_t cluster_bits;
- uint8_t l2_bits;
- uint32_t crypt_method;
- uint64_t l1_table_offset;
-} QCowHeader;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVQcowState {
- BlockDriverState *hd;
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
- uint64_t *l2_cache;
- uint64_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
-} BDRVQcowState;
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
-
-static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(QCowHeader) &&
- be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVQcowState *s = bs->opaque;
- int len, i, shift, ret;
- QCowHeader header;
-
- ret = bdrv_file_open(&s->hd, filename, flags);
- if (ret < 0)
- return ret;
- if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
- goto fail;
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be32_to_cpus(&header.mtime);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
-
- if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
- goto fail;
- if (header.size <= 1 || header.cluster_bits < 9)
- goto fail;
- if (header.crypt_method > QCOW_CRYPT_AES)
- goto fail;
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header)
- bs->encrypted = 1;
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = header.l2_bits;
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
-
- /* read the level 1 table */
- shift = s->cluster_bits + s->l2_bits;
- s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
-
- s->l1_table_offset = header.l1_table_offset;
- s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!s->l1_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
- s->l1_size * sizeof(uint64_t))
- goto fail;
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- /* alloc L2 cache */
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- if (!s->l2_cache)
- goto fail;
- s->cluster_cache = qemu_malloc(s->cluster_size);
- if (!s->cluster_cache)
- goto fail;
- s->cluster_data = qemu_malloc(s->cluster_size);
- if (!s->cluster_data)
- goto fail;
- s->cluster_cache_offset = -1;
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023)
- len = 1023;
- if (bdrv_pread(s->hd, header.backing_file_offset, bs->backing_file, len) != len)
- goto fail;
- bs->backing_file[len] = '\0';
- }
- return 0;
-
- fail:
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- bdrv_delete(s->hd);
- return -1;
-}
-
-static int qcow_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
-#if 0
- /* test */
- {
- uint8_t in[16];
- uint8_t out[16];
- uint8_t tmp[16];
- for(i=0;i<16;i++)
- in[i] = i;
- AES_encrypt(in, tmp, &s->aes_encrypt_key);
- AES_decrypt(tmp, out, &s->aes_decrypt_key);
- for(i = 0; i < 16; i++)
- printf(" %02x", tmp[i]);
- printf("\n");
- for(i = 0; i < 16; i++)
- printf(" %02x", out[i]);
- printf("\n");
- }
-#endif
- return 0;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-/* 'allocate' is:
- *
- * 0 to not allocate.
- *
- * 1 to allocate a normal cluster (for sector indexes 'n_start' to
- * 'n_end')
- *
- * 2 to allocate a compressed cluster of size
- * 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
- *
- * return 0 if not allocated.
- */
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset, int allocate,
- int compressed_size,
- int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index, i, j, l1_index, l2_index;
- uint64_t l2_offset, *l2_table, cluster_offset, tmp;
- uint32_t min_count;
- int new_l2_table;
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- l2_offset = s->l1_table[l1_index];
- new_l2_table = 0;
- if (!l2_offset) {
- if (!allocate)
- return 0;
- /* allocate a new l2 entry */
- l2_offset = bdrv_getlength(s->hd);
- /* round to cluster size */
- l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
- /* update the L1 entry */
- s->l1_table[l1_index] = l2_offset;
- tmp = cpu_to_be64(l2_offset);
- if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- new_l2_table = 1;
- }
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i << s->l2_bits);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index << s->l2_bits);
- if (new_l2_table) {
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- if (bdrv_pwrite(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- } else {
- if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- }
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (!cluster_offset ||
- ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
- if (!allocate)
- return 0;
- /* allocate a new cluster */
- if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
- (n_end - n_start) < s->cluster_sectors) {
- /* if the cluster is already compressed, we must
- decompress it in the case it is not completely
- overwritten */
- if (decompress_cluster(s, cluster_offset) < 0)
- return 0;
- cluster_offset = bdrv_getlength(s->hd);
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- /* write the cluster content */
- if (bdrv_pwrite(s->hd, cluster_offset, s->cluster_cache, s->cluster_size) !=
- s->cluster_size)
- return -1;
- } else {
- cluster_offset = bdrv_getlength(s->hd);
- /* round to cluster size */
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- bdrv_truncate(s->hd, cluster_offset + s->cluster_size);
- /* if encrypted, we must initialize the cluster
- content which won't be written */
- if (s->crypt_method &&
- (n_end - n_start) < s->cluster_sectors) {
- uint64_t start_sect;
- start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
- memset(s->cluster_data + 512, 0x00, 512);
- for(i = 0; i < s->cluster_sectors; i++) {
- if (i < n_start || i >= n_end) {
- encrypt_sectors(s, start_sect + i,
- s->cluster_data,
- s->cluster_data + 512, 1, 1,
- &s->aes_encrypt_key);
- if (bdrv_pwrite(s->hd, cluster_offset + i * 512,
- s->cluster_data, 512) != 512)
- return -1;
- }
- }
- }
- }
- /* update L2 table */
- tmp = cpu_to_be64(cluster_offset);
- l2_table[l2_index] = tmp;
- if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- }
- return cluster_offset;
-}
-
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
-{
- int ret, csize;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- csize = cluster_offset >> (63 - s->cluster_bits);
- csize &= (s->cluster_size - 1);
- ret = bdrv_pread(s->hd, coffset, s->cluster_data, csize);
- if (ret != csize)
- return -1;
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data, csize) < 0) {
- return -1;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-#if 0
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- if (!cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- memset(buf, 0, 512 * n);
- }
- } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- if (decompress_cluster(s, cluster_offset) < 0)
- return -1;
- memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
- } else {
- ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- if (ret != n * 512)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
- &s->aes_decrypt_key);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-#endif
-
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
- index_in_cluster,
- index_in_cluster + n);
- if (!cluster_offset)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
- &s->aes_encrypt_key);
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
- s->cluster_data, n * 512);
- } else {
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- }
- if (ret != n * 512)
- return -1;
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- s->cluster_cache_offset = -1; /* disable compressed cache */
- return 0;
-}
-
-typedef struct QCowAIOCB {
- BlockDriverAIOCB common;
- int64_t sector_num;
- uint8_t *buf;
- int nb_sectors;
- int n;
- uint64_t cluster_offset;
- uint8_t *cluster_data;
- BlockDriverAIOCB *hd_aiocb;
-} QCowAIOCB;
-
-static void qcow_aio_read_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
-
- acb->hd_aiocb = NULL;
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- redo:
- /* post process the read buffer */
- if (!acb->cluster_offset) {
- /* nothing to do */
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* nothing to do */
- } else {
- if (s->crypt_method) {
- encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->n, 0,
- &s->aes_decrypt_key);
- }
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- /* prepare next AIO request */
- acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
- 0, 0, 0, 0);
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- acb->n = s->cluster_sectors - index_in_cluster;
- if (acb->n > acb->nb_sectors)
- acb->n = acb->nb_sectors;
-
- if (!acb->cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- acb->hd_aiocb = bdrv_aio_read(bs->backing_hd,
- acb->sector_num, acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- } else {
- /* Note: in this case, no need to wait */
- memset(acb->buf, 0, 512 * acb->n);
- goto redo;
- }
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* add AIO support for compressed blocks ? */
- if (decompress_cluster(s, acb->cluster_offset) < 0)
- goto fail;
- memcpy(acb->buf,
- s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
- goto redo;
- } else {
- if ((acb->cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- acb->hd_aiocb = bdrv_aio_read(s->hd,
- (acb->cluster_offset >> 9) + index_in_cluster,
- acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- }
-}
-
-static BlockDriverAIOCB *qcow_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QCowAIOCB *acb;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->hd_aiocb = NULL;
- acb->sector_num = sector_num;
- acb->buf = buf;
- acb->nb_sectors = nb_sectors;
- acb->n = 0;
- acb->cluster_offset = 0;
-
- qcow_aio_read_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_write_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- uint64_t cluster_offset;
- const uint8_t *src_buf;
-
- acb->hd_aiocb = NULL;
-
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- acb->n = s->cluster_sectors - index_in_cluster;
- if (acb->n > acb->nb_sectors)
- acb->n = acb->nb_sectors;
- cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
- index_in_cluster,
- index_in_cluster + acb->n);
- if (!cluster_offset || (cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- if (s->crypt_method) {
- if (!acb->cluster_data) {
- acb->cluster_data = qemu_mallocz(s->cluster_size);
- if (!acb->cluster_data) {
- ret = -ENOMEM;
- goto fail;
- }
- }
- encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
- acb->n, 1, &s->aes_encrypt_key);
- src_buf = acb->cluster_data;
- } else {
- src_buf = acb->buf;
- }
- acb->hd_aiocb = bdrv_aio_write(s->hd,
- (cluster_offset >> 9) + index_in_cluster,
- src_buf, acb->n,
- qcow_aio_write_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
-}
-
-static BlockDriverAIOCB *qcow_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVQcowState *s = bs->opaque;
- QCowAIOCB *acb;
-
- s->cluster_cache_offset = -1; /* disable compressed cache */
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->hd_aiocb = NULL;
- acb->sector_num = sector_num;
- acb->buf = (uint8_t *)buf;
- acb->nb_sectors = nb_sectors;
- acb->n = 0;
-
- qcow_aio_write_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- QCowAIOCB *acb = (QCowAIOCB *)blockacb;
- if (acb->hd_aiocb)
- bdrv_aio_cancel(acb->hd_aiocb);
- qemu_aio_release(acb);
-}
-
-static void qcow_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- bdrv_delete(s->hd);
-}
-
-static int qcow_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd, header_size, backing_filename_len, l1_size, i, shift;
- QCowHeader header;
- uint64_t tmp;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
- if (fd < 0)
- return -1;
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(QCOW_VERSION);
- header.size = cpu_to_be64(total_size * 512);
- header_size = sizeof(header);
- backing_filename_len = 0;
- if (backing_file) {
- if (strcmp(backing_file, "fat:")) {
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_file);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
- } else {
- /* special backing file for vvfat */
- backing_file = NULL;
- }
- header.cluster_bits = 9; /* 512 byte cluster to avoid copying
- unmodifyed sectors */
- header.l2_bits = 12; /* 32 KB L2 tables */
- } else {
- header.cluster_bits = 12; /* 4 KB clusters */
- header.l2_bits = 9; /* 4 KB L2 tables */
- }
- header_size = (header_size + 7) & ~7;
- shift = header.cluster_bits + header.l2_bits;
- l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
-
- header.l1_table_offset = cpu_to_be64(header_size);
- if (flags & BLOCK_FLAG_ENCRYPT) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
-
- /* write all the data */
- write(fd, &header, sizeof(header));
- if (backing_file) {
- write(fd, backing_file, backing_filename_len);
- }
- lseek(fd, header_size, SEEK_SET);
- tmp = 0;
- for(i = 0;i < l1_size; i++) {
- write(fd, &tmp, sizeof(tmp));
- }
- close(fd);
- return 0;
-}
-
-static int qcow_make_empty(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- uint32_t l1_length = s->l1_size * sizeof(uint64_t);
- int ret;
-
- memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite(s->hd, s->l1_table_offset, s->l1_table, l1_length) < 0)
- return -1;
- ret = bdrv_truncate(s->hd, s->l1_table_offset + l1_length);
- if (ret < 0)
- return ret;
-
- memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
- memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
-
- return 0;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (nb_sectors != s->cluster_sectors)
- return -EINVAL;
-
- out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
- if (!out_buf)
- return -1;
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- qemu_free(out_buf);
- return -1;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- qemu_free(out_buf);
- deflateEnd(&strm);
- return -1;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- qcow_write(bs, sector_num, buf, s->cluster_sectors);
- } else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
- out_len, 0, 0);
- cluster_offset &= s->cluster_offset_mask;
- if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
- qemu_free(out_buf);
- return -1;
- }
- }
-
- qemu_free(out_buf);
- return 0;
-}
-
-static void qcow_flush(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- bdrv_flush(s->hd);
-}
-
-static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQcowState *s = bs->opaque;
- bdi->cluster_size = s->cluster_size;
- return 0;
-}
-
-BlockDriver bdrv_qcow = {
- "qcow",
- sizeof(BDRVQcowState),
- qcow_probe,
- qcow_open,
- NULL,
- NULL,
- qcow_close,
- qcow_create,
- qcow_flush,
- qcow_is_allocated,
- qcow_set_key,
- qcow_make_empty,
-
- .bdrv_aio_read = qcow_aio_read,
- .bdrv_aio_write = qcow_aio_write,
- .bdrv_aio_cancel = qcow_aio_cancel,
- .aiocb_size = sizeof(QCowAIOCB),
- .bdrv_write_compressed = qcow_write_compressed,
- .bdrv_get_info = qcow_get_info,
-};
diff --git a/block-qcow2.c b/block-qcow2.c
deleted file mode 100644
index 5f0fbe8..0000000
--- a/block-qcow2.c
+++ /dev/null
@@ -1,2620 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-#include <zlib.h>
-#include "aes.h"
-#include <assert.h>
-
-/*
- Differences with QCOW:
-
- - Support for multiple incremental snapshots.
- - Memory management by reference counts.
- - Clusters which have a reference count of one have the bit
- QCOW_OFLAG_COPIED to optimize write performance.
- - Size of compressed clusters is stored in sectors to reduce bit usage
- in the cluster offsets.
- - Support for storing additional data (such as the VM state) in the
- snapshots.
- - If a backing store is used, the cluster size is not constrained
- (could be backported to QCOW).
- - L2 tables have always a size of one cluster.
-*/
-
-//#define DEBUG_ALLOC
-//#define DEBUG_ALLOC2
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW_VERSION 2
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-#define QCOW_MAX_CRYPT_CLUSTERS 32
-
-/* indicate that the refcount of the referenced cluster is exactly one. */
-#define QCOW_OFLAG_COPIED (1LL << 63)
-/* indicate that the cluster is compressed (they never have the copied flag) */
-#define QCOW_OFLAG_COMPRESSED (1LL << 62)
-
-#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t cluster_bits;
- uint64_t size; /* in bytes */
- uint32_t crypt_method;
- uint32_t l1_size; /* XXX: save number of clusters instead ? */
- uint64_t l1_table_offset;
- uint64_t refcount_table_offset;
- uint32_t refcount_table_clusters;
- uint32_t nb_snapshots;
- uint64_t snapshots_offset;
-} QCowHeader;
-
-typedef struct __attribute__((packed)) QCowSnapshotHeader {
- /* header is 8 byte aligned */
- uint64_t l1_table_offset;
-
- uint32_t l1_size;
- uint16_t id_str_size;
- uint16_t name_size;
-
- uint32_t date_sec;
- uint32_t date_nsec;
-
- uint64_t vm_clock_nsec;
-
- uint32_t vm_state_size;
- uint32_t extra_data_size; /* for extension */
- /* extra data follows */
- /* id_str follows */
- /* name follows */
-} QCowSnapshotHeader;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct QCowSnapshot {
- uint64_t l1_table_offset;
- uint32_t l1_size;
- char *id_str;
- char *name;
- uint32_t vm_state_size;
- uint32_t date_sec;
- uint32_t date_nsec;
- uint64_t vm_clock_nsec;
-} QCowSnapshot;
-
-typedef struct BDRVQcowState {
- BlockDriverState *hd;
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- int l1_vm_state_index;
- int csize_shift;
- int csize_mask;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
- uint64_t *l2_cache;
- uint64_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
-
- uint64_t *refcount_table;
- uint64_t refcount_table_offset;
- uint32_t refcount_table_size;
- uint64_t refcount_block_cache_offset;
- uint16_t *refcount_block_cache;
- int64_t free_cluster_index;
- int64_t free_byte_offset;
-
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
- uint64_t snapshots_offset;
- int snapshots_size;
- int nb_snapshots;
- QCowSnapshot *snapshots;
-} BDRVQcowState;
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-static int qcow_read_snapshots(BlockDriverState *bs);
-static void qcow_free_snapshots(BlockDriverState *bs);
-static int refcount_init(BlockDriverState *bs);
-static void refcount_close(BlockDriverState *bs);
-static int get_refcount(BlockDriverState *bs, int64_t cluster_index);
-static int update_cluster_refcount(BlockDriverState *bs,
- int64_t cluster_index,
- int addend);
-static void update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
- int addend);
-static int64_t alloc_clusters(BlockDriverState *bs, int64_t size);
-static int64_t alloc_bytes(BlockDriverState *bs, int size);
-static void free_clusters(BlockDriverState *bs,
- int64_t offset, int64_t size);
-#ifdef DEBUG_ALLOC
-static void check_refcounts(BlockDriverState *bs);
-#endif
-
-static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(QCowHeader) &&
- be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVQcowState *s = bs->opaque;
- int len, i, shift, ret;
- QCowHeader header;
-
- ret = bdrv_file_open(&s->hd, filename, flags);
- if (ret < 0)
- return ret;
- if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
- goto fail;
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.cluster_bits);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
- be32_to_cpus(&header.l1_size);
- be64_to_cpus(&header.refcount_table_offset);
- be32_to_cpus(&header.refcount_table_clusters);
- be64_to_cpus(&header.snapshots_offset);
- be32_to_cpus(&header.nb_snapshots);
-
- if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
- goto fail;
- if (header.size <= 1 ||
- header.cluster_bits < 9 ||
- header.cluster_bits > 16)
- goto fail;
- if (header.crypt_method > QCOW_CRYPT_AES)
- goto fail;
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header)
- bs->encrypted = 1;
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->csize_shift = (62 - (s->cluster_bits - 8));
- s->csize_mask = (1 << (s->cluster_bits - 8)) - 1;
- s->cluster_offset_mask = (1LL << s->csize_shift) - 1;
- s->refcount_table_offset = header.refcount_table_offset;
- s->refcount_table_size =
- header.refcount_table_clusters << (s->cluster_bits - 3);
-
- s->snapshots_offset = header.snapshots_offset;
- s->nb_snapshots = header.nb_snapshots;
-
- /* read the level 1 table */
- s->l1_size = header.l1_size;
- shift = s->cluster_bits + s->l2_bits;
- s->l1_vm_state_index = (header.size + (1LL << shift) - 1) >> shift;
- /* the L1 table must contain at least enough entries to put
- header.size bytes */
- if (s->l1_size < s->l1_vm_state_index)
- goto fail;
- s->l1_table_offset = header.l1_table_offset;
- s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!s->l1_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
- s->l1_size * sizeof(uint64_t))
- goto fail;
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- /* alloc L2 cache */
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- if (!s->l2_cache)
- goto fail;
- s->cluster_cache = qemu_malloc(s->cluster_size);
- if (!s->cluster_cache)
- goto fail;
- /* one more sector for decompressed data alignment */
- s->cluster_data = qemu_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size
- + 512);
- if (!s->cluster_data)
- goto fail;
- s->cluster_cache_offset = -1;
-
- if (refcount_init(bs) < 0)
- goto fail;
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023)
- len = 1023;
- if (bdrv_pread(s->hd, header.backing_file_offset, bs->backing_file, len) != len)
- goto fail;
- bs->backing_file[len] = '\0';
- }
- if (qcow_read_snapshots(bs) < 0)
- goto fail;
-
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
-
- fail:
- qcow_free_snapshots(bs);
- refcount_close(bs);
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- bdrv_delete(s->hd);
- return -1;
-}
-
-static int qcow_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
-#if 0
- /* test */
- {
- uint8_t in[16];
- uint8_t out[16];
- uint8_t tmp[16];
- for(i=0;i<16;i++)
- in[i] = i;
- AES_encrypt(in, tmp, &s->aes_encrypt_key);
- AES_decrypt(tmp, out, &s->aes_decrypt_key);
- for(i = 0; i < 16; i++)
- printf(" %02x", tmp[i]);
- printf("\n");
- for(i = 0; i < 16; i++)
- printf(" %02x", out[i]);
- printf("\n");
- }
-#endif
- return 0;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
- uint64_t cluster_offset, int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int n, ret;
-
- n = n_end - n_start;
- if (n <= 0)
- return 0;
- ret = qcow_read(bs, start_sect + n_start, s->cluster_data, n);
- if (ret < 0)
- return ret;
- if (s->crypt_method) {
- encrypt_sectors(s, start_sect + n_start,
- s->cluster_data,
- s->cluster_data, n, 1,
- &s->aes_encrypt_key);
- }
- ret = bdrv_write(s->hd, (cluster_offset >> 9) + n_start,
- s->cluster_data, n);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static void l2_cache_reset(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
-
- memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
- memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
-}
-
-static inline int l2_cache_new_entry(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- uint32_t min_count;
- int min_index, i;
-
- /* find a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- return min_index;
-}
-
-static int64_t align_offset(int64_t offset, int n)
-{
- offset = (offset + n - 1) & ~(n - 1);
- return offset;
-}
-
-static int grow_l1_table(BlockDriverState *bs, int min_size)
-{
- BDRVQcowState *s = bs->opaque;
- int new_l1_size, new_l1_size2, ret, i;
- uint64_t *new_l1_table;
- uint64_t new_l1_table_offset;
- uint64_t data64;
- uint32_t data32;
-
- new_l1_size = s->l1_size;
- if (min_size <= new_l1_size)
- return 0;
- while (min_size > new_l1_size) {
- new_l1_size = (new_l1_size * 3 + 1) / 2;
- }
-#ifdef DEBUG_ALLOC2
- printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
-#endif
-
- new_l1_size2 = sizeof(uint64_t) * new_l1_size;
- new_l1_table = qemu_mallocz(new_l1_size2);
- if (!new_l1_table)
- return -ENOMEM;
- memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
-
- /* write new table (align to cluster) */
- new_l1_table_offset = alloc_clusters(bs, new_l1_size2);
-
- for(i = 0; i < s->l1_size; i++)
- new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
- ret = bdrv_pwrite(s->hd, new_l1_table_offset, new_l1_table, new_l1_size2);
- if (ret != new_l1_size2)
- goto fail;
- for(i = 0; i < s->l1_size; i++)
- new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
-
- /* set new table */
- data64 = cpu_to_be64(new_l1_table_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_table_offset),
- &data64, sizeof(data64)) != sizeof(data64))
- goto fail;
- data32 = cpu_to_be32(new_l1_size);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size),
- &data32, sizeof(data32)) != sizeof(data32))
- goto fail;
- qemu_free(s->l1_table);
- free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
- s->l1_table_offset = new_l1_table_offset;
- s->l1_table = new_l1_table;
- s->l1_size = new_l1_size;
- return 0;
- fail:
- qemu_free(s->l1_table);
- return -EIO;
-}
-
-/*
- * seek_l2_table
- *
- * seek l2_offset in the l2_cache table
- * if not found, return NULL,
- * if found,
- * increments the l2 cache hit count of the entry,
- * if counter overflow, divide by two all counters
- * return the pointer to the l2 cache entry
- *
- */
-
-static uint64_t *seek_l2_table(BDRVQcowState *s, uint64_t l2_offset)
-{
- int i, j;
-
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- return s->l2_cache + (i << s->l2_bits);
- }
- }
- return NULL;
-}
-
-/*
- * l2_load
- *
- * Loads a L2 table into memory. If the table is in the cache, the cache
- * is used; otherwise the L2 table is loaded from the image file.
- *
- * Returns a pointer to the L2 table on success, or NULL if the read from
- * the image file failed.
- */
-
-static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index;
- uint64_t *l2_table;
-
- /* seek if the table for the given offset is in the cache */
-
- l2_table = seek_l2_table(s, l2_offset);
- if (l2_table != NULL)
- return l2_table;
-
- /* not found: load a new entry in the least used one */
-
- min_index = l2_cache_new_entry(bs);
- l2_table = s->l2_cache + (min_index << s->l2_bits);
- if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return NULL;
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
-
- return l2_table;
-}
-
-/*
- * l2_allocate
- *
- * Allocate a new l2 entry in the file. If l1_index points to an already
- * used entry in the L2 table (i.e. we are doing a copy on write for the L2
- * table) copy the contents of the old L2 table into the newly allocated one.
- * Otherwise the new table is initialized with zeros.
- *
- */
-
-static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index;
- uint64_t old_l2_offset, tmp;
- uint64_t *l2_table, l2_offset;
-
- old_l2_offset = s->l1_table[l1_index];
-
- /* allocate a new l2 entry */
-
- l2_offset = alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
-
- /* update the L1 entry */
-
- s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
-
- tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED);
- if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
- &tmp, sizeof(tmp)) != sizeof(tmp))
- return NULL;
-
- /* allocate a new entry in the l2 cache */
-
- min_index = l2_cache_new_entry(bs);
- l2_table = s->l2_cache + (min_index << s->l2_bits);
-
- if (old_l2_offset == 0) {
- /* if there was no old l2 table, clear the new table */
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- } else {
- /* if there was an old l2 table, read it from the disk */
- if (bdrv_pread(s->hd, old_l2_offset,
- l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return NULL;
- }
- /* write the l2 table to the file */
- if (bdrv_pwrite(s->hd, l2_offset,
- l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return NULL;
-
- /* update the l2 cache entry */
-
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
-
- return l2_table;
-}
-
-/*
- * get_cluster_offset
- *
- * For a given offset of the disk image, return cluster offset in
- * qcow2 file.
- *
- * on entry, *num is the number of contiguous clusters we'd like to
- * access following offset.
- *
- * on exit, *num is the number of contiguous clusters we can read.
- *
- * Return 1, if the offset is found
- * Return 0, otherwise.
- *
- */
-
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset, int *num)
-{
- BDRVQcowState *s = bs->opaque;
- int l1_index, l2_index;
- uint64_t l2_offset, *l2_table, cluster_offset, next;
- int l1_bits;
- int index_in_cluster, nb_available, nb_needed;
-
- index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
- nb_needed = *num + index_in_cluster;
-
- l1_bits = s->l2_bits + s->cluster_bits;
-
- /* compute how many bytes there are between the offset and
- * and the end of the l1 entry
- */
-
- nb_available = (1 << l1_bits) - (offset & ((1 << l1_bits) - 1));
-
- /* compute the number of available sectors */
-
- nb_available = (nb_available >> 9) + index_in_cluster;
-
- cluster_offset = 0;
-
- /* seek the the l2 offset in the l1 table */
-
- l1_index = offset >> l1_bits;
- if (l1_index >= s->l1_size)
- goto out;
-
- l2_offset = s->l1_table[l1_index];
-
- /* seek the l2 table of the given l2 offset */
-
- if (!l2_offset)
- goto out;
-
- /* load the l2 table in memory */
-
- l2_offset &= ~QCOW_OFLAG_COPIED;
- l2_table = l2_load(bs, l2_offset);
- if (l2_table == NULL)
- return 0;
-
- /* find the cluster offset for the given disk offset */
-
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- nb_available = s->cluster_sectors;
- l2_index++;
-
- if (!cluster_offset) {
-
- /* how many empty clusters ? */
-
- while (nb_available < nb_needed && !l2_table[l2_index]) {
- l2_index++;
- nb_available += s->cluster_sectors;
- }
- } else {
-
- /* how many allocated clusters ? */
-
- cluster_offset &= ~QCOW_OFLAG_COPIED;
- while (nb_available < nb_needed) {
- next = be64_to_cpu(l2_table[l2_index]) & ~QCOW_OFLAG_COPIED;
- if (next != cluster_offset + (nb_available << 9))
- break;
- l2_index++;
- nb_available += s->cluster_sectors;
- }
- }
-
-out:
- if (nb_available > nb_needed)
- nb_available = nb_needed;
-
- *num = nb_available - index_in_cluster;
-
- return cluster_offset;
-}
-
-/*
- * free_any_clusters
- *
- * free clusters according to its type: compressed or not
- *
- */
-
-static void free_any_clusters(BlockDriverState *bs,
- uint64_t cluster_offset, int nb_clusters)
-{
- BDRVQcowState *s = bs->opaque;
-
- /* free the cluster */
-
- if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- int nb_csectors;
- nb_csectors = ((cluster_offset >> s->csize_shift) &
- s->csize_mask) + 1;
- free_clusters(bs, (cluster_offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512);
- return;
- }
-
- free_clusters(bs, cluster_offset, nb_clusters << s->cluster_bits);
-
- return;
-}
-
-/*
- * get_cluster_table
- *
- * for a given disk offset, load (and allocate if needed)
- * the l2 table.
- *
- * the l2 table offset in the qcow2 file and the cluster index
- * in the l2 table are given to the caller.
- *
- */
-
-static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
- uint64_t **new_l2_table,
- uint64_t *new_l2_offset,
- int *new_l2_index)
-{
- BDRVQcowState *s = bs->opaque;
- int l1_index, l2_index, ret;
- uint64_t l2_offset, *l2_table;
-
- /* seek the the l2 offset in the l1 table */
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- if (l1_index >= s->l1_size) {
- ret = grow_l1_table(bs, l1_index + 1);
- if (ret < 0)
- return 0;
- }
- l2_offset = s->l1_table[l1_index];
-
- /* seek the l2 table of the given l2 offset */
-
- if (l2_offset & QCOW_OFLAG_COPIED) {
- /* load the l2 table in memory */
- l2_offset &= ~QCOW_OFLAG_COPIED;
- l2_table = l2_load(bs, l2_offset);
- if (l2_table == NULL)
- return 0;
- } else {
- if (l2_offset)
- free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
- l2_table = l2_allocate(bs, l1_index);
- if (l2_table == NULL)
- return 0;
- l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
- }
-
- /* find the cluster offset for the given disk offset */
-
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
-
- *new_l2_table = l2_table;
- *new_l2_offset = l2_offset;
- *new_l2_index = l2_index;
-
- return 1;
-}
-
-/*
- * alloc_compressed_cluster_offset
- *
- * For a given offset of the disk image, return cluster offset in
- * qcow2 file.
- *
- * If the offset is not found, allocate a new compressed cluster.
- *
- * Return the cluster offset if successful,
- * Return 0, otherwise.
- *
- */
-
-static uint64_t alloc_compressed_cluster_offset(BlockDriverState *bs,
- uint64_t offset,
- int compressed_size)
-{
- BDRVQcowState *s = bs->opaque;
- int l2_index, ret;
- uint64_t l2_offset, *l2_table, cluster_offset;
- int nb_csectors;
-
- ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
- if (ret == 0)
- return 0;
-
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (cluster_offset & QCOW_OFLAG_COPIED)
- return cluster_offset & ~QCOW_OFLAG_COPIED;
-
- if (cluster_offset)
- free_any_clusters(bs, cluster_offset, 1);
-
- cluster_offset = alloc_bytes(bs, compressed_size);
- nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
- (cluster_offset >> 9);
-
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- ((uint64_t)nb_csectors << s->csize_shift);
-
- /* update L2 table */
-
- /* compressed clusters never have the copied flag */
-
- l2_table[l2_index] = cpu_to_be64(cluster_offset);
- if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(uint64_t),
- l2_table + l2_index,
- sizeof(uint64_t)) != sizeof(uint64_t))
- return 0;
-
- return cluster_offset;
-}
-
-/*
- * alloc_cluster_offset
- *
- * For a given offset of the disk image, return cluster offset in
- * qcow2 file.
- *
- * If the offset is not found, allocate a new cluster.
- *
- * Return the cluster offset if successful,
- * Return 0, otherwise.
- *
- */
-
-static uint64_t alloc_cluster_offset(BlockDriverState *bs,
- uint64_t offset,
- int n_start, int n_end,
- int *num)
-{
- BDRVQcowState *s = bs->opaque;
- int l2_index, ret;
- uint64_t l2_offset, *l2_table, cluster_offset;
- int nb_available, nb_clusters, i, j;
- uint64_t start_sect, current;
-
- ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
- if (ret == 0)
- return 0;
-
- nb_clusters = ((n_end << 9) + s->cluster_size - 1) >>
- s->cluster_bits;
- if (nb_clusters > s->l2_size - l2_index)
- nb_clusters = s->l2_size - l2_index;
-
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
-
- /* We keep all QCOW_OFLAG_COPIED clusters */
-
- if (cluster_offset & QCOW_OFLAG_COPIED) {
-
- for (i = 1; i < nb_clusters; i++) {
- current = be64_to_cpu(l2_table[l2_index + i]);
- if (cluster_offset + (i << s->cluster_bits) != current)
- break;
- }
- nb_clusters = i;
-
- nb_available = nb_clusters << (s->cluster_bits - 9);
- if (nb_available > n_end)
- nb_available = n_end;
-
- cluster_offset &= ~QCOW_OFLAG_COPIED;
-
- goto out;
- }
-
- /* for the moment, multiple compressed clusters are not managed */
-
- if (cluster_offset & QCOW_OFLAG_COMPRESSED)
- nb_clusters = 1;
-
- /* how many available clusters ? */
-
- i = 0;
- while (i < nb_clusters) {
-
- i++;
-
- if (!cluster_offset) {
-
- /* how many free clusters ? */
-
- while (i < nb_clusters) {
- cluster_offset = l2_table[l2_index + i];
- if (cluster_offset != 0)
- break;
- i++;
- }
-
- if ((cluster_offset & QCOW_OFLAG_COPIED) ||
- (cluster_offset & QCOW_OFLAG_COMPRESSED))
- break;
-
- } else {
-
- /* how many contiguous clusters ? */
-
- j = 1;
- current = 0;
- while (i < nb_clusters) {
- current = be64_to_cpu(l2_table[l2_index + i]);
- if (cluster_offset + (j << s->cluster_bits) != current)
- break;
-
- i++;
- j++;
- }
-
- free_any_clusters(bs, cluster_offset, j);
- if (current)
- break;
- cluster_offset = current;
- }
- }
- nb_clusters = i;
-
- /* allocate a new cluster */
-
- cluster_offset = alloc_clusters(bs, nb_clusters * s->cluster_size);
-
- /* we must initialize the cluster content which won't be
- written */
-
- nb_available = nb_clusters << (s->cluster_bits - 9);
- if (nb_available > n_end)
- nb_available = n_end;
-
- /* copy content of unmodified sectors */
-
- start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
- if (n_start) {
- ret = copy_sectors(bs, start_sect, cluster_offset, 0, n_start);
- if (ret < 0)
- return 0;
- }
-
- if (nb_available & (s->cluster_sectors - 1)) {
- uint64_t end = nb_available & ~(uint64_t)(s->cluster_sectors - 1);
- ret = copy_sectors(bs, start_sect + end,
- cluster_offset + (end << 9),
- nb_available - end,
- s->cluster_sectors);
- if (ret < 0)
- return 0;
- }
-
- /* update L2 table */
-
- for (i = 0; i < nb_clusters; i++)
- l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
- (i << s->cluster_bits)) |
- QCOW_OFLAG_COPIED);
-
- if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(uint64_t),
- l2_table + l2_index,
- nb_clusters * sizeof(uint64_t)) !=
- nb_clusters * sizeof(uint64_t))
- return 0;
-
-out:
- *num = nb_available - n_start;
-
- return cluster_offset;
-}
-
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- uint64_t cluster_offset;
-
- *pnum = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, pnum);
-
- return (cluster_offset != 0);
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
-{
- int ret, csize, nb_csectors, sector_offset;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
- sector_offset = coffset & 511;
- csize = nb_csectors * 512 - sector_offset;
- ret = bdrv_read(s->hd, coffset >> 9, s->cluster_data, nb_csectors);
- if (ret < 0) {
- return -1;
- }
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data + sector_offset, csize) < 0) {
- return -1;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-/* handle reading after the end of the backing file */
-static int backing_read1(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors)
-{
- int n1;
- if ((sector_num + nb_sectors) <= bs->total_sectors)
- return nb_sectors;
- if (sector_num >= bs->total_sectors)
- n1 = 0;
- else
- n1 = bs->total_sectors - sector_num;
- memset(buf + n1 * 512, 0, 512 * (nb_sectors - n1));
- return n1;
-}
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n, n1;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, &n);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- if (!cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- n1 = backing_read1(bs->backing_hd, sector_num, buf, n);
- if (n1 > 0) {
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
- if (ret < 0)
- return -1;
- }
- } else {
- memset(buf, 0, 512 * n);
- }
- } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- if (decompress_cluster(s, cluster_offset) < 0)
- return -1;
- memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
- } else {
- ret = bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- if (ret != n * 512)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
- &s->aes_decrypt_key);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
- int n_end;
-
- while (nb_sectors > 0) {
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n_end = index_in_cluster + nb_sectors;
- if (s->crypt_method &&
- n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
- n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
- cluster_offset = alloc_cluster_offset(bs, sector_num << 9,
- index_in_cluster,
- n_end, &n);
- if (!cluster_offset)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
- &s->aes_encrypt_key);
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512,
- s->cluster_data, n * 512);
- } else {
- ret = bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512);
- }
- if (ret != n * 512)
- return -1;
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- s->cluster_cache_offset = -1; /* disable compressed cache */
- return 0;
-}
-
-typedef struct QCowAIOCB {
- BlockDriverAIOCB common;
- int64_t sector_num;
- uint8_t *buf;
- int nb_sectors;
- int n;
- uint64_t cluster_offset;
- uint8_t *cluster_data;
- BlockDriverAIOCB *hd_aiocb;
-} QCowAIOCB;
-
-static void qcow_aio_read_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n1;
-
- acb->hd_aiocb = NULL;
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- redo:
- /* post process the read buffer */
- if (!acb->cluster_offset) {
- /* nothing to do */
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* nothing to do */
- } else {
- if (s->crypt_method) {
- encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
- acb->n, 0,
- &s->aes_decrypt_key);
- }
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- /* prepare next AIO request */
- acb->n = acb->nb_sectors;
- acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, &acb->n);
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-
- if (!acb->cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- n1 = backing_read1(bs->backing_hd, acb->sector_num,
- acb->buf, acb->n);
- if (n1 > 0) {
- acb->hd_aiocb = bdrv_aio_read(bs->backing_hd, acb->sector_num,
- acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- } else {
- goto redo;
- }
- } else {
- /* Note: in this case, no need to wait */
- memset(acb->buf, 0, 512 * acb->n);
- goto redo;
- }
- } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* add AIO support for compressed blocks ? */
- if (decompress_cluster(s, acb->cluster_offset) < 0)
- goto fail;
- memcpy(acb->buf,
- s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
- goto redo;
- } else {
- if ((acb->cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- acb->hd_aiocb = bdrv_aio_read(s->hd,
- (acb->cluster_offset >> 9) + index_in_cluster,
- acb->buf, acb->n, qcow_aio_read_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
- }
-}
-
-static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QCowAIOCB *acb;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->hd_aiocb = NULL;
- acb->sector_num = sector_num;
- acb->buf = buf;
- acb->nb_sectors = nb_sectors;
- acb->n = 0;
- acb->cluster_offset = 0;
- return acb;
-}
-
-static BlockDriverAIOCB *qcow_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QCowAIOCB *acb;
-
- acb = qcow_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
-
- qcow_aio_read_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_write_cb(void *opaque, int ret)
-{
- QCowAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- uint64_t cluster_offset;
- const uint8_t *src_buf;
- int n_end;
-
- acb->hd_aiocb = NULL;
-
- if (ret < 0) {
- fail:
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- return;
- }
-
- acb->nb_sectors -= acb->n;
- acb->sector_num += acb->n;
- acb->buf += acb->n * 512;
-
- if (acb->nb_sectors == 0) {
- /* request completed */
- acb->common.cb(acb->common.opaque, 0);
- qemu_aio_release(acb);
- return;
- }
-
- index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
- n_end = index_in_cluster + acb->nb_sectors;
- if (s->crypt_method &&
- n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
- n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
-
- cluster_offset = alloc_cluster_offset(bs, acb->sector_num << 9,
- index_in_cluster,
- n_end, &acb->n);
- if (!cluster_offset || (cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
- if (s->crypt_method) {
- if (!acb->cluster_data) {
- acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
- s->cluster_size);
- if (!acb->cluster_data) {
- ret = -ENOMEM;
- goto fail;
- }
- }
- encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
- acb->n, 1, &s->aes_encrypt_key);
- src_buf = acb->cluster_data;
- } else {
- src_buf = acb->buf;
- }
- acb->hd_aiocb = bdrv_aio_write(s->hd,
- (cluster_offset >> 9) + index_in_cluster,
- src_buf, acb->n,
- qcow_aio_write_cb, acb);
- if (acb->hd_aiocb == NULL)
- goto fail;
-}
-
-static BlockDriverAIOCB *qcow_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVQcowState *s = bs->opaque;
- QCowAIOCB *acb;
-
- s->cluster_cache_offset = -1; /* disable compressed cache */
-
- acb = qcow_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
-
- qcow_aio_write_cb(acb, 0);
- return &acb->common;
-}
-
-static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- QCowAIOCB *acb = (QCowAIOCB *)blockacb;
- if (acb->hd_aiocb)
- bdrv_aio_cancel(acb->hd_aiocb);
- qemu_aio_release(acb);
-}
-
-static void qcow_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- refcount_close(bs);
- bdrv_delete(s->hd);
-}
-
-/* XXX: use std qcow open function ? */
-typedef struct QCowCreateState {
- int cluster_size;
- int cluster_bits;
- uint16_t *refcount_block;
- uint64_t *refcount_table;
- int64_t l1_table_offset;
- int64_t refcount_table_offset;
- int64_t refcount_block_offset;
-} QCowCreateState;
-
-static void create_refcount_update(QCowCreateState *s,
- int64_t offset, int64_t size)
-{
- int refcount;
- int64_t start, last, cluster_offset;
- uint16_t *p;
-
- start = offset & ~(s->cluster_size - 1);
- last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- p = &s->refcount_block[cluster_offset >> s->cluster_bits];
- refcount = be16_to_cpu(*p);
- refcount++;
- *p = cpu_to_be16(refcount);
- }
-}
-
-static int qcow_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
- QCowHeader header;
- uint64_t tmp, offset;
- QCowCreateState s1, *s = &s1;
-
- memset(s, 0, sizeof(*s));
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
- if (fd < 0)
- return -1;
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(QCOW_VERSION);
- header.size = cpu_to_be64(total_size * 512);
- header_size = sizeof(header);
- backing_filename_len = 0;
- if (backing_file) {
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_file);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
- }
- s->cluster_bits = 12; /* 4 KB clusters */
- s->cluster_size = 1 << s->cluster_bits;
- header.cluster_bits = cpu_to_be32(s->cluster_bits);
- header_size = (header_size + 7) & ~7;
- if (flags & BLOCK_FLAG_ENCRYPT) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
- l2_bits = s->cluster_bits - 3;
- shift = s->cluster_bits + l2_bits;
- l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);
- offset = align_offset(header_size, s->cluster_size);
- s->l1_table_offset = offset;
- header.l1_table_offset = cpu_to_be64(s->l1_table_offset);
- header.l1_size = cpu_to_be32(l1_size);
- offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
-
- s->refcount_table = qemu_mallocz(s->cluster_size);
- if (!s->refcount_table)
- goto fail;
- s->refcount_block = qemu_mallocz(s->cluster_size);
- if (!s->refcount_block)
- goto fail;
-
- s->refcount_table_offset = offset;
- header.refcount_table_offset = cpu_to_be64(offset);
- header.refcount_table_clusters = cpu_to_be32(1);
- offset += s->cluster_size;
-
- s->refcount_table[0] = cpu_to_be64(offset);
- s->refcount_block_offset = offset;
- offset += s->cluster_size;
-
- /* update refcounts */
- create_refcount_update(s, 0, header_size);
- create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
- create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
- create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
-
- /* write all the data */
- write(fd, &header, sizeof(header));
- if (backing_file) {
- write(fd, backing_file, backing_filename_len);
- }
- lseek(fd, s->l1_table_offset, SEEK_SET);
- tmp = 0;
- for(i = 0;i < l1_size; i++) {
- write(fd, &tmp, sizeof(tmp));
- }
- lseek(fd, s->refcount_table_offset, SEEK_SET);
- write(fd, s->refcount_table, s->cluster_size);
-
- lseek(fd, s->refcount_block_offset, SEEK_SET);
- write(fd, s->refcount_block, s->cluster_size);
-
- qemu_free(s->refcount_table);
- qemu_free(s->refcount_block);
- close(fd);
- return 0;
- fail:
- qemu_free(s->refcount_table);
- qemu_free(s->refcount_block);
- close(fd);
- return -ENOMEM;
-}
-
-static int qcow_make_empty(BlockDriverState *bs)
-{
-#if 0
- /* XXX: not correct */
- BDRVQcowState *s = bs->opaque;
- uint32_t l1_length = s->l1_size * sizeof(uint64_t);
- int ret;
-
- memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite(s->hd, s->l1_table_offset, s->l1_table, l1_length) < 0)
- return -1;
- ret = bdrv_truncate(s->hd, s->l1_table_offset + l1_length);
- if (ret < 0)
- return ret;
-
- l2_cache_reset(bs);
-#endif
- return 0;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (nb_sectors == 0) {
- /* align end of file to a sector boundary to ease reading with
- sector based I/Os */
- cluster_offset = bdrv_getlength(s->hd);
- cluster_offset = (cluster_offset + 511) & ~511;
- bdrv_truncate(s->hd, cluster_offset);
- return 0;
- }
-
- if (nb_sectors != s->cluster_sectors)
- return -EINVAL;
-
- out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
- if (!out_buf)
- return -ENOMEM;
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- qemu_free(out_buf);
- return -1;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- qemu_free(out_buf);
- deflateEnd(&strm);
- return -1;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- qcow_write(bs, sector_num, buf, s->cluster_sectors);
- } else {
- cluster_offset = alloc_compressed_cluster_offset(bs, sector_num << 9,
- out_len);
- if (!cluster_offset)
- return -1;
- cluster_offset &= s->cluster_offset_mask;
- if (bdrv_pwrite(s->hd, cluster_offset, out_buf, out_len) != out_len) {
- qemu_free(out_buf);
- return -1;
- }
- }
-
- qemu_free(out_buf);
- return 0;
-}
-
-static void qcow_flush(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- bdrv_flush(s->hd);
-}
-
-static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQcowState *s = bs->opaque;
- bdi->cluster_size = s->cluster_size;
- bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
- (s->cluster_bits + s->l2_bits);
- return 0;
-}
-
-/*********************************************************/
-/* snapshot support */
-
-/* update the refcounts of snapshots and the copied flag */
-static int update_snapshot_refcount(BlockDriverState *bs,
- int64_t l1_table_offset,
- int l1_size,
- int addend)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated;
- int64_t old_offset, old_l2_offset;
- int l2_size, i, j, l1_modified, l2_modified, nb_csectors, refcount;
-
- l2_cache_reset(bs);
-
- l2_table = NULL;
- l1_table = NULL;
- l1_size2 = l1_size * sizeof(uint64_t);
- l1_allocated = 0;
- if (l1_table_offset != s->l1_table_offset) {
- l1_table = qemu_malloc(l1_size2);
- if (!l1_table)
- goto fail;
- l1_allocated = 1;
- if (bdrv_pread(s->hd, l1_table_offset,
- l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
- } else {
- assert(l1_size == s->l1_size);
- l1_table = s->l1_table;
- l1_allocated = 0;
- }
-
- l2_size = s->l2_size * sizeof(uint64_t);
- l2_table = qemu_malloc(l2_size);
- if (!l2_table)
- goto fail;
- l1_modified = 0;
- for(i = 0; i < l1_size; i++) {
- l2_offset = l1_table[i];
- if (l2_offset) {
- old_l2_offset = l2_offset;
- l2_offset &= ~QCOW_OFLAG_COPIED;
- l2_modified = 0;
- if (bdrv_pread(s->hd, l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
- for(j = 0; j < s->l2_size; j++) {
- offset = be64_to_cpu(l2_table[j]);
- if (offset != 0) {
- old_offset = offset;
- offset &= ~QCOW_OFLAG_COPIED;
- if (offset & QCOW_OFLAG_COMPRESSED) {
- nb_csectors = ((offset >> s->csize_shift) &
- s->csize_mask) + 1;
- if (addend != 0)
- update_refcount(bs, (offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512, addend);
- /* compressed clusters are never modified */
- refcount = 2;
- } else {
- if (addend != 0) {
- refcount = update_cluster_refcount(bs, offset >> s->cluster_bits, addend);
- } else {
- refcount = get_refcount(bs, offset >> s->cluster_bits);
- }
- }
-
- if (refcount == 1) {
- offset |= QCOW_OFLAG_COPIED;
- }
- if (offset != old_offset) {
- l2_table[j] = cpu_to_be64(offset);
- l2_modified = 1;
- }
- }
- }
- if (l2_modified) {
- if (bdrv_pwrite(s->hd,
- l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
- }
-
- if (addend != 0) {
- refcount = update_cluster_refcount(bs, l2_offset >> s->cluster_bits, addend);
- } else {
- refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
- }
- if (refcount == 1) {
- l2_offset |= QCOW_OFLAG_COPIED;
- }
- if (l2_offset != old_l2_offset) {
- l1_table[i] = l2_offset;
- l1_modified = 1;
- }
- }
- }
- if (l1_modified) {
- for(i = 0; i < l1_size; i++)
- cpu_to_be64s(&l1_table[i]);
- if (bdrv_pwrite(s->hd, l1_table_offset, l1_table,
- l1_size2) != l1_size2)
- goto fail;
- for(i = 0; i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
- }
- if (l1_allocated)
- qemu_free(l1_table);
- qemu_free(l2_table);
- return 0;
- fail:
- if (l1_allocated)
- qemu_free(l1_table);
- qemu_free(l2_table);
- return -EIO;
-}
-
-static void qcow_free_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- qemu_free(s->snapshots[i].name);
- qemu_free(s->snapshots[i].id_str);
- }
- qemu_free(s->snapshots);
- s->snapshots = NULL;
- s->nb_snapshots = 0;
-}
-
-static int qcow_read_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshotHeader h;
- QCowSnapshot *sn;
- int i, id_str_size, name_size;
- int64_t offset;
- uint32_t extra_data_size;
-
- offset = s->snapshots_offset;
- s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot));
- if (!s->snapshots)
- goto fail;
- for(i = 0; i < s->nb_snapshots; i++) {
- offset = align_offset(offset, 8);
- if (bdrv_pread(s->hd, offset, &h, sizeof(h)) != sizeof(h))
- goto fail;
- offset += sizeof(h);
- sn = s->snapshots + i;
- sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
- sn->l1_size = be32_to_cpu(h.l1_size);
- sn->vm_state_size = be32_to_cpu(h.vm_state_size);
- sn->date_sec = be32_to_cpu(h.date_sec);
- sn->date_nsec = be32_to_cpu(h.date_nsec);
- sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
- extra_data_size = be32_to_cpu(h.extra_data_size);
-
- id_str_size = be16_to_cpu(h.id_str_size);
- name_size = be16_to_cpu(h.name_size);
-
- offset += extra_data_size;
-
- sn->id_str = qemu_malloc(id_str_size + 1);
- if (!sn->id_str)
- goto fail;
- if (bdrv_pread(s->hd, offset, sn->id_str, id_str_size) != id_str_size)
- goto fail;
- offset += id_str_size;
- sn->id_str[id_str_size] = '\0';
-
- sn->name = qemu_malloc(name_size + 1);
- if (!sn->name)
- goto fail;
- if (bdrv_pread(s->hd, offset, sn->name, name_size) != name_size)
- goto fail;
- offset += name_size;
- sn->name[name_size] = '\0';
- }
- s->snapshots_size = offset - s->snapshots_offset;
- return 0;
- fail:
- qcow_free_snapshots(bs);
- return -1;
-}
-
-/* add at the end of the file a new list of snapshots */
-static int qcow_write_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- QCowSnapshotHeader h;
- int i, name_size, id_str_size, snapshots_size;
- uint64_t data64;
- uint32_t data32;
- int64_t offset, snapshots_offset;
-
- /* compute the size of the snapshots */
- offset = 0;
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- offset = align_offset(offset, 8);
- offset += sizeof(h);
- offset += strlen(sn->id_str);
- offset += strlen(sn->name);
- }
- snapshots_size = offset;
-
- snapshots_offset = alloc_clusters(bs, snapshots_size);
- offset = snapshots_offset;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- memset(&h, 0, sizeof(h));
- h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
- h.l1_size = cpu_to_be32(sn->l1_size);
- h.vm_state_size = cpu_to_be32(sn->vm_state_size);
- h.date_sec = cpu_to_be32(sn->date_sec);
- h.date_nsec = cpu_to_be32(sn->date_nsec);
- h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
-
- id_str_size = strlen(sn->id_str);
- name_size = strlen(sn->name);
- h.id_str_size = cpu_to_be16(id_str_size);
- h.name_size = cpu_to_be16(name_size);
- offset = align_offset(offset, 8);
- if (bdrv_pwrite(s->hd, offset, &h, sizeof(h)) != sizeof(h))
- goto fail;
- offset += sizeof(h);
- if (bdrv_pwrite(s->hd, offset, sn->id_str, id_str_size) != id_str_size)
- goto fail;
- offset += id_str_size;
- if (bdrv_pwrite(s->hd, offset, sn->name, name_size) != name_size)
- goto fail;
- offset += name_size;
- }
-
- /* update the various header fields */
- data64 = cpu_to_be64(snapshots_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, snapshots_offset),
- &data64, sizeof(data64)) != sizeof(data64))
- goto fail;
- data32 = cpu_to_be32(s->nb_snapshots);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, nb_snapshots),
- &data32, sizeof(data32)) != sizeof(data32))
- goto fail;
-
- /* free the old snapshot table */
- free_clusters(bs, s->snapshots_offset, s->snapshots_size);
- s->snapshots_offset = snapshots_offset;
- s->snapshots_size = snapshots_size;
- return 0;
- fail:
- return -1;
-}
-
-static void find_new_snapshot_id(BlockDriverState *bs,
- char *id_str, int id_str_size)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int i, id, id_max = 0;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- id = strtoul(sn->id_str, NULL, 10);
- if (id > id_max)
- id_max = id;
- }
- snprintf(id_str, id_str_size, "%d", id_max + 1);
-}
-
-static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- if (!strcmp(s->snapshots[i].id_str, id_str))
- return i;
- }
- return -1;
-}
-
-static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name)
-{
- BDRVQcowState *s = bs->opaque;
- int i, ret;
-
- ret = find_snapshot_by_id(bs, name);
- if (ret >= 0)
- return ret;
- for(i = 0; i < s->nb_snapshots; i++) {
- if (!strcmp(s->snapshots[i].name, name))
- return i;
- }
- return -1;
-}
-
-/* if no id is provided, a new one is constructed */
-static int qcow_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *snapshots1, sn1, *sn = &sn1;
- int i, ret;
- uint64_t *l1_table = NULL;
-
- memset(sn, 0, sizeof(*sn));
-
- if (sn_info->id_str[0] == '\0') {
- /* compute a new id */
- find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
- }
-
- /* check that the ID is unique */
- if (find_snapshot_by_id(bs, sn_info->id_str) >= 0)
- return -ENOENT;
-
- sn->id_str = qemu_strdup(sn_info->id_str);
- if (!sn->id_str)
- goto fail;
- sn->name = qemu_strdup(sn_info->name);
- if (!sn->name)
- goto fail;
- sn->vm_state_size = sn_info->vm_state_size;
- sn->date_sec = sn_info->date_sec;
- sn->date_nsec = sn_info->date_nsec;
- sn->vm_clock_nsec = sn_info->vm_clock_nsec;
-
- ret = update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1);
- if (ret < 0)
- goto fail;
-
- /* create the L1 table of the snapshot */
- sn->l1_table_offset = alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
- sn->l1_size = s->l1_size;
-
- l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!l1_table)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- l1_table[i] = cpu_to_be64(s->l1_table[i]);
- }
- if (bdrv_pwrite(s->hd, sn->l1_table_offset,
- l1_table, s->l1_size * sizeof(uint64_t)) !=
- (s->l1_size * sizeof(uint64_t)))
- goto fail;
- qemu_free(l1_table);
- l1_table = NULL;
-
- snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
- if (!snapshots1)
- goto fail;
- memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot));
- s->snapshots = snapshots1;
- s->snapshots[s->nb_snapshots++] = *sn;
-
- if (qcow_write_snapshots(bs) < 0)
- goto fail;
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
- fail:
- qemu_free(sn->name);
- qemu_free(l1_table);
- return -1;
-}
-
-/* copy the snapshot 'snapshot_name' into the current disk image */
-static int qcow_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int i, snapshot_index, l1_size2;
-
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
- if (snapshot_index < 0)
- return -ENOENT;
- sn = &s->snapshots[snapshot_index];
-
- if (update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0)
- goto fail;
-
- if (grow_l1_table(bs, sn->l1_size) < 0)
- goto fail;
-
- s->l1_size = sn->l1_size;
- l1_size2 = s->l1_size * sizeof(uint64_t);
- /* copy the snapshot l1 table to the current l1 table */
- if (bdrv_pread(s->hd, sn->l1_table_offset,
- s->l1_table, l1_size2) != l1_size2)
- goto fail;
- if (bdrv_pwrite(s->hd, s->l1_table_offset,
- s->l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
-
- if (update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1) < 0)
- goto fail;
-
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
- fail:
- return -EIO;
-}
-
-static int qcow_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int snapshot_index, ret;
-
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
- if (snapshot_index < 0)
- return -ENOENT;
- sn = &s->snapshots[snapshot_index];
-
- ret = update_snapshot_refcount(bs, sn->l1_table_offset, sn->l1_size, -1);
- if (ret < 0)
- return ret;
- /* must update the copied flag on the current cluster offsets */
- ret = update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
- if (ret < 0)
- return ret;
- free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t));
-
- qemu_free(sn->id_str);
- qemu_free(sn->name);
- memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn));
- s->nb_snapshots--;
- ret = qcow_write_snapshots(bs);
- if (ret < 0) {
- /* XXX: restore snapshot if error ? */
- return ret;
- }
-#ifdef DEBUG_ALLOC
- check_refcounts(bs);
-#endif
- return 0;
-}
-
-static int qcow_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_tab)
-{
- BDRVQcowState *s = bs->opaque;
- QEMUSnapshotInfo *sn_tab, *sn_info;
- QCowSnapshot *sn;
- int i;
-
- sn_tab = qemu_mallocz(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
- if (!sn_tab)
- goto fail;
- for(i = 0; i < s->nb_snapshots; i++) {
- sn_info = sn_tab + i;
- sn = s->snapshots + i;
- pstrcpy(sn_info->id_str, sizeof(sn_info->id_str),
- sn->id_str);
- pstrcpy(sn_info->name, sizeof(sn_info->name),
- sn->name);
- sn_info->vm_state_size = sn->vm_state_size;
- sn_info->date_sec = sn->date_sec;
- sn_info->date_nsec = sn->date_nsec;
- sn_info->vm_clock_nsec = sn->vm_clock_nsec;
- }
- *psn_tab = sn_tab;
- return s->nb_snapshots;
- fail:
- qemu_free(sn_tab);
- *psn_tab = NULL;
- return -ENOMEM;
-}
-
-/*********************************************************/
-/* refcount handling */
-
-static int refcount_init(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, refcount_table_size2, i;
-
- s->refcount_block_cache = qemu_malloc(s->cluster_size);
- if (!s->refcount_block_cache)
- goto fail;
- refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
- s->refcount_table = qemu_malloc(refcount_table_size2);
- if (!s->refcount_table)
- goto fail;
- if (s->refcount_table_size > 0) {
- ret = bdrv_pread(s->hd, s->refcount_table_offset,
- s->refcount_table, refcount_table_size2);
- if (ret != refcount_table_size2)
- goto fail;
- for(i = 0; i < s->refcount_table_size; i++)
- be64_to_cpus(&s->refcount_table[i]);
- }
- return 0;
- fail:
- return -ENOMEM;
-}
-
-static void refcount_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->refcount_block_cache);
- qemu_free(s->refcount_table);
-}
-
-
-static int load_refcount_block(BlockDriverState *bs,
- int64_t refcount_block_offset)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
- ret = bdrv_pread(s->hd, refcount_block_offset, s->refcount_block_cache,
- s->cluster_size);
- if (ret != s->cluster_size)
- return -EIO;
- s->refcount_block_cache_offset = refcount_block_offset;
- return 0;
-}
-
-static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
-{
- BDRVQcowState *s = bs->opaque;
- int refcount_table_index, block_index;
- int64_t refcount_block_offset;
-
- refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
- if (refcount_table_index >= s->refcount_table_size)
- return 0;
- refcount_block_offset = s->refcount_table[refcount_table_index];
- if (!refcount_block_offset)
- return 0;
- if (refcount_block_offset != s->refcount_block_cache_offset) {
- /* better than nothing: return allocated if read error */
- if (load_refcount_block(bs, refcount_block_offset) < 0)
- return 1;
- }
- block_index = cluster_index &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
- return be16_to_cpu(s->refcount_block_cache[block_index]);
-}
-
-/* return < 0 if error */
-static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
-{
- BDRVQcowState *s = bs->opaque;
- int i, nb_clusters;
-
- nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;
- for(;;) {
- if (get_refcount(bs, s->free_cluster_index) == 0) {
- s->free_cluster_index++;
- for(i = 1; i < nb_clusters; i++) {
- if (get_refcount(bs, s->free_cluster_index) != 0)
- goto not_found;
- s->free_cluster_index++;
- }
-#ifdef DEBUG_ALLOC2
- printf("alloc_clusters: size=%lld -> %lld\n",
- size,
- (s->free_cluster_index - nb_clusters) << s->cluster_bits);
-#endif
- return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
- } else {
- not_found:
- s->free_cluster_index++;
- }
- }
-}
-
-static int64_t alloc_clusters(BlockDriverState *bs, int64_t size)
-{
- int64_t offset;
-
- offset = alloc_clusters_noref(bs, size);
- update_refcount(bs, offset, size, 1);
- return offset;
-}
-
-/* only used to allocate compressed sectors. We try to allocate
- contiguous sectors. size must be <= cluster_size */
-static int64_t alloc_bytes(BlockDriverState *bs, int size)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t offset, cluster_offset;
- int free_in_cluster;
-
- assert(size > 0 && size <= s->cluster_size);
- if (s->free_byte_offset == 0) {
- s->free_byte_offset = alloc_clusters(bs, s->cluster_size);
- }
- redo:
- free_in_cluster = s->cluster_size -
- (s->free_byte_offset & (s->cluster_size - 1));
- if (size <= free_in_cluster) {
- /* enough space in current cluster */
- offset = s->free_byte_offset;
- s->free_byte_offset += size;
- free_in_cluster -= size;
- if (free_in_cluster == 0)
- s->free_byte_offset = 0;
- if ((offset & (s->cluster_size - 1)) != 0)
- update_cluster_refcount(bs, offset >> s->cluster_bits, 1);
- } else {
- offset = alloc_clusters(bs, s->cluster_size);
- cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1);
- if ((cluster_offset + s->cluster_size) == offset) {
- /* we are lucky: contiguous data */
- offset = s->free_byte_offset;
- update_cluster_refcount(bs, offset >> s->cluster_bits, 1);
- s->free_byte_offset += size;
- } else {
- s->free_byte_offset = offset;
- goto redo;
- }
- }
- return offset;
-}
-
-static void free_clusters(BlockDriverState *bs,
- int64_t offset, int64_t size)
-{
- update_refcount(bs, offset, size, -1);
-}
-
-static int grow_refcount_table(BlockDriverState *bs, int min_size)
-{
- BDRVQcowState *s = bs->opaque;
- int new_table_size, new_table_size2, refcount_table_clusters, i, ret;
- uint64_t *new_table;
- int64_t table_offset;
- uint64_t data64;
- uint32_t data32;
- int old_table_size;
- int64_t old_table_offset;
-
- if (min_size <= s->refcount_table_size)
- return 0;
- /* compute new table size */
- refcount_table_clusters = s->refcount_table_size >> (s->cluster_bits - 3);
- for(;;) {
- if (refcount_table_clusters == 0) {
- refcount_table_clusters = 1;
- } else {
- refcount_table_clusters = (refcount_table_clusters * 3 + 1) / 2;
- }
- new_table_size = refcount_table_clusters << (s->cluster_bits - 3);
- if (min_size <= new_table_size)
- break;
- }
-#ifdef DEBUG_ALLOC2
- printf("grow_refcount_table from %d to %d\n",
- s->refcount_table_size,
- new_table_size);
-#endif
- new_table_size2 = new_table_size * sizeof(uint64_t);
- new_table = qemu_mallocz(new_table_size2);
- if (!new_table)
- return -ENOMEM;
- memcpy(new_table, s->refcount_table,
- s->refcount_table_size * sizeof(uint64_t));
- for(i = 0; i < s->refcount_table_size; i++)
- cpu_to_be64s(&new_table[i]);
- /* Note: we cannot update the refcount now to avoid recursion */
- table_offset = alloc_clusters_noref(bs, new_table_size2);
- ret = bdrv_pwrite(s->hd, table_offset, new_table, new_table_size2);
- if (ret != new_table_size2)
- goto fail;
- for(i = 0; i < s->refcount_table_size; i++)
- be64_to_cpus(&new_table[i]);
-
- data64 = cpu_to_be64(table_offset);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
- &data64, sizeof(data64)) != sizeof(data64))
- goto fail;
- data32 = cpu_to_be32(refcount_table_clusters);
- if (bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_clusters),
- &data32, sizeof(data32)) != sizeof(data32))
- goto fail;
- qemu_free(s->refcount_table);
- old_table_offset = s->refcount_table_offset;
- old_table_size = s->refcount_table_size;
- s->refcount_table = new_table;
- s->refcount_table_size = new_table_size;
- s->refcount_table_offset = table_offset;
-
- update_refcount(bs, table_offset, new_table_size2, 1);
- free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t));
- return 0;
- fail:
- free_clusters(bs, table_offset, new_table_size2);
- qemu_free(new_table);
- return -EIO;
-}
-
-/* addend must be 1 or -1 */
-/* XXX: cache several refcount block clusters ? */
-static int update_cluster_refcount(BlockDriverState *bs,
- int64_t cluster_index,
- int addend)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t offset, refcount_block_offset;
- int ret, refcount_table_index, block_index, refcount;
- uint64_t data64;
-
- refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
- if (refcount_table_index >= s->refcount_table_size) {
- if (addend < 0)
- return -EINVAL;
- ret = grow_refcount_table(bs, refcount_table_index + 1);
- if (ret < 0)
- return ret;
- }
- refcount_block_offset = s->refcount_table[refcount_table_index];
- if (!refcount_block_offset) {
- if (addend < 0)
- return -EINVAL;
- /* create a new refcount block */
- /* Note: we cannot update the refcount now to avoid recursion */
- offset = alloc_clusters_noref(bs, s->cluster_size);
- memset(s->refcount_block_cache, 0, s->cluster_size);
- ret = bdrv_pwrite(s->hd, offset, s->refcount_block_cache, s->cluster_size);
- if (ret != s->cluster_size)
- return -EINVAL;
- s->refcount_table[refcount_table_index] = offset;
- data64 = cpu_to_be64(offset);
- ret = bdrv_pwrite(s->hd, s->refcount_table_offset +
- refcount_table_index * sizeof(uint64_t),
- &data64, sizeof(data64));
- if (ret != sizeof(data64))
- return -EINVAL;
-
- refcount_block_offset = offset;
- s->refcount_block_cache_offset = offset;
- update_refcount(bs, offset, s->cluster_size, 1);
- } else {
- if (refcount_block_offset != s->refcount_block_cache_offset) {
- if (load_refcount_block(bs, refcount_block_offset) < 0)
- return -EIO;
- }
- }
- /* we can update the count and save it */
- block_index = cluster_index &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
- refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
- refcount += addend;
- if (refcount < 0 || refcount > 0xffff)
- return -EINVAL;
- if (refcount == 0 && cluster_index < s->free_cluster_index) {
- s->free_cluster_index = cluster_index;
- }
- s->refcount_block_cache[block_index] = cpu_to_be16(refcount);
- if (bdrv_pwrite(s->hd,
- refcount_block_offset + (block_index << REFCOUNT_SHIFT),
- &s->refcount_block_cache[block_index], 2) != 2)
- return -EIO;
- return refcount;
-}
-
-static void update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
- int addend)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t start, last, cluster_offset;
-
-#ifdef DEBUG_ALLOC2
- printf("update_refcount: offset=%lld size=%lld addend=%d\n",
- offset, length, addend);
-#endif
- if (length <= 0)
- return;
- start = offset & ~(s->cluster_size - 1);
- last = (offset + length - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- update_cluster_refcount(bs, cluster_offset >> s->cluster_bits, addend);
- }
-}
-
-#ifdef DEBUG_ALLOC
-static void inc_refcounts(BlockDriverState *bs,
- uint16_t *refcount_table,
- int refcount_table_size,
- int64_t offset, int64_t size)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t start, last, cluster_offset;
- int k;
-
- if (size <= 0)
- return;
-
- start = offset & ~(s->cluster_size - 1);
- last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- k = cluster_offset >> s->cluster_bits;
- if (k < 0 || k >= refcount_table_size) {
- printf("ERROR: invalid cluster offset=0x%llx\n", cluster_offset);
- } else {
- if (++refcount_table[k] == 0) {
- printf("ERROR: overflow cluster offset=0x%llx\n", cluster_offset);
- }
- }
- }
-}
-
-static int check_refcounts_l1(BlockDriverState *bs,
- uint16_t *refcount_table,
- int refcount_table_size,
- int64_t l1_table_offset, int l1_size,
- int check_copied)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2;
- int l2_size, i, j, nb_csectors, refcount;
-
- l2_table = NULL;
- l1_size2 = l1_size * sizeof(uint64_t);
-
- inc_refcounts(bs, refcount_table, refcount_table_size,
- l1_table_offset, l1_size2);
-
- l1_table = qemu_malloc(l1_size2);
- if (!l1_table)
- goto fail;
- if (bdrv_pread(s->hd, l1_table_offset,
- l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
-
- l2_size = s->l2_size * sizeof(uint64_t);
- l2_table = qemu_malloc(l2_size);
- if (!l2_table)
- goto fail;
- for(i = 0; i < l1_size; i++) {
- l2_offset = l1_table[i];
- if (l2_offset) {
- if (check_copied) {
- refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED) >> s->cluster_bits);
- if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
- printf("ERROR OFLAG_COPIED: l2_offset=%llx refcount=%d\n",
- l2_offset, refcount);
- }
- }
- l2_offset &= ~QCOW_OFLAG_COPIED;
- if (bdrv_pread(s->hd, l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
- for(j = 0; j < s->l2_size; j++) {
- offset = be64_to_cpu(l2_table[j]);
- if (offset != 0) {
- if (offset & QCOW_OFLAG_COMPRESSED) {
- if (offset & QCOW_OFLAG_COPIED) {
- printf("ERROR: cluster %lld: copied flag must never be set for compressed clusters\n",
- offset >> s->cluster_bits);
- offset &= ~QCOW_OFLAG_COPIED;
- }
- nb_csectors = ((offset >> s->csize_shift) &
- s->csize_mask) + 1;
- offset &= s->cluster_offset_mask;
- inc_refcounts(bs, refcount_table,
- refcount_table_size,
- offset & ~511, nb_csectors * 512);
- } else {
- if (check_copied) {
- refcount = get_refcount(bs, (offset & ~QCOW_OFLAG_COPIED) >> s->cluster_bits);
- if ((refcount == 1) != ((offset & QCOW_OFLAG_COPIED) != 0)) {
- printf("ERROR OFLAG_COPIED: offset=%llx refcount=%d\n",
- offset, refcount);
- }
- }
- offset &= ~QCOW_OFLAG_COPIED;
- inc_refcounts(bs, refcount_table,
- refcount_table_size,
- offset, s->cluster_size);
- }
- }
- }
- inc_refcounts(bs, refcount_table,
- refcount_table_size,
- l2_offset,
- s->cluster_size);
- }
- }
- qemu_free(l1_table);
- qemu_free(l2_table);
- return 0;
- fail:
- printf("ERROR: I/O error in check_refcounts_l1\n");
- qemu_free(l1_table);
- qemu_free(l2_table);
- return -EIO;
-}
-
-static void check_refcounts(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t size;
- int nb_clusters, refcount1, refcount2, i;
- QCowSnapshot *sn;
- uint16_t *refcount_table;
-
- size = bdrv_getlength(s->hd);
- nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;
- refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t));
-
- /* header */
- inc_refcounts(bs, refcount_table, nb_clusters,
- 0, s->cluster_size);
-
- check_refcounts_l1(bs, refcount_table, nb_clusters,
- s->l1_table_offset, s->l1_size, 1);
-
- /* snapshots */
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- check_refcounts_l1(bs, refcount_table, nb_clusters,
- sn->l1_table_offset, sn->l1_size, 0);
- }
- inc_refcounts(bs, refcount_table, nb_clusters,
- s->snapshots_offset, s->snapshots_size);
-
- /* refcount data */
- inc_refcounts(bs, refcount_table, nb_clusters,
- s->refcount_table_offset,
- s->refcount_table_size * sizeof(uint64_t));
- for(i = 0; i < s->refcount_table_size; i++) {
- int64_t offset;
- offset = s->refcount_table[i];
- if (offset != 0) {
- inc_refcounts(bs, refcount_table, nb_clusters,
- offset, s->cluster_size);
- }
- }
-
- /* compare ref counts */
- for(i = 0; i < nb_clusters; i++) {
- refcount1 = get_refcount(bs, i);
- refcount2 = refcount_table[i];
- if (refcount1 != refcount2)
- printf("ERROR cluster %d refcount=%d reference=%d\n",
- i, refcount1, refcount2);
- }
-
- qemu_free(refcount_table);
-}
-
-#if 0
-static void dump_refcounts(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t nb_clusters, k, k1, size;
- int refcount;
-
- size = bdrv_getlength(s->hd);
- nb_clusters = (size + s->cluster_size - 1) >> s->cluster_bits;
- for(k = 0; k < nb_clusters;) {
- k1 = k;
- refcount = get_refcount(bs, k);
- k++;
- while (k < nb_clusters && get_refcount(bs, k) == refcount)
- k++;
- printf("%lld: refcount=%d nb=%lld\n", k, refcount, k - k1);
- }
-}
-#endif
-#endif
-
-BlockDriver bdrv_qcow2 = {
- "qcow2",
- sizeof(BDRVQcowState),
- qcow_probe,
- qcow_open,
- NULL,
- NULL,
- qcow_close,
- qcow_create,
- qcow_flush,
- qcow_is_allocated,
- qcow_set_key,
- qcow_make_empty,
-
- .bdrv_aio_read = qcow_aio_read,
- .bdrv_aio_write = qcow_aio_write,
- .bdrv_aio_cancel = qcow_aio_cancel,
- .aiocb_size = sizeof(QCowAIOCB),
- .bdrv_write_compressed = qcow_write_compressed,
-
- .bdrv_snapshot_create = qcow_snapshot_create,
- .bdrv_snapshot_goto = qcow_snapshot_goto,
- .bdrv_snapshot_delete = qcow_snapshot_delete,
- .bdrv_snapshot_list = qcow_snapshot_list,
- .bdrv_get_info = qcow_get_info,
-};
diff --git a/block-raw-posix.c b/block-raw-posix.c
deleted file mode 100644
index 7c42c10..0000000
--- a/block-raw-posix.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/*
- * Block driver for RAW files (posix)
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "qemu-timer.h"
-#include "qemu-char.h"
-#include "block_int.h"
-#include "compatfd.h"
-#include <assert.h>
-#ifdef CONFIG_AIO
-#include <aio.h>
-#endif
-
-#ifdef CONFIG_COCOA
-#include <paths.h>
-#include <sys/param.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/storage/IOMediaBSDClient.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOCDMedia.h>
-//#include <IOKit/storage/IOCDTypes.h>
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-#ifdef __sun__
-#define _POSIX_PTHREAD_SEMANTICS 1
-#include <signal.h>
-#include <sys/dkio.h>
-#endif
-#ifdef __linux__
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
-#include <linux/fd.h>
-#endif
-#ifdef __FreeBSD__
-#include <signal.h>
-#include <sys/disk.h>
-#endif
-
-#ifdef __OpenBSD__
-#include <sys/ioctl.h>
-#include <sys/disklabel.h>
-#include <sys/dkio.h>
-#endif
-
-//#define DEBUG_FLOPPY
-
-//#define DEBUG_BLOCK
-#if defined(DEBUG_BLOCK)
-#define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \
- { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
-#else
-#define DEBUG_BLOCK_PRINT(formatCstr, args...)
-#endif
-
-#define FTYPE_FILE 0
-#define FTYPE_CD 1
-#define FTYPE_FD 2
-
-#define ALIGNED_BUFFER_SIZE (32 * 512)
-
-/* if the FD is not accessed during that time (in ms), we try to
- reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
-
-typedef struct BDRVRawState {
- int fd;
- int type;
- unsigned int lseek_err_cnt;
-#if defined(__linux__)
- /* linux floppy specific */
- int fd_open_flags;
- int64_t fd_open_time;
- int64_t fd_error_time;
- int fd_got_error;
- int fd_media_changed;
-#endif
-#if defined(O_DIRECT)
- uint8_t* aligned_buf;
-#endif
-} BDRVRawState;
-
-static int fd_open(BlockDriverState *bs);
-
-static int raw_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int fd, open_flags, ret;
-
- s->lseek_err_cnt = 0;
-
- open_flags = O_BINARY;
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- open_flags |= O_RDWR;
- } else {
- open_flags |= O_RDONLY;
- bs->read_only = 1;
- }
- if (flags & BDRV_O_CREAT)
- open_flags |= O_CREAT | O_TRUNC;
-#ifdef O_DIRECT
- if (flags & BDRV_O_DIRECT)
- open_flags |= O_DIRECT;
-#endif
-
- s->type = FTYPE_FILE;
-
- fd = open(filename, open_flags, 0644);
- if (fd < 0) {
- ret = -errno;
- if (ret == -EROFS)
- ret = -EACCES;
- return ret;
- }
- s->fd = fd;
-#if defined(O_DIRECT)
- s->aligned_buf = NULL;
- if (flags & BDRV_O_DIRECT) {
- s->aligned_buf = qemu_memalign(512, ALIGNED_BUFFER_SIZE);
- if (s->aligned_buf == NULL) {
- ret = -errno;
- close(fd);
- return ret;
- }
- }
-#endif
- return 0;
-}
-
-/* XXX: use host sector size if necessary with:
-#ifdef DIOCGSECTORSIZE
- {
- unsigned int sectorsize = 512;
- if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
- sectorsize > bufsize)
- bufsize = sectorsize;
- }
-#endif
-#ifdef CONFIG_COCOA
- u_int32_t blockSize = 512;
- if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
- bufsize = blockSize;
- }
-#endif
-*/
-
-/*
- * offset and count are in bytes, but must be multiples of 512 for files
- * opened with O_DIRECT. buf must be aligned to 512 bytes then.
- *
- * This function may be called without alignment if the caller ensures
- * that O_DIRECT is not in effect.
- */
-static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- ret = fd_open(bs);
- if (ret < 0)
- return ret;
-
- if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
- ++(s->lseek_err_cnt);
- if(s->lseek_err_cnt <= 10) {
- DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
- "] lseek failed : %d = %s\n",
- s->fd, bs->filename, offset, buf, count,
- bs->total_sectors, errno, strerror(errno));
- }
- return -1;
- }
- s->lseek_err_cnt=0;
-
- ret = read(s->fd, buf, count);
- if (ret == count)
- goto label__raw_read__success;
-
- DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
- "] read failed %d : %d = %s\n",
- s->fd, bs->filename, offset, buf, count,
- bs->total_sectors, ret, errno, strerror(errno));
-
- /* Try harder for CDrom. */
- if (bs->type == BDRV_TYPE_CDROM) {
- lseek(s->fd, offset, SEEK_SET);
- ret = read(s->fd, buf, count);
- if (ret == count)
- goto label__raw_read__success;
- lseek(s->fd, offset, SEEK_SET);
- ret = read(s->fd, buf, count);
- if (ret == count)
- goto label__raw_read__success;
-
- DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
- "] retry read failed %d : %d = %s\n",
- s->fd, bs->filename, offset, buf, count,
- bs->total_sectors, ret, errno, strerror(errno));
- }
-
-label__raw_read__success:
-
- return ret;
-}
-
-/*
- * offset and count are in bytes, but must be multiples of 512 for files
- * opened with O_DIRECT. buf must be aligned to 512 bytes then.
- *
- * This function may be called without alignment if the caller ensures
- * that O_DIRECT is not in effect.
- */
-static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- ret = fd_open(bs);
- if (ret < 0)
- return ret;
-
- if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
- ++(s->lseek_err_cnt);
- if(s->lseek_err_cnt) {
- DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
- PRId64 "] lseek failed : %d = %s\n",
- s->fd, bs->filename, offset, buf, count,
- bs->total_sectors, errno, strerror(errno));
- }
- return -1;
- }
- s->lseek_err_cnt = 0;
-
- ret = write(s->fd, buf, count);
- if (ret == count)
- goto label__raw_write__success;
-
- DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
- "] write failed %d : %d = %s\n",
- s->fd, bs->filename, offset, buf, count,
- bs->total_sectors, ret, errno, strerror(errno));
-
-label__raw_write__success:
-
- return ret;
-}
-
-
-#if defined(O_DIRECT)
-/*
- * offset and count are in bytes and possibly not aligned. For files opened
- * with O_DIRECT, necessary alignments are ensured before calling
- * raw_pread_aligned to do the actual read.
- */
-static int raw_pread(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- int size, ret, shift, sum;
-
- sum = 0;
-
- if (s->aligned_buf != NULL) {
-
- if (offset & 0x1ff) {
- /* align offset on a 512 bytes boundary */
-
- shift = offset & 0x1ff;
- size = (shift + count + 0x1ff) & ~0x1ff;
- if (size > ALIGNED_BUFFER_SIZE)
- size = ALIGNED_BUFFER_SIZE;
- ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
- if (ret < 0)
- return ret;
-
- size = 512 - shift;
- if (size > count)
- size = count;
- memcpy(buf, s->aligned_buf + shift, size);
-
- buf += size;
- offset += size;
- count -= size;
- sum += size;
-
- if (count == 0)
- return sum;
- }
- if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
-
- /* read on aligned buffer */
-
- while (count) {
-
- size = (count + 0x1ff) & ~0x1ff;
- if (size > ALIGNED_BUFFER_SIZE)
- size = ALIGNED_BUFFER_SIZE;
-
- ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
- if (ret < 0)
- return ret;
-
- size = ret;
- if (size > count)
- size = count;
-
- memcpy(buf, s->aligned_buf, size);
-
- buf += size;
- offset += size;
- count -= size;
- sum += size;
- }
-
- return sum;
- }
- }
-
- return raw_pread_aligned(bs, offset, buf, count) + sum;
-}
-
-/*
- * offset and count are in bytes and possibly not aligned. For files opened
- * with O_DIRECT, necessary alignments are ensured before calling
- * raw_pwrite_aligned to do the actual write.
- */
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- int size, ret, shift, sum;
-
- sum = 0;
-
- if (s->aligned_buf != NULL) {
-
- if (offset & 0x1ff) {
- /* align offset on a 512 bytes boundary */
- shift = offset & 0x1ff;
- ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
- if (ret < 0)
- return ret;
-
- size = 512 - shift;
- if (size > count)
- size = count;
- memcpy(s->aligned_buf + shift, buf, size);
-
- ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
- if (ret < 0)
- return ret;
-
- buf += size;
- offset += size;
- count -= size;
- sum += size;
-
- if (count == 0)
- return sum;
- }
- if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
-
- while ((size = (count & ~0x1ff)) != 0) {
-
- if (size > ALIGNED_BUFFER_SIZE)
- size = ALIGNED_BUFFER_SIZE;
-
- memcpy(s->aligned_buf, buf, size);
-
- ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
- if (ret < 0)
- return ret;
-
- buf += ret;
- offset += ret;
- count -= ret;
- sum += ret;
- }
- /* here, count < 512 because (count & ~0x1ff) == 0 */
- if (count) {
- ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
- if (ret < 0)
- return ret;
- memcpy(s->aligned_buf, buf, count);
-
- ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
- if (ret < 0)
- return ret;
- if (count < ret)
- ret = count;
-
- sum += ret;
- }
- return sum;
- }
- }
- return raw_pwrite_aligned(bs, offset, buf, count) + sum;
-}
-
-#else
-#define raw_pread raw_pread_aligned
-#define raw_pwrite raw_pwrite_aligned
-#endif
-
-
-#ifdef CONFIG_AIO
-/***********************************************************/
-/* Unix AIO using POSIX AIO */
-
-typedef struct RawAIOCB {
- BlockDriverAIOCB common;
- struct aiocb aiocb;
- struct RawAIOCB *next;
- int ret;
-} RawAIOCB;
-
-static int aio_sig_fd = -1;
-static int aio_sig_num = SIGUSR2;
-static RawAIOCB *first_aio; /* AIO issued */
-static int aio_initialized = 0;
-
-static void qemu_aio_poll(void *opaque)
-{
- RawAIOCB *acb, **pacb;
- int ret;
- size_t offset;
- union {
- struct qemu_signalfd_siginfo siginfo;
- char buf[128];
- } sig;
-
- /* try to read from signalfd, don't freak out if we can't read anything */
- offset = 0;
- while (offset < 128) {
- ssize_t len;
-
- len = read(aio_sig_fd, sig.buf + offset, 128 - offset);
- if (len == -1 && errno == EINTR)
- continue;
- if (len == -1 && errno == EAGAIN) {
- /* there is no natural reason for this to happen,
- * so we'll spin hard until we get everything just
- * to be on the safe side. */
- if (offset > 0)
- continue;
- }
-
- offset += len;
- }
-
- for(;;) {
- pacb = &first_aio;
- for(;;) {
- acb = *pacb;
- if (!acb)
- goto the_end;
- ret = aio_error(&acb->aiocb);
- if (ret == ECANCELED) {
- /* remove the request */
- *pacb = acb->next;
- qemu_aio_release(acb);
- } else if (ret != EINPROGRESS) {
- /* end of aio */
- if (ret == 0) {
- ret = aio_return(&acb->aiocb);
- if (ret == acb->aiocb.aio_nbytes)
- ret = 0;
- else
- ret = -EINVAL;
- } else {
- ret = -ret;
- }
- /* remove the request */
- *pacb = acb->next;
- /* call the callback */
- acb->common.cb(acb->common.opaque, ret);
- qemu_aio_release(acb);
- break;
- } else {
- pacb = &acb->next;
- }
- }
- }
- the_end: ;
-}
-
-void qemu_aio_init(void)
-{
- sigset_t mask;
-
- aio_initialized = 1;
-
- /* Make sure to block AIO signal */
- sigemptyset(&mask);
- sigaddset(&mask, aio_sig_num);
- sigprocmask(SIG_BLOCK, &mask, NULL);
-
- aio_sig_fd = qemu_signalfd(&mask);
-
- fcntl(aio_sig_fd, F_SETFL, O_NONBLOCK);
-
- qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL);
-
-#if defined(__GLIBC__) && defined(__linux__)
- {
- /* XXX: aio thread exit seems to hang on RedHat 9 and this init
- seems to fix the problem. */
- struct aioinit ai;
- memset(&ai, 0, sizeof(ai));
- ai.aio_threads = 1;
- ai.aio_num = 1;
- ai.aio_idle_time = 365 * 100000;
- aio_init(&ai);
- }
-#endif
-}
-
-/* Wait for all IO requests to complete. */
-void qemu_aio_flush(void)
-{
- qemu_aio_poll(NULL);
- while (first_aio) {
- qemu_aio_wait();
- }
-}
-
-void qemu_aio_wait(void)
-{
- int ret;
-
- if (qemu_bh_poll())
- return;
-
- if (!first_aio)
- return;
-
- do {
- fd_set rdfds;
-
- FD_ZERO(&rdfds);
- FD_SET(aio_sig_fd, &rdfds);
-
- ret = select(aio_sig_fd + 1, &rdfds, NULL, NULL, NULL);
- if (ret == -1 && errno == EINTR)
- continue;
- } while (ret == 0);
-
- qemu_aio_poll(NULL);
-}
-
-static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb;
-
- if (fd_open(bs) < 0)
- return NULL;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb)
- return NULL;
- acb->aiocb.aio_fildes = s->fd;
- acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
- acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- acb->aiocb.aio_buf = buf;
- if (nb_sectors < 0)
- acb->aiocb.aio_nbytes = -nb_sectors;
- else
- acb->aiocb.aio_nbytes = nb_sectors * 512;
- acb->aiocb.aio_offset = sector_num * 512;
- acb->next = first_aio;
- first_aio = acb;
- return acb;
-}
-
-static void raw_aio_em_cb(void* opaque)
-{
- RawAIOCB *acb = opaque;
- acb->common.cb(acb->common.opaque, acb->ret);
- qemu_aio_release(acb);
-}
-
-static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
-
- /*
- * If O_DIRECT is used and the buffer is not aligned fall back
- * to synchronous IO.
- */
-#if defined(O_DIRECT)
- BDRVRawState *s = bs->opaque;
-
- if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
- QEMUBH *bh;
- acb = qemu_aio_get(bs, cb, opaque);
- acb->ret = raw_pread(bs, 512 * sector_num, buf, 512 * nb_sectors);
- bh = qemu_bh_new(raw_aio_em_cb, acb);
- qemu_bh_schedule(bh);
- return &acb->common;
- }
-#endif
-
- acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- if (aio_read(&acb->aiocb) < 0) {
- qemu_aio_release(acb);
- return NULL;
- }
- return &acb->common;
-}
-
-static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
-
- /*
- * If O_DIRECT is used and the buffer is not aligned fall back
- * to synchronous IO.
- */
-#if defined(O_DIRECT)
- BDRVRawState *s = bs->opaque;
-
- if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
- QEMUBH *bh;
- acb = qemu_aio_get(bs, cb, opaque);
- acb->ret = raw_pwrite(bs, 512 * sector_num, buf, 512 * nb_sectors);
- bh = qemu_bh_new(raw_aio_em_cb, acb);
- qemu_bh_schedule(bh);
- return &acb->common;
- }
-#endif
-
- acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- if (aio_write(&acb->aiocb) < 0) {
- qemu_aio_release(acb);
- return NULL;
- }
- return &acb->common;
-}
-
-static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- int ret;
- RawAIOCB *acb = (RawAIOCB *)blockacb;
- RawAIOCB **pacb;
-
- ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
- if (ret == AIO_NOTCANCELED) {
- /* fail safe: if the aio could not be canceled, we wait for
- it */
- while (aio_error(&acb->aiocb) == EINPROGRESS);
- }
-
- /* remove the callback from the queue */
- pacb = &first_aio;
- for(;;) {
- if (*pacb == NULL) {
- break;
- } else if (*pacb == acb) {
- *pacb = acb->next;
- qemu_aio_release(acb);
- break;
- }
- pacb = &acb->next;
- }
-}
-
-# else /* CONFIG_AIO */
-
-void qemu_aio_init(void)
-{
-}
-
-void qemu_aio_flush(void)
-{
-}
-
-void qemu_aio_wait(void)
-{
- qemu_bh_poll();
-}
-
-#endif /* CONFIG_AIO */
-
-static void raw_close(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- if (s->fd >= 0) {
- close(s->fd);
- s->fd = -1;
-#if defined(O_DIRECT)
- if (s->aligned_buf != NULL)
- qemu_free(s->aligned_buf);
-#endif
- }
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
- BDRVRawState *s = bs->opaque;
- if (s->type != FTYPE_FILE)
- return -ENOTSUP;
- if (ftruncate(s->fd, offset) < 0)
- return -errno;
- return 0;
-}
-
-#ifdef __OpenBSD__
-static int64_t raw_getlength(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int fd = s->fd;
- struct stat st;
-
- if (fstat(fd, &st))
- return -1;
- if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
- struct disklabel dl;
-
- if (ioctl(fd, DIOCGDINFO, &dl))
- return -1;
- return (uint64_t)dl.d_secsize *
- dl.d_partitions[DISKPART(st.st_rdev)].p_size;
- } else
- return st.st_size;
-}
-#else /* !__OpenBSD__ */
-static int64_t raw_getlength(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int fd = s->fd;
- int64_t size;
-#ifdef _BSD
- struct stat sb;
-#endif
-#ifdef __sun__
- struct dk_minfo minfo;
- int rv;
-#endif
- int ret;
-
- ret = fd_open(bs);
- if (ret < 0)
- return ret;
-
-#ifdef _BSD
- if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
-#ifdef DIOCGMEDIASIZE
- if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
-#endif
-#ifdef CONFIG_COCOA
- size = LONG_LONG_MAX;
-#else
- size = lseek(fd, 0LL, SEEK_END);
-#endif
- } else
-#endif
-#ifdef __sun__
- /*
- * use the DKIOCGMEDIAINFO ioctl to read the size.
- */
- rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
- if ( rv != -1 ) {
- size = minfo.dki_lbsize * minfo.dki_capacity;
- } else /* there are reports that lseek on some devices
- fails, but irc discussion said that contingency
- on contingency was overkill */
-#endif
- {
- size = lseek(fd, 0, SEEK_END);
- }
- return size;
-}
-#endif
-
-static int raw_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd;
-
- if (flags || backing_file)
- return -ENOTSUP;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- 0644);
- if (fd < 0)
- return -EIO;
- ftruncate(fd, total_size * 512);
- close(fd);
- return 0;
-}
-
-static void raw_flush(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- fsync(s->fd);
-}
-
-BlockDriver bdrv_raw = {
- "raw",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- raw_open,
- NULL,
- NULL,
- raw_close,
- raw_create,
- raw_flush,
-
-#ifdef CONFIG_AIO
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB),
-#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_truncate = raw_truncate,
- .bdrv_getlength = raw_getlength,
-};
-
-/***********************************************/
-/* host device */
-
-#ifdef CONFIG_COCOA
-static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
-static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
-
-kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
-{
- kern_return_t kernResult;
- mach_port_t masterPort;
- CFMutableDictionaryRef classesToMatch;
-
- kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
- if ( KERN_SUCCESS != kernResult ) {
- printf( "IOMasterPort returned %d\n", kernResult );
- }
-
- classesToMatch = IOServiceMatching( kIOCDMediaClass );
- if ( classesToMatch == NULL ) {
- printf( "IOServiceMatching returned a NULL dictionary.\n" );
- } else {
- CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
- }
- kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
- if ( KERN_SUCCESS != kernResult )
- {
- printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
- }
-
- return kernResult;
-}
-
-kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
-{
- io_object_t nextMedia;
- kern_return_t kernResult = KERN_FAILURE;
- *bsdPath = '\0';
- nextMedia = IOIteratorNext( mediaIterator );
- if ( nextMedia )
- {
- CFTypeRef bsdPathAsCFString;
- bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
- if ( bsdPathAsCFString ) {
- size_t devPathLength;
- strcpy( bsdPath, _PATH_DEV );
- strcat( bsdPath, "r" );
- devPathLength = strlen( bsdPath );
- if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
- kernResult = KERN_SUCCESS;
- }
- CFRelease( bsdPathAsCFString );
- }
- IOObjectRelease( nextMedia );
- }
-
- return kernResult;
-}
-
-#endif
-
-static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int fd, open_flags, ret;
-
-#ifdef CONFIG_COCOA
- if (strstart(filename, "/dev/cdrom", NULL)) {
- kern_return_t kernResult;
- io_iterator_t mediaIterator;
- char bsdPath[ MAXPATHLEN ];
- int fd;
-
- kernResult = FindEjectableCDMedia( &mediaIterator );
- kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
-
- if ( bsdPath[ 0 ] != '\0' ) {
- strcat(bsdPath,"s0");
- /* some CDs don't have a partition 0 */
- fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0) {
- bsdPath[strlen(bsdPath)-1] = '1';
- } else {
- close(fd);
- }
- filename = bsdPath;
- }
-
- if ( mediaIterator )
- IOObjectRelease( mediaIterator );
- }
-#endif
- open_flags = O_BINARY;
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- open_flags |= O_RDWR;
- } else {
- open_flags |= O_RDONLY;
- bs->read_only = 1;
- }
-#ifdef O_DIRECT
- if (flags & BDRV_O_DIRECT)
- open_flags |= O_DIRECT;
-#endif
-
- s->type = FTYPE_FILE;
-#if defined(__linux__)
- if (strstart(filename, "/dev/cd", NULL)) {
- /* open will not fail even if no CD is inserted */
- open_flags |= O_NONBLOCK;
- s->type = FTYPE_CD;
- } else if (strstart(filename, "/dev/fd", NULL)) {
- s->type = FTYPE_FD;
- s->fd_open_flags = open_flags;
- /* open will not fail even if no floppy is inserted */
- open_flags |= O_NONBLOCK;
- } else if (strstart(filename, "/dev/sg", NULL)) {
- bs->sg = 1;
- }
-#endif
- fd = open(filename, open_flags, 0644);
- if (fd < 0) {
- ret = -errno;
- if (ret == -EROFS)
- ret = -EACCES;
- return ret;
- }
- s->fd = fd;
-#if defined(__linux__)
- /* close fd so that we can reopen it as needed */
- if (s->type == FTYPE_FD) {
- close(s->fd);
- s->fd = -1;
- s->fd_media_changed = 1;
- }
-#endif
- return 0;
-}
-
-#if defined(__linux__)
-
-/* Note: we do not have a reliable method to detect if the floppy is
- present. The current method is to try to open the floppy at every
- I/O and to keep it opened during a few hundreds of ms. */
-static int fd_open(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int last_media_present;
-
- if (s->type != FTYPE_FD)
- return 0;
- last_media_present = (s->fd >= 0);
- if (s->fd >= 0 &&
- (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
- close(s->fd);
- s->fd = -1;
-#ifdef DEBUG_FLOPPY
- printf("Floppy closed\n");
-#endif
- }
- if (s->fd < 0) {
- if (s->fd_got_error &&
- (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
-#ifdef DEBUG_FLOPPY
- printf("No floppy (open delayed)\n");
-#endif
- return -EIO;
- }
- s->fd = open(bs->filename, s->fd_open_flags);
- if (s->fd < 0) {
- s->fd_error_time = qemu_get_clock(rt_clock);
- s->fd_got_error = 1;
- if (last_media_present)
- s->fd_media_changed = 1;
-#ifdef DEBUG_FLOPPY
- printf("No floppy\n");
-#endif
- return -EIO;
- }
-#ifdef DEBUG_FLOPPY
- printf("Floppy opened\n");
-#endif
- }
- if (!last_media_present)
- s->fd_media_changed = 1;
- s->fd_open_time = qemu_get_clock(rt_clock);
- s->fd_got_error = 0;
- return 0;
-}
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- switch(s->type) {
- case FTYPE_CD:
- ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
- if (ret == CDS_DISC_OK)
- return 1;
- else
- return 0;
- break;
- case FTYPE_FD:
- ret = fd_open(bs);
- return (ret >= 0);
- default:
- return 1;
- }
-}
-
-/* currently only used by fdc.c, but a CD version would be good too */
-static int raw_media_changed(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
-
- switch(s->type) {
- case FTYPE_FD:
- {
- int ret;
- /* XXX: we do not have a true media changed indication. It
- does not work if the floppy is changed without trying
- to read it */
- fd_open(bs);
- ret = s->fd_media_changed;
- s->fd_media_changed = 0;
-#ifdef DEBUG_FLOPPY
- printf("Floppy changed=%d\n", ret);
-#endif
- return ret;
- }
- default:
- return -ENOTSUP;
- }
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- BDRVRawState *s = bs->opaque;
-
- switch(s->type) {
- case FTYPE_CD:
- if (eject_flag) {
- if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
- perror("CDROMEJECT");
- } else {
- if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
- perror("CDROMEJECT");
- }
- break;
- case FTYPE_FD:
- {
- int fd;
- if (s->fd >= 0) {
- close(s->fd);
- s->fd = -1;
- }
- fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
- if (fd >= 0) {
- if (ioctl(fd, FDEJECT, 0) < 0)
- perror("FDEJECT");
- close(fd);
- }
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- BDRVRawState *s = bs->opaque;
-
- switch(s->type) {
- case FTYPE_CD:
- if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
- /* Note: an error can happen if the distribution automatically
- mounts the CD-ROM */
- // perror("CDROM_LOCKDOOR");
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
- BDRVRawState *s = bs->opaque;
-
- return ioctl(s->fd, req, buf);
-}
-#else
-
-static int fd_open(BlockDriverState *bs)
-{
- return 0;
-}
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
- return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- return -ENOTSUP;
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- return -ENOTSUP;
-}
-
-static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
- return -ENOTSUP;
-}
-#endif /* !linux */
-
-BlockDriver bdrv_host_device = {
- "host_device",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- hdev_open,
- NULL,
- NULL,
- raw_close,
- NULL,
- raw_flush,
-
-#ifdef CONFIG_AIO
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB),
-#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_getlength = raw_getlength,
-
- /* removable device support */
- .bdrv_is_inserted = raw_is_inserted,
- .bdrv_media_changed = raw_media_changed,
- .bdrv_eject = raw_eject,
- .bdrv_set_locked = raw_set_locked,
- /* generic scsi device */
- .bdrv_ioctl = raw_ioctl,
-};
diff --git a/block-raw-win32.c b/block-raw-win32.c
deleted file mode 100644
index 71404ac..0000000
--- a/block-raw-win32.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Block driver for RAW files (win32)
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "qemu-timer.h"
-#include "block_int.h"
-#include <assert.h>
-#include <winioctl.h>
-
-//#define WIN32_AIO
-
-#define FTYPE_FILE 0
-#define FTYPE_CD 1
-#define FTYPE_HARDDISK 2
-
-typedef struct BDRVRawState {
- HANDLE hfile;
- int type;
- char drive_path[16]; /* format: "d:\" */
-} BDRVRawState;
-
-typedef struct RawAIOCB {
- BlockDriverAIOCB common;
- HANDLE hEvent;
- OVERLAPPED ov;
- int count;
-} RawAIOCB;
-
-int qemu_ftruncate64(int fd, int64_t length)
-{
- LARGE_INTEGER li;
- LONG high;
- HANDLE h;
- BOOL res;
-
- if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
- return -1;
-
- h = (HANDLE)_get_osfhandle(fd);
-
- /* get current position, ftruncate do not change position */
- li.HighPart = 0;
- li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
- if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
- return -1;
-
- high = length >> 32;
- if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
- return -1;
- res = SetEndOfFile(h);
-
- /* back to old position */
- SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
- return res ? 0 : -1;
-}
-
-static int set_sparse(int fd)
-{
- DWORD returned;
- return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
- NULL, 0, NULL, 0, &returned, NULL);
-}
-
-static int raw_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int access_flags, create_flags;
- DWORD overlapped;
-
- s->type = FTYPE_FILE;
-
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- access_flags = GENERIC_READ | GENERIC_WRITE;
- } else {
- access_flags = GENERIC_READ;
- }
- if (flags & BDRV_O_CREAT) {
- create_flags = CREATE_ALWAYS;
- } else {
- create_flags = OPEN_EXISTING;
- }
-#ifdef WIN32_AIO
- overlapped = FILE_FLAG_OVERLAPPED;
-#else
- overlapped = FILE_ATTRIBUTE_NORMAL;
-#endif
- if (flags & BDRV_O_DIRECT)
- overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
- s->hfile = CreateFile(filename, access_flags,
- FILE_SHARE_READ, NULL,
- create_flags, overlapped, NULL);
- if (s->hfile == INVALID_HANDLE_VALUE) {
- int err = GetLastError();
-
- if (err == ERROR_ACCESS_DENIED)
- return -EACCES;
- return -1;
- }
- return 0;
-}
-
-static int raw_pread(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- OVERLAPPED ov;
- DWORD ret_count;
- int ret;
-
- memset(&ov, 0, sizeof(ov));
- ov.Offset = offset;
- ov.OffsetHigh = offset >> 32;
- ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
- if (!ret) {
-#ifdef WIN32_AIO
- ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
- if (!ret)
- return -EIO;
- else
-#endif
- return ret_count;
- }
- return ret_count;
-}
-
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count)
-{
- BDRVRawState *s = bs->opaque;
- OVERLAPPED ov;
- DWORD ret_count;
- int ret;
-
- memset(&ov, 0, sizeof(ov));
- ov.Offset = offset;
- ov.OffsetHigh = offset >> 32;
- ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
- if (!ret) {
-#ifdef WIN32_AIO
- ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
- if (!ret)
- return -EIO;
- else
-#endif
- return ret_count;
- }
- return ret_count;
-}
-
-#ifdef WIN32_AIO
-static void raw_aio_cb(void *opaque)
-{
- RawAIOCB *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
- BDRVRawState *s = bs->opaque;
- DWORD ret_count;
- int ret;
-
- ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
- if (!ret || ret_count != acb->count) {
- acb->common.cb(acb->common.opaque, -EIO);
- } else {
- acb->common.cb(acb->common.opaque, 0);
- }
-}
-
-static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- RawAIOCB *acb;
- int64_t offset;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (acb->hEvent) {
- acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!acb->hEvent) {
- qemu_aio_release(acb);
- return NULL;
- }
- }
- memset(&acb->ov, 0, sizeof(acb->ov));
- offset = sector_num * 512;
- acb->ov.Offset = offset;
- acb->ov.OffsetHigh = offset >> 32;
- acb->ov.hEvent = acb->hEvent;
- acb->count = nb_sectors * 512;
- qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
- return acb;
-}
-
-static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb;
- int ret;
-
- acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
- if (!ret) {
- qemu_aio_release(acb);
- return NULL;
- }
- qemu_aio_release(acb);
- return (BlockDriverAIOCB *)acb;
-}
-
-static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BDRVRawState *s = bs->opaque;
- RawAIOCB *acb;
- int ret;
-
- acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
- if (!acb)
- return NULL;
- ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
- if (!ret) {
- qemu_aio_release(acb);
- return NULL;
- }
- qemu_aio_release(acb);
- return (BlockDriverAIOCB *)acb;
-}
-
-static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- RawAIOCB *acb = (RawAIOCB *)blockacb;
- BlockDriverState *bs = acb->common.bs;
- BDRVRawState *s = bs->opaque;
-
- qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
- /* XXX: if more than one async I/O it is not correct */
- CancelIo(s->hfile);
- qemu_aio_release(acb);
-}
-#endif /* #if WIN32_AIO */
-
-static void raw_flush(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- FlushFileBuffers(s->hfile);
-}
-
-static void raw_close(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- CloseHandle(s->hfile);
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
- BDRVRawState *s = bs->opaque;
- DWORD low, high;
-
- low = offset;
- high = offset >> 32;
- if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
- return -EIO;
- if (!SetEndOfFile(s->hfile))
- return -EIO;
- return 0;
-}
-
-static int64_t raw_getlength(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- LARGE_INTEGER l;
- ULARGE_INTEGER available, total, total_free;
- DISK_GEOMETRY_EX dg;
- DWORD count;
- BOOL status;
-
- switch(s->type) {
- case FTYPE_FILE:
- l.LowPart = GetFileSize(s->hfile, &l.HighPart);
- if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
- return -EIO;
- break;
- case FTYPE_CD:
- if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
- return -EIO;
- l.QuadPart = total.QuadPart;
- break;
- case FTYPE_HARDDISK:
- status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
- NULL, 0, &dg, sizeof(dg), &count, NULL);
- if (status != 0) {
- l = dg.DiskSize;
- }
- break;
- default:
- return -EIO;
- }
- return l.QuadPart;
-}
-
-static int raw_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd;
-
- if (flags || backing_file)
- return -ENOTSUP;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- 0644);
- if (fd < 0)
- return -EIO;
- set_sparse(fd);
- ftruncate(fd, total_size * 512);
- close(fd);
- return 0;
-}
-
-void qemu_aio_init(void)
-{
-}
-
-void qemu_aio_flush(void)
-{
-}
-
-void qemu_aio_wait(void)
-{
- qemu_bh_poll();
-}
-
-BlockDriver bdrv_raw = {
- "raw",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- raw_open,
- NULL,
- NULL,
- raw_close,
- raw_create,
- raw_flush,
-
-#ifdef WIN32_AIO
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB);
-#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_truncate = raw_truncate,
- .bdrv_getlength = raw_getlength,
-};
-
-/***********************************************/
-/* host device */
-
-static int find_cdrom(char *cdrom_name, int cdrom_name_size)
-{
- char drives[256], *pdrv = drives;
- UINT type;
-
- memset(drives, 0, sizeof(drives));
- GetLogicalDriveStrings(sizeof(drives), drives);
- while(pdrv[0] != '\0') {
- type = GetDriveType(pdrv);
- switch(type) {
- case DRIVE_CDROM:
- snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
- return 0;
- break;
- }
- pdrv += lstrlen(pdrv) + 1;
- }
- return -1;
-}
-
-static int find_device_type(BlockDriverState *bs, const char *filename)
-{
- BDRVRawState *s = bs->opaque;
- UINT type;
- const char *p;
-
- if (strstart(filename, "\\\\.\\", &p) ||
- strstart(filename, "//./", &p)) {
- if (stristart(p, "PhysicalDrive", NULL))
- return FTYPE_HARDDISK;
- snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
- type = GetDriveType(s->drive_path);
- if (type == DRIVE_CDROM)
- return FTYPE_CD;
- else
- return FTYPE_FILE;
- } else {
- return FTYPE_FILE;
- }
-}
-
-static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVRawState *s = bs->opaque;
- int access_flags, create_flags;
- DWORD overlapped;
- char device_name[64];
-
- if (strstart(filename, "/dev/cdrom", NULL)) {
- if (find_cdrom(device_name, sizeof(device_name)) < 0)
- return -ENOENT;
- filename = device_name;
- } else {
- /* transform drive letters into device name */
- if (((filename[0] >= 'a' && filename[0] <= 'z') ||
- (filename[0] >= 'A' && filename[0] <= 'Z')) &&
- filename[1] == ':' && filename[2] == '\0') {
- snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
- filename = device_name;
- }
- }
- s->type = find_device_type(bs, filename);
-
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
- access_flags = GENERIC_READ | GENERIC_WRITE;
- } else {
- access_flags = GENERIC_READ;
- }
- create_flags = OPEN_EXISTING;
-
-#ifdef WIN32_AIO
- overlapped = FILE_FLAG_OVERLAPPED;
-#else
- overlapped = FILE_ATTRIBUTE_NORMAL;
-#endif
- if (flags & BDRV_O_DIRECT)
- overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
- s->hfile = CreateFile(filename, access_flags,
- FILE_SHARE_READ, NULL,
- create_flags, overlapped, NULL);
- if (s->hfile == INVALID_HANDLE_VALUE) {
- int err = GetLastError();
-
- if (err == ERROR_ACCESS_DENIED)
- return -EACCES;
- return -1;
- }
- return 0;
-}
-
-#if 0
-/***********************************************/
-/* removable device additional commands */
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
- return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- DWORD ret_count;
-
- if (s->type == FTYPE_FILE)
- return -ENOTSUP;
- if (eject_flag) {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
- NULL, 0, NULL, 0, &lpBytesReturned, NULL);
- } else {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
- NULL, 0, NULL, 0, &lpBytesReturned, NULL);
- }
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- return -ENOTSUP;
-}
-#endif
-
-BlockDriver bdrv_host_device = {
- "host_device",
- sizeof(BDRVRawState),
- NULL, /* no probe for protocols */
- hdev_open,
- NULL,
- NULL,
- raw_close,
- NULL,
- raw_flush,
-
-#ifdef WIN32_AIO
- .bdrv_aio_read = raw_aio_read,
- .bdrv_aio_write = raw_aio_write,
- .bdrv_aio_cancel = raw_aio_cancel,
- .aiocb_size = sizeof(RawAIOCB);
-#endif
- .bdrv_pread = raw_pread,
- .bdrv_pwrite = raw_pwrite,
- .bdrv_getlength = raw_getlength,
-};
diff --git a/block-vmdk.c b/block-vmdk.c
deleted file mode 100644
index 8d67c2f..0000000
--- a/block-vmdk.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * Block driver for the VMDK format
- *
- * Copyright (c) 2004 Fabrice Bellard
- * Copyright (c) 2005 Filip Navara
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "block_int.h"
-
-#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
-#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
-
-typedef struct {
- uint32_t version;
- uint32_t flags;
- uint32_t disk_sectors;
- uint32_t granularity;
- uint32_t l1dir_offset;
- uint32_t l1dir_size;
- uint32_t file_sectors;
- uint32_t cylinders;
- uint32_t heads;
- uint32_t sectors_per_track;
-} VMDK3Header;
-
-typedef struct {
- uint32_t version;
- uint32_t flags;
- int64_t capacity;
- int64_t granularity;
- int64_t desc_offset;
- int64_t desc_size;
- int32_t num_gtes_per_gte;
- int64_t rgd_offset;
- int64_t gd_offset;
- int64_t grain_offset;
- char filler[1];
- char check_bytes[4];
-} __attribute__((packed)) VMDK4Header;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVVmdkState {
- BlockDriverState *hd;
- int64_t l1_table_offset;
- int64_t l1_backup_table_offset;
- uint32_t *l1_table;
- uint32_t *l1_backup_table;
- unsigned int l1_size;
- uint32_t l1_entry_sectors;
-
- unsigned int l2_size;
- uint32_t *l2_cache;
- uint32_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
-
- unsigned int cluster_sectors;
- uint32_t parent_cid;
- int is_parent;
-} BDRVVmdkState;
-
-typedef struct VmdkMetaData {
- uint32_t offset;
- unsigned int l1_index;
- unsigned int l2_index;
- unsigned int l2_offset;
- int valid;
-} VmdkMetaData;
-
-typedef struct ActiveBDRVState{
- BlockDriverState *hd; // active image handler
- uint64_t cluster_offset; // current write offset
-}ActiveBDRVState;
-
-static ActiveBDRVState activeBDRV;
-
-
-static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- uint32_t magic;
-
- if (buf_size < 4)
- return 0;
- magic = be32_to_cpu(*(uint32_t *)buf);
- if (magic == VMDK3_MAGIC ||
- magic == VMDK4_MAGIC)
- return 100;
- else
- return 0;
-}
-
-#define CHECK_CID 1
-
-#define SECTOR_SIZE 512
-#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
-#define HEADER_SIZE 512 // first sector of 512 bytes
-
-static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
-{
- BDRVVmdkState *s = bs->opaque;
- char desc[DESC_SIZE];
- uint32_t cid;
- const char *p_name, *cid_str;
- size_t cid_str_size;
-
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return 0;
-
- if (parent) {
- cid_str = "parentCID";
- cid_str_size = sizeof("parentCID");
- } else {
- cid_str = "CID";
- cid_str_size = sizeof("CID");
- }
-
- if ((p_name = strstr(desc,cid_str)) != 0) {
- p_name += cid_str_size;
- sscanf(p_name,"%x",&cid);
- }
-
- return cid;
-}
-
-static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
-{
- BDRVVmdkState *s = bs->opaque;
- char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
- char *p_name, *tmp_str;
-
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
-
- tmp_str = strstr(desc,"parentCID");
- pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
- if ((p_name = strstr(desc,"CID")) != 0) {
- p_name += sizeof("CID");
- snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);
- pstrcat(desc, sizeof(desc), tmp_desc);
- }
-
- if (bdrv_pwrite(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
- return 0;
-}
-
-static int vmdk_is_cid_valid(BlockDriverState *bs)
-{
-#ifdef CHECK_CID
- BDRVVmdkState *s = bs->opaque;
- BlockDriverState *p_bs = s->hd->backing_hd;
- uint32_t cur_pcid;
-
- if (p_bs) {
- cur_pcid = vmdk_read_cid(p_bs,0);
- if (s->parent_cid != cur_pcid)
- // CID not valid
- return 0;
- }
-#endif
- // CID valid
- return 1;
-}
-
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
-{
- int snp_fd, p_fd;
- uint32_t p_cid;
- char *p_name, *gd_buf, *rgd_buf;
- const char *real_filename, *temp_str;
- VMDK4Header header;
- uint32_t gde_entries, gd_size;
- int64_t gd_offset, rgd_offset, capacity, gt_size;
- char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
- static const char desc_template[] =
- "# Disk DescriptorFile\n"
- "version=1\n"
- "CID=%x\n"
- "parentCID=%x\n"
- "createType=\"monolithicSparse\"\n"
- "parentFileNameHint=\"%s\"\n"
- "\n"
- "# Extent description\n"
- "RW %u SPARSE \"%s\"\n"
- "\n"
- "# The Disk Data Base \n"
- "#DDB\n"
- "\n";
-
- snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
- if (snp_fd < 0)
- return -1;
- p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (p_fd < 0) {
- close(snp_fd);
- return -1;
- }
-
- /* read the header */
- if (lseek(p_fd, 0x0, SEEK_SET) == -1)
- goto fail;
- if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE)
- goto fail;
-
- /* write the header */
- if (lseek(snp_fd, 0x0, SEEK_SET) == -1)
- goto fail;
- if (write(snp_fd, hdr, HEADER_SIZE) == -1)
- goto fail;
-
- memset(&header, 0, sizeof(header));
- memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
-
- ftruncate(snp_fd, header.grain_offset << 9);
- /* the descriptor offset = 0x200 */
- if (lseek(p_fd, 0x200, SEEK_SET) == -1)
- goto fail;
- if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE)
- goto fail;
-
- if ((p_name = strstr(p_desc,"CID")) != 0) {
- p_name += sizeof("CID");
- sscanf(p_name,"%x",&p_cid);
- }
-
- real_filename = filename;
- if ((temp_str = strrchr(real_filename, '\\')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, '/')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, ':')) != NULL)
- real_filename = temp_str + 1;
-
- snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,
- (uint32_t)header.capacity, real_filename);
-
- /* write the descriptor */
- if (lseek(snp_fd, 0x200, SEEK_SET) == -1)
- goto fail;
- if (write(snp_fd, s_desc, strlen(s_desc)) == -1)
- goto fail;
-
- gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table
- rgd_offset = header.rgd_offset * SECTOR_SIZE; // offset of RGD table
- capacity = header.capacity * SECTOR_SIZE; // Extent size
- /*
- * Each GDE span 32M disk, means:
- * 512 GTE per GT, each GTE points to grain
- */
- gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
- if (!gt_size)
- goto fail;
- gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
- gd_size = gde_entries * sizeof(uint32_t);
-
- /* write RGD */
- rgd_buf = qemu_malloc(gd_size);
- if (!rgd_buf)
- goto fail;
- if (lseek(p_fd, rgd_offset, SEEK_SET) == -1)
- goto fail_rgd;
- if (read(p_fd, rgd_buf, gd_size) != gd_size)
- goto fail_rgd;
- if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1)
- goto fail_rgd;
- if (write(snp_fd, rgd_buf, gd_size) == -1)
- goto fail_rgd;
- qemu_free(rgd_buf);
-
- /* write GD */
- gd_buf = qemu_malloc(gd_size);
- if (!gd_buf)
- goto fail_rgd;
- if (lseek(p_fd, gd_offset, SEEK_SET) == -1)
- goto fail_gd;
- if (read(p_fd, gd_buf, gd_size) != gd_size)
- goto fail_gd;
- if (lseek(snp_fd, gd_offset, SEEK_SET) == -1)
- goto fail_gd;
- if (write(snp_fd, gd_buf, gd_size) == -1)
- goto fail_gd;
- qemu_free(gd_buf);
-
- close(p_fd);
- close(snp_fd);
- return 0;
-
- fail_gd:
- qemu_free(gd_buf);
- fail_rgd:
- qemu_free(rgd_buf);
- fail:
- close(p_fd);
- close(snp_fd);
- return -1;
-}
-
-static void vmdk_parent_close(BlockDriverState *bs)
-{
- if (bs->backing_hd)
- bdrv_close(bs->backing_hd);
-}
-
-int parent_open = 0;
-static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
-{
- BDRVVmdkState *s = bs->opaque;
- char *p_name;
- char desc[DESC_SIZE];
- char parent_img_name[1024];
-
- /* the descriptor offset = 0x200 */
- if (bdrv_pread(s->hd, 0x200, desc, DESC_SIZE) != DESC_SIZE)
- return -1;
-
- if ((p_name = strstr(desc,"parentFileNameHint")) != 0) {
- char *end_name;
- struct stat file_buf;
-
- p_name += sizeof("parentFileNameHint") + 1;
- if ((end_name = strchr(p_name,'\"')) == 0)
- return -1;
- if ((end_name - p_name) > sizeof (s->hd->backing_file) - 1)
- return -1;
-
- strncpy(s->hd->backing_file, p_name, end_name - p_name);
- if (stat(s->hd->backing_file, &file_buf) != 0) {
- path_combine(parent_img_name, sizeof(parent_img_name),
- filename, s->hd->backing_file);
- } else {
- pstrcpy(parent_img_name, sizeof(parent_img_name),
- s->hd->backing_file);
- }
-
- s->hd->backing_hd = bdrv_new("");
- if (!s->hd->backing_hd) {
- failure:
- bdrv_close(s->hd);
- return -1;
- }
- parent_open = 1;
- if (bdrv_open(s->hd->backing_hd, parent_img_name, BDRV_O_RDONLY) < 0)
- goto failure;
- parent_open = 0;
- }
-
- return 0;
-}
-
-static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVVmdkState *s = bs->opaque;
- uint32_t magic;
- int l1_size, i, ret;
-
- if (parent_open)
- // Parent must be opened as RO.
- flags = BDRV_O_RDONLY;
-
- ret = bdrv_file_open(&s->hd, filename, flags);
- if (ret < 0)
- return ret;
- if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))
- goto fail;
-
- magic = be32_to_cpu(magic);
- if (magic == VMDK3_MAGIC) {
- VMDK3Header header;
-
- if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))
- goto fail;
- s->cluster_sectors = le32_to_cpu(header.granularity);
- s->l2_size = 1 << 9;
- s->l1_size = 1 << 6;
- bs->total_sectors = le32_to_cpu(header.disk_sectors);
- s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;
- s->l1_backup_table_offset = 0;
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
- } else if (magic == VMDK4_MAGIC) {
- VMDK4Header header;
-
- if (bdrv_pread(s->hd, sizeof(magic), &header, sizeof(header)) != sizeof(header))
- goto fail;
- bs->total_sectors = le64_to_cpu(header.capacity);
- s->cluster_sectors = le64_to_cpu(header.granularity);
- s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
- if (s->l1_entry_sectors <= 0)
- goto fail;
- s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
- / s->l1_entry_sectors;
- s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
- s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
-
- if (parent_open)
- s->is_parent = 1;
- else
- s->is_parent = 0;
-
- // try to open parent images, if exist
- if (vmdk_parent_open(bs, filename) != 0)
- goto fail;
- // write the CID once after the image creation
- s->parent_cid = vmdk_read_cid(bs,1);
- } else {
- goto fail;
- }
-
- /* read the L1 table */
- l1_size = s->l1_size * sizeof(uint32_t);
- s->l1_table = qemu_malloc(l1_size);
- if (!s->l1_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, l1_size) != l1_size)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- le32_to_cpus(&s->l1_table[i]);
- }
-
- if (s->l1_backup_table_offset) {
- s->l1_backup_table = qemu_malloc(l1_size);
- if (!s->l1_backup_table)
- goto fail;
- if (bdrv_pread(s->hd, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- le32_to_cpus(&s->l1_backup_table[i]);
- }
- }
-
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
- if (!s->l2_cache)
- goto fail;
- return 0;
- fail:
- qemu_free(s->l1_backup_table);
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- bdrv_delete(s->hd);
- return -1;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
- uint64_t offset, int allocate);
-
-static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
- uint64_t offset, int allocate)
-{
- uint64_t parent_cluster_offset;
- BDRVVmdkState *s = bs->opaque;
- uint8_t whole_grain[s->cluster_sectors*512]; // 128 sectors * 512 bytes each = grain size 64KB
-
- // we will be here if it's first write on non-exist grain(cluster).
- // try to read from parent image, if exist
- if (s->hd->backing_hd) {
- BDRVVmdkState *ps = s->hd->backing_hd->opaque;
-
- if (!vmdk_is_cid_valid(bs))
- return -1;
-
- parent_cluster_offset = get_cluster_offset(s->hd->backing_hd, NULL, offset, allocate);
-
- if (parent_cluster_offset) {
- BDRVVmdkState *act_s = activeBDRV.hd->opaque;
-
- if (bdrv_pread(ps->hd, parent_cluster_offset, whole_grain, ps->cluster_sectors*512) != ps->cluster_sectors*512)
- return -1;
-
- //Write grain only into the active image
- if (bdrv_pwrite(act_s->hd, activeBDRV.cluster_offset << 9, whole_grain, sizeof(whole_grain)) != sizeof(whole_grain))
- return -1;
- }
- }
- return 0;
-}
-
-static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
-{
- BDRVVmdkState *s = bs->opaque;
-
- /* update L2 table */
- if (bdrv_pwrite(s->hd, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
- &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
- return -1;
- /* update backup L2 table */
- if (s->l1_backup_table_offset != 0) {
- m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
- if (bdrv_pwrite(s->hd, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
- &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
- return -1;
- }
-
- return 0;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
- uint64_t offset, int allocate)
-{
- BDRVVmdkState *s = bs->opaque;
- unsigned int l1_index, l2_offset, l2_index;
- int min_index, i, j;
- uint32_t min_count, *l2_table, tmp = 0;
- uint64_t cluster_offset;
-
- if (m_data)
- m_data->valid = 0;
-
- l1_index = (offset >> 9) / s->l1_entry_sectors;
- if (l1_index >= s->l1_size)
- return 0;
- l2_offset = s->l1_table[l1_index];
- if (!l2_offset)
- return 0;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i * s->l2_size);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index * s->l2_size);
- if (bdrv_pread(s->hd, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
- s->l2_size * sizeof(uint32_t))
- return 0;
-
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
- cluster_offset = le32_to_cpu(l2_table[l2_index]);
-
- if (!cluster_offset) {
- if (!allocate)
- return 0;
- // Avoid the L2 tables update for the images that have snapshots.
- if (!s->is_parent) {
- cluster_offset = bdrv_getlength(s->hd);
- bdrv_truncate(s->hd, cluster_offset + (s->cluster_sectors << 9));
-
- cluster_offset >>= 9;
- tmp = cpu_to_le32(cluster_offset);
- l2_table[l2_index] = tmp;
- // Save the active image state
- activeBDRV.cluster_offset = cluster_offset;
- activeBDRV.hd = bs;
- }
- /* First of all we write grain itself, to avoid race condition
- * that may to corrupt the image.
- * This problem may occur because of insufficient space on host disk
- * or inappropriate VM shutdown.
- */
- if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
- return 0;
-
- if (m_data) {
- m_data->offset = tmp;
- m_data->l1_index = l1_index;
- m_data->l2_index = l2_index;
- m_data->l2_offset = l2_offset;
- m_data->valid = 1;
- }
- }
- cluster_offset <<= 9;
- return cluster_offset;
-}
-
-static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
- index_in_cluster = sector_num % s->cluster_sectors;
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n, ret;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
- index_in_cluster = sector_num % s->cluster_sectors;
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- if (!cluster_offset) {
- // try to read from parent image, if exist
- if (s->hd->backing_hd) {
- if (!vmdk_is_cid_valid(bs))
- return -1;
- ret = bdrv_read(s->hd->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- memset(buf, 0, 512 * n);
- }
- } else {
- if(bdrv_pread(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
- return -1;
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVVmdkState *s = bs->opaque;
- VmdkMetaData m_data;
- int index_in_cluster, n;
- uint64_t cluster_offset;
- static int cid_update = 0;
-
- if (sector_num > bs->total_sectors) {
- fprintf(stderr,
- "(VMDK) Wrong offset: sector_num=0x%" PRIx64
- " total_sectors=0x%" PRIx64 "\n",
- sector_num, bs->total_sectors);
- return -1;
- }
-
- while (nb_sectors > 0) {
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
- if (!cluster_offset)
- return -1;
-
- if (bdrv_pwrite(s->hd, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
- return -1;
- if (m_data.valid) {
- /* update L2 tables */
- if (vmdk_L2update(bs, &m_data) == -1)
- return -1;
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
-
- // update CID on the first write every time the virtual disk is opened
- if (!cid_update) {
- vmdk_write_cid(bs, time(NULL));
- cid_update++;
- }
- }
- return 0;
-}
-
-static int vmdk_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd, i;
- VMDK4Header header;
- uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
- static const char desc_template[] =
- "# Disk DescriptorFile\n"
- "version=1\n"
- "CID=%x\n"
- "parentCID=ffffffff\n"
- "createType=\"monolithicSparse\"\n"
- "\n"
- "# Extent description\n"
- "RW %lu SPARSE \"%s\"\n"
- "\n"
- "# The Disk Data Base \n"
- "#DDB\n"
- "\n"
- "ddb.virtualHWVersion = \"%d\"\n"
- "ddb.geometry.cylinders = \"%lu\"\n"
- "ddb.geometry.heads = \"16\"\n"
- "ddb.geometry.sectors = \"63\"\n"
- "ddb.adapterType = \"ide\"\n";
- char desc[1024];
- const char *real_filename, *temp_str;
-
- /* XXX: add support for backing file */
- if (backing_file) {
- return vmdk_snapshot_create(filename, backing_file);
- }
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
- 0644);
- if (fd < 0)
- return -1;
- magic = cpu_to_be32(VMDK4_MAGIC);
- memset(&header, 0, sizeof(header));
- header.version = cpu_to_le32(1);
- header.flags = cpu_to_le32(3); /* ?? */
- header.capacity = cpu_to_le64(total_size);
- header.granularity = cpu_to_le64(128);
- header.num_gtes_per_gte = cpu_to_le32(512);
-
- grains = (total_size + header.granularity - 1) / header.granularity;
- gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
- gt_count = (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
- gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
-
- header.desc_offset = 1;
- header.desc_size = 20;
- header.rgd_offset = header.desc_offset + header.desc_size;
- header.gd_offset = header.rgd_offset + gd_size + (gt_size * gt_count);
- header.grain_offset =
- ((header.gd_offset + gd_size + (gt_size * gt_count) +
- header.granularity - 1) / header.granularity) *
- header.granularity;
-
- header.desc_offset = cpu_to_le64(header.desc_offset);
- header.desc_size = cpu_to_le64(header.desc_size);
- header.rgd_offset = cpu_to_le64(header.rgd_offset);
- header.gd_offset = cpu_to_le64(header.gd_offset);
- header.grain_offset = cpu_to_le64(header.grain_offset);
-
- header.check_bytes[0] = 0xa;
- header.check_bytes[1] = 0x20;
- header.check_bytes[2] = 0xd;
- header.check_bytes[3] = 0xa;
-
- /* write all the data */
- write(fd, &magic, sizeof(magic));
- write(fd, &header, sizeof(header));
-
- ftruncate(fd, header.grain_offset << 9);
-
- /* write grain directory */
- lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
- for (i = 0, tmp = header.rgd_offset + gd_size;
- i < gt_count; i++, tmp += gt_size)
- write(fd, &tmp, sizeof(tmp));
-
- /* write backup grain directory */
- lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
- for (i = 0, tmp = header.gd_offset + gd_size;
- i < gt_count; i++, tmp += gt_size)
- write(fd, &tmp, sizeof(tmp));
-
- /* compose the descriptor */
- real_filename = filename;
- if ((temp_str = strrchr(real_filename, '\\')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, '/')) != NULL)
- real_filename = temp_str + 1;
- if ((temp_str = strrchr(real_filename, ':')) != NULL)
- real_filename = temp_str + 1;
- snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL),
- (unsigned long)total_size, real_filename,
- (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), total_size / (63 * 16));
-
- /* write the descriptor */
- lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
- write(fd, desc, strlen(desc));
-
- close(fd);
- return 0;
-}
-
-static void vmdk_close(BlockDriverState *bs)
-{
- BDRVVmdkState *s = bs->opaque;
-
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- // try to close parent image, if exist
- vmdk_parent_close(s->hd);
- bdrv_delete(s->hd);
-}
-
-static void vmdk_flush(BlockDriverState *bs)
-{
- BDRVVmdkState *s = bs->opaque;
- bdrv_flush(s->hd);
-}
-
-BlockDriver bdrv_vmdk = {
- "vmdk",
- sizeof(BDRVVmdkState),
- vmdk_probe,
- vmdk_open,
- vmdk_read,
- vmdk_write,
- vmdk_close,
- vmdk_create,
- vmdk_flush,
- vmdk_is_allocated,
-};
diff --git a/block-vpc.c b/block-vpc.c
deleted file mode 100644
index f76c451..0000000
--- a/block-vpc.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Block driver for Conectix/Microsoft Virtual PC images
- *
- * Copyright (c) 2005 Alex Beregszaszi
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block_int.h"
-
-/**************************************************************/
-
-#define HEADER_SIZE 512
-
-//#define CACHE
-
-// always big-endian
-struct vpc_subheader {
- char magic[8]; // "conectix" / "cxsparse"
- union {
- struct {
- uint32_t unk1[2];
- uint32_t unk2; // always zero?
- uint32_t subheader_offset;
- uint32_t unk3; // some size?
- char creator[4]; // "vpc "
- uint16_t major;
- uint16_t minor;
- char guest[4]; // "Wi2k"
- uint32_t unk4[7];
- uint8_t vnet_id[16]; // virtual network id, purpose unknown
- // next 16 longs are used, but dunno the purpose
- // next 6 longs unknown, following 7 long maybe a serial
- char padding[HEADER_SIZE - 84];
- } main;
- struct {
- uint32_t unk1[2]; // all bits set
- uint32_t unk2; // always zero?
- uint32_t pagetable_offset;
- uint32_t unk3;
- uint32_t pagetable_entries; // 32bit/entry
- uint32_t pageentry_size; // 512*8*512
- uint32_t nb_sectors;
- char padding[HEADER_SIZE - 40];
- } sparse;
- char padding[HEADER_SIZE - 8];
- } type;
-};
-
-typedef struct BDRVVPCState {
- int fd;
-
- int pagetable_entries;
- uint32_t *pagetable;
-
- uint32_t pageentry_size;
-#ifdef CACHE
- uint8_t *pageentry_u8;
- uint32_t *pageentry_u32;
- uint16_t *pageentry_u16;
-
- uint64_t last_bitmap;
-#endif
-} BDRVVPCState;
-
-static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- if (buf_size >= 8 && !strncmp((char *)buf, "conectix", 8))
- return 100;
- return 0;
-}
-
-static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
-{
- BDRVVPCState *s = bs->opaque;
- int fd, i;
- struct vpc_subheader header;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
-
- bs->read_only = 1; // no write support yet
-
- s->fd = fd;
-
- if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
- goto fail;
-
- if (strncmp(header.magic, "conectix", 8))
- goto fail;
- lseek(s->fd, be32_to_cpu(header.type.main.subheader_offset), SEEK_SET);
-
- if (read(fd, &header, HEADER_SIZE) != HEADER_SIZE)
- goto fail;
-
- if (strncmp(header.magic, "cxsparse", 8))
- goto fail;
-
- bs->total_sectors = ((uint64_t)be32_to_cpu(header.type.sparse.pagetable_entries) *
- be32_to_cpu(header.type.sparse.pageentry_size)) / 512;
-
- lseek(s->fd, be32_to_cpu(header.type.sparse.pagetable_offset), SEEK_SET);
-
- s->pagetable_entries = be32_to_cpu(header.type.sparse.pagetable_entries);
- s->pagetable = qemu_malloc(s->pagetable_entries * 4);
- if (!s->pagetable)
- goto fail;
- if (read(s->fd, s->pagetable, s->pagetable_entries * 4) !=
- s->pagetable_entries * 4)
- goto fail;
- for (i = 0; i < s->pagetable_entries; i++)
- be32_to_cpus(&s->pagetable[i]);
-
- s->pageentry_size = be32_to_cpu(header.type.sparse.pageentry_size);
-#ifdef CACHE
- s->pageentry_u8 = qemu_malloc(512);
- if (!s->pageentry_u8)
- goto fail;
- s->pageentry_u32 = s->pageentry_u8;
- s->pageentry_u16 = s->pageentry_u8;
- s->last_pagetable = -1;
-#endif
-
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
-{
- BDRVVPCState *s = bs->opaque;
- uint64_t offset = sector_num * 512;
- uint64_t bitmap_offset, block_offset;
- uint32_t pagetable_index, pageentry_index;
-
- pagetable_index = offset / s->pageentry_size;
- pageentry_index = (offset % s->pageentry_size) / 512;
-
- if (pagetable_index > s->pagetable_entries || s->pagetable[pagetable_index] == 0xffffffff)
- return -1; // not allocated
-
- bitmap_offset = 512 * s->pagetable[pagetable_index];
- block_offset = bitmap_offset + 512 + (512 * pageentry_index);
-
-// printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
-// sector_num, pagetable_index, pageentry_index,
-// bitmap_offset, block_offset);
-
-// disabled by reason
-#if 0
-#ifdef CACHE
- if (bitmap_offset != s->last_bitmap)
- {
- lseek(s->fd, bitmap_offset, SEEK_SET);
-
- s->last_bitmap = bitmap_offset;
-
- // Scary! Bitmap is stored as big endian 32bit entries,
- // while we used to look it up byte by byte
- read(s->fd, s->pageentry_u8, 512);
- for (i = 0; i < 128; i++)
- be32_to_cpus(&s->pageentry_u32[i]);
- }
-
- if ((s->pageentry_u8[pageentry_index / 8] >> (pageentry_index % 8)) & 1)
- return -1;
-#else
- lseek(s->fd, bitmap_offset + (pageentry_index / 8), SEEK_SET);
-
- read(s->fd, &bitmap_entry, 1);
-
- if ((bitmap_entry >> (pageentry_index % 8)) & 1)
- return -1; // not allocated
-#endif
-#endif
- lseek(s->fd, block_offset, SEEK_SET);
-
- return 0;
-}
-
-static int vpc_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVPCState *s = bs->opaque;
- int ret;
-
- while (nb_sectors > 0) {
- if (!seek_to_sector(bs, sector_num))
- {
- ret = read(s->fd, buf, 512);
- if (ret != 512)
- return -1;
- }
- else
- memset(buf, 0, 512);
- nb_sectors--;
- sector_num++;
- buf += 512;
- }
- return 0;
-}
-
-static void vpc_close(BlockDriverState *bs)
-{
- BDRVVPCState *s = bs->opaque;
- qemu_free(s->pagetable);
-#ifdef CACHE
- qemu_free(s->pageentry_u8);
-#endif
- close(s->fd);
-}
-
-BlockDriver bdrv_vpc = {
- "vpc",
- sizeof(BDRVVPCState),
- vpc_probe,
- vpc_open,
- vpc_read,
- NULL,
- vpc_close,
-};
diff --git a/block-vvfat.c b/block-vvfat.c
deleted file mode 100644
index 79804a7..0000000
--- a/block-vvfat.c
+++ /dev/null
@@ -1,2847 +0,0 @@
-/* vim:set shiftwidth=4 ts=8: */
-/*
- * QEMU Block driver for virtual VFAT (shadows a local directory)
- *
- * Copyright (c) 2004,2005 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <sys/stat.h>
-#include <dirent.h>
-#include <assert.h>
-#include "qemu-common.h"
-#include "block_int.h"
-
-#ifndef S_IWGRP
-#define S_IWGRP 0
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 0
-#endif
-
-/* TODO: add ":bootsector=blabla.img:" */
-/* LATER TODO: add automatic boot sector generation from
- BOOTEASY.ASM and Ranish Partition Manager
- Note that DOS assumes the system files to be the first files in the
- file system (test if the boot sector still relies on that fact)! */
-/* MAYBE TODO: write block-visofs.c */
-/* TODO: call try_commit() only after a timeout */
-
-/* #define DEBUG */
-
-#ifdef DEBUG
-
-#define DLOG(a) a
-
-#undef stderr
-#define stderr STDERR
-FILE* stderr = NULL;
-
-static void checkpoint(void);
-
-#ifdef __MINGW32__
-void nonono(const char* file, int line, const char* msg) {
- fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
- exit(-5);
-}
-#undef assert
-#define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
-#endif
-
-#else
-
-#define DLOG(a)
-
-#endif
-
-/* dynamic array functions */
-typedef struct array_t {
- char* pointer;
- unsigned int size,next,item_size;
-} array_t;
-
-static inline void array_init(array_t* array,unsigned int item_size)
-{
- array->pointer=0;
- array->size=0;
- array->next=0;
- array->item_size=item_size;
-}
-
-static inline void array_free(array_t* array)
-{
- if(array->pointer)
- free(array->pointer);
- array->size=array->next=0;
-}
-
-/* does not automatically grow */
-static inline void* array_get(array_t* array,unsigned int index) {
- assert(index < array->next);
- return array->pointer + index * array->item_size;
-}
-
-static inline int array_ensure_allocated(array_t* array, int index)
-{
- if((index + 1) * array->item_size > array->size) {
- int new_size = (index + 32) * array->item_size;
- array->pointer = qemu_realloc(array->pointer, new_size);
- if (!array->pointer)
- return -1;
- array->size = new_size;
- array->next = index + 1;
- }
-
- return 0;
-}
-
-static inline void* array_get_next(array_t* array) {
- unsigned int next = array->next;
- void* result;
-
- if (array_ensure_allocated(array, next) < 0)
- return NULL;
-
- array->next = next + 1;
- result = array_get(array, next);
-
- return result;
-}
-
-static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
- if((array->next+count)*array->item_size>array->size) {
- int increment=count*array->item_size;
- array->pointer=qemu_realloc(array->pointer,array->size+increment);
- if(!array->pointer)
- return 0;
- array->size+=increment;
- }
- memmove(array->pointer+(index+count)*array->item_size,
- array->pointer+index*array->item_size,
- (array->next-index)*array->item_size);
- array->next+=count;
- return array->pointer+index*array->item_size;
-}
-
-/* this performs a "roll", so that the element which was at index_from becomes
- * index_to, but the order of all other elements is preserved. */
-static inline int array_roll(array_t* array,int index_to,int index_from,int count)
-{
- char* buf;
- char* from;
- char* to;
- int is;
-
- if(!array ||
- index_to<0 || index_to>=array->next ||
- index_from<0 || index_from>=array->next)
- return -1;
-
- if(index_to==index_from)
- return 0;
-
- is=array->item_size;
- from=array->pointer+index_from*is;
- to=array->pointer+index_to*is;
- buf=malloc(is*count);
- memcpy(buf,from,is*count);
-
- if(index_to<index_from)
- memmove(to+is*count,to,from-to);
- else
- memmove(from,from+is*count,to-from);
-
- memcpy(to,buf,is*count);
-
- free(buf);
-
- return 0;
-}
-
-static inline int array_remove_slice(array_t* array,int index, int count)
-{
- assert(index >=0);
- assert(count > 0);
- assert(index + count <= array->next);
- if(array_roll(array,array->next-1,index,count))
- return -1;
- array->next -= count;
- return 0;
-}
-
-static int array_remove(array_t* array,int index)
-{
- return array_remove_slice(array, index, 1);
-}
-
-/* return the index for a given member */
-static int array_index(array_t* array, void* pointer)
-{
- size_t offset = (char*)pointer - array->pointer;
- assert((offset % array->item_size) == 0);
- assert(offset/array->item_size < array->next);
- return offset/array->item_size;
-}
-
-/* These structures are used to fake a disk and the VFAT filesystem.
- * For this reason we need to use __attribute__((packed)). */
-
-typedef struct bootsector_t {
- uint8_t jump[3];
- uint8_t name[8];
- uint16_t sector_size;
- uint8_t sectors_per_cluster;
- uint16_t reserved_sectors;
- uint8_t number_of_fats;
- uint16_t root_entries;
- uint16_t total_sectors16;
- uint8_t media_type;
- uint16_t sectors_per_fat;
- uint16_t sectors_per_track;
- uint16_t number_of_heads;
- uint32_t hidden_sectors;
- uint32_t total_sectors;
- union {
- struct {
- uint8_t drive_number;
- uint8_t current_head;
- uint8_t signature;
- uint32_t id;
- uint8_t volume_label[11];
- } __attribute__((packed)) fat16;
- struct {
- uint32_t sectors_per_fat;
- uint16_t flags;
- uint8_t major,minor;
- uint32_t first_cluster_of_root_directory;
- uint16_t info_sector;
- uint16_t backup_boot_sector;
- uint16_t ignored;
- } __attribute__((packed)) fat32;
- } u;
- uint8_t fat_type[8];
- uint8_t ignored[0x1c0];
- uint8_t magic[2];
-} __attribute__((packed)) bootsector_t;
-
-typedef struct {
- uint8_t head;
- uint8_t sector;
- uint8_t cylinder;
-} mbr_chs_t;
-
-typedef struct partition_t {
- uint8_t attributes; /* 0x80 = bootable */
- mbr_chs_t start_CHS;
- uint8_t fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
- mbr_chs_t end_CHS;
- uint32_t start_sector_long;
- uint32_t length_sector_long;
-} __attribute__((packed)) partition_t;
-
-typedef struct mbr_t {
- uint8_t ignored[0x1b8];
- uint32_t nt_id;
- uint8_t ignored2[2];
- partition_t partition[4];
- uint8_t magic[2];
-} __attribute__((packed)) mbr_t;
-
-typedef struct direntry_t {
- uint8_t name[8];
- uint8_t extension[3];
- uint8_t attributes;
- uint8_t reserved[2];
- uint16_t ctime;
- uint16_t cdate;
- uint16_t adate;
- uint16_t begin_hi;
- uint16_t mtime;
- uint16_t mdate;
- uint16_t begin;
- uint32_t size;
-} __attribute__((packed)) direntry_t;
-
-/* this structure are used to transparently access the files */
-
-typedef struct mapping_t {
- /* begin is the first cluster, end is the last+1 */
- uint32_t begin,end;
- /* as s->directory is growable, no pointer may be used here */
- unsigned int dir_index;
- /* the clusters of a file may be in any order; this points to the first */
- int first_mapping_index;
- union {
- /* offset is
- * - the offset in the file (in clusters) for a file, or
- * - the next cluster of the directory for a directory, and
- * - the address of the buffer for a faked entry
- */
- struct {
- uint32_t offset;
- } file;
- struct {
- int parent_mapping_index;
- int first_dir_index;
- } dir;
- } info;
- /* path contains the full path, i.e. it always starts with s->path */
- char* path;
-
- enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
- MODE_DIRECTORY = 4, MODE_FAKED = 8,
- MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
- int read_only;
-} mapping_t;
-
-#ifdef DEBUG
-static void print_direntry(const struct direntry_t*);
-static void print_mapping(const struct mapping_t* mapping);
-#endif
-
-/* here begins the real VVFAT driver */
-
-typedef struct BDRVVVFATState {
- BlockDriverState* bs; /* pointer to parent */
- unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
- unsigned char first_sectors[0x40*0x200];
-
- int fat_type; /* 16 or 32 */
- array_t fat,directory,mapping;
-
- unsigned int cluster_size;
- unsigned int sectors_per_cluster;
- unsigned int sectors_per_fat;
- unsigned int sectors_of_root_directory;
- uint32_t last_cluster_of_root_directory;
- unsigned int faked_sectors; /* how many sectors are faked before file data */
- uint32_t sector_count; /* total number of sectors of the partition */
- uint32_t cluster_count; /* total number of clusters of this partition */
- uint32_t max_fat_value;
-
- int current_fd;
- mapping_t* current_mapping;
- unsigned char* cluster; /* points to current cluster */
- unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
- unsigned int current_cluster;
-
- /* write support */
- BlockDriverState* write_target;
- char* qcow_filename;
- BlockDriverState* qcow;
- void* fat2;
- char* used_clusters;
- array_t commits;
- const char* path;
- int downcase_short_names;
-} BDRVVVFATState;
-
-/* take the sector position spos and convert it to Cylinder/Head/Sector position
- * if the position is outside the specified geometry, fill maximum value for CHS
- * and return 1 to signal overflow.
- */
-static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
- int head,sector;
- sector = spos % (bs->secs); spos/= bs->secs;
- head = spos % (bs->heads); spos/= bs->heads;
- if(spos >= bs->cyls){
- /* Overflow,
- it happens if 32bit sector positions are used, while CHS is only 24bit.
- Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
- chs->head = 0xFF;
- chs->sector = 0xFF;
- chs->cylinder = 0xFF;
- return 1;
- }
- chs->head = (uint8_t)head;
- chs->sector = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
- chs->cylinder = (uint8_t)spos;
- return 0;
-}
-
-static void init_mbr(BDRVVVFATState* s)
-{
- /* TODO: if the files mbr.img and bootsect.img exist, use them */
- mbr_t* real_mbr=(mbr_t*)s->first_sectors;
- partition_t* partition=&(real_mbr->partition[0]);
- int lba;
-
- memset(s->first_sectors,0,512);
-
- /* Win NT Disk Signature */
- real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);
-
- partition->attributes=0x80; /* bootable */
-
- /* LBA is used when partition is outside the CHS geometry */
- lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
- lba|= sector2CHS(s->bs, &partition->end_CHS, s->sector_count);
-
- /*LBA partitions are identified only by start/length_sector_long not by CHS*/
- partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
- partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);
-
- /* FAT12/FAT16/FAT32 */
- /* DOS uses different types when partition is LBA,
- probably to prevent older versions from using CHS on them */
- partition->fs_type= s->fat_type==12 ? 0x1:
- s->fat_type==16 ? (lba?0xe:0x06):
- /*fat_tyoe==32*/ (lba?0xc:0x0b);
-
- real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
-}
-
-/* direntry functions */
-
-/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
-static inline int short2long_name(char* dest,const char* src)
-{
- int i;
- int len;
- for(i=0;i<129 && src[i];i++) {
- dest[2*i]=src[i];
- dest[2*i+1]=0;
- }
- len=2*i;
- dest[2*i]=dest[2*i+1]=0;
- for(i=2*i+2;(i%26);i++)
- dest[i]=0xff;
- return len;
-}
-
-static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
-{
- char buffer[258];
- int length=short2long_name(buffer,filename),
- number_of_entries=(length+25)/26,i;
- direntry_t* entry;
-
- for(i=0;i<number_of_entries;i++) {
- entry=array_get_next(&(s->directory));
- entry->attributes=0xf;
- entry->reserved[0]=0;
- entry->begin=0;
- entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
- }
- for(i=0;i<26*number_of_entries;i++) {
- int offset=(i%26);
- if(offset<10) offset=1+offset;
- else if(offset<22) offset=14+offset-10;
- else offset=28+offset-22;
- entry=array_get(&(s->directory),s->directory.next-1-(i/26));
- entry->name[offset]=buffer[i];
- }
- return array_get(&(s->directory),s->directory.next-number_of_entries);
-}
-
-static char is_free(const direntry_t* direntry)
-{
- return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
-}
-
-static char is_volume_label(const direntry_t* direntry)
-{
- return direntry->attributes == 0x28;
-}
-
-static char is_long_name(const direntry_t* direntry)
-{
- return direntry->attributes == 0xf;
-}
-
-static char is_short_name(const direntry_t* direntry)
-{
- return !is_volume_label(direntry) && !is_long_name(direntry)
- && !is_free(direntry);
-}
-
-static char is_directory(const direntry_t* direntry)
-{
- return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
-}
-
-static inline char is_dot(const direntry_t* direntry)
-{
- return is_short_name(direntry) && direntry->name[0] == '.';
-}
-
-static char is_file(const direntry_t* direntry)
-{
- return is_short_name(direntry) && !is_directory(direntry);
-}
-
-static inline uint32_t begin_of_direntry(const direntry_t* direntry)
-{
- return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
-}
-
-static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
-{
- return le32_to_cpu(direntry->size);
-}
-
-static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
-{
- direntry->begin = cpu_to_le16(begin & 0xffff);
- direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
-}
-
-/* fat functions */
-
-static inline uint8_t fat_chksum(const direntry_t* entry)
-{
- uint8_t chksum=0;
- int i;
-
- for(i=0;i<11;i++)
- chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0))
- +(unsigned char)entry->name[i];
-
- return chksum;
-}
-
-/* if return_time==0, this returns the fat_date, else the fat_time */
-static uint16_t fat_datetime(time_t time,int return_time) {
- struct tm* t;
-#ifdef _WIN32
- t=localtime(&time); /* this is not thread safe */
-#else
- struct tm t1;
- t=&t1;
- localtime_r(&time,t);
-#endif
- if(return_time)
- return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
- return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
-}
-
-static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
-{
- if(s->fat_type==32) {
- uint32_t* entry=array_get(&(s->fat),cluster);
- *entry=cpu_to_le32(value);
- } else if(s->fat_type==16) {
- uint16_t* entry=array_get(&(s->fat),cluster);
- *entry=cpu_to_le16(value&0xffff);
- } else {
- int offset = (cluster*3/2);
- unsigned char* p = array_get(&(s->fat), offset);
- switch (cluster&1) {
- case 0:
- p[0] = value&0xff;
- p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
- break;
- case 1:
- p[0] = (p[0]&0xf) | ((value&0xf)<<4);
- p[1] = (value>>4);
- break;
- }
- }
-}
-
-static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
-{
- if(s->fat_type==32) {
- uint32_t* entry=array_get(&(s->fat),cluster);
- return le32_to_cpu(*entry);
- } else if(s->fat_type==16) {
- uint16_t* entry=array_get(&(s->fat),cluster);
- return le16_to_cpu(*entry);
- } else {
- const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
- return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
- }
-}
-
-static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
-{
- if(fat_entry>s->max_fat_value-8)
- return -1;
- return 0;
-}
-
-static inline void init_fat(BDRVVVFATState* s)
-{
- if (s->fat_type == 12) {
- array_init(&(s->fat),1);
- array_ensure_allocated(&(s->fat),
- s->sectors_per_fat * 0x200 * 3 / 2 - 1);
- } else {
- array_init(&(s->fat),(s->fat_type==32?4:2));
- array_ensure_allocated(&(s->fat),
- s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
- }
- memset(s->fat.pointer,0,s->fat.size);
-
- switch(s->fat_type) {
- case 12: s->max_fat_value=0xfff; break;
- case 16: s->max_fat_value=0xffff; break;
- case 32: s->max_fat_value=0x0fffffff; break;
- default: s->max_fat_value=0; /* error... */
- }
-
-}
-
-/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
-/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
-static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
- unsigned int directory_start, const char* filename, int is_dot)
-{
- int i,j,long_index=s->directory.next;
- direntry_t* entry=0;
- direntry_t* entry_long=0;
-
- if(is_dot) {
- entry=array_get_next(&(s->directory));
- memset(entry->name,0x20,11);
- memcpy(entry->name,filename,strlen(filename));
- return entry;
- }
-
- entry_long=create_long_filename(s,filename);
-
- i = strlen(filename);
- for(j = i - 1; j>0 && filename[j]!='.';j--);
- if (j > 0)
- i = (j > 8 ? 8 : j);
- else if (i > 8)
- i = 8;
-
- entry=array_get_next(&(s->directory));
- memset(entry->name,0x20,11);
- strncpy((char*)entry->name,filename,i);
-
- if(j > 0)
- for (i = 0; i < 3 && filename[j+1+i]; i++)
- entry->extension[i] = filename[j+1+i];
-
- /* upcase & remove unwanted characters */
- for(i=10;i>=0;i--) {
- if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
- if(entry->name[i]<=' ' || entry->name[i]>0x7f
- || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
- entry->name[i]='_';
- else if(entry->name[i]>='a' && entry->name[i]<='z')
- entry->name[i]+='A'-'a';
- }
-
- /* mangle duplicates */
- while(1) {
- direntry_t* entry1=array_get(&(s->directory),directory_start);
- int j;
-
- for(;entry1<entry;entry1++)
- if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
- break; /* found dupe */
- if(entry1==entry) /* no dupe found */
- break;
-
- /* use all 8 characters of name */
- if(entry->name[7]==' ') {
- int j;
- for(j=6;j>0 && entry->name[j]==' ';j--)
- entry->name[j]='~';
- }
-
- /* increment number */
- for(j=7;j>0 && entry->name[j]=='9';j--)
- entry->name[j]='0';
- if(j>0) {
- if(entry->name[j]<'0' || entry->name[j]>'9')
- entry->name[j]='0';
- else
- entry->name[j]++;
- }
- }
-
- /* calculate checksum; propagate to long name */
- if(entry_long) {
- uint8_t chksum=fat_chksum(entry);
-
- /* calculate anew, because realloc could have taken place */
- entry_long=array_get(&(s->directory),long_index);
- while(entry_long<entry && is_long_name(entry_long)) {
- entry_long->reserved[1]=chksum;
- entry_long++;
- }
- }
-
- return entry;
-}
-
-/*
- * Read a directory. (the index of the corresponding mapping must be passed).
- */
-static int read_directory(BDRVVVFATState* s, int mapping_index)
-{
- mapping_t* mapping = array_get(&(s->mapping), mapping_index);
- direntry_t* direntry;
- const char* dirname = mapping->path;
- int first_cluster = mapping->begin;
- int parent_index = mapping->info.dir.parent_mapping_index;
- mapping_t* parent_mapping = (mapping_t*)
- (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : 0);
- int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;
-
- DIR* dir=opendir(dirname);
- struct dirent* entry;
- int i;
-
- assert(mapping->mode & MODE_DIRECTORY);
-
- if(!dir) {
- mapping->end = mapping->begin;
- return -1;
- }
-
- i = mapping->info.dir.first_dir_index =
- first_cluster == 0 ? 0 : s->directory.next;
-
- /* actually read the directory, and allocate the mappings */
- while((entry=readdir(dir))) {
- unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
- char* buffer;
- direntry_t* direntry;
- struct stat st;
- int is_dot=!strcmp(entry->d_name,".");
- int is_dotdot=!strcmp(entry->d_name,"..");
-
- if(first_cluster == 0 && (is_dotdot || is_dot))
- continue;
-
- buffer=(char*)malloc(length);
- assert(buffer);
- snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
-
- if(stat(buffer,&st)<0) {
- free(buffer);
- continue;
- }
-
- /* create directory entry for this file */
- direntry=create_short_and_long_name(s, i, entry->d_name,
- is_dot || is_dotdot);
- direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
- direntry->reserved[0]=direntry->reserved[1]=0;
- direntry->ctime=fat_datetime(st.st_ctime,1);
- direntry->cdate=fat_datetime(st.st_ctime,0);
- direntry->adate=fat_datetime(st.st_atime,0);
- direntry->begin_hi=0;
- direntry->mtime=fat_datetime(st.st_mtime,1);
- direntry->mdate=fat_datetime(st.st_mtime,0);
- if(is_dotdot)
- set_begin_of_direntry(direntry, first_cluster_of_parent);
- else if(is_dot)
- set_begin_of_direntry(direntry, first_cluster);
- else
- direntry->begin=0; /* do that later */
- if (st.st_size > 0x7fffffff) {
- fprintf(stderr, "File %s is larger than 2GB\n", buffer);
- free(buffer);
- return -2;
- }
- direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
-
- /* create mapping for this file */
- if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
- s->current_mapping=(mapping_t*)array_get_next(&(s->mapping));
- s->current_mapping->begin=0;
- s->current_mapping->end=st.st_size;
- /*
- * we get the direntry of the most recent direntry, which
- * contains the short name and all the relevant information.
- */
- s->current_mapping->dir_index=s->directory.next-1;
- s->current_mapping->first_mapping_index = -1;
- if (S_ISDIR(st.st_mode)) {
- s->current_mapping->mode = MODE_DIRECTORY;
- s->current_mapping->info.dir.parent_mapping_index =
- mapping_index;
- } else {
- s->current_mapping->mode = MODE_UNDEFINED;
- s->current_mapping->info.file.offset = 0;
- }
- s->current_mapping->path=buffer;
- s->current_mapping->read_only =
- (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
- }
- }
- closedir(dir);
-
- /* fill with zeroes up to the end of the cluster */
- while(s->directory.next%(0x10*s->sectors_per_cluster)) {
- direntry_t* direntry=array_get_next(&(s->directory));
- memset(direntry,0,sizeof(direntry_t));
- }
-
-/* TODO: if there are more entries, bootsector has to be adjusted! */
-#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
- if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
- /* root directory */
- int cur = s->directory.next;
- array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
- memset(array_get(&(s->directory), cur), 0,
- (ROOT_ENTRIES - cur) * sizeof(direntry_t));
- }
-
- /* reget the mapping, since s->mapping was possibly realloc()ed */
- mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
- first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
- * 0x20 / s->cluster_size;
- mapping->end = first_cluster;
-
- direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
- set_begin_of_direntry(direntry, mapping->begin);
-
- return 0;
-}
-
-static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
-{
- return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
-}
-
-static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
-{
- return s->faked_sectors + s->sectors_per_cluster * cluster_num;
-}
-
-static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
-{
- return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
-}
-
-#ifdef DBG
-static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
-{
- if(mapping->mode==MODE_UNDEFINED)
- return 0;
- return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
-}
-#endif
-
-static int init_directories(BDRVVVFATState* s,
- const char* dirname)
-{
- bootsector_t* bootsector;
- mapping_t* mapping;
- unsigned int i;
- unsigned int cluster;
-
- memset(&(s->first_sectors[0]),0,0x40*0x200);
-
- s->cluster_size=s->sectors_per_cluster*0x200;
- s->cluster_buffer=malloc(s->cluster_size);
- assert(s->cluster_buffer);
-
- /*
- * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
- * where sc is sector_count,
- * spf is sectors_per_fat,
- * spc is sectors_per_clusters, and
- * fat_type = 12, 16 or 32.
- */
- i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
- s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
-
- array_init(&(s->mapping),sizeof(mapping_t));
- array_init(&(s->directory),sizeof(direntry_t));
-
- /* add volume label */
- {
- direntry_t* entry=array_get_next(&(s->directory));
- entry->attributes=0x28; /* archive | volume label */
- snprintf((char*)entry->name,11,"QEMU VVFAT");
- }
-
- /* Now build FAT, and write back information into directory */
- init_fat(s);
-
- s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
- s->cluster_count=sector2cluster(s, s->sector_count);
-
- mapping = array_get_next(&(s->mapping));
- mapping->begin = 0;
- mapping->dir_index = 0;
- mapping->info.dir.parent_mapping_index = -1;
- mapping->first_mapping_index = -1;
- mapping->path = strdup(dirname);
- i = strlen(mapping->path);
- if (i > 0 && mapping->path[i - 1] == '/')
- mapping->path[i - 1] = '\0';
- mapping->mode = MODE_DIRECTORY;
- mapping->read_only = 0;
- s->path = mapping->path;
-
- for (i = 0, cluster = 0; i < s->mapping.next; i++) {
- int j;
- /* MS-DOS expects the FAT to be 0 for the root directory
- * (except for the media byte). */
- /* LATER TODO: still true for FAT32? */
- int fix_fat = (i != 0);
- mapping = array_get(&(s->mapping), i);
-
- if (mapping->mode & MODE_DIRECTORY) {
- mapping->begin = cluster;
- if(read_directory(s, i)) {
- fprintf(stderr, "Could not read directory %s\n",
- mapping->path);
- return -1;
- }
- mapping = array_get(&(s->mapping), i);
- } else {
- assert(mapping->mode == MODE_UNDEFINED);
- mapping->mode=MODE_NORMAL;
- mapping->begin = cluster;
- if (mapping->end > 0) {
- direntry_t* direntry = array_get(&(s->directory),
- mapping->dir_index);
-
- mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
- set_begin_of_direntry(direntry, mapping->begin);
- } else {
- mapping->end = cluster + 1;
- fix_fat = 0;
- }
- }
-
- assert(mapping->begin < mapping->end);
-
- /* fix fat for entry */
- if (fix_fat) {
- for(j = mapping->begin; j < mapping->end - 1; j++)
- fat_set(s, j, j+1);
- fat_set(s, mapping->end - 1, s->max_fat_value);
- }
-
- /* next free cluster */
- cluster = mapping->end;
-
- if(cluster > s->cluster_count) {
- fprintf(stderr,"Directory does not fit in FAT%d\n",s->fat_type);
- return -1;
- }
- }
-
- mapping = array_get(&(s->mapping), 0);
- s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
- s->last_cluster_of_root_directory = mapping->end;
-
- /* the FAT signature */
- fat_set(s,0,s->max_fat_value);
- fat_set(s,1,s->max_fat_value);
-
- s->current_mapping = NULL;
-
- bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
- bootsector->jump[0]=0xeb;
- bootsector->jump[1]=0x3e;
- bootsector->jump[2]=0x90;
- memcpy(bootsector->name,"QEMU ",8);
- bootsector->sector_size=cpu_to_le16(0x200);
- bootsector->sectors_per_cluster=s->sectors_per_cluster;
- bootsector->reserved_sectors=cpu_to_le16(1);
- bootsector->number_of_fats=0x2; /* number of FATs */
- bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
- bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
- bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */
- s->fat.pointer[0] = bootsector->media_type;
- bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
- bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
- bootsector->number_of_heads=cpu_to_le16(s->bs->heads);
- bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
- bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
-
- /* LATER TODO: if FAT32, this is wrong */
- bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */
- bootsector->u.fat16.current_head=0;
- bootsector->u.fat16.signature=0x29;
- bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
-
- memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);
- memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12 ":s->fat_type==16?"FAT16 ":"FAT32 "),8);
- bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
-
- return 0;
-}
-
-#ifdef DEBUG
-static BDRVVVFATState *vvv = NULL;
-#endif
-
-static int enable_write_target(BDRVVVFATState *s);
-static int is_consistent(BDRVVVFATState *s);
-
-static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
-{
- BDRVVVFATState *s = bs->opaque;
- int floppy = 0;
- int i;
-
-#ifdef DEBUG
- vvv = s;
-#endif
-
-DLOG(if (stderr == NULL) {
- stderr = fopen("vvfat.log", "a");
- setbuf(stderr, NULL);
-})
-
- s->bs = bs;
-
- s->fat_type=16;
- /* LATER TODO: if FAT32, adjust */
- s->sectors_per_cluster=0x10;
- /* 504MB disk*/
- bs->cyls=1024; bs->heads=16; bs->secs=63;
-
- s->current_cluster=0xffffffff;
-
- s->first_sectors_number=0x40;
- /* read only is the default for safety */
- bs->read_only = 1;
- s->qcow = s->write_target = NULL;
- s->qcow_filename = NULL;
- s->fat2 = NULL;
- s->downcase_short_names = 1;
-
- if (!strstart(dirname, "fat:", NULL))
- return -1;
-
- if (strstr(dirname, ":floppy:")) {
- floppy = 1;
- s->fat_type = 12;
- s->first_sectors_number = 1;
- s->sectors_per_cluster=2;
- bs->cyls = 80; bs->heads = 2; bs->secs = 36;
- }
-
- s->sector_count=bs->cyls*bs->heads*bs->secs;
-
- if (strstr(dirname, ":32:")) {
- fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
- s->fat_type = 32;
- } else if (strstr(dirname, ":16:")) {
- s->fat_type = 16;
- } else if (strstr(dirname, ":12:")) {
- s->fat_type = 12;
- s->sector_count=2880;
- }
-
- if (strstr(dirname, ":rw:")) {
- if (enable_write_target(s))
- return -1;
- bs->read_only = 0;
- }
-
- i = strrchr(dirname, ':') - dirname;
- assert(i >= 3);
- if (dirname[i-2] == ':' && isalpha(dirname[i-1]))
- /* workaround for DOS drive names */
- dirname += i-1;
- else
- dirname += i+1;
-
- bs->total_sectors=bs->cyls*bs->heads*bs->secs;
-
- if(init_directories(s, dirname))
- return -1;
-
- s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
-
- if(s->first_sectors_number==0x40)
- init_mbr(s);
-
- /* for some reason or other, MS-DOS does not like to know about CHS... */
- if (floppy)
- bs->heads = bs->cyls = bs->secs = 0;
-
- // assert(is_consistent(s));
- return 0;
-}
-
-static inline void vvfat_close_current_file(BDRVVVFATState *s)
-{
- if(s->current_mapping) {
- s->current_mapping = NULL;
- if (s->current_fd) {
- close(s->current_fd);
- s->current_fd = 0;
- }
- }
- s->current_cluster = -1;
-}
-
-/* mappings between index1 and index2-1 are supposed to be ordered
- * return value is the index of the last mapping for which end>cluster_num
- */
-static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
-{
- int index3=index1+1;
- while(1) {
- mapping_t* mapping;
- index3=(index1+index2)/2;
- mapping=array_get(&(s->mapping),index3);
- assert(mapping->begin < mapping->end);
- if(mapping->begin>=cluster_num) {
- assert(index2!=index3 || index2==0);
- if(index2==index3)
- return index1;
- index2=index3;
- } else {
- if(index1==index3)
- return mapping->end<=cluster_num ? index2 : index1;
- index1=index3;
- }
- assert(index1<=index2);
- DLOG(mapping=array_get(&(s->mapping),index1);
- assert(mapping->begin<=cluster_num);
- assert(index2 >= s->mapping.next ||
- ((mapping = array_get(&(s->mapping),index2)) &&
- mapping->end>cluster_num)));
- }
-}
-
-static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
-{
- int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
- mapping_t* mapping;
- if(index>=s->mapping.next)
- return 0;
- mapping=array_get(&(s->mapping),index);
- if(mapping->begin>cluster_num)
- return 0;
- assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
- return mapping;
-}
-
-/*
- * This function simply compares path == mapping->path. Since the mappings
- * are sorted by cluster, this is expensive: O(n).
- */
-static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
- const char* path)
-{
- int i;
-
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->first_mapping_index < 0 &&
- !strcmp(path, mapping->path))
- return mapping;
- }
-
- return NULL;
-}
-
-static int open_file(BDRVVVFATState* s,mapping_t* mapping)
-{
- if(!mapping)
- return -1;
- if(!s->current_mapping ||
- strcmp(s->current_mapping->path,mapping->path)) {
- /* open file */
- int fd = open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
- if(fd<0)
- return -1;
- vvfat_close_current_file(s);
- s->current_fd = fd;
- s->current_mapping = mapping;
- }
- return 0;
-}
-
-static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
-{
- if(s->current_cluster != cluster_num) {
- int result=0;
- off_t offset;
- assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
- if(!s->current_mapping
- || s->current_mapping->begin>cluster_num
- || s->current_mapping->end<=cluster_num) {
- /* binary search of mappings for file */
- mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
-
- assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
-
- if (mapping && mapping->mode & MODE_DIRECTORY) {
- vvfat_close_current_file(s);
- s->current_mapping = mapping;
-read_cluster_directory:
- offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
- s->cluster = (unsigned char*)s->directory.pointer+offset
- + 0x20*s->current_mapping->info.dir.first_dir_index;
- assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
- assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
- s->current_cluster = cluster_num;
- return 0;
- }
-
- if(open_file(s,mapping))
- return -2;
- } else if (s->current_mapping->mode & MODE_DIRECTORY)
- goto read_cluster_directory;
-
- assert(s->current_fd);
-
- offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
- if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
- return -3;
- s->cluster=s->cluster_buffer;
- result=read(s->current_fd,s->cluster,s->cluster_size);
- if(result<0) {
- s->current_cluster = -1;
- return -1;
- }
- s->current_cluster = cluster_num;
- }
- return 0;
-}
-
-#ifdef DEBUG
-static void hexdump(const void* address, uint32_t len)
-{
- const unsigned char* p = address;
- int i, j;
-
- for (i = 0; i < len; i += 16) {
- for (j = 0; j < 16 && i + j < len; j++)
- fprintf(stderr, "%02x ", p[i + j]);
- for (; j < 16; j++)
- fprintf(stderr, " ");
- fprintf(stderr, " ");
- for (j = 0; j < 16 && i + j < len; j++)
- fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
- fprintf(stderr, "\n");
- }
-}
-
-static void print_direntry(const direntry_t* direntry)
-{
- int j = 0;
- char buffer[1024];
-
- fprintf(stderr, "direntry 0x%x: ", (int)direntry);
- if(!direntry)
- return;
- if(is_long_name(direntry)) {
- unsigned char* c=(unsigned char*)direntry;
- int i;
- for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
-#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = '°'; j++;}
- ADD_CHAR(c[i]);
- for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
- ADD_CHAR(c[i]);
- for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
- ADD_CHAR(c[i]);
- buffer[j] = 0;
- fprintf(stderr, "%s\n", buffer);
- } else {
- int i;
- for(i=0;i<11;i++)
- ADD_CHAR(direntry->name[i]);
- buffer[j] = 0;
- fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
- buffer,
- direntry->attributes,
- begin_of_direntry(direntry),le32_to_cpu(direntry->size));
- }
-}
-
-static void print_mapping(const mapping_t* mapping)
-{
- fprintf(stderr, "mapping (0x%x): begin, end = %d, %d, dir_index = %d, first_mapping_index = %d, name = %s, mode = 0x%x, " , (int)mapping, mapping->begin, mapping->end, mapping->dir_index, mapping->first_mapping_index, mapping->path, mapping->mode);
- if (mapping->mode & MODE_DIRECTORY)
- fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
- else
- fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
-}
-#endif
-
-static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVVFATState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++,sector_num++) {
- if (sector_num >= s->sector_count)
- return -1;
- if (s->qcow) {
- int n;
- if (s->qcow->drv->bdrv_is_allocated(s->qcow,
- sector_num, nb_sectors-i, &n)) {
-DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
- if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n))
- return -1;
- i += n - 1;
- sector_num += n - 1;
- continue;
- }
-DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
- }
- if(sector_num<s->faked_sectors) {
- if(sector_num<s->first_sectors_number)
- memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
- else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
- memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
- else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
- memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
- } else {
- uint32_t sector=sector_num-s->faked_sectors,
- sector_offset_in_cluster=(sector%s->sectors_per_cluster),
- cluster_num=sector/s->sectors_per_cluster;
- if(read_cluster(s, cluster_num) != 0) {
- /* LATER TODO: strict: return -1; */
- memset(buf+i*0x200,0,0x200);
- continue;
- }
- memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
- }
- }
- return 0;
-}
-
-/* LATER TODO: statify all functions */
-
-/*
- * Idea of the write support (use snapshot):
- *
- * 1. check if all data is consistent, recording renames, modifications,
- * new files and directories (in s->commits).
- *
- * 2. if the data is not consistent, stop committing
- *
- * 3. handle renames, and create new files and directories (do not yet
- * write their contents)
- *
- * 4. walk the directories, fixing the mapping and direntries, and marking
- * the handled mappings as not deleted
- *
- * 5. commit the contents of the files
- *
- * 6. handle deleted files and directories
- *
- */
-
-typedef struct commit_t {
- char* path;
- union {
- struct { uint32_t cluster; } rename;
- struct { int dir_index; uint32_t modified_offset; } writeout;
- struct { uint32_t first_cluster; } new_file;
- struct { uint32_t cluster; } mkdir;
- } param;
- /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
- enum {
- ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
- } action;
-} commit_t;
-
-static void clear_commits(BDRVVVFATState* s)
-{
- int i;
-DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
- for (i = 0; i < s->commits.next; i++) {
- commit_t* commit = array_get(&(s->commits), i);
- assert(commit->path || commit->action == ACTION_WRITEOUT);
- if (commit->action != ACTION_WRITEOUT) {
- assert(commit->path);
- free(commit->path);
- } else
- assert(commit->path == NULL);
- }
- s->commits.next = 0;
-}
-
-static void schedule_rename(BDRVVVFATState* s,
- uint32_t cluster, char* new_path)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = new_path;
- commit->param.rename.cluster = cluster;
- commit->action = ACTION_RENAME;
-}
-
-static void schedule_writeout(BDRVVVFATState* s,
- int dir_index, uint32_t modified_offset)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = NULL;
- commit->param.writeout.dir_index = dir_index;
- commit->param.writeout.modified_offset = modified_offset;
- commit->action = ACTION_WRITEOUT;
-}
-
-static void schedule_new_file(BDRVVVFATState* s,
- char* path, uint32_t first_cluster)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = path;
- commit->param.new_file.first_cluster = first_cluster;
- commit->action = ACTION_NEW_FILE;
-}
-
-static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
-{
- commit_t* commit = array_get_next(&(s->commits));
- commit->path = path;
- commit->param.mkdir.cluster = cluster;
- commit->action = ACTION_MKDIR;
-}
-
-typedef struct {
- /*
- * Since the sequence number is at most 0x3f, and the filename
- * length is at most 13 times the sequence number, the maximal
- * filename length is 0x3f * 13 bytes.
- */
- unsigned char name[0x3f * 13 + 1];
- int checksum, len;
- int sequence_number;
-} long_file_name;
-
-static void lfn_init(long_file_name* lfn)
-{
- lfn->sequence_number = lfn->len = 0;
- lfn->checksum = 0x100;
-}
-
-/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
-static int parse_long_name(long_file_name* lfn,
- const direntry_t* direntry)
-{
- int i, j, offset;
- const unsigned char* pointer = (const unsigned char*)direntry;
-
- if (!is_long_name(direntry))
- return 1;
-
- if (pointer[0] & 0x40) {
- lfn->sequence_number = pointer[0] & 0x3f;
- lfn->checksum = pointer[13];
- lfn->name[0] = 0;
- lfn->name[lfn->sequence_number * 13] = 0;
- } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
- return -1;
- else if (pointer[13] != lfn->checksum)
- return -2;
- else if (pointer[12] || pointer[26] || pointer[27])
- return -3;
-
- offset = 13 * (lfn->sequence_number - 1);
- for (i = 0, j = 1; i < 13; i++, j+=2) {
- if (j == 11)
- j = 14;
- else if (j == 26)
- j = 28;
-
- if (pointer[j+1] == 0)
- lfn->name[offset + i] = pointer[j];
- else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
- return -4;
- else
- lfn->name[offset + i] = 0;
- }
-
- if (pointer[0] & 0x40)
- lfn->len = offset + strlen((char*)lfn->name + offset);
-
- return 0;
-}
-
-/* returns 0 if successful, >0 if no short_name, and <0 on error */
-static int parse_short_name(BDRVVVFATState* s,
- long_file_name* lfn, direntry_t* direntry)
-{
- int i, j;
-
- if (!is_short_name(direntry))
- return 1;
-
- for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
- for (i = 0; i <= j; i++) {
- if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
- return -1;
- else if (s->downcase_short_names)
- lfn->name[i] = tolower(direntry->name[i]);
- else
- lfn->name[i] = direntry->name[i];
- }
-
- for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
- if (j >= 0) {
- lfn->name[i++] = '.';
- lfn->name[i + j + 1] = '\0';
- for (;j >= 0; j--) {
- if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
- return -2;
- else if (s->downcase_short_names)
- lfn->name[i + j] = tolower(direntry->extension[j]);
- else
- lfn->name[i + j] = direntry->extension[j];
- }
- } else
- lfn->name[i + j + 1] = '\0';
-
- lfn->len = strlen((char*)lfn->name);
-
- return 0;
-}
-
-static inline uint32_t modified_fat_get(BDRVVVFATState* s,
- unsigned int cluster)
-{
- if (cluster < s->last_cluster_of_root_directory) {
- if (cluster + 1 == s->last_cluster_of_root_directory)
- return s->max_fat_value;
- else
- return cluster + 1;
- }
-
- if (s->fat_type==32) {
- uint32_t* entry=((uint32_t*)s->fat2)+cluster;
- return le32_to_cpu(*entry);
- } else if (s->fat_type==16) {
- uint16_t* entry=((uint16_t*)s->fat2)+cluster;
- return le16_to_cpu(*entry);
- } else {
- const uint8_t* x=s->fat2+cluster*3/2;
- return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
- }
-}
-
-static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
-{
- int was_modified = 0;
- int i, dummy;
-
- if (s->qcow == NULL)
- return 0;
-
- for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
- was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow,
- cluster2sector(s, cluster_num) + i, 1, &dummy);
-
- return was_modified;
-}
-
-static const char* get_basename(const char* path)
-{
- char* basename = strrchr(path, '/');
- if (basename == NULL)
- return path;
- else
- return basename + 1; /* strip '/' */
-}
-
-/*
- * The array s->used_clusters holds the states of the clusters. If it is
- * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
- * was modified, bit 3 is set.
- * If any cluster is allocated, but not part of a file or directory, this
- * driver refuses to commit.
- */
-typedef enum {
- USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
-} used_t;
-
-/*
- * get_cluster_count_for_direntry() not only determines how many clusters
- * are occupied by direntry, but also if it was renamed or modified.
- *
- * A file is thought to be renamed *only* if there already was a file with
- * exactly the same first cluster, but a different name.
- *
- * Further, the files/directories handled by this function are
- * assumed to be *not* deleted (and *only* those).
- */
-static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
- direntry_t* direntry, const char* path)
-{
- /*
- * This is a little bit tricky:
- * IF the guest OS just inserts a cluster into the file chain,
- * and leaves the rest alone, (i.e. the original file had clusters
- * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
- *
- * - do_commit will write the cluster into the file at the given
- * offset, but
- *
- * - the cluster which is overwritten should be moved to a later
- * position in the file.
- *
- * I am not aware that any OS does something as braindead, but this
- * situation could happen anyway when not committing for a long time.
- * Just to be sure that this does not bite us, detect it, and copy the
- * contents of the clusters to-be-overwritten into the qcow.
- */
- int copy_it = 0;
- int was_modified = 0;
- int32_t ret = 0;
-
- uint32_t cluster_num = begin_of_direntry(direntry);
- uint32_t offset = 0;
- int first_mapping_index = -1;
- mapping_t* mapping = NULL;
- const char* basename2 = NULL;
-
- vvfat_close_current_file(s);
-
- /* the root directory */
- if (cluster_num == 0)
- return 0;
-
- /* write support */
- if (s->qcow) {
- basename2 = get_basename(path);
-
- mapping = find_mapping_for_cluster(s, cluster_num);
-
- if (mapping) {
- const char* basename;
-
- assert(mapping->mode & MODE_DELETED);
- mapping->mode &= ~MODE_DELETED;
-
- basename = get_basename(mapping->path);
-
- assert(mapping->mode & MODE_NORMAL);
-
- /* rename */
- if (strcmp(basename, basename2))
- schedule_rename(s, cluster_num, strdup(path));
- } else if (is_file(direntry))
- /* new file */
- schedule_new_file(s, strdup(path), cluster_num);
- else {
- assert(0);
- return 0;
- }
- }
-
- while(1) {
- if (s->qcow) {
- if (!copy_it && cluster_was_modified(s, cluster_num)) {
- if (mapping == NULL ||
- mapping->begin > cluster_num ||
- mapping->end <= cluster_num)
- mapping = find_mapping_for_cluster(s, cluster_num);
-
-
- if (mapping &&
- (mapping->mode & MODE_DIRECTORY) == 0) {
-
- /* was modified in qcow */
- if (offset != mapping->info.file.offset + s->cluster_size
- * (cluster_num - mapping->begin)) {
- /* offset of this cluster in file chain has changed */
- assert(0);
- copy_it = 1;
- } else if (offset == 0) {
- const char* basename = get_basename(mapping->path);
-
- if (strcmp(basename, basename2))
- copy_it = 1;
- first_mapping_index = array_index(&(s->mapping), mapping);
- }
-
- if (mapping->first_mapping_index != first_mapping_index
- && mapping->info.file.offset > 0) {
- assert(0);
- copy_it = 1;
- }
-
- /* need to write out? */
- if (!was_modified && is_file(direntry)) {
- was_modified = 1;
- schedule_writeout(s, mapping->dir_index, offset);
- }
- }
- }
-
- if (copy_it) {
- int i, dummy;
- /*
- * This is horribly inefficient, but that is okay, since
- * it is rarely executed, if at all.
- */
- int64_t offset = cluster2sector(s, cluster_num);
-
- vvfat_close_current_file(s);
- for (i = 0; i < s->sectors_per_cluster; i++)
- if (!s->qcow->drv->bdrv_is_allocated(s->qcow,
- offset + i, 1, &dummy)) {
- if (vvfat_read(s->bs,
- offset, s->cluster_buffer, 1))
- return -1;
- if (s->qcow->drv->bdrv_write(s->qcow,
- offset, s->cluster_buffer, 1))
- return -2;
- }
- }
- }
-
- ret++;
- if (s->used_clusters[cluster_num] & USED_ANY)
- return 0;
- s->used_clusters[cluster_num] = USED_FILE;
-
- cluster_num = modified_fat_get(s, cluster_num);
-
- if (fat_eof(s, cluster_num))
- return ret;
- else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
- return -1;
-
- offset += s->cluster_size;
- }
-}
-
-/*
- * This function looks at the modified data (qcow).
- * It returns 0 upon inconsistency or error, and the number of clusters
- * used by the directory, its subdirectories and their files.
- */
-static int check_directory_consistency(BDRVVVFATState *s,
- int cluster_num, const char* path)
-{
- int ret = 0;
- unsigned char* cluster = malloc(s->cluster_size);
- direntry_t* direntries = (direntry_t*)cluster;
- mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
-
- long_file_name lfn;
- int path_len = strlen(path);
- char path2[PATH_MAX];
-
- assert(path_len < PATH_MAX); /* len was tested before! */
- pstrcpy(path2, sizeof(path2), path);
- path2[path_len] = '/';
- path2[path_len + 1] = '\0';
-
- if (mapping) {
- const char* basename = get_basename(mapping->path);
- const char* basename2 = get_basename(path);
-
- assert(mapping->mode & MODE_DIRECTORY);
-
- assert(mapping->mode & MODE_DELETED);
- mapping->mode &= ~MODE_DELETED;
-
- if (strcmp(basename, basename2))
- schedule_rename(s, cluster_num, strdup(path));
- } else
- /* new directory */
- schedule_mkdir(s, cluster_num, strdup(path));
-
- lfn_init(&lfn);
- do {
- int i;
- int subret = 0;
-
- ret++;
-
- if (s->used_clusters[cluster_num] & USED_ANY) {
- fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
- return 0;
- }
- s->used_clusters[cluster_num] = USED_DIRECTORY;
-
-DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
- subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
- s->sectors_per_cluster);
- if (subret) {
- fprintf(stderr, "Error fetching direntries\n");
- fail:
- free(cluster);
- return 0;
- }
-
- for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
- int cluster_count;
-
-DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));
- if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
- is_free(direntries + i))
- continue;
-
- subret = parse_long_name(&lfn, direntries + i);
- if (subret < 0) {
- fprintf(stderr, "Error in long name\n");
- goto fail;
- }
- if (subret == 0 || is_free(direntries + i))
- continue;
-
- if (fat_chksum(direntries+i) != lfn.checksum) {
- subret = parse_short_name(s, &lfn, direntries + i);
- if (subret < 0) {
- fprintf(stderr, "Error in short name (%d)\n", subret);
- goto fail;
- }
- if (subret > 0 || !strcmp((char*)lfn.name, ".")
- || !strcmp((char*)lfn.name, ".."))
- continue;
- }
- lfn.checksum = 0x100; /* cannot use long name twice */
-
- if (path_len + 1 + lfn.len >= PATH_MAX) {
- fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
- goto fail;
- }
- pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
- (char*)lfn.name);
-
- if (is_directory(direntries + i)) {
- if (begin_of_direntry(direntries + i) == 0) {
- DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
- goto fail;
- }
- cluster_count = check_directory_consistency(s,
- begin_of_direntry(direntries + i), path2);
- if (cluster_count == 0) {
- DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
- goto fail;
- }
- } else if (is_file(direntries + i)) {
- /* check file size with FAT */
- cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
- if (cluster_count !=
- (le32_to_cpu(direntries[i].size) + s->cluster_size
- - 1) / s->cluster_size) {
- DLOG(fprintf(stderr, "Cluster count mismatch\n"));
- goto fail;
- }
- } else
- assert(0); /* cluster_count = 0; */
-
- ret += cluster_count;
- }
-
- cluster_num = modified_fat_get(s, cluster_num);
- } while(!fat_eof(s, cluster_num));
-
- free(cluster);
- return ret;
-}
-
-/* returns 1 on success */
-static int is_consistent(BDRVVVFATState* s)
-{
- int i, check;
- int used_clusters_count = 0;
-
-DLOG(checkpoint());
- /*
- * - get modified FAT
- * - compare the two FATs (TODO)
- * - get buffer for marking used clusters
- * - recurse direntries from root (using bs->bdrv_read to make
- * sure to get the new data)
- * - check that the FAT agrees with the size
- * - count the number of clusters occupied by this directory and
- * its files
- * - check that the cumulative used cluster count agrees with the
- * FAT
- * - if all is fine, return number of used clusters
- */
- if (s->fat2 == NULL) {
- int size = 0x200 * s->sectors_per_fat;
- s->fat2 = malloc(size);
- memcpy(s->fat2, s->fat.pointer, size);
- }
- check = vvfat_read(s->bs,
- s->first_sectors_number, s->fat2, s->sectors_per_fat);
- if (check) {
- fprintf(stderr, "Could not copy fat\n");
- return 0;
- }
- assert (s->used_clusters);
- for (i = 0; i < sector2cluster(s, s->sector_count); i++)
- s->used_clusters[i] &= ~USED_ANY;
-
- clear_commits(s);
-
- /* mark every mapped file/directory as deleted.
- * (check_directory_consistency() will unmark those still present). */
- if (s->qcow)
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->first_mapping_index < 0)
- mapping->mode |= MODE_DELETED;
- }
-
- used_clusters_count = check_directory_consistency(s, 0, s->path);
- if (used_clusters_count <= 0) {
- DLOG(fprintf(stderr, "problem in directory\n"));
- return 0;
- }
-
- check = s->last_cluster_of_root_directory;
- for (i = check; i < sector2cluster(s, s->sector_count); i++) {
- if (modified_fat_get(s, i)) {
- if(!s->used_clusters[i]) {
- DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
- return 0;
- }
- check++;
- }
-
- if (s->used_clusters[i] == USED_ALLOCATED) {
- /* allocated, but not used... */
- DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
- return 0;
- }
- }
-
- if (check != used_clusters_count)
- return 0;
-
- return used_clusters_count;
-}
-
-static inline void adjust_mapping_indices(BDRVVVFATState* s,
- int offset, int adjust)
-{
- int i;
-
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
-
-#define ADJUST_MAPPING_INDEX(name) \
- if (mapping->name >= offset) \
- mapping->name += adjust
-
- ADJUST_MAPPING_INDEX(first_mapping_index);
- if (mapping->mode & MODE_DIRECTORY)
- ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
- }
-}
-
-/* insert or update mapping */
-static mapping_t* insert_mapping(BDRVVVFATState* s,
- uint32_t begin, uint32_t end)
-{
- /*
- * - find mapping where mapping->begin >= begin,
- * - if mapping->begin > begin: insert
- * - adjust all references to mappings!
- * - else: adjust
- * - replace name
- */
- int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
- mapping_t* mapping = NULL;
- mapping_t* first_mapping = array_get(&(s->mapping), 0);
-
- if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
- && mapping->begin < begin) {
- mapping->end = begin;
- index++;
- mapping = array_get(&(s->mapping), index);
- }
- if (index >= s->mapping.next || mapping->begin > begin) {
- mapping = array_insert(&(s->mapping), index, 1);
- mapping->path = NULL;
- adjust_mapping_indices(s, index, +1);
- }
-
- mapping->begin = begin;
- mapping->end = end;
-
-DLOG(mapping_t* next_mapping;
-assert(index + 1 >= s->mapping.next ||
-((next_mapping = array_get(&(s->mapping), index + 1)) &&
- next_mapping->begin >= end)));
-
- if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
- s->current_mapping = array_get(&(s->mapping),
- s->current_mapping - first_mapping);
-
- return mapping;
-}
-
-static int remove_mapping(BDRVVVFATState* s, int mapping_index)
-{
- mapping_t* mapping = array_get(&(s->mapping), mapping_index);
- mapping_t* first_mapping = array_get(&(s->mapping), 0);
-
- /* free mapping */
- if (mapping->first_mapping_index < 0)
- free(mapping->path);
-
- /* remove from s->mapping */
- array_remove(&(s->mapping), mapping_index);
-
- /* adjust all references to mappings */
- adjust_mapping_indices(s, mapping_index, -1);
-
- if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
- s->current_mapping = array_get(&(s->mapping),
- s->current_mapping - first_mapping);
-
- return 0;
-}
-
-static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
-{
- int i;
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->dir_index >= offset)
- mapping->dir_index += adjust;
- if ((mapping->mode & MODE_DIRECTORY) &&
- mapping->info.dir.first_dir_index >= offset)
- mapping->info.dir.first_dir_index += adjust;
- }
-}
-
-static direntry_t* insert_direntries(BDRVVVFATState* s,
- int dir_index, int count)
-{
- /*
- * make room in s->directory,
- * adjust_dirindices
- */
- direntry_t* result = array_insert(&(s->directory), dir_index, count);
- if (result == NULL)
- return NULL;
- adjust_dirindices(s, dir_index, count);
- return result;
-}
-
-static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
-{
- int ret = array_remove_slice(&(s->directory), dir_index, count);
- if (ret)
- return ret;
- adjust_dirindices(s, dir_index, -count);
- return 0;
-}
-
-/*
- * Adapt the mappings of the cluster chain starting at first cluster
- * (i.e. if a file starts at first_cluster, the chain is followed according
- * to the modified fat, and the corresponding entries in s->mapping are
- * adjusted)
- */
-static int commit_mappings(BDRVVVFATState* s,
- uint32_t first_cluster, int dir_index)
-{
- mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
- direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t cluster = first_cluster;
-
- vvfat_close_current_file(s);
-
- assert(mapping);
- assert(mapping->begin == first_cluster);
- mapping->first_mapping_index = -1;
- mapping->dir_index = dir_index;
- mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
- MODE_DIRECTORY : MODE_NORMAL;
-
- while (!fat_eof(s, cluster)) {
- uint32_t c, c1;
-
- for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
- c = c1, c1 = modified_fat_get(s, c1));
-
- c++;
- if (c > mapping->end) {
- int index = array_index(&(s->mapping), mapping);
- int i, max_i = s->mapping.next - index;
- for (i = 1; i < max_i && mapping[i].begin < c; i++);
- while (--i > 0)
- remove_mapping(s, index + 1);
- }
- assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
- || mapping[1].begin >= c);
- mapping->end = c;
-
- if (!fat_eof(s, c1)) {
- int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
- mapping_t* next_mapping = i >= s->mapping.next ? NULL :
- array_get(&(s->mapping), i);
-
- if (next_mapping == NULL || next_mapping->begin > c1) {
- int i1 = array_index(&(s->mapping), mapping);
-
- next_mapping = insert_mapping(s, c1, c1+1);
-
- if (c1 < c)
- i1++;
- mapping = array_get(&(s->mapping), i1);
- }
-
- next_mapping->dir_index = mapping->dir_index;
- next_mapping->first_mapping_index =
- mapping->first_mapping_index < 0 ?
- array_index(&(s->mapping), mapping) :
- mapping->first_mapping_index;
- next_mapping->path = mapping->path;
- next_mapping->mode = mapping->mode;
- next_mapping->read_only = mapping->read_only;
- if (mapping->mode & MODE_DIRECTORY) {
- next_mapping->info.dir.parent_mapping_index =
- mapping->info.dir.parent_mapping_index;
- next_mapping->info.dir.first_dir_index =
- mapping->info.dir.first_dir_index +
- 0x10 * s->sectors_per_cluster *
- (mapping->end - mapping->begin);
- } else
- next_mapping->info.file.offset = mapping->info.file.offset +
- mapping->end - mapping->begin;
-
- mapping = next_mapping;
- }
-
- cluster = c1;
- }
-
- return 0;
-}
-
-static int commit_direntries(BDRVVVFATState* s,
- int dir_index, int parent_mapping_index)
-{
- direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
- mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
-
- int factor = 0x10 * s->sectors_per_cluster;
- int old_cluster_count, new_cluster_count;
- int current_dir_index = mapping->info.dir.first_dir_index;
- int first_dir_index = current_dir_index;
- int ret, i;
- uint32_t c;
-
-DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
-
- assert(direntry);
- assert(mapping);
- assert(mapping->begin == first_cluster);
- assert(mapping->info.dir.first_dir_index < s->directory.next);
- assert(mapping->mode & MODE_DIRECTORY);
- assert(dir_index == 0 || is_directory(direntry));
-
- mapping->info.dir.parent_mapping_index = parent_mapping_index;
-
- if (first_cluster == 0) {
- old_cluster_count = new_cluster_count =
- s->last_cluster_of_root_directory;
- } else {
- for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
- c = fat_get(s, c))
- old_cluster_count++;
-
- for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
- c = modified_fat_get(s, c))
- new_cluster_count++;
- }
-
- if (new_cluster_count > old_cluster_count) {
- if (insert_direntries(s,
- current_dir_index + factor * old_cluster_count,
- factor * (new_cluster_count - old_cluster_count)) == NULL)
- return -1;
- } else if (new_cluster_count < old_cluster_count)
- remove_direntries(s,
- current_dir_index + factor * new_cluster_count,
- factor * (old_cluster_count - new_cluster_count));
-
- for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
- void* direntry = array_get(&(s->directory), current_dir_index);
- int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
- s->sectors_per_cluster);
- if (ret)
- return ret;
- assert(!strncmp(s->directory.pointer, "QEMU", 4));
- current_dir_index += factor;
- }
-
- ret = commit_mappings(s, first_cluster, dir_index);
- if (ret)
- return ret;
-
- /* recurse */
- for (i = 0; i < factor * new_cluster_count; i++) {
- direntry = array_get(&(s->directory), first_dir_index + i);
- if (is_directory(direntry) && !is_dot(direntry)) {
- mapping = find_mapping_for_cluster(s, first_cluster);
- assert(mapping->mode & MODE_DIRECTORY);
- ret = commit_direntries(s, first_dir_index + i,
- array_index(&(s->mapping), mapping));
- if (ret)
- return ret;
- }
- }
-
- return 0;
-}
-
-/* commit one file (adjust contents, adjust mapping),
- return first_mapping_index */
-static int commit_one_file(BDRVVVFATState* s,
- int dir_index, uint32_t offset)
-{
- direntry_t* direntry = array_get(&(s->directory), dir_index);
- uint32_t c = begin_of_direntry(direntry);
- uint32_t first_cluster = c;
- mapping_t* mapping = find_mapping_for_cluster(s, c);
- uint32_t size = filesize_of_direntry(direntry);
- char* cluster = malloc(s->cluster_size);
- uint32_t i;
- int fd = 0;
-
- assert(offset < size);
- assert((offset % s->cluster_size) == 0);
-
- for (i = s->cluster_size; i < offset; i += s->cluster_size)
- c = modified_fat_get(s, c);
-
- fd = open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
- if (fd < 0) {
- fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
- strerror(errno), errno);
- return fd;
- }
- if (offset > 0)
- if (lseek(fd, offset, SEEK_SET) != offset)
- return -3;
-
- while (offset < size) {
- uint32_t c1;
- int rest_size = (size - offset > s->cluster_size ?
- s->cluster_size : size - offset);
- int ret;
-
- c1 = modified_fat_get(s, c);
-
- assert((size - offset == 0 && fat_eof(s, c)) ||
- (size > offset && c >=2 && !fat_eof(s, c)));
-
- ret = vvfat_read(s->bs, cluster2sector(s, c),
- (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
-
- if (ret < 0)
- return ret;
-
- if (write(fd, cluster, rest_size) < 0)
- return -2;
-
- offset += rest_size;
- c = c1;
- }
-
- ftruncate(fd, size);
- close(fd);
-
- return commit_mappings(s, first_cluster, dir_index);
-}
-
-#ifdef DEBUG
-/* test, if all mappings point to valid direntries */
-static void check1(BDRVVVFATState* s)
-{
- int i;
- for (i = 0; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->mode & MODE_DELETED) {
- fprintf(stderr, "deleted\n");
- continue;
- }
- assert(mapping->dir_index >= 0);
- assert(mapping->dir_index < s->directory.next);
- direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
- assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
- if (mapping->mode & MODE_DIRECTORY) {
- assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
- assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
- }
- }
-}
-
-/* test, if all direntries have mappings */
-static void check2(BDRVVVFATState* s)
-{
- int i;
- int first_mapping = -1;
-
- for (i = 0; i < s->directory.next; i++) {
- direntry_t* direntry = array_get(&(s->directory), i);
-
- if (is_short_name(direntry) && begin_of_direntry(direntry)) {
- mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
- assert(mapping);
- assert(mapping->dir_index == i || is_dot(direntry));
- assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
- }
-
- if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
- /* cluster start */
- int j, count = 0;
-
- for (j = 0; j < s->mapping.next; j++) {
- mapping_t* mapping = array_get(&(s->mapping), j);
- if (mapping->mode & MODE_DELETED)
- continue;
- if (mapping->mode & MODE_DIRECTORY) {
- if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
- assert(++count == 1);
- if (mapping->first_mapping_index == -1)
- first_mapping = array_index(&(s->mapping), mapping);
- else
- assert(first_mapping == mapping->first_mapping_index);
- if (mapping->info.dir.parent_mapping_index < 0)
- assert(j == 0);
- else {
- mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
- assert(parent->mode & MODE_DIRECTORY);
- assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
- }
- }
- }
- }
- if (count == 0)
- first_mapping = -1;
- }
- }
-}
-#endif
-
-static int handle_renames_and_mkdirs(BDRVVVFATState* s)
-{
- int i;
-
-#ifdef DEBUG
- fprintf(stderr, "handle_renames\n");
- for (i = 0; i < s->commits.next; i++) {
- commit_t* commit = array_get(&(s->commits), i);
- fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
- }
-#endif
-
- for (i = 0; i < s->commits.next;) {
- commit_t* commit = array_get(&(s->commits), i);
- if (commit->action == ACTION_RENAME) {
- mapping_t* mapping = find_mapping_for_cluster(s,
- commit->param.rename.cluster);
- char* old_path = mapping->path;
-
- assert(commit->path);
- mapping->path = commit->path;
- if (rename(old_path, mapping->path))
- return -2;
-
- if (mapping->mode & MODE_DIRECTORY) {
- int l1 = strlen(mapping->path);
- int l2 = strlen(old_path);
- int diff = l1 - l2;
- direntry_t* direntry = array_get(&(s->directory),
- mapping->info.dir.first_dir_index);
- uint32_t c = mapping->begin;
- int i = 0;
-
- /* recurse */
- while (!fat_eof(s, c)) {
- do {
- direntry_t* d = direntry + i;
-
- if (is_file(d) || (is_directory(d) && !is_dot(d))) {
- mapping_t* m = find_mapping_for_cluster(s,
- begin_of_direntry(d));
- int l = strlen(m->path);
- char* new_path = malloc(l + diff + 1);
-
- assert(!strncmp(m->path, mapping->path, l2));
-
- pstrcpy(new_path, l + diff + 1, mapping->path);
- pstrcpy(new_path + l1, l + diff + 1 - l1,
- m->path + l2);
-
- schedule_rename(s, m->begin, new_path);
- }
- i++;
- } while((i % (0x10 * s->sectors_per_cluster)) != 0);
- c = fat_get(s, c);
- }
- }
-
- free(old_path);
- array_remove(&(s->commits), i);
- continue;
- } else if (commit->action == ACTION_MKDIR) {
- mapping_t* mapping;
- int j, parent_path_len;
-
-#ifdef __MINGW32__
- if (mkdir(commit->path))
- return -5;
-#else
- if (mkdir(commit->path, 0755))
- return -5;
-#endif
-
- mapping = insert_mapping(s, commit->param.mkdir.cluster,
- commit->param.mkdir.cluster + 1);
- if (mapping == NULL)
- return -6;
-
- mapping->mode = MODE_DIRECTORY;
- mapping->read_only = 0;
- mapping->path = commit->path;
- j = s->directory.next;
- assert(j);
- insert_direntries(s, s->directory.next,
- 0x10 * s->sectors_per_cluster);
- mapping->info.dir.first_dir_index = j;
-
- parent_path_len = strlen(commit->path)
- - strlen(get_basename(commit->path)) - 1;
- for (j = 0; j < s->mapping.next; j++) {
- mapping_t* m = array_get(&(s->mapping), j);
- if (m->first_mapping_index < 0 && m != mapping &&
- !strncmp(m->path, mapping->path, parent_path_len) &&
- strlen(m->path) == parent_path_len)
- break;
- }
- assert(j < s->mapping.next);
- mapping->info.dir.parent_mapping_index = j;
-
- array_remove(&(s->commits), i);
- continue;
- }
-
- i++;
- }
- return 0;
-}
-
-/*
- * TODO: make sure that the short name is not matching *another* file
- */
-static int handle_commits(BDRVVVFATState* s)
-{
- int i, fail = 0;
-
- vvfat_close_current_file(s);
-
- for (i = 0; !fail && i < s->commits.next; i++) {
- commit_t* commit = array_get(&(s->commits), i);
- switch(commit->action) {
- case ACTION_RENAME: case ACTION_MKDIR:
- assert(0);
- fail = -2;
- break;
- case ACTION_WRITEOUT: {
- direntry_t* entry = array_get(&(s->directory),
- commit->param.writeout.dir_index);
- uint32_t begin = begin_of_direntry(entry);
- mapping_t* mapping = find_mapping_for_cluster(s, begin);
-
- assert(mapping);
- assert(mapping->begin == begin);
- assert(commit->path == NULL);
-
- if (commit_one_file(s, commit->param.writeout.dir_index,
- commit->param.writeout.modified_offset))
- fail = -3;
-
- break;
- }
- case ACTION_NEW_FILE: {
- int begin = commit->param.new_file.first_cluster;
- mapping_t* mapping = find_mapping_for_cluster(s, begin);
- direntry_t* entry;
- int i;
-
- /* find direntry */
- for (i = 0; i < s->directory.next; i++) {
- entry = array_get(&(s->directory), i);
- if (is_file(entry) && begin_of_direntry(entry) == begin)
- break;
- }
-
- if (i >= s->directory.next) {
- fail = -6;
- continue;
- }
-
- /* make sure there exists an initial mapping */
- if (mapping && mapping->begin != begin) {
- mapping->end = begin;
- mapping = NULL;
- }
- if (mapping == NULL) {
- mapping = insert_mapping(s, begin, begin+1);
- }
- /* most members will be fixed in commit_mappings() */
- assert(commit->path);
- mapping->path = commit->path;
- mapping->read_only = 0;
- mapping->mode = MODE_NORMAL;
- mapping->info.file.offset = 0;
-
- if (commit_one_file(s, i, 0))
- fail = -7;
-
- break;
- }
- default:
- assert(0);
- }
- }
- if (i > 0 && array_remove_slice(&(s->commits), 0, i))
- return -1;
- return fail;
-}
-
-static int handle_deletes(BDRVVVFATState* s)
-{
- int i, deferred = 1, deleted = 1;
-
- /* delete files corresponding to mappings marked as deleted */
- /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
- while (deferred && deleted) {
- deferred = 0;
- deleted = 0;
-
- for (i = 1; i < s->mapping.next; i++) {
- mapping_t* mapping = array_get(&(s->mapping), i);
- if (mapping->mode & MODE_DELETED) {
- direntry_t* entry = array_get(&(s->directory),
- mapping->dir_index);
-
- if (is_free(entry)) {
- /* remove file/directory */
- if (mapping->mode & MODE_DIRECTORY) {
- int j, next_dir_index = s->directory.next,
- first_dir_index = mapping->info.dir.first_dir_index;
-
- if (rmdir(mapping->path) < 0) {
- if (errno == ENOTEMPTY) {
- deferred++;
- continue;
- } else
- return -5;
- }
-
- for (j = 1; j < s->mapping.next; j++) {
- mapping_t* m = array_get(&(s->mapping), j);
- if (m->mode & MODE_DIRECTORY &&
- m->info.dir.first_dir_index >
- first_dir_index &&
- m->info.dir.first_dir_index <
- next_dir_index)
- next_dir_index =
- m->info.dir.first_dir_index;
- }
- remove_direntries(s, first_dir_index,
- next_dir_index - first_dir_index);
-
- deleted++;
- }
- } else {
- if (unlink(mapping->path))
- return -4;
- deleted++;
- }
- DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
- remove_mapping(s, i);
- }
- }
- }
-
- return 0;
-}
-
-/*
- * synchronize mapping with new state:
- *
- * - copy FAT (with bdrv_read)
- * - mark all filenames corresponding to mappings as deleted
- * - recurse direntries from root (using bs->bdrv_read)
- * - delete files corresponding to mappings marked as deleted
- */
-static int do_commit(BDRVVVFATState* s)
-{
- int ret = 0;
-
- /* the real meat are the commits. Nothing to do? Move along! */
- if (s->commits.next == 0)
- return 0;
-
- vvfat_close_current_file(s);
-
- ret = handle_renames_and_mkdirs(s);
- if (ret) {
- fprintf(stderr, "Error handling renames (%d)\n", ret);
- assert(0);
- return ret;
- }
-
- /* copy FAT (with bdrv_read) */
- memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);
-
- /* recurse direntries from root (using bs->bdrv_read) */
- ret = commit_direntries(s, 0, -1);
- if (ret) {
- fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
- assert(0);
- return ret;
- }
-
- ret = handle_commits(s);
- if (ret) {
- fprintf(stderr, "Error handling commits (%d)\n", ret);
- assert(0);
- return ret;
- }
-
- ret = handle_deletes(s);
- if (ret) {
- fprintf(stderr, "Error deleting\n");
- assert(0);
- return ret;
- }
-
- s->qcow->drv->bdrv_make_empty(s->qcow);
-
- memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
-
-DLOG(checkpoint());
- return 0;
-}
-
-static int try_commit(BDRVVVFATState* s)
-{
- vvfat_close_current_file(s);
-DLOG(checkpoint());
- if(!is_consistent(s))
- return -1;
- return do_commit(s);
-}
-
-static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVVVFATState *s = bs->opaque;
- int i, ret;
-
-DLOG(checkpoint());
-
- vvfat_close_current_file(s);
-
- /*
- * Some sanity checks:
- * - do not allow writing to the boot sector
- * - do not allow to write non-ASCII filenames
- */
-
- if (sector_num < s->first_sectors_number)
- return -1;
-
- for (i = sector2cluster(s, sector_num);
- i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
- mapping_t* mapping = find_mapping_for_cluster(s, i);
- if (mapping) {
- if (mapping->read_only) {
- fprintf(stderr, "Tried to write to write-protected file %s\n",
- mapping->path);
- return -1;
- }
-
- if (mapping->mode & MODE_DIRECTORY) {
- int begin = cluster2sector(s, i);
- int end = begin + s->sectors_per_cluster, k;
- int dir_index;
- const direntry_t* direntries;
- long_file_name lfn;
-
- lfn_init(&lfn);
-
- if (begin < sector_num)
- begin = sector_num;
- if (end > sector_num + nb_sectors)
- end = sector_num + nb_sectors;
- dir_index = mapping->dir_index +
- 0x10 * (begin - mapping->begin * s->sectors_per_cluster);
- direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
-
- for (k = 0; k < (end - begin) * 0x10; k++) {
- /* do not allow non-ASCII filenames */
- if (parse_long_name(&lfn, direntries + k) < 0) {
- fprintf(stderr, "Warning: non-ASCII filename\n");
- return -1;
- }
- /* no access to the direntry of a read-only file */
- else if (is_short_name(direntries+k) &&
- (direntries[k].attributes & 1)) {
- if (memcmp(direntries + k,
- array_get(&(s->directory), dir_index + k),
- sizeof(direntry_t))) {
- fprintf(stderr, "Warning: tried to write to write-protected file\n");
- return -1;
- }
- }
- }
- }
- i = mapping->end;
- } else
- i++;
- }
-
- /*
- * Use qcow backend. Commit later.
- */
-DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
- ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors);
- if (ret < 0) {
- fprintf(stderr, "Error writing to qcow backend\n");
- return ret;
- }
-
- for (i = sector2cluster(s, sector_num);
- i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
- if (i >= 0)
- s->used_clusters[i] |= USED_ALLOCATED;
-
-DLOG(checkpoint());
- /* TODO: add timeout */
- try_commit(s);
-
-DLOG(checkpoint());
- return 0;
-}
-
-static int vvfat_is_allocated(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, int* n)
-{
- BDRVVVFATState* s = bs->opaque;
- *n = s->sector_count - sector_num;
- if (*n > nb_sectors)
- *n = nb_sectors;
- else if (*n < 0)
- return 0;
- return 1;
-}
-
-static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
- const uint8_t* buffer, int nb_sectors) {
- BDRVVVFATState* s = bs->opaque;
- return try_commit(s);
-}
-
-static void write_target_close(BlockDriverState *bs) {
- BDRVVVFATState* s = bs->opaque;
- bdrv_delete(s->qcow);
- free(s->qcow_filename);
-}
-
-static BlockDriver vvfat_write_target = {
- "vvfat_write_target", 0, NULL, NULL, NULL,
- write_target_commit,
- write_target_close,
- NULL, NULL, NULL
-};
-
-static int enable_write_target(BDRVVVFATState *s)
-{
- int size = sector2cluster(s, s->sector_count);
- s->used_clusters = calloc(size, 1);
-
- array_init(&(s->commits), sizeof(commit_t));
-
- s->qcow_filename = malloc(1024);
- get_tmp_filename(s->qcow_filename, 1024);
- if (bdrv_create(&bdrv_qcow,
- s->qcow_filename, s->sector_count, "fat:", 0) < 0)
- return -1;
- s->qcow = bdrv_new("");
- if (s->qcow == NULL || bdrv_open(s->qcow, s->qcow_filename, 0) < 0)
- return -1;
-
-#ifndef _WIN32
- unlink(s->qcow_filename);
-#endif
-
- s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
- s->bs->backing_hd->drv = &vvfat_write_target;
- s->bs->backing_hd->opaque = s;
-
- return 0;
-}
-
-static void vvfat_close(BlockDriverState *bs)
-{
- BDRVVVFATState *s = bs->opaque;
-
- vvfat_close_current_file(s);
- array_free(&(s->fat));
- array_free(&(s->directory));
- array_free(&(s->mapping));
- if(s->cluster_buffer)
- free(s->cluster_buffer);
-}
-
-BlockDriver bdrv_vvfat = {
- "vvfat",
- sizeof(BDRVVVFATState),
- NULL, /* no probe for protocols */
- vvfat_open,
- vvfat_read,
- vvfat_write,
- vvfat_close,
- NULL, /* ??? Not sure if we can do any meaningful flushing. */
- NULL,
- vvfat_is_allocated,
- .protocol_name = "fat",
-};
-
-#ifdef DEBUG
-static void checkpoint(void) {
- assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
- check1(vvv);
- check2(vvv);
- assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
-#if 0
- if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
- fprintf(stderr, "Nonono!\n");
- mapping_t* mapping;
- direntry_t* direntry;
- assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
- assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
- if (vvv->mapping.next<47)
- return;
- assert((mapping = array_get(&(vvv->mapping), 47)));
- assert(mapping->dir_index < vvv->directory.next);
- direntry = array_get(&(vvv->directory), mapping->dir_index);
- assert(!memcmp(direntry->name, "USB H ", 11) || direntry->name[0]==0);
-#endif
- return;
- /* avoid compiler warnings: */
- hexdump(NULL, 100);
- remove_mapping(vvv, NULL);
- print_mapping(NULL);
- print_direntry(NULL);
-}
-#endif
-
diff --git a/block.c b/block.c
deleted file mode 100644
index 23ce5e4..0000000
--- a/block.c
+++ /dev/null
@@ -1,1433 +0,0 @@
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "console.h"
-#include "block_int.h"
-
-#ifdef _BSD
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <sys/disk.h>
-#endif
-
-#define SECTOR_BITS 9
-#define SECTOR_SIZE (1 << SECTOR_BITS)
-
-typedef struct BlockDriverAIOCBSync {
- BlockDriverAIOCB common;
- QEMUBH *bh;
- int ret;
-} BlockDriverAIOCBSync;
-
-static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-
-static BlockDriver *first_drv;
-
-int path_is_absolute(const char *path)
-{
- const char *p;
-#ifdef _WIN32
- /* specific case for names like: "\\.\d:" */
- if (*path == '/' || *path == '\\')
- return 1;
-#endif
- p = strchr(path, ':');
- if (p)
- p++;
- else
- p = path;
-#ifdef _WIN32
- return (*p == '/' || *p == '\\');
-#else
- return (*p == '/');
-#endif
-}
-
-/* if filename is absolute, just copy it to dest. Otherwise, build a
- path to it by considering it is relative to base_path. URL are
- supported. */
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename)
-{
- const char *p, *p1;
- int len;
-
- if (dest_size <= 0)
- return;
- if (path_is_absolute(filename)) {
- pstrcpy(dest, dest_size, filename);
- } else {
- p = strchr(base_path, ':');
- if (p)
- p++;
- else
- p = base_path;
- p1 = strrchr(base_path, '/');
-#ifdef _WIN32
- {
- const char *p2;
- p2 = strrchr(base_path, '\\');
- if (!p1 || p2 > p1)
- p1 = p2;
- }
-#endif
- if (p1)
- p1++;
- else
- p1 = base_path;
- if (p1 > p)
- p = p1;
- len = p - base_path;
- if (len > dest_size - 1)
- len = dest_size - 1;
- memcpy(dest, base_path, len);
- dest[len] = '\0';
- pstrcat(dest, dest_size, filename);
- }
-}
-
-
-static void bdrv_register(BlockDriver *bdrv)
-{
- if (!bdrv->bdrv_aio_read) {
- /* add AIO emulation layer */
- bdrv->bdrv_aio_read = bdrv_aio_read_em;
- bdrv->bdrv_aio_write = bdrv_aio_write_em;
- bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
- bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
- } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
- /* add synchronous IO emulation layer */
- bdrv->bdrv_read = bdrv_read_em;
- bdrv->bdrv_write = bdrv_write_em;
- }
- bdrv->next = first_drv;
- first_drv = bdrv;
-}
-
-/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name)
-{
- BlockDriverState **pbs, *bs;
-
- bs = qemu_mallocz(sizeof(BlockDriverState));
- if(!bs)
- return NULL;
- pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
- if (device_name[0] != '\0') {
- /* insert at the end */
- pbs = &bdrv_first;
- while (*pbs != NULL)
- pbs = &(*pbs)->next;
- *pbs = bs;
- }
- return bs;
-}
-
-BlockDriver *bdrv_find_format(const char *format_name)
-{
- BlockDriver *drv1;
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (!strcmp(drv1->format_name, format_name))
- return drv1;
- }
- return NULL;
-}
-
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags)
-{
- if (!drv->bdrv_create)
- return -ENOTSUP;
- return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
-}
-
-#ifdef _WIN32
-void get_tmp_filename(char *filename, int size)
-{
- char temp_dir[MAX_PATH];
-
- GetTempPath(MAX_PATH, temp_dir);
- GetTempFileName(temp_dir, "qem", 0, filename);
-}
-#else
-void get_tmp_filename(char *filename, int size)
-{
- int fd;
- const char *tmpdir;
- /* XXX: race condition possible */
- tmpdir = getenv("TMPDIR");
- if (!tmpdir)
- tmpdir = "/tmp";
- snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
- fd = mkstemp(filename);
- close(fd);
-}
-#endif
-
-#ifdef _WIN32
-static int is_windows_drive_prefix(const char *filename)
-{
- return (((filename[0] >= 'a' && filename[0] <= 'z') ||
- (filename[0] >= 'A' && filename[0] <= 'Z')) &&
- filename[1] == ':');
-}
-
-static int is_windows_drive(const char *filename)
-{
- if (is_windows_drive_prefix(filename) &&
- filename[2] == '\0')
- return 1;
- if (strstart(filename, "\\\\.\\", NULL) ||
- strstart(filename, "//./", NULL))
- return 1;
- return 0;
-}
-#endif
-
-static BlockDriver *find_protocol(const char *filename)
-{
- BlockDriver *drv1;
- char protocol[128];
- int len;
- const char *p;
-
-#ifdef _WIN32
- if (is_windows_drive(filename) ||
- is_windows_drive_prefix(filename))
- return &bdrv_raw;
-#endif
- p = strchr(filename, ':');
- if (!p)
- return &bdrv_raw;
- len = p - filename;
- if (len > sizeof(protocol) - 1)
- len = sizeof(protocol) - 1;
- memcpy(protocol, filename, len);
- protocol[len] = '\0';
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (drv1->protocol_name &&
- !strcmp(drv1->protocol_name, protocol))
- return drv1;
- }
- return NULL;
-}
-
-/* XXX: force raw format if block or character device ? It would
- simplify the BSD case */
-static BlockDriver *find_image_format(const char *filename)
-{
- int ret, score, score_max;
- BlockDriver *drv1, *drv;
- uint8_t buf[2048];
- BlockDriverState *bs;
-
- /* detect host devices. By convention, /dev/cdrom[N] is always
- recognized as a host CDROM */
- if (strstart(filename, "/dev/cdrom", NULL))
- return &bdrv_host_device;
-#ifdef _WIN32
- if (is_windows_drive(filename))
- return &bdrv_host_device;
-#else
- {
- struct stat st;
- if (stat(filename, &st) >= 0 &&
- (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
- return &bdrv_host_device;
- }
- }
-#endif
-
- drv = find_protocol(filename);
- /* no need to test disk image formats for vvfat */
- if (drv == &bdrv_vvfat)
- return drv;
-
- ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
- if (ret < 0)
- return NULL;
- ret = bdrv_pread(bs, 0, buf, sizeof(buf));
- bdrv_delete(bs);
- if (ret < 0) {
- return NULL;
- }
-
- score_max = 0;
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (drv1->bdrv_probe) {
- score = drv1->bdrv_probe(buf, ret, filename);
- if (score > score_max) {
- score_max = score;
- drv = drv1;
- }
- }
- }
- return drv;
-}
-
-int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
-{
- BlockDriverState *bs;
- int ret;
-
- bs = bdrv_new("");
- if (!bs)
- return -ENOMEM;
- ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
- if (ret < 0) {
- bdrv_delete(bs);
- return ret;
- }
- *pbs = bs;
- return 0;
-}
-
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
-{
- return bdrv_open2(bs, filename, flags, NULL);
-}
-
-int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
- BlockDriver *drv)
-{
- int ret, open_flags;
- char tmp_filename[PATH_MAX];
- char backing_filename[PATH_MAX];
-
- bs->read_only = 0;
- bs->is_temporary = 0;
- bs->encrypted = 0;
-
- if (flags & BDRV_O_SNAPSHOT) {
- BlockDriverState *bs1;
- int64_t total_size;
- int is_protocol = 0;
-
- /* if snapshot, we create a temporary backing file and open it
- instead of opening 'filename' directly */
-
- /* if there is a backing file, use it */
- bs1 = bdrv_new("");
- if (!bs1) {
- return -ENOMEM;
- }
- if (bdrv_open(bs1, filename, 0) < 0) {
- bdrv_delete(bs1);
- return -1;
- }
- total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
-
- if (bs1->drv && bs1->drv->protocol_name)
- is_protocol = 1;
-
- bdrv_delete(bs1);
-
- get_tmp_filename(tmp_filename, sizeof(tmp_filename));
-
- /* Real path is meaningless for protocols */
- if (is_protocol)
- snprintf(backing_filename, sizeof(backing_filename),
- "%s", filename);
- else
- realpath(filename, backing_filename);
-
- if (bdrv_create(&bdrv_qcow2, tmp_filename,
- total_size, backing_filename, 0) < 0) {
- return -1;
- }
- filename = tmp_filename;
- bs->is_temporary = 1;
- }
-
- pstrcpy(bs->filename, sizeof(bs->filename), filename);
- if (flags & BDRV_O_FILE) {
- drv = find_protocol(filename);
- if (!drv)
- return -ENOENT;
- } else {
- if (!drv) {
- drv = find_image_format(filename);
- if (!drv)
- return -1;
- }
- }
- bs->drv = drv;
- bs->opaque = qemu_mallocz(drv->instance_size);
- if (bs->opaque == NULL && drv->instance_size > 0)
- return -1;
- /* Note: for compatibility, we open disk image files as RDWR, and
- RDONLY as fallback */
- if (!(flags & BDRV_O_FILE))
- open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
- else
- open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
- ret = drv->bdrv_open(bs, filename, open_flags);
- if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
- ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
- bs->read_only = 1;
- }
- if (ret < 0) {
- qemu_free(bs->opaque);
- bs->opaque = NULL;
- bs->drv = NULL;
- return ret;
- }
- if (drv->bdrv_getlength) {
- bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
- }
-#ifndef _WIN32
- if (bs->is_temporary) {
- unlink(filename);
- }
-#endif
- if (bs->backing_file[0] != '\0') {
- /* if there is a backing file, use it */
- bs->backing_hd = bdrv_new("");
- if (!bs->backing_hd) {
- fail:
- bdrv_close(bs);
- return -ENOMEM;
- }
- path_combine(backing_filename, sizeof(backing_filename),
- filename, bs->backing_file);
- if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
- goto fail;
- }
-
- /* call the change callback */
- bs->media_changed = 1;
- if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
-
- return 0;
-}
-
-void bdrv_close(BlockDriverState *bs)
-{
- if (bs->drv) {
- if (bs->backing_hd)
- bdrv_delete(bs->backing_hd);
- bs->drv->bdrv_close(bs);
- qemu_free(bs->opaque);
-#ifdef _WIN32
- if (bs->is_temporary) {
- unlink(bs->filename);
- }
-#endif
- bs->opaque = NULL;
- bs->drv = NULL;
-
- /* call the change callback */
- bs->media_changed = 1;
- if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
- }
-}
-
-void bdrv_delete(BlockDriverState *bs)
-{
- BlockDriverState **pbs;
-
- pbs = &bdrv_first;
- while (*pbs != bs && *pbs != NULL)
- pbs = &(*pbs)->next;
- if (*pbs == bs)
- *pbs = bs->next;
-
- bdrv_close(bs);
- qemu_free(bs);
-}
-
-/* commit COW file into the raw image */
-int bdrv_commit(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int64_t i, total_sectors;
- int n, j;
- unsigned char sector[512];
-
- if (!drv)
- return -ENOMEDIUM;
-
- if (bs->read_only) {
- return -EACCES;
- }
-
- if (!bs->backing_hd) {
- return -ENOTSUP;
- }
-
- total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
- for (i = 0; i < total_sectors;) {
- if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
- for(j = 0; j < n; j++) {
- if (bdrv_read(bs, i, sector, 1) != 0) {
- return -EIO;
- }
-
- if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
- return -EIO;
- }
- i++;
- }
- } else {
- i += n;
- }
- }
-
- if (drv->bdrv_make_empty)
- return drv->bdrv_make_empty(bs);
-
- return 0;
-}
-
-/* return < 0 if error. See bdrv_write() for the return codes */
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return -ENOMEDIUM;
-
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(buf, bs->boot_sector_data, 512);
- sector_num++;
- nb_sectors--;
- buf += 512;
- if (nb_sectors == 0)
- return 0;
- }
- if (drv->bdrv_pread) {
- int ret, len;
- len = nb_sectors * 512;
- ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EINVAL;
- else {
- bs->rd_bytes += (unsigned) len;
- bs->rd_ops ++;
- return 0;
- }
- } else {
- return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
- }
-}
-
-/* Return < 0 if error. Important errors are:
- -EIO generic I/O error (may happen for all errors)
- -ENOMEDIUM No media inserted.
- -EINVAL Invalid sector number or nb_sectors
- -EACCES Trying to write a read-only device
-*/
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
- if (!bs->drv)
- return -ENOMEDIUM;
- if (bs->read_only)
- return -EACCES;
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
- }
- if (drv->bdrv_pwrite) {
- int ret, len;
- len = nb_sectors * 512;
- ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- else {
- bs->wr_bytes += (unsigned) len;
- bs->wr_ops ++;
- return 0;
- }
- } else {
- return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
- }
-}
-
-static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count1)
-{
- uint8_t tmp_buf[SECTOR_SIZE];
- int len, nb_sectors, count;
- int64_t sector_num;
-
- count = count1;
- /* first read to align to sector start */
- len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
- if (len > count)
- len = count;
- sector_num = offset >> SECTOR_BITS;
- if (len > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
- count -= len;
- if (count == 0)
- return count1;
- sector_num++;
- buf += len;
- }
-
- /* read the sectors "in place" */
- nb_sectors = count >> SECTOR_BITS;
- if (nb_sectors > 0) {
- if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
- return -EIO;
- sector_num += nb_sectors;
- len = nb_sectors << SECTOR_BITS;
- buf += len;
- count -= len;
- }
-
- /* add data from the last sector */
- if (count > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(buf, tmp_buf, count);
- }
- return count1;
-}
-
-static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count1)
-{
- uint8_t tmp_buf[SECTOR_SIZE];
- int len, nb_sectors, count;
- int64_t sector_num;
-
- count = count1;
- /* first write to align to sector start */
- len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
- if (len > count)
- len = count;
- sector_num = offset >> SECTOR_BITS;
- if (len > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
- if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- count -= len;
- if (count == 0)
- return count1;
- sector_num++;
- buf += len;
- }
-
- /* write the sectors "in place" */
- nb_sectors = count >> SECTOR_BITS;
- if (nb_sectors > 0) {
- if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
- return -EIO;
- sector_num += nb_sectors;
- len = nb_sectors << SECTOR_BITS;
- buf += len;
- count -= len;
- }
-
- /* add data from the last sector */
- if (count > 0) {
- if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- memcpy(tmp_buf, buf, count);
- if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
- return -EIO;
- }
- return count1;
-}
-
-/**
- * Read with byte offsets (needed only for file protocols)
- */
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf1, int count1)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_pread)
- return bdrv_pread_em(bs, offset, buf1, count1);
- return drv->bdrv_pread(bs, offset, buf1, count1);
-}
-
-/**
- * Write with byte offsets (needed only for file protocols)
- */
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf1, int count1)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_pwrite)
- return bdrv_pwrite_em(bs, offset, buf1, count1);
- return drv->bdrv_pwrite(bs, offset, buf1, count1);
-}
-
-/**
- * Truncate file to 'offset' bytes (needed only for file protocols)
- */
-int bdrv_truncate(BlockDriverState *bs, int64_t offset)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_truncate)
- return -ENOTSUP;
- return drv->bdrv_truncate(bs, offset);
-}
-
-/**
- * Length of a file in bytes. Return < 0 if error or unknown.
- */
-int64_t bdrv_getlength(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_getlength) {
- /* legacy mode */
- return bs->total_sectors * SECTOR_SIZE;
- }
- return drv->bdrv_getlength(bs);
-}
-
-/* return 0 as number of sectors if no device present or error */
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
-{
- int64_t length;
- length = bdrv_getlength(bs);
- if (length < 0)
- length = 0;
- else
- length = length >> SECTOR_BITS;
- *nb_sectors_ptr = length;
-}
-
-/* force a given boot sector. */
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
-{
- bs->boot_sector_enabled = 1;
- if (size > 512)
- size = 512;
- memcpy(bs->boot_sector_data, data, size);
- memset(bs->boot_sector_data + size, 0, 512 - size);
-}
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs)
-{
- bs->cyls = cyls;
- bs->heads = heads;
- bs->secs = secs;
-}
-
-void bdrv_set_type_hint(BlockDriverState *bs, int type)
-{
- bs->type = type;
- bs->removable = ((type == BDRV_TYPE_CDROM ||
- type == BDRV_TYPE_FLOPPY));
-}
-
-void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
-{
- bs->translation = translation;
-}
-
-void bdrv_get_geometry_hint(BlockDriverState *bs,
- int *pcyls, int *pheads, int *psecs)
-{
- *pcyls = bs->cyls;
- *pheads = bs->heads;
- *psecs = bs->secs;
-}
-
-int bdrv_get_type_hint(BlockDriverState *bs)
-{
- return bs->type;
-}
-
-int bdrv_get_translation_hint(BlockDriverState *bs)
-{
- return bs->translation;
-}
-
-int bdrv_is_removable(BlockDriverState *bs)
-{
- return bs->removable;
-}
-
-int bdrv_is_read_only(BlockDriverState *bs)
-{
- return bs->read_only;
-}
-
-int bdrv_is_sg(BlockDriverState *bs)
-{
- return bs->sg;
-}
-
-/* XXX: no longer used */
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque)
-{
- bs->change_cb = change_cb;
- bs->change_opaque = opaque;
-}
-
-int bdrv_is_encrypted(BlockDriverState *bs)
-{
- if (bs->backing_hd && bs->backing_hd->encrypted)
- return 1;
- return bs->encrypted;
-}
-
-int bdrv_set_key(BlockDriverState *bs, const char *key)
-{
- int ret;
- if (bs->backing_hd && bs->backing_hd->encrypted) {
- ret = bdrv_set_key(bs->backing_hd, key);
- if (ret < 0)
- return ret;
- if (!bs->encrypted)
- return 0;
- }
- if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
- return -1;
- return bs->drv->bdrv_set_key(bs, key);
-}
-
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
-{
- if (!bs->drv) {
- buf[0] = '\0';
- } else {
- pstrcpy(buf, buf_size, bs->drv->format_name);
- }
-}
-
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque)
-{
- BlockDriver *drv;
-
- for (drv = first_drv; drv != NULL; drv = drv->next) {
- it(opaque, drv->format_name);
- }
-}
-
-BlockDriverState *bdrv_find(const char *name)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- if (!strcmp(name, bs->device_name))
- return bs;
- }
- return NULL;
-}
-
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- it(opaque, bs->device_name);
- }
-}
-
-const char *bdrv_get_device_name(BlockDriverState *bs)
-{
- return bs->device_name;
-}
-
-void bdrv_flush(BlockDriverState *bs)
-{
- if (bs->drv->bdrv_flush)
- bs->drv->bdrv_flush(bs);
- if (bs->backing_hd)
- bdrv_flush(bs->backing_hd);
-}
-
-/*
- * Returns true iff the specified sector is present in the disk image. Drivers
- * not implementing the functionality are assumed to not support backing files,
- * hence all their sectors are reported as allocated.
- *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
- * allocated/unallocated state.
- *
- * 'nb_sectors' is the max value 'pnum' should be set to.
- */
-int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
- int *pnum)
-{
- int64_t n;
- if (!bs->drv->bdrv_is_allocated) {
- if (sector_num >= bs->total_sectors) {
- *pnum = 0;
- return 0;
- }
- n = bs->total_sectors - sector_num;
- *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
- return 1;
- }
- return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
-}
-
-void bdrv_info(void)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- term_printf("%s:", bs->device_name);
- term_printf(" type=");
- switch(bs->type) {
- case BDRV_TYPE_HD:
- term_printf("hd");
- break;
- case BDRV_TYPE_CDROM:
- term_printf("cdrom");
- break;
- case BDRV_TYPE_FLOPPY:
- term_printf("floppy");
- break;
- }
- term_printf(" removable=%d", bs->removable);
- if (bs->removable) {
- term_printf(" locked=%d", bs->locked);
- }
- if (bs->drv) {
- term_printf(" file=");
- term_print_filename(bs->filename);
- if (bs->backing_file[0] != '\0') {
- term_printf(" backing_file=");
- term_print_filename(bs->backing_file);
- }
- term_printf(" ro=%d", bs->read_only);
- term_printf(" drv=%s", bs->drv->format_name);
- if (bs->encrypted)
- term_printf(" encrypted");
- } else {
- term_printf(" [not inserted]");
- }
- term_printf("\n");
- }
-}
-
-/* The "info blockstats" command. */
-void bdrv_info_stats (void)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- term_printf ("%s:"
- " rd_bytes=%" PRIu64
- " wr_bytes=%" PRIu64
- " rd_operations=%" PRIu64
- " wr_operations=%" PRIu64
- "\n",
- bs->device_name,
- bs->rd_bytes, bs->wr_bytes,
- bs->rd_ops, bs->wr_ops);
- }
-}
-
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size)
-{
- if (!bs->backing_hd) {
- pstrcpy(filename, filename_size, "");
- } else {
- pstrcpy(filename, filename_size, bs->backing_file);
- }
-}
-
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_write_compressed)
- return -ENOTSUP;
- return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
-}
-
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_get_info)
- return -ENOTSUP;
- memset(bdi, 0, sizeof(*bdi));
- return drv->bdrv_get_info(bs, bdi);
-}
-
-/**************************************************************/
-/* handling of snapshots */
-
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_create)
- return -ENOTSUP;
- return drv->bdrv_snapshot_create(bs, sn_info);
-}
-
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_goto)
- return -ENOTSUP;
- return drv->bdrv_snapshot_goto(bs, snapshot_id);
-}
-
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_delete)
- return -ENOTSUP;
- return drv->bdrv_snapshot_delete(bs, snapshot_id);
-}
-
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_snapshot_list)
- return -ENOTSUP;
- return drv->bdrv_snapshot_list(bs, psn_info);
-}
-
-#define NB_SUFFIXES 4
-
-char *get_human_readable_size(char *buf, int buf_size, int64_t size)
-{
- static const char suffixes[NB_SUFFIXES] = "KMGT";
- int64_t base;
- int i;
-
- if (size <= 999) {
- snprintf(buf, buf_size, "%" PRId64, size);
- } else {
- base = 1024;
- for(i = 0; i < NB_SUFFIXES; i++) {
- if (size < (10 * base)) {
- snprintf(buf, buf_size, "%0.1f%c",
- (double)size / base,
- suffixes[i]);
- break;
- } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
- snprintf(buf, buf_size, "%" PRId64 "%c",
- ((size + (base >> 1)) / base),
- suffixes[i]);
- break;
- }
- base = base * 1024;
- }
- }
- return buf;
-}
-
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
-{
- char buf1[128], date_buf[128], clock_buf[128];
-#ifdef _WIN32
- struct tm *ptm;
-#else
- struct tm tm;
-#endif
- time_t ti;
- int64_t secs;
-
- if (!sn) {
- snprintf(buf, buf_size,
- "%-10s%-20s%7s%20s%15s",
- "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
- } else {
- ti = sn->date_sec;
-#ifdef _WIN32
- ptm = localtime(&ti);
- strftime(date_buf, sizeof(date_buf),
- "%Y-%m-%d %H:%M:%S", ptm);
-#else
- localtime_r(&ti, &tm);
- strftime(date_buf, sizeof(date_buf),
- "%Y-%m-%d %H:%M:%S", &tm);
-#endif
- secs = sn->vm_clock_nsec / 1000000000;
- snprintf(clock_buf, sizeof(clock_buf),
- "%02d:%02d:%02d.%03d",
- (int)(secs / 3600),
- (int)((secs / 60) % 60),
- (int)(secs % 60),
- (int)((sn->vm_clock_nsec / 1000000) % 1000));
- snprintf(buf, buf_size,
- "%-10s%-20s%7s%20s%15s",
- sn->id_str, sn->name,
- get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
- date_buf,
- clock_buf);
- }
- return buf;
-}
-
-
-/**************************************************************/
-/* async I/Os */
-
-BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriver *drv = bs->drv;
- BlockDriverAIOCB *ret;
-
- if (!drv)
- return NULL;
-
- /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(buf, bs->boot_sector_data, 512);
- sector_num++;
- nb_sectors--;
- buf += 512;
- }
-
- ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
-
- if (ret) {
- /* Update stats even though technically transfer has not happened. */
- bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
- bs->rd_ops ++;
- }
-
- return ret;
-}
-
-BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriver *drv = bs->drv;
- BlockDriverAIOCB *ret;
-
- if (!drv)
- return NULL;
- if (bs->read_only)
- return NULL;
- if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
- memcpy(bs->boot_sector_data, buf, 512);
- }
-
- ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
-
- if (ret) {
- /* Update stats even though technically transfer has not happened. */
- bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
- bs->wr_ops ++;
- }
-
- return ret;
-}
-
-void bdrv_aio_cancel(BlockDriverAIOCB *acb)
-{
- BlockDriver *drv = acb->bs->drv;
-
- drv->bdrv_aio_cancel(acb);
-}
-
-
-/**************************************************************/
-/* async block device emulation */
-
-static void bdrv_aio_bh_cb(void *opaque)
-{
- BlockDriverAIOCBSync *acb = opaque;
- acb->common.cb(acb->common.opaque, acb->ret);
- qemu_aio_release(acb);
-}
-
-static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriverAIOCBSync *acb;
- int ret;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb->bh)
- acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
- ret = bdrv_read(bs, sector_num, buf, nb_sectors);
- acb->ret = ret;
- qemu_bh_schedule(acb->bh);
- return &acb->common;
-}
-
-static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriverAIOCBSync *acb;
- int ret;
-
- acb = qemu_aio_get(bs, cb, opaque);
- if (!acb->bh)
- acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
- ret = bdrv_write(bs, sector_num, buf, nb_sectors);
- acb->ret = ret;
- qemu_bh_schedule(acb->bh);
- return &acb->common;
-}
-
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
-{
- BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
- qemu_bh_cancel(acb->bh);
- qemu_aio_release(acb);
-}
-
-/**************************************************************/
-/* sync block device emulation */
-
-static void bdrv_rw_em_cb(void *opaque, int ret)
-{
- *(int *)opaque = ret;
-}
-
-#define NOT_DONE 0x7fffffff
-
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- int async_ret;
- BlockDriverAIOCB *acb;
-
- async_ret = NOT_DONE;
- acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
- bdrv_rw_em_cb, &async_ret);
- if (acb == NULL)
- return -1;
-
- while (async_ret == NOT_DONE) {
- qemu_aio_wait();
- }
-
- return async_ret;
-}
-
-static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- int async_ret;
- BlockDriverAIOCB *acb;
-
- async_ret = NOT_DONE;
- acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
- bdrv_rw_em_cb, &async_ret);
- if (acb == NULL)
- return -1;
- while (async_ret == NOT_DONE) {
- qemu_aio_wait();
- }
- return async_ret;
-}
-
-void bdrv_init(void)
-{
- bdrv_register(&bdrv_raw);
- bdrv_register(&bdrv_host_device);
-#ifndef _WIN32
- bdrv_register(&bdrv_cow);
-#endif
- bdrv_register(&bdrv_qcow);
-#if 0
- bdrv_register(&bdrv_vmdk);
-#endif
- bdrv_register(&bdrv_cloop);
- bdrv_register(&bdrv_dmg);
-#if 0
- bdrv_register(&bdrv_bochs);
- bdrv_register(&bdrv_vpc);
-#endif
- bdrv_register(&bdrv_vvfat);
-#if 0
- bdrv_register(&bdrv_qcow2);
- bdrv_register(&bdrv_parallels);
- bdrv_register(&bdrv_nbd);
-#endif
- qemu_aio_init();
-}
-
-void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- BlockDriver *drv;
- BlockDriverAIOCB *acb;
-
- drv = bs->drv;
- if (drv->free_aiocb) {
- acb = drv->free_aiocb;
- drv->free_aiocb = acb->next;
- } else {
- acb = qemu_mallocz(drv->aiocb_size);
- if (!acb)
- return NULL;
- }
- acb->bs = bs;
- acb->cb = cb;
- acb->opaque = opaque;
- return acb;
-}
-
-void qemu_aio_release(void *p)
-{
- BlockDriverAIOCB *acb = p;
- BlockDriver *drv = acb->bs->drv;
- acb->next = drv->free_aiocb;
- drv->free_aiocb = acb;
-}
-
-/**************************************************************/
-/* removable device support */
-
-/**
- * Return TRUE if the media is present
- */
-int bdrv_is_inserted(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int ret;
- if (!drv)
- return 0;
- if (!drv->bdrv_is_inserted)
- return 1;
- ret = drv->bdrv_is_inserted(bs);
- return ret;
-}
-
-/**
- * Return TRUE if the media changed since the last call to this
- * function. It is currently only used for floppy disks
- */
-int bdrv_media_changed(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int ret;
-
- if (!drv || !drv->bdrv_media_changed)
- ret = -ENOTSUP;
- else
- ret = drv->bdrv_media_changed(bs);
- if (ret == -ENOTSUP)
- ret = bs->media_changed;
- bs->media_changed = 0;
- return ret;
-}
-
-/**
- * If eject_flag is TRUE, eject the media. Otherwise, close the tray
- */
-void bdrv_eject(BlockDriverState *bs, int eject_flag)
-{
- BlockDriver *drv = bs->drv;
- int ret;
-
- if (!drv || !drv->bdrv_eject) {
- ret = -ENOTSUP;
- } else {
- ret = drv->bdrv_eject(bs, eject_flag);
- }
- if (ret == -ENOTSUP) {
- if (eject_flag)
- bdrv_close(bs);
- }
-}
-
-int bdrv_is_locked(BlockDriverState *bs)
-{
- return bs->locked;
-}
-
-/**
- * Lock or unlock the media (if it is locked, the user won't be able
- * to eject it manually).
- */
-void bdrv_set_locked(BlockDriverState *bs, int locked)
-{
- BlockDriver *drv = bs->drv;
-
- bs->locked = locked;
- if (drv && drv->bdrv_set_locked) {
- drv->bdrv_set_locked(bs, locked);
- }
-}
-
-/* needed for generic scsi interface */
-
-int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
- BlockDriver *drv = bs->drv;
-
- if (drv && drv->bdrv_ioctl)
- return drv->bdrv_ioctl(bs, req, buf);
- return -ENOTSUP;
-}
diff --git a/block.h b/block.h
deleted file mode 100644
index d774a2e..0000000
--- a/block.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef BLOCK_H
-#define BLOCK_H
-
-/* block.c */
-typedef struct BlockDriver BlockDriver;
-
-extern BlockDriver bdrv_raw;
-extern BlockDriver bdrv_host_device;
-extern BlockDriver bdrv_cow;
-extern BlockDriver bdrv_qcow;
-extern BlockDriver bdrv_vmdk;
-extern BlockDriver bdrv_cloop;
-extern BlockDriver bdrv_dmg;
-extern BlockDriver bdrv_bochs;
-extern BlockDriver bdrv_vpc;
-extern BlockDriver bdrv_vvfat;
-extern BlockDriver bdrv_qcow2;
-extern BlockDriver bdrv_parallels;
-extern BlockDriver bdrv_nbd;
-
-typedef struct BlockDriverInfo {
- /* in bytes, 0 if irrelevant */
- int cluster_size;
- /* offset at which the VM state can be saved (0 if not possible) */
- int64_t vm_state_offset;
-} BlockDriverInfo;
-
-typedef struct QEMUSnapshotInfo {
- char id_str[128]; /* unique snapshot id */
- /* the following fields are informative. They are not needed for
- the consistency of the snapshot */
- char name[256]; /* user choosen name */
- uint32_t vm_state_size; /* VM state info size */
- uint32_t date_sec; /* UTC date of the snapshot */
- uint32_t date_nsec;
- uint64_t vm_clock_nsec; /* VM clock relative to boot */
-} QEMUSnapshotInfo;
-
-#define BDRV_O_RDONLY 0x0000
-#define BDRV_O_RDWR 0x0002
-#define BDRV_O_ACCESS 0x0003
-#define BDRV_O_CREAT 0x0004 /* create an empty file */
-#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
-#define BDRV_O_FILE 0x0010 /* open as a raw file (do not try to
- use a disk image format on top of
- it (default for
- bdrv_file_open()) */
-#define BDRV_O_DIRECT 0x0020
-
-void bdrv_info(void);
-void bdrv_info_stats(void);
-
-void bdrv_init(void);
-BlockDriver *bdrv_find_format(const char *format_name);
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags);
-BlockDriverState *bdrv_new(const char *device_name);
-void bdrv_delete(BlockDriverState *bs);
-int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
-int bdrv_open(BlockDriverState *bs, const char *filename, int flags);
-int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
- BlockDriver *drv);
-void bdrv_close(BlockDriverState *bs);
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf, int count);
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf, int count);
-int bdrv_truncate(BlockDriverState *bs, int64_t offset);
-int64_t bdrv_getlength(BlockDriverState *bs);
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
-int bdrv_commit(BlockDriverState *bs);
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
-/* async block I/O */
-typedef struct BlockDriverAIOCB BlockDriverAIOCB;
-typedef void BlockDriverCompletionFunc(void *opaque, int ret);
-
-BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-void bdrv_aio_cancel(BlockDriverAIOCB *acb);
-
-void qemu_aio_init(void);
-void qemu_aio_flush(void);
-void qemu_aio_wait(void);
-
-int qemu_key_check(BlockDriverState *bs, const char *name);
-
-/* Ensure contents are flushed to disk. */
-void bdrv_flush(BlockDriverState *bs);
-int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
- int *pnum);
-
-#define BDRV_TYPE_HD 0
-#define BDRV_TYPE_CDROM 1
-#define BDRV_TYPE_FLOPPY 2
-#define BIOS_ATA_TRANSLATION_AUTO 0
-#define BIOS_ATA_TRANSLATION_NONE 1
-#define BIOS_ATA_TRANSLATION_LBA 2
-#define BIOS_ATA_TRANSLATION_LARGE 3
-#define BIOS_ATA_TRANSLATION_RECHS 4
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs);
-void bdrv_set_type_hint(BlockDriverState *bs, int type);
-void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
-void bdrv_get_geometry_hint(BlockDriverState *bs,
- int *pcyls, int *pheads, int *psecs);
-int bdrv_get_type_hint(BlockDriverState *bs);
-int bdrv_get_translation_hint(BlockDriverState *bs);
-int bdrv_is_removable(BlockDriverState *bs);
-int bdrv_is_read_only(BlockDriverState *bs);
-int bdrv_is_sg(BlockDriverState *bs);
-int bdrv_is_inserted(BlockDriverState *bs);
-int bdrv_media_changed(BlockDriverState *bs);
-int bdrv_is_locked(BlockDriverState *bs);
-void bdrv_set_locked(BlockDriverState *bs, int locked);
-void bdrv_eject(BlockDriverState *bs, int eject_flag);
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque);
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
-BlockDriverState *bdrv_find(const char *name);
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
-int bdrv_is_encrypted(BlockDriverState *bs);
-int bdrv_set_key(BlockDriverState *bs, const char *key);
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque);
-const char *bdrv_get_device_name(BlockDriverState *bs);
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
-
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size);
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id);
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
-char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
-int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
-
-char *get_human_readable_size(char *buf, int buf_size, int64_t size);
-int path_is_absolute(const char *path);
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename);
-
-#endif
diff --git a/block_int.h b/block_int.h
deleted file mode 100644
index 137000e..0000000
--- a/block_int.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef BLOCK_INT_H
-#define BLOCK_INT_H
-
-#include "block.h"
-
-#define BLOCK_FLAG_ENCRYPT 1
-#define BLOCK_FLAG_COMPRESS 2
-#define BLOCK_FLAG_COMPAT6 4
-
-struct BlockDriver {
- const char *format_name;
- int instance_size;
- int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
- int (*bdrv_open)(BlockDriverState *bs, const char *filename, int flags);
- int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
- int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
- void (*bdrv_close)(BlockDriverState *bs);
- int (*bdrv_create)(const char *filename, int64_t total_sectors,
- const char *backing_file, int flags);
- void (*bdrv_flush)(BlockDriverState *bs);
- int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum);
- int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
- int (*bdrv_make_empty)(BlockDriverState *bs);
- /* aio */
- BlockDriverAIOCB *(*bdrv_aio_read)(BlockDriverState *bs,
- int64_t sector_num, uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- BlockDriverAIOCB *(*bdrv_aio_write)(BlockDriverState *bs,
- int64_t sector_num, const uint8_t *buf, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- void (*bdrv_aio_cancel)(BlockDriverAIOCB *acb);
- int aiocb_size;
-
- const char *protocol_name;
- int (*bdrv_pread)(BlockDriverState *bs, int64_t offset,
- uint8_t *buf, int count);
- int (*bdrv_pwrite)(BlockDriverState *bs, int64_t offset,
- const uint8_t *buf, int count);
- int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
- int64_t (*bdrv_getlength)(BlockDriverState *bs);
- int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-
- int (*bdrv_snapshot_create)(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
- int (*bdrv_snapshot_goto)(BlockDriverState *bs,
- const char *snapshot_id);
- int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id);
- int (*bdrv_snapshot_list)(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
- int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
-
- /* removable device specific */
- int (*bdrv_is_inserted)(BlockDriverState *bs);
- int (*bdrv_media_changed)(BlockDriverState *bs);
- int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
- int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
-
- /* to control generic scsi devices */
- int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
-
- BlockDriverAIOCB *free_aiocb;
- struct BlockDriver *next;
-};
-
-struct BlockDriverState {
- int64_t total_sectors; /* if we are reading a disk image, give its
- size in sectors */
- int read_only; /* if true, the media is read only */
- int removable; /* if true, the media can be removed */
- int locked; /* if true, the media cannot temporarily be ejected */
- int encrypted; /* if true, the media is encrypted */
- int sg; /* if true, the device is a /dev/sg* */
- /* event callback when inserting/removing */
- void (*change_cb)(void *opaque);
- void *change_opaque;
-
- BlockDriver *drv; /* NULL means no media */
- void *opaque;
-
- int boot_sector_enabled;
- uint8_t boot_sector_data[512];
-
- char filename[1024];
- char backing_file[1024]; /* if non zero, the image is a diff of
- this file image */
- int is_temporary;
- int media_changed;
-
- BlockDriverState *backing_hd;
- /* async read/write emulation */
-
- void *sync_aiocb;
-
- /* I/O stats (display with "info blockstats"). */
- uint64_t rd_bytes;
- uint64_t wr_bytes;
- uint64_t rd_ops;
- uint64_t wr_ops;
-
- /* NOTE: the following infos are only hints for real hardware
- drivers. They are not used by the block driver */
- int cyls, heads, secs, translation;
- int type;
- char device_name[32];
- BlockDriverState *next;
-};
-
-struct BlockDriverAIOCB {
- BlockDriverState *bs;
- BlockDriverCompletionFunc *cb;
- void *opaque;
- BlockDriverAIOCB *next;
-};
-
-void get_tmp_filename(char *filename, int size);
-
-void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
- void *opaque);
-void qemu_aio_release(void *p);
-
-BlockDriverState *bdrv_first;
-
-#endif /* BLOCK_INT_H */
diff --git a/bswap.h b/bswap.h
deleted file mode 100644
index 523d805..0000000
--- a/bswap.h
+++ /dev/null
@@ -1,209 +0,0 @@
-#ifndef BSWAP_H
-#define BSWAP_H
-
-#include "config-host.h"
-
-#include <inttypes.h>
-
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-
-#define bswap_16(x) \
-({ \
- uint16_t __x = (x); \
- ((uint16_t)( \
- (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
- (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
-})
-
-#define bswap_32(x) \
-({ \
- uint32_t __x = (x); \
- ((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
-})
-
-#define bswap_64(x) \
-({ \
- uint64_t __x = (x); \
- ((uint64_t)( \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
-})
-
-#endif /* !HAVE_BYTESWAP_H */
-
-static inline uint16_t bswap16(uint16_t x)
-{
- return bswap_16(x);
-}
-
-static inline uint32_t bswap32(uint32_t x)
-{
- return bswap_32(x);
-}
-
-static inline uint64_t bswap64(uint64_t x)
-{
- return bswap_64(x);
-}
-
-static inline void bswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void bswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void bswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#if defined(WORDS_BIGENDIAN)
-#define be_bswap(v, size) (v)
-#define le_bswap(v, size) bswap ## size(v)
-#define be_bswaps(v, size)
-#define le_bswaps(p, size) *p = bswap ## size(*p);
-#else
-#define le_bswap(v, size) (v)
-#define be_bswap(v, size) bswap ## size(v)
-#define le_bswaps(v, size)
-#define be_bswaps(p, size) *p = bswap ## size(*p);
-#endif
-
-#define CPU_CONVERT(endian, size, type)\
-static inline type endian ## size ## _to_cpu(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-static inline type cpu_to_ ## endian ## size(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-static inline void endian ## size ## _to_cpus(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## s(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-static inline type endian ## size ## _to_cpup(const type *p)\
-{\
- return endian ## size ## _to_cpu(*p);\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
-{\
- *p = cpu_to_ ## endian ## size(v);\
-}
-
-CPU_CONVERT(be, 16, uint16_t)
-CPU_CONVERT(be, 32, uint32_t)
-CPU_CONVERT(be, 64, uint64_t)
-
-CPU_CONVERT(le, 16, uint16_t)
-CPU_CONVERT(le, 32, uint32_t)
-CPU_CONVERT(le, 64, uint64_t)
-
-/* unaligned versions (optimized for frequent unaligned accesses)*/
-
-#if defined(__i386__) || defined(__powerpc__)
-
-#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
-#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
-#define le16_to_cpupu(p) le16_to_cpup(p)
-#define le32_to_cpupu(p) le32_to_cpup(p)
-#define be32_to_cpupu(p) be32_to_cpup(p)
-
-#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
-#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
-
-#else
-
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v;
- p1[1] = v >> 8;
-}
-
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v;
- p1[1] = v >> 8;
- p1[2] = v >> 16;
- p1[3] = v >> 24;
-}
-
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[0] | (p1[1] << 8);
-}
-
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
-}
-
-static inline uint32_t be32_to_cpupu(const uint32_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[3] | (p1[2] << 8) | (p1[1] << 16) | (p1[0] << 24);
-}
-
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v >> 8;
- p1[1] = v;
-}
-
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v >> 24;
- p1[1] = v >> 16;
- p1[2] = v >> 8;
- p1[3] = v;
-}
-
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define cpu_to_32wu cpu_to_be32wu
-#else
-#define cpu_to_32wu cpu_to_le32wu
-#endif
-
-#undef le_bswap
-#undef be_bswap
-#undef le_bswaps
-#undef be_bswaps
-
-#endif /* BSWAP_H */
diff --git a/cbuffer.c b/cbuffer.c
deleted file mode 100644
index 0e99237..0000000
--- a/cbuffer.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "cbuffer.h"
-#include "android/utils/stralloc.h"
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-
-#define DEBUG 0
-
-#if DEBUG
-# define ASSERT(cond,fmt,...) ({ if (!(cond)) { fprintf(stderr, fmt, __VA_ARGS__); assert(cond); } })
-#else
-# define ASSERT(cond,fmt,...) ((void)0)
-#endif
-
-#if DEBUG
-void
-cbuffer_assert( CBuffer* cb, const char* file, long lineno )
-{
- const char* reason = NULL;
-
- if (cb->rpos < 0 || cb->rpos >= cb->size) {
- reason = "rpos is out of bounds";
- }
- else if (cb->count < 0 || cb->count > cb->size) {
- reason = "count is incorrect";
- }
- if (!reason)
- return;
-
- fprintf(stderr, "assert:%s:%ld: assertion failed: %s (pos=%d count=%d size=%d)\n",
- file, lineno, reason, cb->rpos, cb->count, cb->size);
- assert(0);
-}
-# define CBUFFER_ASSERT(cb) cbuffer_assert(cb,__FUNCTION__,__LINE__)
-#else
-# define CBUFFER_ASSERT(cb) ((void)0)
-#endif
-
-int
-cbuffer_write_peek( CBuffer* cb, uint8_t* *pbase )
-{
- int wpos = cb->rpos + cb->count;
- int avail = cb->size - cb->count;
-
- CBUFFER_ASSERT(cb);
-
- if (wpos >= cb->size)
- wpos -= cb->size;
-
- if (wpos + avail > cb->size)
- avail = cb->size - wpos;
-
- *pbase = cb->buff + wpos;
- return avail;
-}
-
-void
-cbuffer_write_step( CBuffer* cb, int len )
-{
- CBUFFER_ASSERT(cb);
-
- cb->count += len;
- if (cb->count > cb->size)
- cb->count = cb->size;
-}
-
-
-int
-cbuffer_write( CBuffer* cb, const void* from, int len )
-{
- int len2 = len;
-
- CBUFFER_ASSERT(cb);
-
- while (len2 > 0) {
- int avail = cb->size - cb->count;
- int wpos = cb->rpos + cb->count;
-
- ASSERT(avail >= 0, "avail is negative: %d", avail);
-
- if (avail == 0)
- break;
-
- if (wpos >= cb->size)
- wpos -= cb->size;
-
- ASSERT( wpos >= 0 && wpos < cb->size, "wpos is out-of-bounds: %d (rpos=%d)", wpos, cb->rpos);
-
- if (wpos + avail > cb->size)
- avail = cb->size - wpos;
-
- if (avail > len2)
- avail = len2;
-
- memcpy( cb->buff + wpos, (const char*)from, avail );
-
- from = (char*)from + avail;
- len2 -= avail;
- cb->count += avail;
- }
- return len - len2;
-}
-
-int
-cbuffer_read( CBuffer* cb, void* to, int len )
-{
- int len2 = len;
-
- CBUFFER_ASSERT(cb);
-
- while (len2 > 0) {
- int avail = cb->count;
- int rpos = cb->rpos;
-
- ASSERT(avail >= 0, "avail is negative: %d", avail);
-
- if (avail == 0)
- break;
-
- ASSERT((rpos >= 0 && rpos < cb->size), "rpos is out-of-bounds: %d", rpos);
-
- if (rpos+avail > cb->size)
- avail = cb->size - rpos;
-
- if (avail > len2)
- avail = len2;
-
- memcpy( (char*)to, (const char*)cb->buff + rpos, avail );
- to = (char*)to + avail;
- len2 -= avail;
- cb->count -= avail;
- cb->rpos += avail;
- if (cb->rpos >= cb->size)
- cb->rpos -= cb->size;
- }
- return len - len2;
-}
-
-int
-cbuffer_read_peek( CBuffer* cb, uint8_t* *pbase )
-{
- int rpos = cb->rpos;
- int avail = cb->count;
-
- CBUFFER_ASSERT(cb);
-
- if (rpos + avail > cb->size)
- avail = cb->size - rpos;
-
- *pbase = cb->buff + rpos;
- return avail;
-}
-
-
-void
-cbuffer_read_step( CBuffer* cb, int len )
-{
- CBUFFER_ASSERT(cb);
-
- if (len > cb->count)
- len = cb->count;
-
- cb->rpos += len;
- if (cb->rpos >= cb->size)
- cb->rpos -= cb->size;
-
- cb->count -= len;
-}
-
-const char*
-cbuffer_quote( CBuffer* cb )
-{
- STRALLOC_DEFINE(s);
- char* q;
-
- stralloc_format( s, "cbuffer %p (pos=%d count=%d size=%d)",
- cb, cb->rpos, cb->count, cb->size );
-
- q = stralloc_to_tempstr( s );
- stralloc_reset(s);
-
- return q;
-}
-
-const char*
-cbuffer_quote_data( CBuffer* cb )
-{
- STRALLOC_DEFINE(s);
- int len = cb->count;
- int rpos = cb->rpos;
- char* result;
-
- while (len > 0) {
- int avail = len;
-
- if (rpos >= cb->size)
- rpos -= cb->size;
-
- if (rpos + avail > cb->size)
- avail = cb->size - rpos;
-
- stralloc_add_quote_bytes( s, cb->buff + rpos, avail );
- rpos += avail;
- len -= avail;
- }
-
- result = stralloc_to_tempstr(s);
- stralloc_reset(s);
-
- return result;
-}
-
-void
-cbuffer_print( CBuffer* cb )
-{
- /* print the content of a cbuffer */
- printf( "%s: %s", cbuffer_quote(cb), cbuffer_quote_data(cb) );
-}
-
diff --git a/cbuffer.h b/cbuffer.h
deleted file mode 100644
index d25d765..0000000
--- a/cbuffer.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _qemu_cbuffer_h
-#define _qemu_cbuffer_h
-
-#include <stdint.h>
-
-/* Basic circular buffer type and methods */
-
-typedef struct {
- uint8_t* buff;
- int size;
- int rpos;
- int count;
-} CBuffer;
-
-static __inline__ void
-cbuffer_reset( CBuffer* cb, void* buff, int size )
-{
- cb->buff = buff;
- cb->size = size;
- cb->rpos = 0;
- cb->count = 0;
-}
-
-static __inline__ int
-cbuffer_write_avail( CBuffer* cb )
-{
- return cb->size - cb->count;
-}
-
-extern int cbuffer_write( CBuffer* cb, const void* from, int len );
-extern int cbuffer_write_peek( CBuffer* cb, uint8_t* *pbase );
-extern void cbuffer_write_step( CBuffer* cb, int len );
-
-static __inline__ int
-cbuffer_read_avail( CBuffer* cb )
-{
- return cb->count;
-}
-
-extern int cbuffer_read( CBuffer* cb, void* to, int len );
-extern int cbuffer_read_peek( CBuffer* cb, uint8_t* *pbase );
-extern void cbuffer_read_step( CBuffer* cb, int len );
-
-extern const char* cbuffer_quote( CBuffer* cb );
-extern const char* cbuffer_quote_data( CBuffer* cb );
-extern void cbuffer_print( CBuffer* cb );
-
-#endif /* qemu_cbuffer_h */
-
-
diff --git a/charpipe.c b/charpipe.c
deleted file mode 100644
index d6b9829..0000000
--- a/charpipe.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu-char.h"
-#include "cbuffer.h"
-#include "qemu_debug.h"
-
-#define xxDEBUG
-
-#ifdef DEBUG
-# include <stdio.h>
-# define D(...) ( fprintf( stderr, __VA_ARGS__ ), fprintf(stderr, "\n") )
-#else
-# define D(...) ((void)0)
-#endif
-
-/* we want to implement a bi-directionnal communication channel
- * between two QEMU character drivers that merge well into the
- * QEMU event loop.
- *
- * each half of the channel has its own object and buffer, and
- * we implement communication through charpipe_poll() which
- * must be called by the main event loop after its call to select()
- *
- */
-
-#define BIP_BUFFER_SIZE 512
-
-typedef struct BipBuffer {
- struct BipBuffer* next;
- CBuffer cb[1];
- char buff[ BIP_BUFFER_SIZE ];
-} BipBuffer;
-
-static BipBuffer* _free_bip_buffers;
-
-static BipBuffer*
-bip_buffer_alloc( void )
-{
- BipBuffer* bip = _free_bip_buffers;
- if (bip != NULL) {
- _free_bip_buffers = bip->next;
- } else {
- bip = malloc( sizeof(*bip) );
- if (bip == NULL) {
- derror( "%s: not enough memory", __FUNCTION__ );
- exit(1);
- }
- }
- bip->next = NULL;
- cbuffer_reset( bip->cb, bip->buff, sizeof(bip->buff) );
- return bip;
-}
-
-static void
-bip_buffer_free( BipBuffer* bip )
-{
- bip->next = _free_bip_buffers;
- _free_bip_buffers = bip;
-}
-
-/* this models each half of the charpipe */
-typedef struct CharPipeHalf {
- CharDriverState cs[1];
- BipBuffer* bip_first;
- BipBuffer* bip_last;
- struct CharPipeHalf* peer; /* NULL if closed */
-} CharPipeHalf;
-
-
-
-static void
-charpipehalf_close( CharDriverState* cs )
-{
- CharPipeHalf* ph = cs->opaque;
-
- while (ph->bip_first) {
- BipBuffer* bip = ph->bip_first;
- ph->bip_first = bip->next;
- bip_buffer_free(bip);
- }
- ph->bip_last = NULL;
- ph->peer = NULL;
-}
-
-
-static int
-charpipehalf_write( CharDriverState* cs, const uint8_t* buf, int len )
-{
- CharPipeHalf* ph = cs->opaque;
- CharPipeHalf* peer = ph->peer;
- BipBuffer* bip = ph->bip_last;
- int ret = 0;
-
- D("%s: writing %d bytes to %p: '%s'", __FUNCTION__,
- len, ph, quote_bytes( buf, len ));
-
- if (bip == NULL && peer != NULL && peer->cs->chr_read != NULL) {
- /* no buffered data, try to write directly to the peer */
- while (len > 0) {
- int size;
-
- if (peer->cs->chr_can_read) {
- size = qemu_chr_can_read( peer->cs );
- if (size == 0)
- break;
-
- if (size > len)
- size = len;
- } else
- size = len;
-
- qemu_chr_read( peer->cs, (uint8_t*)buf, size );
- buf += size;
- len -= size;
- ret += size;
- }
- }
-
- if (len == 0)
- return ret;
-
- /* buffer the remaining data */
- if (bip == NULL) {
- bip = bip_buffer_alloc();
- ph->bip_first = ph->bip_last = bip;
- }
-
- while (len > 0) {
- int len2 = cbuffer_write( bip->cb, buf, len );
-
- buf += len2;
- ret += len2;
- len -= len2;
- if (len == 0)
- break;
-
- /* ok, we need another buffer */
- ph->bip_last = bip_buffer_alloc();
- bip->next = ph->bip_last;
- bip = ph->bip_last;
- }
- return ret;
-}
-
-
-static void
-charpipehalf_poll( CharPipeHalf* ph )
-{
- CharPipeHalf* peer = ph->peer;
- int size;
-
- if (peer == NULL || peer->cs->chr_read == NULL)
- return;
-
- while (1) {
- BipBuffer* bip = ph->bip_first;
- uint8_t* base;
- int avail;
-
- if (bip == NULL)
- break;
-
- size = cbuffer_read_avail(bip->cb);
- if (size == 0) {
- ph->bip_first = bip->next;
- if (ph->bip_first == NULL)
- ph->bip_last = NULL;
- bip_buffer_free(bip);
- continue;
- }
-
- if (ph->cs->chr_can_read) {
- int size2 = qemu_chr_can_read(peer->cs);
-
- if (size2 == 0)
- break;
-
- if (size > size2)
- size = size2;
- }
-
- avail = cbuffer_read_peek( bip->cb, &base );
- if (avail > size)
- avail = size;
- D("%s: sending %d bytes from %p: '%s'", __FUNCTION__,
- avail, ph, quote_bytes( base, avail ));
-
- qemu_chr_read( peer->cs, base, avail );
- cbuffer_read_step( bip->cb, avail );
- }
-}
-
-
-static void
-charpipehalf_init( CharPipeHalf* ph, CharPipeHalf* peer )
-{
- CharDriverState* cs = ph->cs;
-
- ph->bip_first = NULL;
- ph->bip_last = NULL;
- ph->peer = peer;
-
- cs->chr_write = charpipehalf_write;
- cs->chr_ioctl = NULL;
- cs->chr_send_event = NULL;
- cs->chr_close = charpipehalf_close;
- cs->opaque = ph;
-}
-
-
-typedef struct CharPipeState {
- CharPipeHalf a[1];
- CharPipeHalf b[1];
-} CharPipeState;
-
-
-
-#define MAX_CHAR_PIPES 8
-
-static CharPipeState _s_charpipes[ MAX_CHAR_PIPES ];
-
-int
-qemu_chr_open_charpipe( CharDriverState* *pfirst, CharDriverState* *psecond )
-{
- CharPipeState* cp = _s_charpipes;
- CharPipeState* cp_end = cp + MAX_CHAR_PIPES;
-
- for ( ; cp < cp_end; cp++ ) {
- if ( cp->a->peer == NULL && cp->b->peer == NULL )
- break;
- }
-
- if (cp == cp_end) { /* can't allocate one */
- *pfirst = NULL;
- *psecond = NULL;
- return -1;
- }
-
- charpipehalf_init( cp->a, cp->b );
- charpipehalf_init( cp->b, cp->a );
-
- *pfirst = cp->a->cs;
- *psecond = cp->b->cs;
- return 0;
-}
-
-void
-charpipe_poll( void )
-{
- CharPipeState* cp = _s_charpipes;
- CharPipeState* cp_end = cp + MAX_CHAR_PIPES;
-
- for ( ; cp < cp_end; cp++ ) {
- CharPipeHalf* half;
-
- half = cp->a;
- if (half->peer != NULL)
- charpipehalf_poll(half);
-
- half = cp->b;
- if (half->peer != NULL)
- charpipehalf_poll(half);
- }
-}
diff --git a/charpipe.h b/charpipe.h
deleted file mode 100644
index 88dffde..0000000
--- a/charpipe.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _CHARPIPE_H
-#define _CHARPIPE_H
-
-#include "qemu-common.h"
-
-/* open two connected character drivers that can be used to communicate by internal
- * QEMU components. For Android, this is used to connect an emulated serial port
- * with the android modem
- */
-extern int qemu_chr_open_charpipe( CharDriverState* *pfirst, CharDriverState* *psecond );
-
-/* must be called from the main event loop to poll all charpipes */
-extern void charpipe_poll( void );
-
-#endif /* _CHARPIPE_H */
diff --git a/compatfd.c b/compatfd.c
deleted file mode 100644
index 46b0ae7..0000000
--- a/compatfd.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * signalfd/eventfd compatibility
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu-common.h"
-#include "compatfd.h"
-
-#include <sys/syscall.h>
-#include <pthread.h>
-
-struct sigfd_compat_info
-{
- sigset_t mask;
- int fd;
-};
-
-static void *sigwait_compat(void *opaque)
-{
- struct sigfd_compat_info *info = opaque;
- int err;
- sigset_t all;
-
- sigfillset(&all);
- sigprocmask(SIG_BLOCK, &all, NULL);
-
- do {
- siginfo_t siginfo;
-
- err = sigwaitinfo(&info->mask, &siginfo);
- if (err == -1 && errno == EINTR) {
- err = 0;
- continue;
- }
-
- if (err > 0) {
- char buffer[128];
- size_t offset = 0;
-
- memcpy(buffer, &err, sizeof(err));
- while (offset < sizeof(buffer)) {
- ssize_t len;
-
- len = write(info->fd, buffer + offset,
- sizeof(buffer) - offset);
- if (len == -1 && errno == EINTR)
- continue;
-
- if (len <= 0) {
- err = -1;
- break;
- }
-
- offset += len;
- }
- }
- } while (err >= 0);
-
- return NULL;
-}
-
-static int qemu_signalfd_compat(const sigset_t *mask)
-{
- pthread_attr_t attr;
- pthread_t tid;
- struct sigfd_compat_info *info;
- int fds[2];
-
- info = malloc(sizeof(*info));
- if (info == NULL) {
- errno = ENOMEM;
- return -1;
- }
-
- if (pipe(fds) == -1) {
- free(info);
- return -1;
- }
-
- memcpy(&info->mask, mask, sizeof(*mask));
- info->fd = fds[1];
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- pthread_create(&tid, &attr, sigwait_compat, info);
-
- pthread_attr_destroy(&attr);
-
- return fds[0];
-}
-
-int qemu_signalfd(const sigset_t *mask)
-{
-#if defined(SYS_signalfd)
- int ret;
-
- ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8);
- if (!(ret == -1 && errno == ENOSYS))
- return ret;
-#endif
-
- return qemu_signalfd_compat(mask);
-}
-
-int qemu_eventfd(int *fds)
-{
-#if defined(SYS_eventfd)
- int ret;
-
- ret = syscall(SYS_eventfd, 0);
- if (ret >= 0) {
- fds[0] = fds[1] = ret;
- return 0;
- } else if (!(ret == -1 && errno == ENOSYS))
- return ret;
-#endif
-
- return pipe(fds);
-}
diff --git a/compatfd.h b/compatfd.h
deleted file mode 100644
index 55a111a..0000000
--- a/compatfd.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * signalfd/eventfd compatibility
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_COMPATFD_H
-#define QEMU_COMPATFD_H
-
-#include <signal.h>
-
-struct qemu_signalfd_siginfo {
- uint32_t ssi_signo;
- uint8_t pad[124];
-};
-
-int qemu_signalfd(const sigset_t *mask);
-
-int qemu_eventfd(int *fds);
-
-#endif
diff --git a/console.c b/console.c
deleted file mode 100644
index 785710a..0000000
--- a/console.c
+++ /dev/null
@@ -1,1345 +0,0 @@
-/*
- * QEMU graphical console
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "console.h"
-#include "qemu-timer.h"
-
-//#define DEBUG_CONSOLE
-#define DEFAULT_BACKSCROLL 512
-#define MAX_CONSOLES 12
-#define DEFAULT_MONITOR_SIZE "800x600"
-
-#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
-
-typedef struct TextAttributes {
- uint8_t fgcol:4;
- uint8_t bgcol:4;
- uint8_t bold:1;
- uint8_t uline:1;
- uint8_t blink:1;
- uint8_t invers:1;
- uint8_t unvisible:1;
-} TextAttributes;
-
-typedef struct TextCell {
- uint8_t ch;
- TextAttributes t_attrib;
-} TextCell;
-
-#define MAX_ESC_PARAMS 3
-
-enum TTYState {
- TTY_STATE_NORM,
- TTY_STATE_ESC,
- TTY_STATE_CSI,
-};
-
-typedef struct QEMUFIFO {
- uint8_t *buf;
- int buf_size;
- int count, wptr, rptr;
-} QEMUFIFO;
-
-static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
-{
- int l, len;
-
- l = f->buf_size - f->count;
- if (len1 > l)
- len1 = l;
- len = len1;
- while (len > 0) {
- l = f->buf_size - f->wptr;
- if (l > len)
- l = len;
- memcpy(f->buf + f->wptr, buf, l);
- f->wptr += l;
- if (f->wptr >= f->buf_size)
- f->wptr = 0;
- buf += l;
- len -= l;
- }
- f->count += len1;
- return len1;
-}
-
-static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
-{
- int l, len;
-
- if (len1 > f->count)
- len1 = f->count;
- len = len1;
- while (len > 0) {
- l = f->buf_size - f->rptr;
- if (l > len)
- l = len;
- memcpy(buf, f->buf + f->rptr, l);
- f->rptr += l;
- if (f->rptr >= f->buf_size)
- f->rptr = 0;
- buf += l;
- len -= l;
- }
- f->count -= len1;
- return len1;
-}
-
-typedef enum {
- GRAPHIC_CONSOLE,
- TEXT_CONSOLE
-} console_type_t;
-
-/* ??? This is mis-named.
- It is used for both text and graphical consoles. */
-struct TextConsole {
- console_type_t console_type;
- DisplayState *ds;
- /* Graphic console state. */
- vga_hw_update_ptr hw_update;
- vga_hw_invalidate_ptr hw_invalidate;
- vga_hw_screen_dump_ptr hw_screen_dump;
- vga_hw_text_update_ptr hw_text_update;
- void *hw;
-
- int g_width, g_height;
- int width;
- int height;
- int total_height;
- int backscroll_height;
- int x, y;
- int x_saved, y_saved;
- int y_displayed;
- int y_base;
- TextAttributes t_attrib_default; /* default text attributes */
- TextAttributes t_attrib; /* currently active text attributes */
- TextCell *cells;
- int text_x[2], text_y[2], cursor_invalidate;
-
- enum TTYState state;
- int esc_params[MAX_ESC_PARAMS];
- int nb_esc_params;
-
- CharDriverState *chr;
- /* fifo for key pressed */
- QEMUFIFO out_fifo;
- uint8_t out_fifo_buf[16];
- QEMUTimer *kbd_timer;
-};
-
-static TextConsole *active_console;
-static TextConsole *consoles[MAX_CONSOLES];
-static int nb_consoles = 0;
-
-void vga_hw_update(void)
-{
- if (active_console && active_console->hw_update)
- active_console->hw_update(active_console->hw);
-}
-
-void vga_hw_invalidate(void)
-{
- if (active_console->hw_invalidate)
- active_console->hw_invalidate(active_console->hw);
-}
-
-void vga_hw_screen_dump(const char *filename)
-{
- TextConsole *previous_active_console;
-
- previous_active_console = active_console;
- active_console = consoles[0];
- /* There is currently no way of specifying which screen we want to dump,
- so always dump the first one. */
- if (consoles[0]->hw_screen_dump)
- consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
- active_console = previous_active_console;
-}
-
-void vga_hw_text_update(console_ch_t *chardata)
-{
- if (active_console && active_console->hw_text_update)
- active_console->hw_text_update(active_console->hw, chardata);
-}
-
-/* convert a RGBA color to a color index usable in graphic primitives */
-static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
-{
- unsigned int r, g, b, color;
-
- switch(ds->depth) {
-#if 0
- case 8:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = (rgb_to_index[r] * 6 * 6) +
- (rgb_to_index[g] * 6) +
- (rgb_to_index[b]);
- break;
-#endif
- case 15:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
- break;
- case 16:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
- break;
- case 32:
- default:
- color = rgba;
- break;
- }
- return color;
-}
-
-static void vga_fill_rect (DisplayState *ds,
- int posx, int posy, int width, int height, uint32_t color)
-{
- uint8_t *d, *d1;
- int x, y, bpp;
-
- bpp = (ds->depth + 7) >> 3;
- d1 = ds->data +
- ds->linesize * posy + bpp * posx;
- for (y = 0; y < height; y++) {
- d = d1;
- switch(bpp) {
- case 1:
- for (x = 0; x < width; x++) {
- *((uint8_t *)d) = color;
- d++;
- }
- break;
- case 2:
- for (x = 0; x < width; x++) {
- *((uint16_t *)d) = color;
- d += 2;
- }
- break;
- case 4:
- for (x = 0; x < width; x++) {
- *((uint32_t *)d) = color;
- d += 4;
- }
- break;
- }
- d1 += ds->linesize;
- }
-}
-
-/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
-static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
-{
- const uint8_t *s;
- uint8_t *d;
- int wb, y, bpp;
-
- bpp = (ds->depth + 7) >> 3;
- wb = w * bpp;
- if (yd <= ys) {
- s = ds->data +
- ds->linesize * ys + bpp * xs;
- d = ds->data +
- ds->linesize * yd + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d += ds->linesize;
- s += ds->linesize;
- }
- } else {
- s = ds->data +
- ds->linesize * (ys + h - 1) + bpp * xs;
- d = ds->data +
- ds->linesize * (yd + h - 1) + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d -= ds->linesize;
- s -= ds->linesize;
- }
- }
-}
-
-/***********************************************************/
-/* basic char display */
-
-#define FONT_HEIGHT 16
-#define FONT_WIDTH 8
-
-#include "vgafont.h"
-
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) x
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
-static uint32_t color_table[2][8];
-
-enum color_names {
- COLOR_BLACK = 0,
- COLOR_RED = 1,
- COLOR_GREEN = 2,
- COLOR_YELLOW = 3,
- COLOR_BLUE = 4,
- COLOR_MAGENTA = 5,
- COLOR_CYAN = 6,
- COLOR_WHITE = 7
-};
-
-static const uint32_t color_table_rgb[2][8] = {
- { /* dark */
- QEMU_RGB(0x00, 0x00, 0x00), /* black */
- QEMU_RGB(0xaa, 0x00, 0x00), /* red */
- QEMU_RGB(0x00, 0xaa, 0x00), /* green */
- QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */
- QEMU_RGB(0x00, 0x00, 0xaa), /* blue */
- QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */
- QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */
- QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */
- },
- { /* bright */
- QEMU_RGB(0x00, 0x00, 0x00), /* black */
- QEMU_RGB(0xff, 0x00, 0x00), /* red */
- QEMU_RGB(0x00, 0xff, 0x00), /* green */
- QEMU_RGB(0xff, 0xff, 0x00), /* yellow */
- QEMU_RGB(0x00, 0x00, 0xff), /* blue */
- QEMU_RGB(0xff, 0x00, 0xff), /* magenta */
- QEMU_RGB(0x00, 0xff, 0xff), /* cyan */
- QEMU_RGB(0xff, 0xff, 0xff), /* white */
- }
-};
-
-static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
-{
- switch(ds->depth) {
- case 8:
- col |= col << 8;
- col |= col << 16;
- break;
- case 15:
- case 16:
- col |= col << 16;
- break;
- default:
- break;
- }
-
- return col;
-}
-#ifdef DEBUG_CONSOLE
-static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
-{
- if (t_attrib->bold) {
- printf("b");
- } else {
- printf(" ");
- }
- if (t_attrib->uline) {
- printf("u");
- } else {
- printf(" ");
- }
- if (t_attrib->blink) {
- printf("l");
- } else {
- printf(" ");
- }
- if (t_attrib->invers) {
- printf("i");
- } else {
- printf(" ");
- }
- if (t_attrib->unvisible) {
- printf("n");
- } else {
- printf(" ");
- }
-
- printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch);
-}
-#endif
-
-static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
- TextAttributes *t_attrib)
-{
- uint8_t *d;
- const uint8_t *font_ptr;
- unsigned int font_data, linesize, xorcol, bpp;
- int i;
- unsigned int fgcol, bgcol;
-
-#ifdef DEBUG_CONSOLE
- printf("x: %2i y: %2i", x, y);
- console_print_text_attributes(t_attrib, ch);
-#endif
-
- if (t_attrib->invers) {
- bgcol = color_table[t_attrib->bold][t_attrib->fgcol];
- fgcol = color_table[t_attrib->bold][t_attrib->bgcol];
- } else {
- fgcol = color_table[t_attrib->bold][t_attrib->fgcol];
- bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
- }
-
- bpp = (ds->depth + 7) >> 3;
- d = ds->data +
- ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
- linesize = ds->linesize;
- font_ptr = vgafont16 + FONT_HEIGHT * ch;
- xorcol = bgcol ^ fgcol;
- switch(ds->depth) {
- case 8:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- if (t_attrib->uline
- && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
- font_data = 0xFFFF;
- }
- ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- case 16:
- case 15:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- if (t_attrib->uline
- && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
- font_data = 0xFFFF;
- }
- ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- case 32:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
- font_data = 0xFFFF;
- }
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- }
-}
-
-static void text_console_resize(TextConsole *s)
-{
- TextCell *cells, *c, *c1;
- int w1, x, y, last_width;
-
- last_width = s->width;
- s->width = s->g_width / FONT_WIDTH;
- s->height = s->g_height / FONT_HEIGHT;
-
- w1 = last_width;
- if (s->width < w1)
- w1 = s->width;
-
- cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
- for(y = 0; y < s->total_height; y++) {
- c = &cells[y * s->width];
- if (w1 > 0) {
- c1 = &s->cells[y * last_width];
- for(x = 0; x < w1; x++) {
- *c++ = *c1++;
- }
- }
- for(x = w1; x < s->width; x++) {
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- }
- }
- qemu_free(s->cells);
- s->cells = cells;
-}
-
-static inline void text_update_xy(TextConsole *s, int x, int y)
-{
- s->text_x[0] = MIN(s->text_x[0], x);
- s->text_x[1] = MAX(s->text_x[1], x);
- s->text_y[0] = MIN(s->text_y[0], y);
- s->text_y[1] = MAX(s->text_y[1], y);
-}
-
-static void update_xy(TextConsole *s, int x, int y)
-{
- TextCell *c;
- int y1, y2;
-
- if (s == active_console) {
- if (!s->ds->depth) {
- text_update_xy(s, x, y);
- return;
- }
-
- y1 = (s->y_base + y) % s->total_height;
- y2 = y1 - s->y_displayed;
- if (y2 < 0)
- y2 += s->total_height;
- if (y2 < s->height) {
- c = &s->cells[y1 * s->width + x];
- vga_putcharxy(s->ds, x, y2, c->ch,
- &(c->t_attrib));
- dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
- FONT_WIDTH, FONT_HEIGHT);
- }
- }
-}
-
-static void console_show_cursor(TextConsole *s, int show)
-{
- TextCell *c;
- int y, y1;
-
- if (s == active_console) {
- int x = s->x;
-
- if (!s->ds->depth) {
- s->cursor_invalidate = 1;
- return;
- }
-
- if (x >= s->width) {
- x = s->width - 1;
- }
- y1 = (s->y_base + s->y) % s->total_height;
- y = y1 - s->y_displayed;
- if (y < 0)
- y += s->total_height;
- if (y < s->height) {
- c = &s->cells[y1 * s->width + x];
- if (show) {
- TextAttributes t_attrib = s->t_attrib_default;
- t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
- vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
- } else {
- vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib));
- }
- dpy_update(s->ds, x * FONT_WIDTH, y * FONT_HEIGHT,
- FONT_WIDTH, FONT_HEIGHT);
- }
- }
-}
-
-static void console_refresh(TextConsole *s)
-{
- TextCell *c;
- int x, y, y1;
-
- if (s != active_console)
- return;
- if (!s->ds->depth) {
- s->text_x[0] = 0;
- s->text_y[0] = 0;
- s->text_x[1] = s->width - 1;
- s->text_y[1] = s->height - 1;
- s->cursor_invalidate = 1;
- return;
- }
-
- vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
- color_table[0][COLOR_BLACK]);
- y1 = s->y_displayed;
- for(y = 0; y < s->height; y++) {
- c = s->cells + y1 * s->width;
- for(x = 0; x < s->width; x++) {
- vga_putcharxy(s->ds, x, y, c->ch,
- &(c->t_attrib));
- c++;
- }
- if (++y1 == s->total_height)
- y1 = 0;
- }
- dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);
- console_show_cursor(s, 1);
-}
-
-static void console_scroll(int ydelta)
-{
- TextConsole *s;
- int i, y1;
-
- s = active_console;
- if (!s || (s->console_type == GRAPHIC_CONSOLE))
- return;
-
- if (ydelta > 0) {
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == s->y_base)
- break;
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- } else {
- ydelta = -ydelta;
- i = s->backscroll_height;
- if (i > s->total_height - s->height)
- i = s->total_height - s->height;
- y1 = s->y_base - i;
- if (y1 < 0)
- y1 += s->total_height;
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == y1)
- break;
- if (--s->y_displayed < 0)
- s->y_displayed = s->total_height - 1;
- }
- }
- console_refresh(s);
-}
-
-static void console_put_lf(TextConsole *s)
-{
- TextCell *c;
- int x, y1;
-
- s->y++;
- if (s->y >= s->height) {
- s->y = s->height - 1;
-
- if (s->y_displayed == s->y_base) {
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- if (++s->y_base == s->total_height)
- s->y_base = 0;
- if (s->backscroll_height < s->total_height)
- s->backscroll_height++;
- y1 = (s->y_base + s->height - 1) % s->total_height;
- c = &s->cells[y1 * s->width];
- for(x = 0; x < s->width; x++) {
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- }
- if (s == active_console && s->y_displayed == s->y_base) {
- if (!s->ds->depth) {
- s->text_x[0] = 0;
- s->text_y[0] = 0;
- s->text_x[1] = s->width - 1;
- s->text_y[1] = s->height - 1;
- return;
- }
-
- vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
- s->width * FONT_WIDTH,
- (s->height - 1) * FONT_HEIGHT);
- vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
- s->width * FONT_WIDTH, FONT_HEIGHT,
- color_table[0][s->t_attrib_default.bgcol]);
- dpy_update(s->ds, 0, 0,
- s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
- }
- }
-}
-
-/* Set console attributes depending on the current escape codes.
- * NOTE: I know this code is not very efficient (checking every color for it
- * self) but it is more readable and better maintainable.
- */
-static void console_handle_escape(TextConsole *s)
-{
- int i;
-
- for (i=0; i<s->nb_esc_params; i++) {
- switch (s->esc_params[i]) {
- case 0: /* reset all console attributes to default */
- s->t_attrib = s->t_attrib_default;
- break;
- case 1:
- s->t_attrib.bold = 1;
- break;
- case 4:
- s->t_attrib.uline = 1;
- break;
- case 5:
- s->t_attrib.blink = 1;
- break;
- case 7:
- s->t_attrib.invers = 1;
- break;
- case 8:
- s->t_attrib.unvisible = 1;
- break;
- case 22:
- s->t_attrib.bold = 0;
- break;
- case 24:
- s->t_attrib.uline = 0;
- break;
- case 25:
- s->t_attrib.blink = 0;
- break;
- case 27:
- s->t_attrib.invers = 0;
- break;
- case 28:
- s->t_attrib.unvisible = 0;
- break;
- /* set foreground color */
- case 30:
- s->t_attrib.fgcol=COLOR_BLACK;
- break;
- case 31:
- s->t_attrib.fgcol=COLOR_RED;
- break;
- case 32:
- s->t_attrib.fgcol=COLOR_GREEN;
- break;
- case 33:
- s->t_attrib.fgcol=COLOR_YELLOW;
- break;
- case 34:
- s->t_attrib.fgcol=COLOR_BLUE;
- break;
- case 35:
- s->t_attrib.fgcol=COLOR_MAGENTA;
- break;
- case 36:
- s->t_attrib.fgcol=COLOR_CYAN;
- break;
- case 37:
- s->t_attrib.fgcol=COLOR_WHITE;
- break;
- /* set background color */
- case 40:
- s->t_attrib.bgcol=COLOR_BLACK;
- break;
- case 41:
- s->t_attrib.bgcol=COLOR_RED;
- break;
- case 42:
- s->t_attrib.bgcol=COLOR_GREEN;
- break;
- case 43:
- s->t_attrib.bgcol=COLOR_YELLOW;
- break;
- case 44:
- s->t_attrib.bgcol=COLOR_BLUE;
- break;
- case 45:
- s->t_attrib.bgcol=COLOR_MAGENTA;
- break;
- case 46:
- s->t_attrib.bgcol=COLOR_CYAN;
- break;
- case 47:
- s->t_attrib.bgcol=COLOR_WHITE;
- break;
- }
- }
-}
-
-static void console_clear_xy(TextConsole *s, int x, int y)
-{
- int y1 = (s->y_base + y) % s->total_height;
- TextCell *c = &s->cells[y1 * s->width + x];
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- update_xy(s, x, y);
-}
-
-static void console_putchar(TextConsole *s, int ch)
-{
- TextCell *c;
- int y1, i;
- int x, y;
-
- switch(s->state) {
- case TTY_STATE_NORM:
- switch(ch) {
- case '\r': /* carriage return */
- s->x = 0;
- break;
- case '\n': /* newline */
- console_put_lf(s);
- break;
- case '\b': /* backspace */
- if (s->x > 0)
- s->x--;
- break;
- case '\t': /* tabspace */
- if (s->x + (8 - (s->x % 8)) > s->width) {
- s->x = 0;
- console_put_lf(s);
- } else {
- s->x = s->x + (8 - (s->x % 8));
- }
- break;
- case '\a': /* alert aka. bell */
- /* TODO: has to be implemented */
- break;
- case 14:
- /* SI (shift in), character set 0 (ignored) */
- break;
- case 15:
- /* SO (shift out), character set 1 (ignored) */
- break;
- case 27: /* esc (introducing an escape sequence) */
- s->state = TTY_STATE_ESC;
- break;
- default:
- if (s->x >= s->width) {
- /* line wrap */
- s->x = 0;
- console_put_lf(s);
- }
- y1 = (s->y_base + s->y) % s->total_height;
- c = &s->cells[y1 * s->width + s->x];
- c->ch = ch;
- c->t_attrib = s->t_attrib;
- update_xy(s, s->x, s->y);
- s->x++;
- break;
- }
- break;
- case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
- if (ch == '[') {
- for(i=0;i<MAX_ESC_PARAMS;i++)
- s->esc_params[i] = 0;
- s->nb_esc_params = 0;
- s->state = TTY_STATE_CSI;
- } else {
- s->state = TTY_STATE_NORM;
- }
- break;
- case TTY_STATE_CSI: /* handle escape sequence parameters */
- if (ch >= '0' && ch <= '9') {
- if (s->nb_esc_params < MAX_ESC_PARAMS) {
- s->esc_params[s->nb_esc_params] =
- s->esc_params[s->nb_esc_params] * 10 + ch - '0';
- }
- } else {
- s->nb_esc_params++;
- if (ch == ';')
- break;
-#ifdef DEBUG_CONSOLE
- fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
- s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
-#endif
- s->state = TTY_STATE_NORM;
- switch(ch) {
- case 'A':
- /* move cursor up */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->y -= s->esc_params[0];
- if (s->y < 0) {
- s->y = 0;
- }
- break;
- case 'B':
- /* move cursor down */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->y += s->esc_params[0];
- if (s->y >= s->height) {
- s->y = s->height - 1;
- }
- break;
- case 'C':
- /* move cursor right */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->x += s->esc_params[0];
- if (s->x >= s->width) {
- s->x = s->width - 1;
- }
- break;
- case 'D':
- /* move cursor left */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- s->x -= s->esc_params[0];
- if (s->x < 0) {
- s->x = 0;
- }
- break;
- case 'G':
- /* move cursor to column */
- s->x = s->esc_params[0] - 1;
- if (s->x < 0) {
- s->x = 0;
- }
- break;
- case 'f':
- case 'H':
- /* move cursor to row, column */
- s->x = s->esc_params[1] - 1;
- if (s->x < 0) {
- s->x = 0;
- }
- s->y = s->esc_params[0] - 1;
- if (s->y < 0) {
- s->y = 0;
- }
- break;
- case 'J':
- switch (s->esc_params[0]) {
- case 0:
- /* clear to end of screen */
- for (y = s->y; y < s->height; y++) {
- for (x = 0; x < s->width; x++) {
- if (y == s->y && x < s->x) {
- continue;
- }
- console_clear_xy(s, x, y);
- }
- }
- break;
- case 1:
- /* clear from beginning of screen */
- for (y = 0; y <= s->y; y++) {
- for (x = 0; x < s->width; x++) {
- if (y == s->y && x > s->x) {
- break;
- }
- console_clear_xy(s, x, y);
- }
- }
- break;
- case 2:
- /* clear entire screen */
- for (y = 0; y <= s->height; y++) {
- for (x = 0; x < s->width; x++) {
- console_clear_xy(s, x, y);
- }
- }
- break;
- }
- case 'K':
- switch (s->esc_params[0]) {
- case 0:
- /* clear to eol */
- for(x = s->x; x < s->width; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- case 1:
- /* clear from beginning of line */
- for (x = 0; x <= s->x; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- case 2:
- /* clear entire line */
- for(x = 0; x < s->width; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- }
- break;
- case 'm':
- console_handle_escape(s);
- break;
- case 'n':
- /* report cursor position */
- /* TODO: send ESC[row;colR */
- break;
- case 's':
- /* save cursor position */
- s->x_saved = s->x;
- s->y_saved = s->y;
- break;
- case 'u':
- /* restore cursor position */
- s->x = s->x_saved;
- s->y = s->y_saved;
- break;
- default:
-#ifdef DEBUG_CONSOLE
- fprintf(stderr, "unhandled escape character '%c'\n", ch);
-#endif
- break;
- }
- break;
- }
- }
-}
-
-void console_select(unsigned int index)
-{
- TextConsole *s;
-
- if (index >= MAX_CONSOLES)
- return;
- s = consoles[index];
- if (s) {
- active_console = s;
- if (s->g_width && s->g_height
- && (s->g_width != s->ds->width || s->g_height != s->ds->height))
- dpy_resize(s->ds, s->g_width, s->g_height);
- vga_hw_invalidate();
- }
-}
-
-static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
-{
- TextConsole *s = chr->opaque;
- int i;
-
- console_show_cursor(s, 0);
- for(i = 0; i < len; i++) {
- console_putchar(s, buf[i]);
- }
- console_show_cursor(s, 1);
- return len;
-}
-
-static void console_send_event(CharDriverState *chr, int event)
-{
- TextConsole *s = chr->opaque;
- int i;
-
- if (event == CHR_EVENT_FOCUS) {
- for(i = 0; i < nb_consoles; i++) {
- if (consoles[i] == s) {
- console_select(i);
- break;
- }
- }
- }
-}
-
-static void kbd_send_chars(void *opaque)
-{
- TextConsole *s = opaque;
- int len;
- uint8_t buf[16];
-
- len = qemu_chr_can_read(s->chr);
- if (len > s->out_fifo.count)
- len = s->out_fifo.count;
- if (len > 0) {
- if (len > sizeof(buf))
- len = sizeof(buf);
- qemu_fifo_read(&s->out_fifo, buf, len);
- qemu_chr_read(s->chr, buf, len);
- }
- /* characters are pending: we send them a bit later (XXX:
- horrible, should change char device API) */
- if (s->out_fifo.count > 0) {
- qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
- }
-}
-
-/* called when an ascii key is pressed */
-void kbd_put_keysym(int keysym)
-{
- TextConsole *s;
- uint8_t buf[16], *q;
- int c;
-
- s = active_console;
- if (!s || (s->console_type == GRAPHIC_CONSOLE))
- return;
-
- switch(keysym) {
- case QEMU_KEY_CTRL_UP:
- console_scroll(-1);
- break;
- case QEMU_KEY_CTRL_DOWN:
- console_scroll(1);
- break;
- case QEMU_KEY_CTRL_PAGEUP:
- console_scroll(-10);
- break;
- case QEMU_KEY_CTRL_PAGEDOWN:
- console_scroll(10);
- break;
- default:
- /* convert the QEMU keysym to VT100 key string */
- q = buf;
- if (keysym >= 0xe100 && keysym <= 0xe11f) {
- *q++ = '\033';
- *q++ = '[';
- c = keysym - 0xe100;
- if (c >= 10)
- *q++ = '0' + (c / 10);
- *q++ = '0' + (c % 10);
- *q++ = '~';
- } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
- *q++ = '\033';
- *q++ = '[';
- *q++ = keysym & 0xff;
- } else {
- *q++ = keysym;
- }
- if (s->chr->chr_read) {
- qemu_fifo_write(&s->out_fifo, buf, q - buf);
- kbd_send_chars(s);
- }
- break;
- }
-}
-
-static void text_console_invalidate(void *opaque)
-{
- TextConsole *s = (TextConsole *) opaque;
-
- console_refresh(s);
-}
-
-static void text_console_update(void *opaque, console_ch_t *chardata)
-{
- TextConsole *s = (TextConsole *) opaque;
- int i, j, src;
-
- if (s->text_x[0] <= s->text_x[1]) {
- src = (s->y_base + s->text_y[0]) * s->width;
- chardata += s->text_y[0] * s->width;
- for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
- for (j = 0; j < s->width; j ++, src ++)
- console_write_ch(chardata ++, s->cells[src].ch |
- (s->cells[src].t_attrib.fgcol << 12) |
- (s->cells[src].t_attrib.bgcol << 8) |
- (s->cells[src].t_attrib.bold << 21));
- dpy_update(s->ds, s->text_x[0], s->text_y[0],
- s->text_x[1] - s->text_x[0], i - s->text_y[0]);
- s->text_x[0] = s->width;
- s->text_y[0] = s->height;
- s->text_x[1] = 0;
- s->text_y[1] = 0;
- }
- if (s->cursor_invalidate) {
- dpy_cursor(s->ds, s->x, s->y);
- s->cursor_invalidate = 0;
- }
-}
-
-static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
-{
- TextConsole *s;
- int i;
-
- if (nb_consoles >= MAX_CONSOLES)
- return NULL;
- s = qemu_mallocz(sizeof(TextConsole));
- if (!s) {
- return NULL;
- }
- if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
- (console_type == GRAPHIC_CONSOLE))) {
- active_console = s;
- }
- s->ds = ds;
- s->console_type = console_type;
- if (console_type != GRAPHIC_CONSOLE) {
- consoles[nb_consoles++] = s;
- } else {
- /* HACK: Put graphical consoles before text consoles. */
- for (i = nb_consoles; i > 0; i--) {
- if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
- break;
- consoles[i] = consoles[i - 1];
- }
- consoles[i] = s;
- }
- return s;
-}
-
-TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- vga_hw_text_update_ptr text_update,
- void *opaque)
-{
- TextConsole *s;
-
- s = new_console(ds, GRAPHIC_CONSOLE);
- if (!s)
- return NULL;
- s->hw_update = update;
- s->hw_invalidate = invalidate;
- s->hw_screen_dump = screen_dump;
- s->hw_text_update = text_update;
- s->hw = opaque;
- return s;
-}
-
-int is_graphic_console(void)
-{
- return active_console && active_console->console_type == GRAPHIC_CONSOLE;
-}
-
-void console_color_init(DisplayState *ds)
-{
- int i, j;
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 8; i++) {
- color_table[j][i] = col_expand(ds,
- vga_get_color(ds, color_table_rgb[j][i]));
- }
- }
-}
-
-CharDriverState *text_console_init(DisplayState *ds, const char *p)
-{
- CharDriverState *chr;
- TextConsole *s;
- unsigned width;
- unsigned height;
- static int color_inited;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = new_console(ds, TEXT_CONSOLE);
- if (!s) {
- free(chr);
- return NULL;
- }
- if (!p)
- p = DEFAULT_MONITOR_SIZE;
-
- chr->opaque = s;
- chr->chr_write = console_puts;
- chr->chr_send_event = console_send_event;
-
- s->chr = chr;
- s->out_fifo.buf = s->out_fifo_buf;
- s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
- s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
-
- if (!color_inited) {
- color_inited = 1;
- console_color_init(s->ds);
- }
- s->y_displayed = 0;
- s->y_base = 0;
- s->total_height = DEFAULT_BACKSCROLL;
- s->x = 0;
- s->y = 0;
- width = s->ds->width;
- height = s->ds->height;
- if (p != 0) {
- width = strtoul(p, (char **)&p, 10);
- if (*p == 'C') {
- p++;
- width *= FONT_WIDTH;
- }
- if (*p == 'x') {
- p++;
- height = strtoul(p, (char **)&p, 10);
- if (*p == 'C') {
- p++;
- height *= FONT_HEIGHT;
- }
- }
- }
- s->g_width = width;
- s->g_height = height;
-
- s->hw_invalidate = text_console_invalidate;
- s->hw_text_update = text_console_update;
- s->hw = s;
-
- /* Set text attribute defaults */
- s->t_attrib_default.bold = 0;
- s->t_attrib_default.uline = 0;
- s->t_attrib_default.blink = 0;
- s->t_attrib_default.invers = 0;
- s->t_attrib_default.unvisible = 0;
- s->t_attrib_default.fgcol = COLOR_WHITE;
- s->t_attrib_default.bgcol = COLOR_BLACK;
-
- /* set current text attributes to default */
- s->t_attrib = s->t_attrib_default;
- text_console_resize(s);
-
- qemu_chr_reset(chr);
-
- return chr;
-}
-
-void qemu_console_resize(QEMUConsole *console, int width, int height)
-{
- if (console->g_width != width || console->g_height != height
- || !console->ds->data) {
- console->g_width = width;
- console->g_height = height;
- if (active_console == console) {
- dpy_resize(console->ds, width, height);
- }
- }
-}
diff --git a/console.h b/console.h
deleted file mode 100644
index 52dc4d8..0000000
--- a/console.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#ifndef CONSOLE_H
-#define CONSOLE_H
-
-#include "qemu-char.h"
-
-/* keyboard/mouse support */
-
-#define MOUSE_EVENT_LBUTTON 0x01
-#define MOUSE_EVENT_RBUTTON 0x02
-#define MOUSE_EVENT_MBUTTON 0x04
-
-/* in ms */
-#if 1 /* ANDROID */
-#define GUI_REFRESH_INTERVAL (1000/60) /* 60 frames/s is better */
-#else
-#define GUI_REFRESH_INTERVAL 30
-#endif
-
-typedef void QEMUPutKBDEvent(void *opaque, int keycode);
-typedef void QEMUPutKBDEventN(void *opaque, int* keycodes, int count);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
-typedef void QEMUPutGenericEvent(void* opaque, int type, int code, int value);
-
-typedef struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *qemu_put_mouse_event;
- void *qemu_put_mouse_event_opaque;
- int qemu_put_mouse_event_absolute;
- char *qemu_put_mouse_event_name;
-
- /* used internally by qemu for handling mice */
- struct QEMUPutMouseEntry *next;
-} QEMUPutMouseEntry;
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name);
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
-
-void kbd_put_keycode(int keycode);
-void kbd_put_keycodes(int* keycodes, int count);
-void kbd_generic_event(int type, int code, int value);
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
-int kbd_mouse_is_absolute(void);
-
-struct mouse_transform_info_s {
- /* Touchscreen resolution */
- int x;
- int y;
- /* Calibration values as used/generated by tslib */
- int a[7];
-};
-
-void do_info_mice(void);
-void do_mouse_set(int index);
-
-/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
- constants) */
-#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
-#define QEMU_KEY_BACKSPACE 0x007f
-#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
-#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
-#define QEMU_KEY_RIGHT QEMU_KEY_ESC1('C')
-#define QEMU_KEY_LEFT QEMU_KEY_ESC1('D')
-#define QEMU_KEY_HOME QEMU_KEY_ESC1(1)
-#define QEMU_KEY_END QEMU_KEY_ESC1(4)
-#define QEMU_KEY_PAGEUP QEMU_KEY_ESC1(5)
-#define QEMU_KEY_PAGEDOWN QEMU_KEY_ESC1(6)
-#define QEMU_KEY_DELETE QEMU_KEY_ESC1(3)
-
-#define QEMU_KEY_CTRL_UP 0xe400
-#define QEMU_KEY_CTRL_DOWN 0xe401
-#define QEMU_KEY_CTRL_LEFT 0xe402
-#define QEMU_KEY_CTRL_RIGHT 0xe403
-#define QEMU_KEY_CTRL_HOME 0xe404
-#define QEMU_KEY_CTRL_END 0xe405
-#define QEMU_KEY_CTRL_PAGEUP 0xe406
-#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
-
-void kbd_put_keysym(int keysym);
-
-/* consoles */
-
-struct DisplayState {
- uint8_t *data;
- int linesize;
- int depth;
- int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
- int width;
- int height;
- void *opaque;
- struct QEMUTimer *gui_timer;
- uint64_t gui_timer_interval;
- int idle; /* there is nothing to update (window invisible), set by vnc/sdl */
-
- void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
- void (*dpy_resize)(struct DisplayState *s, int w, int h);
- void (*dpy_refresh)(struct DisplayState *s);
- void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
- int dst_x, int dst_y, int w, int h);
- void (*dpy_fill)(struct DisplayState *s, int x, int y,
- int w, int h, uint32_t c);
- void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
- void (*mouse_set)(int x, int y, int on);
- void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
- uint8_t *image, uint8_t *mask);
-};
-
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
-{
- s->dpy_update(s, x, y, w, h);
-}
-
-static inline void dpy_resize(DisplayState *s, int w, int h)
-{
- s->dpy_resize(s, w, h);
-}
-
-static inline void dpy_cursor(DisplayState *s, int x, int y)
-{
- if (s->dpy_text_cursor)
- s->dpy_text_cursor(s, x, y);
-}
-
-typedef unsigned long console_ch_t;
-static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
-{
- cpu_to_le32wu((uint32_t *) dest, ch);
-}
-
-typedef void (*vga_hw_update_ptr)(void *);
-typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
-typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
-
-TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- vga_hw_text_update_ptr text_update,
- void *opaque);
-void vga_hw_update(void);
-void vga_hw_invalidate(void);
-void vga_hw_screen_dump(const char *filename);
-void vga_hw_text_update(console_ch_t *chardata);
-
-int is_graphic_console(void);
-CharDriverState *text_console_init(DisplayState *ds, const char *p);
-void console_select(unsigned int index);
-void console_color_init(DisplayState *ds);
-void qemu_console_resize(QEMUConsole *console, int width, int height);
-
-/* sdl.c */
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
-
-/* cocoa.m */
-void cocoa_display_init(DisplayState *ds, int full_screen);
-
-/* vnc.c */
-void vnc_display_init(DisplayState *ds);
-void vnc_display_close(DisplayState *ds);
-int vnc_display_open(DisplayState *ds, const char *display);
-int vnc_display_password(DisplayState *ds, const char *password);
-void do_info_vnc(void);
-
-/* curses.c */
-void curses_display_init(DisplayState *ds, int full_screen);
-
-/* x_keymap.c */
-extern uint8_t _translate_keycode(const int key);
-
-/* FIXME: term_printf et al should probably go elsewhere so everything
- does not need to include console.h */
-/* monitor.c */
-void monitor_init(CharDriverState *hd, int show_banner);
-void term_puts(const char *str);
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-void term_print_filename(const char *filename);
-void term_flush(void);
-void term_print_help(void);
-void monitor_readline(const char *prompt, int is_password,
- char *buf, int buf_size);
-
-/* readline.c */
-typedef void ReadLineFunc(void *opaque, const char *str);
-
-extern int completion_index;
-void add_completion(const char *str);
-void readline_handle_byte(int ch);
-void readline_find_completion(const char *cmdline);
-const char *readline_get_history(unsigned int index);
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque);
-
-#endif
diff --git a/cpu-all.h b/cpu-all.h
deleted file mode 100644
index 8f4cb3c..0000000
--- a/cpu-all.h
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * defines common to all virtual CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_ALL_H
-#define CPU_ALL_H
-
-#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__)
-#define WORDS_ALIGNED
-#endif
-
-/* some important defines:
- *
- * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
- * memory accesses.
- *
- * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
- * otherwise little endian.
- *
- * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
- *
- * TARGET_WORDS_BIGENDIAN : same for target cpu
- */
-
-#include "bswap.h"
-#include "softfloat.h"
-
-#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-#define BSWAP_NEEDED
-#endif
-
-#ifdef BSWAP_NEEDED
-
-static inline uint16_t tswap16(uint16_t s)
-{
- return bswap16(s);
-}
-
-static inline uint32_t tswap32(uint32_t s)
-{
- return bswap32(s);
-}
-
-static inline uint64_t tswap64(uint64_t s)
-{
- return bswap64(s);
-}
-
-static inline void tswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void tswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void tswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#else
-
-static inline uint16_t tswap16(uint16_t s)
-{
- return s;
-}
-
-static inline uint32_t tswap32(uint32_t s)
-{
- return s;
-}
-
-static inline uint64_t tswap64(uint64_t s)
-{
- return s;
-}
-
-static inline void tswap16s(uint16_t *s)
-{
-}
-
-static inline void tswap32s(uint32_t *s)
-{
-}
-
-static inline void tswap64s(uint64_t *s)
-{
-}
-
-#endif
-
-#if TARGET_LONG_SIZE == 4
-#define tswapl(s) tswap32(s)
-#define tswapls(s) tswap32s((uint32_t *)(s))
-#define bswaptls(s) bswap32s(s)
-#else
-#define tswapl(s) tswap64(s)
-#define tswapls(s) tswap64s((uint64_t *)(s))
-#define bswaptls(s) bswap64s(s)
-#endif
-
-typedef union {
- float32 f;
- uint32_t l;
-} CPU_FloatU;
-
-/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
- endian ! */
-typedef union {
- float64 d;
-#if defined(WORDS_BIGENDIAN) \
- || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
- struct {
- uint32_t upper;
- uint32_t lower;
- } l;
-#else
- struct {
- uint32_t lower;
- uint32_t upper;
- } l;
-#endif
- uint64_t ll;
-} CPU_DoubleU;
-
-#ifdef TARGET_SPARC
-typedef union {
- float128 q;
-#if defined(WORDS_BIGENDIAN) \
- || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
- struct {
- uint32_t upmost;
- uint32_t upper;
- uint32_t lower;
- uint32_t lowest;
- } l;
- struct {
- uint64_t upper;
- uint64_t lower;
- } ll;
-#else
- struct {
- uint32_t lowest;
- uint32_t lower;
- uint32_t upper;
- uint32_t upmost;
- } l;
- struct {
- uint64_t lower;
- uint64_t upper;
- } ll;
-#endif
-} CPU_QuadU;
-#endif
-
-/* CPU memory access without any memory or io remapping */
-
-/*
- * the generic syntax for the memory accesses is:
- *
- * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
- *
- * store: st{type}{size}{endian}_{access_type}(ptr, val)
- *
- * type is:
- * (empty): integer access
- * f : float access
- *
- * sign is:
- * (empty): for floats or 32 bit size
- * u : unsigned
- * s : signed
- *
- * size is:
- * b: 8 bits
- * w: 16 bits
- * l: 32 bits
- * q: 64 bits
- *
- * endian is:
- * (empty): target cpu endianness or 8 bit access
- * r : reversed target cpu endianness (not implemented yet)
- * be : big endian (not implemented yet)
- * le : little endian (not implemented yet)
- *
- * access_type is:
- * raw : host memory access
- * user : user mode access using soft MMU
- * kernel : kernel mode access using soft MMU
- */
-static inline int ldub_p(void *ptr)
-{
- return *(uint8_t *)ptr;
-}
-
-static inline int ldsb_p(void *ptr)
-{
- return *(int8_t *)ptr;
-}
-
-static inline void stb_p(void *ptr, int v)
-{
- *(uint8_t *)ptr = v;
-}
-
-/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
- kernel handles unaligned load/stores may give better results, but
- it is a system wide setting : bad */
-#if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-/* conservative code for little endian unaligned accesses */
-static inline int lduw_le_p(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return val;
-#else
- uint8_t *p = ptr;
- return p[0] | (p[1] << 8);
-#endif
-}
-
-static inline int ldsw_le_p(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return (int16_t)val;
-#else
- uint8_t *p = ptr;
- return (int16_t)(p[0] | (p[1] << 8));
-#endif
-}
-
-static inline int ldl_le_p(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return val;
-#else
- uint8_t *p = ptr;
- return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-#endif
-}
-
-static inline uint64_t ldq_le_p(void *ptr)
-{
- uint8_t *p = ptr;
- uint32_t v1, v2;
- v1 = ldl_le_p(p);
- v2 = ldl_le_p(p + 4);
- return v1 | ((uint64_t)v2 << 32);
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
-#ifdef __powerpc__
- __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
-#else
- uint8_t *p = ptr;
- p[0] = v;
- p[1] = v >> 8;
-#endif
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
-#ifdef __powerpc__
- __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
-#else
- uint8_t *p = ptr;
- p[0] = v;
- p[1] = v >> 8;
- p[2] = v >> 16;
- p[3] = v >> 24;
-#endif
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
- uint8_t *p = ptr;
- stl_le_p(p, (uint32_t)v);
- stl_le_p(p + 4, v >> 32);
-}
-
-/* float access */
-
-static inline float32 ldfl_le_p(void *ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = ldl_le_p(ptr);
- return u.f;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- stl_le_p(ptr, u.i);
-}
-
-static inline float64 ldfq_le_p(void *ptr)
-{
- CPU_DoubleU u;
- u.l.lower = ldl_le_p(ptr);
- u.l.upper = ldl_le_p(ptr + 4);
- return u.d;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
- CPU_DoubleU u;
- u.d = v;
- stl_le_p(ptr, u.l.lower);
- stl_le_p(ptr + 4, u.l.upper);
-}
-
-#else
-
-static inline int lduw_le_p(void *ptr)
-{
- return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_le_p(void *ptr)
-{
- return *(int16_t *)ptr;
-}
-
-static inline int ldl_le_p(void *ptr)
-{
- return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_le_p(void *ptr)
-{
- return *(uint64_t *)ptr;
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
- *(uint16_t *)ptr = v;
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
- *(uint32_t *)ptr = v;
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
-#if defined(__i386__) && __GNUC__ >= 4
- const union { uint64_t v; uint32_t p[2]; } x = { .v = v };
- ((uint32_t *)ptr)[0] = x.p[0];
- ((uint32_t *)ptr)[1] = x.p[1];
-#else
- *(uint64_t *)ptr = v;
-#endif
-}
-
-/* float access */
-
-static inline float32 ldfl_le_p(void *ptr)
-{
- return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_le_p(void *ptr)
-{
- return *(float64 *)ptr;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
- *(float32 *)ptr = v;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
- *(float64 *)ptr = v;
-}
-#endif
-
-#if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-static inline int lduw_be_p(void *ptr)
-{
-#if defined(__i386__)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return ((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldsw_be_p(void *ptr)
-{
-#if defined(__i386__)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return (int16_t)val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (int16_t)((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldl_be_p(void *ptr)
-{
-#if defined(__i386__) || defined(__x86_64__)
- int val;
- asm volatile ("movl %1, %0\n"
- "bswap %0\n"
- : "=r" (val)
- : "m" (*(uint32_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-#endif
-}
-
-static inline uint64_t ldq_be_p(void *ptr)
-{
- uint32_t a,b;
- a = ldl_be_p(ptr);
- b = ldl_be_p((uint8_t *)ptr + 4);
- return (((uint64_t)a<<32)|b);
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
-#if defined(__i386__)
- asm volatile ("xchgb %b0, %h0\n"
- "movw %w0, %1\n"
- : "=q" (v)
- : "m" (*(uint16_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 8;
- d[1] = v;
-#endif
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- asm volatile ("bswap %0\n"
- "movl %0, %1\n"
- : "=r" (v)
- : "m" (*(uint32_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 24;
- d[1] = v >> 16;
- d[2] = v >> 8;
- d[3] = v;
-#endif
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
- stl_be_p(ptr, v >> 32);
- stl_be_p((uint8_t *)ptr + 4, v);
-}
-
-/* float access */
-
-static inline float32 ldfl_be_p(void *ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = ldl_be_p(ptr);
- return u.f;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- stl_be_p(ptr, u.i);
-}
-
-static inline float64 ldfq_be_p(void *ptr)
-{
- CPU_DoubleU u;
- u.l.upper = ldl_be_p(ptr);
- u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
- return u.d;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
- CPU_DoubleU u;
- u.d = v;
- stl_be_p(ptr, u.l.upper);
- stl_be_p((uint8_t *)ptr + 4, u.l.lower);
-}
-
-#else
-
-static inline int lduw_be_p(void *ptr)
-{
- return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_be_p(void *ptr)
-{
- return *(int16_t *)ptr;
-}
-
-static inline int ldl_be_p(void *ptr)
-{
- return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_be_p(void *ptr)
-{
- return *(uint64_t *)ptr;
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
- *(uint16_t *)ptr = v;
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
- *(uint32_t *)ptr = v;
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
- *(uint64_t *)ptr = v;
-}
-
-/* float access */
-
-static inline float32 ldfl_be_p(void *ptr)
-{
- return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_be_p(void *ptr)
-{
- return *(float64 *)ptr;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
- *(float32 *)ptr = v;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
- *(float64 *)ptr = v;
-}
-
-#endif
-
-/* target CPU memory access functions */
-#if defined(TARGET_WORDS_BIGENDIAN)
-#define lduw_p(p) lduw_be_p(p)
-#define ldsw_p(p) ldsw_be_p(p)
-#define ldl_p(p) ldl_be_p(p)
-#define ldq_p(p) ldq_be_p(p)
-#define ldfl_p(p) ldfl_be_p(p)
-#define ldfq_p(p) ldfq_be_p(p)
-#define stw_p(p, v) stw_be_p(p, v)
-#define stl_p(p, v) stl_be_p(p, v)
-#define stq_p(p, v) stq_be_p(p, v)
-#define stfl_p(p, v) stfl_be_p(p, v)
-#define stfq_p(p, v) stfq_be_p(p, v)
-#else
-#define lduw_p(p) lduw_le_p(p)
-#define ldsw_p(p) ldsw_le_p(p)
-#define ldl_p(p) ldl_le_p(p)
-#define ldq_p(p) ldq_le_p(p)
-#define ldfl_p(p) ldfl_le_p(p)
-#define ldfq_p(p) ldfq_le_p(p)
-#define stw_p(p, v) stw_le_p(p, v)
-#define stl_p(p, v) stl_le_p(p, v)
-#define stq_p(p, v) stq_le_p(p, v)
-#define stfl_p(p, v) stfl_le_p(p, v)
-#define stfq_p(p, v) stfq_le_p(p, v)
-#endif
-
-/* MMU memory access macros */
-
-#if defined(CONFIG_USER_ONLY)
-/* On some host systems the guest address space is reserved on the host.
- * This allows the guest address space to be offset to a convenient location.
- */
-//#define GUEST_BASE 0x20000000
-#define GUEST_BASE 0
-
-/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
-#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
-#define h2g(x) ((target_ulong)((unsigned long)(x) - GUEST_BASE))
-
-#define saddr(x) g2h(x)
-#define laddr(x) g2h(x)
-
-#else /* !CONFIG_USER_ONLY */
-/* NOTE: we use double casts if pointers and target_ulong have
- different sizes */
-#define saddr(x) (uint8_t *)(long)(x)
-#define laddr(x) (uint8_t *)(long)(x)
-#endif
-
-#define ldub_raw(p) ldub_p(laddr((p)))
-#define ldsb_raw(p) ldsb_p(laddr((p)))
-#define lduw_raw(p) lduw_p(laddr((p)))
-#define ldsw_raw(p) ldsw_p(laddr((p)))
-#define ldl_raw(p) ldl_p(laddr((p)))
-#define ldq_raw(p) ldq_p(laddr((p)))
-#define ldfl_raw(p) ldfl_p(laddr((p)))
-#define ldfq_raw(p) ldfq_p(laddr((p)))
-#define stb_raw(p, v) stb_p(saddr((p)), v)
-#define stw_raw(p, v) stw_p(saddr((p)), v)
-#define stl_raw(p, v) stl_p(saddr((p)), v)
-#define stq_raw(p, v) stq_p(saddr((p)), v)
-#define stfl_raw(p, v) stfl_p(saddr((p)), v)
-#define stfq_raw(p, v) stfq_p(saddr((p)), v)
-
-
-#if defined(CONFIG_USER_ONLY)
-
-/* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
-
-#define ldub_code(p) ldub_raw(p)
-#define ldsb_code(p) ldsb_raw(p)
-#define lduw_code(p) lduw_raw(p)
-#define ldsw_code(p) ldsw_raw(p)
-#define ldl_code(p) ldl_raw(p)
-#define ldq_code(p) ldq_raw(p)
-
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldq_kernel(p) ldq_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
-
-#endif /* defined(CONFIG_USER_ONLY) */
-
-/* page related stuff */
-
-#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
-#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
-#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
-
-/* ??? These should be the larger of unsigned long and target_ulong. */
-extern unsigned long qemu_real_host_page_size;
-extern unsigned long qemu_host_page_bits;
-extern unsigned long qemu_host_page_size;
-extern unsigned long qemu_host_page_mask;
-
-#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
-
-/* same as PROT_xxx */
-#define PAGE_READ 0x0001
-#define PAGE_WRITE 0x0002
-#define PAGE_EXEC 0x0004
-#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
-#define PAGE_VALID 0x0008
-/* original state of the write flag (used when tracking self-modifying
- code */
-#define PAGE_WRITE_ORG 0x0010
-#define PAGE_RESERVED 0x0020
-
-void page_dump(FILE *f);
-int page_get_flags(target_ulong address);
-void page_set_flags(target_ulong start, target_ulong end, int flags);
-int page_check_range(target_ulong start, target_ulong len, int flags);
-
-void cpu_exec_init_all(unsigned long tb_size);
-CPUState *cpu_copy(CPUState *env);
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags);
-void cpu_dump_statistics (CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags);
-
-void cpu_abort(CPUState *env, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)))
- __attribute__ ((__noreturn__));
-extern CPUState *first_cpu;
-extern CPUState *cpu_single_env;
-extern int64_t qemu_icount;
-extern int use_icount;
-
-#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
-#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
-#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
-#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
-#define CPU_INTERRUPT_FIQ 0x10 /* Fast interrupt pending. */
-#define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */
-#define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */
-#define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */
-#define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */
-#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */
-
-void cpu_interrupt(CPUState *s, int mask);
-void cpu_reset_interrupt(CPUState *env, int mask);
-
-int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type);
-int cpu_watchpoint_remove(CPUState *env, target_ulong addr);
-void cpu_watchpoint_remove_all(CPUState *env);
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
-void cpu_breakpoint_remove_all(CPUState *env);
-
-#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
-#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
-#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
-
-void cpu_single_step(CPUState *env, int enabled);
-void cpu_reset(CPUState *s);
-
-/* Return the physical page corresponding to a virtual one. Use it
- only for debugging because no protection checks are done. Return -1
- if no page found. */
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
-
-#define CPU_LOG_TB_OUT_ASM (1 << 0)
-#define CPU_LOG_TB_IN_ASM (1 << 1)
-#define CPU_LOG_TB_OP (1 << 2)
-#define CPU_LOG_TB_OP_OPT (1 << 3)
-#define CPU_LOG_INT (1 << 4)
-#define CPU_LOG_EXEC (1 << 5)
-#define CPU_LOG_PCALL (1 << 6)
-#define CPU_LOG_IOPORT (1 << 7)
-#define CPU_LOG_TB_CPU (1 << 8)
-
-/* define log items */
-typedef struct CPULogItem {
- int mask;
- const char *name;
- const char *help;
-} CPULogItem;
-
-extern CPULogItem cpu_log_items[];
-
-void cpu_set_log(int log_flags);
-void cpu_set_log_filename(const char *filename);
-int cpu_str_to_log_mask(const char *str);
-
-/* IO ports API */
-
-/* NOTE: as these functions may be even used when there is an isa
- brige on non x86 targets, we always defined them */
-#ifndef NO_CPU_IO_DEFS
-void cpu_outb(CPUState *env, int addr, int val);
-void cpu_outw(CPUState *env, int addr, int val);
-void cpu_outl(CPUState *env, int addr, int val);
-int cpu_inb(CPUState *env, int addr);
-int cpu_inw(CPUState *env, int addr);
-int cpu_inl(CPUState *env, int addr);
-#endif
-
-/* address in the RAM (different from a physical address) */
-#ifdef USE_KQEMU
-typedef uint32_t ram_addr_t;
-#else
-typedef unsigned long ram_addr_t;
-#endif
-
-/* memory API */
-
-extern ram_addr_t phys_ram_size;
-extern int phys_ram_fd;
-extern uint8_t *phys_ram_base;
-extern uint8_t *phys_ram_dirty;
-extern ram_addr_t ram_size;
-
-/* physical memory access */
-
-/* MMIO pages are identified by a combination of an IO device index and
- 3 flags. The ROMD code stores the page ram offset in iotlb entry,
- so only a limited number of ids are avaiable. */
-
-#define IO_MEM_SHIFT 3
-#define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT))
-
-#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
-#define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT)
-
-/* Acts like a ROM when read and like a device when written. */
-#define IO_MEM_ROMD (1)
-#define IO_MEM_SUBPAGE (2)
-#define IO_MEM_SUBWIDTH (4)
-
-/* Flags stored in the low bits of the TLB virtual address. These are
- defined so that fast path ram access is all zeros. */
-/* Zero if TLB entry is valid. */
-#define TLB_INVALID_MASK (1 << 3)
-/* Set if TLB entry references a clean RAM page. The iotlb entry will
- contain the page physical address. */
-#define TLB_NOTDIRTY (1 << 4)
-/* Set if TLB entry is an IO callback. */
-#define TLB_MMIO (1 << 5)
-
-typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
-
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- ram_addr_t size,
- ram_addr_t phys_offset);
-ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
-ram_addr_t qemu_ram_alloc(ram_addr_t);
-void qemu_ram_free(ram_addr_t addr);
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque);
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
-
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write);
-static inline void cpu_physical_memory_read(target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- cpu_physical_memory_rw(addr, buf, len, 0);
-}
-static inline void cpu_physical_memory_write(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-{
- cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
-}
-uint32_t ldub_phys(target_phys_addr_t addr);
-uint32_t lduw_phys(target_phys_addr_t addr);
-uint32_t ldl_phys(target_phys_addr_t addr);
-uint64_t ldq_phys(target_phys_addr_t addr);
-void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
-void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
-void stb_phys(target_phys_addr_t addr, uint32_t val);
-void stw_phys(target_phys_addr_t addr, uint32_t val);
-void stl_phys(target_phys_addr_t addr, uint32_t val);
-void stq_phys(target_phys_addr_t addr, uint64_t val);
-
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
- const uint8_t *buf, int len);
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write);
-
-#define VGA_DIRTY_FLAG 0x01
-#define CODE_DIRTY_FLAG 0x02
-
-/* read dirty bit (return 0 or 1) */
-static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
-{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
-}
-
-static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
- int dirty_flags)
-{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
-}
-
-static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
-{
- phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
-}
-
-void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
- int dirty_flags);
-void cpu_tlb_update_dirty(CPUState *env);
-
-void dump_exec_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
-
-/*******************************************/
-/* host CPU ticks (if available) */
-
-#if defined(__powerpc__)
-
-static inline uint32_t get_tbl(void)
-{
- uint32_t tbl;
- asm volatile("mftb %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline uint32_t get_tbu(void)
-{
- uint32_t tbl;
- asm volatile("mftbu %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t l, h, h1;
- /* NOTE: we test if wrapping has occurred */
- do {
- h = get_tbu();
- l = get_tbl();
- h1 = get_tbu();
- } while (h != h1);
- return ((int64_t)h << 32) | l;
-}
-
-#elif defined(__i386__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
-}
-
-#elif defined(__x86_64__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t low,high;
- int64_t val;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- val = high;
- val <<= 32;
- val |= low;
- return val;
-}
-
-#elif defined(__hppa__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int val;
- asm volatile ("mfctl %%cr16, %0" : "=r"(val));
- return val;
-}
-
-#elif defined(__ia64)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
- return val;
-}
-
-#elif defined(__s390__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
- return val;
-}
-
-#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
-
-static inline int64_t cpu_get_real_ticks (void)
-{
-#if defined(_LP64)
- uint64_t rval;
- asm volatile("rd %%tick,%0" : "=r"(rval));
- return rval;
-#else
- union {
- uint64_t i64;
- struct {
- uint32_t high;
- uint32_t low;
- } i32;
- } rval;
- asm volatile("rd %%tick,%1; srlx %1,32,%0"
- : "=r"(rval.i32.high), "=r"(rval.i32.low));
- return rval.i64;
-#endif
-}
-
-#elif defined(__mips__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
-#if __mips_isa_rev >= 2
- uint32_t count;
- static uint32_t cyc_per_count = 0;
-
- if (!cyc_per_count)
- __asm__ __volatile__("rdhwr %0, $3" : "=r" (cyc_per_count));
-
- __asm__ __volatile__("rdhwr %1, $2" : "=r" (count));
- return (int64_t)(count * cyc_per_count);
-#else
- /* FIXME */
- static int64_t ticks = 0;
- return ticks++;
-#endif
-}
-
-#else
-/* The host CPU doesn't have an easily accessible cycle counter.
- Just return a monotonically increasing value. This will be
- totally wrong, but hopefully better than nothing. */
-static inline int64_t cpu_get_real_ticks (void)
-{
- static int64_t ticks = 0;
- return ticks++;
-}
-#endif
-
-/* profiling */
-#ifdef CONFIG_PROFILER
-static inline int64_t profile_getclock(void)
-{
- return cpu_get_real_ticks();
-}
-
-extern int64_t kqemu_time, kqemu_time_start;
-extern int64_t qemu_time, qemu_time_start;
-extern int64_t tlb_flush_time;
-extern int64_t kqemu_exec_count;
-extern int64_t dev_time;
-extern int64_t kqemu_ret_int_count;
-extern int64_t kqemu_ret_excp_count;
-extern int64_t kqemu_ret_intr_count;
-#endif
-
-#endif /* CPU_ALL_H */
diff --git a/cpu-defs.h b/cpu-defs.h
deleted file mode 100644
index 108d395..0000000
--- a/cpu-defs.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * common defines for all CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_DEFS_H
-#define CPU_DEFS_H
-
-#include "config.h"
-#include <setjmp.h>
-#include <inttypes.h>
-#include "osdep.h"
-
-#ifndef TARGET_LONG_BITS
-#error TARGET_LONG_BITS must be defined before including this header
-#endif
-
-#ifndef TARGET_PHYS_ADDR_BITS
-#if TARGET_LONG_BITS >= HOST_LONG_BITS
-#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
-#else
-#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
-#endif
-#endif
-
-#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
-
-/* target_ulong is the type of a virtual address */
-#if TARGET_LONG_SIZE == 4
-typedef int32_t target_long;
-typedef uint32_t target_ulong;
-#define TARGET_FMT_lx "%08x"
-#define TARGET_FMT_ld "%d"
-#define TARGET_FMT_lu "%u"
-#elif TARGET_LONG_SIZE == 8
-typedef int64_t target_long;
-typedef uint64_t target_ulong;
-#define TARGET_FMT_lx "%016" PRIx64
-#define TARGET_FMT_ld "%" PRId64
-#define TARGET_FMT_lu "%" PRIu64
-#else
-#error TARGET_LONG_SIZE undefined
-#endif
-
-/* target_phys_addr_t is the type of a physical address (its size can
- be different from 'target_ulong'). We have sizeof(target_phys_addr)
- = max(sizeof(unsigned long),
- sizeof(size_of_target_physical_address)) because we must pass a
- host pointer to memory operations in some cases */
-
-#if TARGET_PHYS_ADDR_BITS == 32
-typedef uint32_t target_phys_addr_t;
-#define TARGET_FMT_plx "%08x"
-#elif TARGET_PHYS_ADDR_BITS == 64
-typedef uint64_t target_phys_addr_t;
-#define TARGET_FMT_plx "%016" PRIx64
-#else
-#error TARGET_PHYS_ADDR_BITS undefined
-#endif
-
-#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
-
-#define EXCP_INTERRUPT 0x10000 /* async interruption */
-#define EXCP_HLT 0x10001 /* hlt instruction reached */
-#define EXCP_DEBUG 0x10002 /* cpu stopped after a breakpoint or singlestep */
-#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
-#define MAX_BREAKPOINTS 32
-#define MAX_WATCHPOINTS 32
-
-#define TB_JMP_CACHE_BITS 12
-#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
-
-/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
- addresses on the same page. The top bits are the same. This allows
- TLB invalidation to quickly clear a subset of the hash table. */
-#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2)
-#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS)
-#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1)
-#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE)
-
-#define CPU_TLB_BITS 8
-#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
-
-#if TARGET_PHYS_ADDR_BITS == 32 && TARGET_LONG_BITS == 32
-#define CPU_TLB_ENTRY_BITS 4
-#else
-#define CPU_TLB_ENTRY_BITS 5
-#endif
-
-typedef struct CPUTLBEntry {
- /* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address
- bit TARGET_PAGE_BITS-1..4 : Nonzero for accesses that should not
- go directly to ram.
- bit 3 : indicates that the entry is invalid
- bit 2..0 : zero
- */
- target_ulong addr_read;
- target_ulong addr_write;
- target_ulong addr_code;
- /* Addend to virtual address to get physical address. IO accesses
- use the correcponding iotlb value. */
-#if TARGET_PHYS_ADDR_BITS == 64
- /* on i386 Linux make sure it is aligned */
- target_phys_addr_t addend __attribute__((aligned(8)));
-#else
- target_phys_addr_t addend;
-#endif
- /* padding to get a power of two size */
- uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -
- (sizeof(target_ulong) * 3 +
- ((-sizeof(target_ulong) * 3) & (sizeof(target_phys_addr_t) - 1)) +
- sizeof(target_phys_addr_t))];
-} CPUTLBEntry;
-
-#ifdef WORDS_BIGENDIAN
-typedef struct icount_decr_u16 {
- uint16_t high;
- uint16_t low;
-} icount_decr_u16;
-#else
-typedef struct icount_decr_u16 {
- uint16_t low;
- uint16_t high;
-} icount_decr_u16;
-#endif
-
-#define CPU_TEMP_BUF_NLONGS 128
-#define CPU_COMMON \
- struct TranslationBlock *current_tb; /* currently executing TB */ \
- /* soft mmu support */ \
- /* in order to avoid passing too many arguments to the MMIO \
- helpers, we store some rarely used information in the CPU \
- context) */ \
- unsigned long mem_io_pc; /* host pc at which the memory was \
- accessed */ \
- target_ulong mem_io_vaddr; /* target virtual addr at which the \
- memory was accessed */ \
- uint32_t halted; /* Nonzero if the CPU is in suspend state */ \
- uint32_t interrupt_request; \
- /* The meaning of the MMU modes is defined in the target code. */ \
- CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
- target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \
- struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
- /* buffer for temporaries in the code generator */ \
- long temp_buf[CPU_TEMP_BUF_NLONGS]; \
- \
- int64_t icount_extra; /* Instructions until next timer event. */ \
- /* Number of cycles left, with interrupt flag in high bit. \
- This allows a single read-compare-cbranch-write sequence to test \
- for both decrementer underflow and exceptions. */ \
- union { \
- uint32_t u32; \
- icount_decr_u16 u16; \
- } icount_decr; \
- uint32_t can_do_io; /* nonzero if memory mapped IO is safe. */ \
- \
- /* from this point: preserved by CPU reset */ \
- /* ice debug support */ \
- target_ulong breakpoints[MAX_BREAKPOINTS]; \
- int nb_breakpoints; \
- int singlestep_enabled; \
- \
- struct { \
- target_ulong vaddr; \
- int type; /* PAGE_READ/PAGE_WRITE */ \
- } watchpoint[MAX_WATCHPOINTS]; \
- int nb_watchpoints; \
- int watchpoint_hit; \
- \
- /* Core interrupt code */ \
- jmp_buf jmp_env; \
- int exception_index; \
- \
- int user_mode_only; \
- \
- void *next_cpu; /* next CPU sharing TB cache */ \
- int cpu_index; /* CPU index (informative) */ \
- int running; /* Nonzero if cpu is currently running(usermode). */ \
- /* user data */ \
- void *opaque; \
- \
- const char *cpu_model_str;
-
-#endif
diff --git a/cpu-exec.c b/cpu-exec.c
deleted file mode 100644
index 8637e2a..0000000
--- a/cpu-exec.c
+++ /dev/null
@@ -1,1487 +0,0 @@
-/*
- * i386 emulator main execution loop
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#define CPU_NO_GLOBAL_REGS
-#include "exec.h"
-#include "disas.h"
-#include "tcg.h"
-
-#if !defined(CONFIG_SOFTMMU)
-#undef EAX
-#undef ECX
-#undef EDX
-#undef EBX
-#undef ESP
-#undef EBP
-#undef ESI
-#undef EDI
-#undef EIP
-#include <signal.h>
-#include <sys/ucontext.h>
-#endif
-
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-// Work around ugly bugs in glibc that mangle global register contents
-#undef env
-#define env cpu_single_env
-#endif
-
-int tb_invalidated_flag;
-
-//#define DEBUG_EXEC
-//#define DEBUG_SIGNAL
-
-void cpu_loop_exit(void)
-{
- /* NOTE: the register at this point must be saved by hand because
- longjmp restore them */
- regs_to_env();
- longjmp(env->jmp_env, 1);
-}
-
-#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
-#define reg_T2
-#endif
-
-/* exit the current TB from a signal handler. The host registers are
- restored in a state compatible with the CPU emulator
- */
-void cpu_resume_from_signal(CPUState *env1, void *puc)
-{
-#if !defined(CONFIG_SOFTMMU)
- struct ucontext *uc = puc;
-#endif
-
- env = env1;
-
- /* XXX: restore cpu registers saved in host registers */
-
-#if !defined(CONFIG_SOFTMMU)
- if (puc) {
- /* XXX: use siglongjmp ? */
- sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
- }
-#endif
- longjmp(env->jmp_env, 1);
-}
-
-/* Execute the code without caching the generated code. An interpreter
- could be used if available. */
-static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
-{
- unsigned long next_tb;
- TranslationBlock *tb;
-
- /* Should never happen.
- We only end up here when an existing TB is too long. */
- if (max_cycles > CF_COUNT_MASK)
- max_cycles = CF_COUNT_MASK;
-
- tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
- max_cycles);
- env->current_tb = tb;
- /* execute the generated code */
- next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
-
- if ((next_tb & 3) == 2) {
- /* Restore PC. This may happen if async event occurs before
- the TB starts executing. */
- CPU_PC_FROM_TB(env, tb);
- }
- tb_phys_invalidate(tb, -1);
- tb_free(tb);
-}
-
-static TranslationBlock *tb_find_slow(target_ulong pc,
- target_ulong cs_base,
- uint64_t flags)
-{
- TranslationBlock *tb, **ptb1;
- unsigned int h;
- target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
-
- tb_invalidated_flag = 0;
-
- regs_to_env(); /* XXX: do it just before cpu_gen_code() */
-
- /* find translated block using physical mappings */
- phys_pc = get_phys_addr_code(env, pc);
- phys_page1 = phys_pc & TARGET_PAGE_MASK;
- phys_page2 = -1;
- h = tb_phys_hash_func(phys_pc);
- ptb1 = &tb_phys_hash[h];
- for(;;) {
- tb = *ptb1;
- if (!tb)
- goto not_found;
- if (tb->pc == pc &&
- tb->page_addr[0] == phys_page1 &&
- tb->cs_base == cs_base &&
- tb->flags == flags) {
- /* check next page if needed */
- if (tb->page_addr[1] != -1) {
- virt_page2 = (pc & TARGET_PAGE_MASK) +
- TARGET_PAGE_SIZE;
- phys_page2 = get_phys_addr_code(env, virt_page2);
- if (tb->page_addr[1] == phys_page2)
- goto found;
- } else {
- goto found;
- }
- }
- ptb1 = &tb->phys_hash_next;
- }
- not_found:
- /* if no translated code available, then translate it now */
- tb = tb_gen_code(env, pc, cs_base, flags, 0);
-
- found:
- /* we add the TB in the virtual pc hash table */
- env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
- return tb;
-}
-
-static inline TranslationBlock *tb_find_fast(void)
-{
- TranslationBlock *tb;
- target_ulong cs_base, pc;
- uint64_t flags;
-
- /* we record a subset of the CPU state. It will
- always be the same before a given translated block
- is executed. */
-#if defined(TARGET_I386)
- flags = env->hflags;
- flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- cs_base = env->segs[R_CS].base;
- pc = cs_base + env->eip;
-#elif defined(TARGET_ARM)
- flags = env->thumb | (env->vfp.vec_len << 1)
- | (env->vfp.vec_stride << 4);
- if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
- flags |= (1 << 6);
- if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
- flags |= (1 << 7);
- flags |= (env->condexec_bits << 8);
- cs_base = 0;
- pc = env->regs[15];
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
- // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- flags = ((env->pstate & PS_AM) << 2)
- | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
- | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
-#else
- // FPU enable . Supervisor
- flags = (env->psref << 4) | env->psrs;
-#endif
- cs_base = env->npc;
- pc = env->pc;
-#elif defined(TARGET_PPC)
- flags = env->hflags;
- cs_base = 0;
- pc = env->nip;
-#elif defined(TARGET_MIPS)
- flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
- cs_base = 0;
- pc = env->active_tc.PC;
-#elif defined(TARGET_M68K)
- flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
- | (env->sr & SR_S) /* Bit 13 */
- | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_SH4)
- flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
- | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */
- | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
- | (env->sr & (SR_MD | SR_RB)); /* Bits 29-30 */
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_ALPHA)
- flags = env->ps;
- cs_base = 0;
- pc = env->pc;
-#elif defined(TARGET_CRIS)
- flags = env->pregs[PR_CCS] & (P_FLAG | U_FLAG | X_FLAG);
- flags |= env->dslot;
- cs_base = 0;
- pc = env->pc;
-#else
-#error unsupported CPU
-#endif
- tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
- if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
- tb->flags != flags)) {
- tb = tb_find_slow(pc, cs_base, flags);
- }
- return tb;
-}
-
-/* main execution loop */
-
-int cpu_exec(CPUState *env1)
-{
-#define DECLARE_HOST_REGS 1
-#include "hostregs_helper.h"
- int ret, interrupt_request;
- TranslationBlock *tb;
- uint8_t *tc_ptr;
- unsigned long next_tb;
-
- if (cpu_halted(env1) == EXCP_HALTED)
- return EXCP_HALTED;
-
- cpu_single_env = env1;
-
- /* first we save global registers */
-#define SAVE_HOST_REGS 1
-#include "hostregs_helper.h"
- env = env1;
-
- env_to_regs();
-#if defined(TARGET_I386)
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_SPARC)
-#elif defined(TARGET_M68K)
- env->cc_op = CC_OP_FLAGS;
- env->cc_dest = env->sr & 0xf;
- env->cc_x = (env->sr >> 4) & 1;
-#elif defined(TARGET_ALPHA)
-#elif defined(TARGET_ARM)
-#elif defined(TARGET_PPC)
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_SH4)
-#elif defined(TARGET_CRIS)
- /* XXXXX */
-#else
-#error unsupported target CPU
-#endif
- env->exception_index = -1;
-
- /* prepare setjmp context for exception handling */
- for(;;) {
- if (setjmp(env->jmp_env) == 0) {
- env->current_tb = NULL;
- /* if an exception is pending, we execute it here */
- if (env->exception_index >= 0) {
- if (env->exception_index >= EXCP_INTERRUPT) {
- /* exit request from the cpu execution loop */
- ret = env->exception_index;
- break;
- } else if (env->user_mode_only) {
- /* if user mode only, we simulate a fake exception
- which will be handled outside the cpu execution
- loop */
-#if defined(TARGET_I386)
- do_interrupt_user(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip);
- /* successfully delivered */
- env->old_exception = -1;
-#endif
- ret = env->exception_index;
- break;
- } else {
-#if defined(TARGET_I386)
- /* simulate a real cpu exception. On i386, it can
- trigger new exceptions, but we do not handle
- double or triple faults yet. */
- do_interrupt(env->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
- /* successfully delivered */
- env->old_exception = -1;
-#elif defined(TARGET_PPC)
- do_interrupt(env);
-#elif defined(TARGET_MIPS)
- do_interrupt(env);
-#elif defined(TARGET_SPARC)
- do_interrupt(env);
-#elif defined(TARGET_ARM)
- do_interrupt(env);
-#elif defined(TARGET_SH4)
- do_interrupt(env);
-#elif defined(TARGET_ALPHA)
- do_interrupt(env);
-#elif defined(TARGET_CRIS)
- do_interrupt(env);
-#elif defined(TARGET_M68K)
- do_interrupt(0);
-#endif
- }
- env->exception_index = -1;
- }
-#ifdef USE_KQEMU
- if (kqemu_is_ok(env) && env->interrupt_request == 0) {
- int ret;
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- ret = kqemu_cpu_exec(env);
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- if (ret == 1) {
- /* exception */
- longjmp(env->jmp_env, 1);
- } else if (ret == 2) {
- /* softmmu execution needed */
- } else {
- if (env->interrupt_request != 0) {
- /* hardware interrupt will be executed just after */
- } else {
- /* otherwise, we restart */
- longjmp(env->jmp_env, 1);
- }
- }
- }
-#endif
-
- next_tb = 0; /* force lookup of first TB */
- for(;;) {
- interrupt_request = env->interrupt_request;
- if (unlikely(interrupt_request) &&
- likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) {
- if (interrupt_request & CPU_INTERRUPT_DEBUG) {
- env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
- env->exception_index = EXCP_DEBUG;
- cpu_loop_exit();
- }
-#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
- defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
- if (interrupt_request & CPU_INTERRUPT_HALT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HALT;
- env->halted = 1;
- env->exception_index = EXCP_HLT;
- cpu_loop_exit();
- }
-#endif
-#if defined(TARGET_I386)
- if (env->hflags2 & HF2_GIF_MASK) {
- if ((interrupt_request & CPU_INTERRUPT_SMI) &&
- !(env->hflags & HF_SMM_MASK)) {
- svm_check_intercept(SVM_EXIT_SMI);
- env->interrupt_request &= ~CPU_INTERRUPT_SMI;
- do_smm_enter();
- next_tb = 0;
- } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
- !(env->hflags2 & HF2_NMI_MASK)) {
- env->interrupt_request &= ~CPU_INTERRUPT_NMI;
- env->hflags2 |= HF2_NMI_MASK;
- do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
- next_tb = 0;
- } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (((env->hflags2 & HF2_VINTR_MASK) &&
- (env->hflags2 & HF2_HIF_MASK)) ||
- (!(env->hflags2 & HF2_VINTR_MASK) &&
- (env->eflags & IF_MASK &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
- int intno;
- svm_check_intercept(SVM_EXIT_INTR);
- env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
- intno = cpu_get_pic_interrupt(env);
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
- }
- do_interrupt(intno, 0, 0, 0, 1);
- /* ensure that no TB jump will be modified as
- the program flow was changed */
- next_tb = 0;
-#if !defined(CONFIG_USER_ONLY)
- } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
- (env->eflags & IF_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
- int intno;
- /* FIXME: this should respect TPR */
- svm_check_intercept(SVM_EXIT_VINTR);
- env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
- intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
- do_interrupt(intno, 0, 0, 0, 1);
- next_tb = 0;
-#endif
- }
- }
-#elif defined(TARGET_PPC)
-#if 0
- if ((interrupt_request & CPU_INTERRUPT_RESET)) {
- cpu_ppc_reset(env);
- }
-#endif
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- ppc_hw_interrupt(env);
- if (env->pending_interrupts == 0)
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- next_tb = 0;
- }
-#elif defined(TARGET_MIPS)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
- (env->CP0_Status & (1 << CP0St_IE)) &&
- !(env->CP0_Status & (1 << CP0St_EXL)) &&
- !(env->CP0_Status & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM)) {
- /* Raise it */
- env->exception_index = EXCP_EXT_INTERRUPT;
- env->error_code = 0;
- do_interrupt(env);
- next_tb = 0;
- }
-#elif defined(TARGET_SPARC)
- if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->psret != 0)) {
- int pil = env->interrupt_index & 15;
- int type = env->interrupt_index & 0xf0;
-
- if (((type == TT_EXTINT) &&
- (pil == 15 || pil > env->psrpil)) ||
- type != TT_EXTINT) {
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
- env->exception_index = env->interrupt_index;
- do_interrupt(env);
- env->interrupt_index = 0;
-#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
- cpu_check_irqs(env);
-#endif
- next_tb = 0;
- }
- } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
- //do_interrupt(0, 0, 0, 0, 0);
- env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
- }
-#elif defined(TARGET_ARM)
- if (interrupt_request & CPU_INTERRUPT_FIQ
- && !(env->uncached_cpsr & CPSR_F)) {
- env->exception_index = EXCP_FIQ;
- do_interrupt(env);
- next_tb = 0;
- }
- /* ARMv7-M interrupt return works by loading a magic value
- into the PC. On real hardware the load causes the
- return to occur. The qemu implementation performs the
- jump normally, then does the exception return when the
- CPU tries to execute code at the magic address.
- This will cause the magic PC value to be pushed to
- the stack if an interrupt occured at the wrong time.
- We avoid this by disabling interrupts when
- pc contains a magic address. */
- if (interrupt_request & CPU_INTERRUPT_HARD
- && ((IS_M(env) && env->regs[15] < 0xfffffff0)
- || !(env->uncached_cpsr & CPSR_I))) {
- env->exception_index = EXCP_IRQ;
- do_interrupt(env);
- next_tb = 0;
- }
-#elif defined(TARGET_SH4)
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- do_interrupt(env);
- next_tb = 0;
- }
-#elif defined(TARGET_ALPHA)
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- do_interrupt(env);
- next_tb = 0;
- }
-#elif defined(TARGET_CRIS)
- if (interrupt_request & CPU_INTERRUPT_HARD
- && (env->pregs[PR_CCS] & I_FLAG)) {
- env->exception_index = EXCP_IRQ;
- do_interrupt(env);
- next_tb = 0;
- }
- if (interrupt_request & CPU_INTERRUPT_NMI
- && (env->pregs[PR_CCS] & M_FLAG)) {
- env->exception_index = EXCP_NMI;
- do_interrupt(env);
- next_tb = 0;
- }
-#elif defined(TARGET_M68K)
- if (interrupt_request & CPU_INTERRUPT_HARD
- && ((env->sr & SR_I) >> SR_I_SHIFT)
- < env->pending_level) {
- /* Real hardware gets the interrupt vector via an
- IACK cycle at this point. Current emulated
- hardware doesn't rely on this, so we
- provide/save the vector when the interrupt is
- first signalled. */
- env->exception_index = env->pending_vector;
- do_interrupt(1);
- next_tb = 0;
- }
-#endif
- /* Don't use the cached interupt_request value,
- do_interrupt may have updated the EXITTB flag. */
- if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
- env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
- /* ensure that no TB jump will be modified as
- the program flow was changed */
- next_tb = 0;
- }
- if (interrupt_request & CPU_INTERRUPT_EXIT) {
- env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
- env->exception_index = EXCP_INTERRUPT;
- cpu_loop_exit();
- }
- }
-#ifdef DEBUG_EXEC
- if ((loglevel & CPU_LOG_TB_CPU)) {
- /* restore flags in standard format */
- regs_to_env();
-#if defined(TARGET_I386)
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-#elif defined(TARGET_ARM)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_SPARC)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_PPC)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_M68K)
- cpu_m68k_flush_flags(env, env->cc_op);
- env->cc_op = CC_OP_FLAGS;
- env->sr = (env->sr & 0xffe0)
- | env->cc_dest | (env->cc_x << 4);
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_MIPS)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_SH4)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_ALPHA)
- cpu_dump_state(env, logfile, fprintf, 0);
-#elif defined(TARGET_CRIS)
- cpu_dump_state(env, logfile, fprintf, 0);
-#else
-#error unsupported target CPU
-#endif
- }
-#endif
- spin_lock(&tb_lock);
- tb = tb_find_fast();
- /* Note: we do it here to avoid a gcc bug on Mac OS X when
- doing it in tb_find_slow */
- if (tb_invalidated_flag) {
- /* as some TB could have been invalidated because
- of memory exceptions while generating the code, we
- must recompute the hash index here */
- next_tb = 0;
- tb_invalidated_flag = 0;
- }
-#ifdef DEBUG_EXEC
- if ((loglevel & CPU_LOG_EXEC)) {
- fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
- (long)tb->tc_ptr, tb->pc,
- lookup_symbol(tb->pc));
- }
-#endif
- /* see if we can patch the calling TB. When the TB
- spans two pages, we cannot safely do a direct
- jump. */
- {
- if (next_tb != 0 &&
-#ifdef USE_KQEMU
- (env->kqemu_enabled != 2) &&
-#endif
- tb->page_addr[1] == -1) {
- tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
- }
- }
- spin_unlock(&tb_lock);
- env->current_tb = tb;
- while (env->current_tb) {
- tc_ptr = tb->tc_ptr;
- /* execute the generated code */
-#if defined(__sparc__) && !defined(HOST_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
- next_tb = tcg_qemu_tb_exec(tc_ptr);
- env->current_tb = NULL;
- if ((next_tb & 3) == 2) {
- /* Instruction counter expired. */
- int insns_left;
- tb = (TranslationBlock *)(long)(next_tb & ~3);
- /* Restore PC. */
- CPU_PC_FROM_TB(env, tb);
- insns_left = env->icount_decr.u32;
- if (env->icount_extra && insns_left >= 0) {
- /* Refill decrementer and continue execution. */
- env->icount_extra += insns_left;
- if (env->icount_extra > 0xffff) {
- insns_left = 0xffff;
- } else {
- insns_left = env->icount_extra;
- }
- env->icount_extra -= insns_left;
- env->icount_decr.u16.low = insns_left;
- } else {
- if (insns_left > 0) {
- /* Execute remaining instructions. */
- cpu_exec_nocache(insns_left, tb);
- }
- env->exception_index = EXCP_INTERRUPT;
- next_tb = 0;
- cpu_loop_exit();
- }
- }
- }
- /* reset soft MMU for next block (it can currently
- only be set by a memory fault) */
-#if defined(USE_KQEMU)
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
- if (kqemu_is_ok(env) &&
- (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
- cpu_loop_exit();
- }
-#endif
- } /* for(;;) */
- } else {
- env_to_regs();
- }
- } /* for(;;) */
-
-
-#if defined(TARGET_I386)
- /* restore flags in standard format */
- env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-#elif defined(TARGET_ARM)
- /* XXX: Save/restore host fpu exception state?. */
-#elif defined(TARGET_SPARC)
-#elif defined(TARGET_PPC)
-#elif defined(TARGET_M68K)
- cpu_m68k_flush_flags(env, env->cc_op);
- env->cc_op = CC_OP_FLAGS;
- env->sr = (env->sr & 0xffe0)
- | env->cc_dest | (env->cc_x << 4);
-#elif defined(TARGET_MIPS)
-#elif defined(TARGET_SH4)
-#elif defined(TARGET_ALPHA)
-#elif defined(TARGET_CRIS)
- /* XXXXX */
-#else
-#error unsupported target CPU
-#endif
-
- /* restore global registers */
-#include "hostregs_helper.h"
-
- /* fail safe : never use cpu_single_env outside cpu_exec() */
- cpu_single_env = NULL;
- return ret;
-}
-
-/* must only be called from the generated code as an exception can be
- generated */
-void tb_invalidate_page_range(target_ulong start, target_ulong end)
-{
- /* XXX: cannot enable it yet because it yields to MMU exception
- where NIP != read address on PowerPC */
-#if 0
- target_ulong phys_addr;
- phys_addr = get_phys_addr_code(env, start);
- tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
-#endif
-}
-
-#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
-
-void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
-{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
- if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
- selector &= 0xffff;
- cpu_x86_load_seg_cache(env, seg_reg, selector,
- (selector << 4), 0xffff, 0);
- } else {
- helper_load_seg(seg_reg, selector);
- }
- env = saved_env;
-}
-
-void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
-{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
-
- helper_fsave(ptr, data32);
-
- env = saved_env;
-}
-
-void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
-{
- CPUX86State *saved_env;
-
- saved_env = env;
- env = s;
-
- helper_frstor(ptr, data32);
-
- env = saved_env;
-}
-
-#endif /* TARGET_I386 */
-
-#if !defined(CONFIG_SOFTMMU)
-
-#if defined(TARGET_I386)
-
-/* 'pc' is the host PC at which the exception was raised. 'address' is
- the effective address of the memory exception. 'is_write' is 1 if a
- write caused the exception and otherwise 0'. 'old_set' is the
- signal set which should be restored */
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
- env->eip, env->cr[2], env->error_code);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- env->hflags |= HF_SOFTMMU_MASK;
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined(TARGET_ARM)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-#elif defined(TARGET_SPARC)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-#elif defined (TARGET_PPC)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined(TARGET_M68K)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(address, pc, puc)) {
- return 1;
- }
- /* see if it is an MMU fault */
- ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_MIPS)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- if (ret == 1) {
-#if 0
- printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
- env->PC, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- do_raise_exception_err(env->exception_index, env->error_code);
- } else {
- /* activate soft MMU for this block */
- cpu_resume_from_signal(env, puc);
- }
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_SH4)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-
-#elif defined (TARGET_ALPHA)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
-#if 0
- printf("PF exception: NIP=0x%08x error=0x%x %p\n",
- env->nip, env->error_code, tb);
-#endif
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-#elif defined (TARGET_CRIS)
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
- int is_write, sigset_t *old_set,
- void *puc)
-{
- TranslationBlock *tb;
- int ret;
-
- if (cpu_single_env)
- env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
- printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
- pc, address, is_write, *(unsigned long *)old_set);
-#endif
- /* XXX: locking issue */
- if (is_write && page_unprotect(h2g(address), pc, puc)) {
- return 1;
- }
-
- /* see if it is an MMU fault */
- ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
- if (ret < 0)
- return 0; /* not an MMU fault */
- if (ret == 0)
- return 1; /* the MMU fault was handled without causing real CPU fault */
-
- /* now we have a real cpu fault */
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, puc);
- }
- /* we restore the process signal mask as the sigreturn should
- do it (XXX: use sigsetjmp) */
- sigprocmask(SIG_SETMASK, old_set, NULL);
- cpu_loop_exit();
- /* never comes here */
- return 1;
-}
-
-#else
-#error unsupported target CPU
-#endif
-
-#if defined(__i386__)
-
-#if defined(__APPLE__)
-# include <sys/ucontext.h>
-
-# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
-# define TRAP_sig(context) ((context)->uc_mcontext->es.trapno)
-# define ERROR_sig(context) ((context)->uc_mcontext->es.err)
-#else
-# define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
-# define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
-# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int trapno;
-
-#ifndef REG_EIP
-/* for glibc 2.1 */
-#define REG_EIP EIP
-#define REG_ERR ERR
-#define REG_TRAPNO TRAPNO
-#endif
- pc = EIP_sig(uc);
- trapno = TRAP_sig(uc);
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- trapno == 0xe ?
- (ERROR_sig(uc) >> 1) & 1 : 0,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__x86_64__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
-
- pc = uc->uc_mcontext.gregs[REG_RIP];
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
- (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__powerpc__)
-
-/***********************************************************************
- * signal context platform-specific definitions
- * From Wine
- */
-#ifdef linux
-/* All Registers access - only for local access */
-# define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name)
-/* Gpr Registers access */
-# define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context)
-# define IAR_sig(context) REG_sig(nip, context) /* Program counter */
-# define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */
-# define CTR_sig(context) REG_sig(ctr, context) /* Count register */
-# define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */
-# define LR_sig(context) REG_sig(link, context) /* Link register */
-# define CR_sig(context) REG_sig(ccr, context) /* Condition register */
-/* Float Registers access */
-# define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
-# define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
-/* Exception Registers access */
-# define DAR_sig(context) REG_sig(dar, context)
-# define DSISR_sig(context) REG_sig(dsisr, context)
-# define TRAP_sig(context) REG_sig(trap, context)
-#endif /* linux */
-
-#ifdef __APPLE__
-# include <sys/ucontext.h>
-typedef struct ucontext SIGCONTEXT;
-/* All Registers access - only for local access */
-# define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name)
-# define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name)
-# define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name)
-# define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name)
-/* Gpr Registers access */
-# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
-# define IAR_sig(context) REG_sig(srr0, context) /* Program counter */
-# define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */
-# define CTR_sig(context) REG_sig(ctr, context)
-# define XER_sig(context) REG_sig(xer, context) /* Link register */
-# define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */
-# define CR_sig(context) REG_sig(cr, context) /* Condition register */
-/* Float Registers access */
-# define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context)
-# define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context))
-/* Exception Registers access */
-# define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */
-# define DSISR_sig(context) EXCEPREG_sig(dsisr, context)
-# define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
-#endif /* __APPLE__ */
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = IAR_sig(uc);
- is_write = 0;
-#if 0
- /* ppc 4xx case */
- if (DSISR_sig(uc) & 0x00800000)
- is_write = 1;
-#else
- if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
- is_write = 1;
-#endif
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__alpha__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- uint32_t *pc = uc->uc_mcontext.sc_pc;
- uint32_t insn = *pc;
- int is_write = 0;
-
- /* XXX: need kernel patch to get write flag faster */
- switch (insn >> 26) {
- case 0x0d: // stw
- case 0x0e: // stb
- case 0x0f: // stq_u
- case 0x24: // stf
- case 0x25: // stg
- case 0x26: // sts
- case 0x27: // stt
- case 0x2c: // stl
- case 0x2d: // stq
- case 0x2e: // stl_c
- case 0x2f: // stq_c
- is_write = 1;
- }
-
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, &uc->uc_sigmask, puc);
-}
-#elif defined(__sparc__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- int is_write;
- uint32_t insn;
-#if !defined(__arch64__) || defined(HOST_SOLARIS)
- uint32_t *regs = (uint32_t *)(info + 1);
- void *sigmask = (regs + 20);
- /* XXX: is there a standard glibc define ? */
- unsigned long pc = regs[1];
-#else
- struct sigcontext *sc = puc;
- unsigned long pc = sc->sigc_regs.tpc;
- void *sigmask = (void *)sc->sigc_mask;
-#endif
-
- /* XXX: need kernel patch to get write flag faster */
- is_write = 0;
- insn = *(uint32_t *)pc;
- if ((insn >> 30) == 3) {
- switch((insn >> 19) & 0x3f) {
- case 0x05: // stb
- case 0x06: // sth
- case 0x04: // st
- case 0x07: // std
- case 0x24: // stf
- case 0x27: // stdf
- case 0x25: // stfsr
- is_write = 1;
- break;
- }
- }
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, sigmask, NULL);
-}
-
-#elif defined(__arm__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
-#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
- pc = uc->uc_mcontext.gregs[R15];
-#else
- pc = uc->uc_mcontext.arm_pc;
-#endif
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__mc68000)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = uc->uc_mcontext.gregs[16];
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__ia64)
-
-#ifndef __ISR_VALID
- /* This ought to be in <bits/siginfo.h>... */
-# define __ISR_VALID 1
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long ip;
- int is_write = 0;
-
- ip = uc->uc_mcontext.sc_ip;
- switch (host_signum) {
- case SIGILL:
- case SIGFPE:
- case SIGSEGV:
- case SIGBUS:
- case SIGTRAP:
- if (info->si_code && (info->si_segvflags & __ISR_VALID))
- /* ISR.W (write-access) is bit 33: */
- is_write = (info->si_isr >> 33) & 1;
- break;
-
- default:
- break;
- }
- return handle_cpu_signal(ip, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#elif defined(__s390__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = uc->uc_mcontext.psw.addr;
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__mips__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- siginfo_t *info = pinfo;
- struct ucontext *uc = puc;
- greg_t pc = uc->uc_mcontext.pc;
- int is_write;
-
- /* XXX: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__hppa__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
- void *puc)
-{
- struct siginfo *info = pinfo;
- struct ucontext *uc = puc;
- unsigned long pc;
- int is_write;
-
- pc = uc->uc_mcontext.sc_iaoq[0];
- /* FIXME: compute is_write */
- is_write = 0;
- return handle_cpu_signal(pc, (unsigned long)info->si_addr,
- is_write,
- &uc->uc_sigmask, puc);
-}
-
-#else
-
-#error host CPU specific signal handler needed
-
-#endif
-
-#endif /* !defined(CONFIG_SOFTMMU) */
diff --git a/curses.c b/curses.c
deleted file mode 100644
index 96b6e49..0000000
--- a/curses.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * QEMU curses/ncurses display driver
- *
- * Copyright (c) 2005 Andrzej Zaborowski <balrog@zabor.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "console.h"
-#include "sysemu.h"
-
-#include <curses.h>
-
-#ifndef _WIN32
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#endif
-
-#ifdef __OpenBSD__
-#define resize_term resizeterm
-#endif
-
-#define FONT_HEIGHT 16
-#define FONT_WIDTH 8
-
-static console_ch_t screen[160 * 100];
-static WINDOW *screenpad = NULL;
-static int width, height, gwidth, gheight, invalidate;
-static int px, py, sminx, sminy, smaxx, smaxy;
-
-static void curses_update(DisplayState *ds, int x, int y, int w, int h)
-{
- chtype *line;
-
- line = ((chtype *) screen) + y * width;
- for (h += y; y < h; y ++, line += width)
- mvwaddchnstr(screenpad, y, 0, line, width);
-
- pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1);
- refresh();
-}
-
-static void curses_calc_pad(void)
-{
- if (is_graphic_console()) {
- width = gwidth;
- height = gheight;
- } else {
- width = COLS;
- height = LINES;
- }
-
- if (screenpad)
- delwin(screenpad);
-
- clear();
- refresh();
-
- screenpad = newpad(height, width);
-
- if (width > COLS) {
- px = (width - COLS) / 2;
- sminx = 0;
- smaxx = COLS;
- } else {
- px = 0;
- sminx = (COLS - width) / 2;
- smaxx = sminx + width;
- }
-
- if (height > LINES) {
- py = (height - LINES) / 2;
- sminy = 0;
- smaxy = LINES;
- } else {
- py = 0;
- sminy = (LINES - height) / 2;
- smaxy = sminy + height;
- }
-}
-
-static void curses_resize(DisplayState *ds, int w, int h)
-{
- if (w == gwidth && h == gheight)
- return;
-
- gwidth = w;
- gheight = h;
-
- curses_calc_pad();
-}
-
-#ifndef _WIN32
-#if defined(SIGWINCH) && defined(KEY_RESIZE)
-static void curses_winch_handler(int signum)
-{
- struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel; /* unused */
- unsigned short ws_ypixel; /* unused */
- } ws;
-
- /* terminal size changed */
- if (ioctl(1, TIOCGWINSZ, &ws) == -1)
- return;
-
- resize_term(ws.ws_row, ws.ws_col);
- curses_calc_pad();
- invalidate = 1;
-
- /* some systems require this */
- signal(SIGWINCH, curses_winch_handler);
-}
-#endif
-#endif
-
-static void curses_cursor_position(DisplayState *ds, int x, int y)
-{
- if (x >= 0) {
- x = sminx + x - px;
- y = sminy + y - py;
-
- if (x >= 0 && y >= 0 && x < COLS && y < LINES) {
- move(y, x);
- curs_set(1);
- /* it seems that curs_set(1) must always be called before
- * curs_set(2) for the latter to have effect */
- if (!is_graphic_console())
- curs_set(2);
- return;
- }
- }
-
- curs_set(0);
-}
-
-/* generic keyboard conversion */
-
-#include "curses_keys.h"
-#include "keymaps.c"
-
-static kbd_layout_t *kbd_layout = 0;
-static int keycode2keysym[CURSES_KEYS];
-
-static void curses_refresh(DisplayState *ds)
-{
- int chr, nextchr, keysym, keycode;
-
- if (invalidate) {
- clear();
- refresh();
- curses_calc_pad();
- ds->width = FONT_WIDTH * width;
- ds->height = FONT_HEIGHT * height;
- vga_hw_invalidate();
- invalidate = 0;
- }
-
- vga_hw_text_update(screen);
-
- nextchr = ERR;
- while (1) {
- /* while there are any pending key strokes to process */
- if (nextchr == ERR)
- chr = getch();
- else {
- chr = nextchr;
- nextchr = ERR;
- }
-
- if (chr == ERR)
- break;
-
-#ifdef KEY_RESIZE
- /* this shouldn't occur when we use a custom SIGWINCH handler */
- if (chr == KEY_RESIZE) {
- clear();
- refresh();
- curses_calc_pad();
- curses_update(ds, 0, 0, width, height);
- ds->width = FONT_WIDTH * width;
- ds->height = FONT_HEIGHT * height;
- continue;
- }
-#endif
-
- keycode = curses2keycode[chr];
- if (keycode == -1)
- continue;
-
- /* alt key */
- if (keycode == 1) {
- nextchr = getch();
-
- if (nextchr != ERR) {
- keycode = curses2keycode[nextchr];
- nextchr = ERR;
- if (keycode == -1)
- continue;
-
- keycode |= ALT;
-
- /* process keys reserved for qemu */
- if (keycode >= QEMU_KEY_CONSOLE0 &&
- keycode < QEMU_KEY_CONSOLE0 + 9) {
- erase();
- wnoutrefresh(stdscr);
- console_select(keycode - QEMU_KEY_CONSOLE0);
-
- invalidate = 1;
- continue;
- }
- }
- }
-
- if (kbd_layout && !(keycode & GREY)) {
- keysym = keycode2keysym[keycode & KEY_MASK];
- if (keysym == -1)
- keysym = chr;
-
- keycode &= ~KEY_MASK;
- keycode |= keysym2scancode(kbd_layout, keysym);
- }
-
- if (is_graphic_console()) {
- /* since terminals don't know about key press and release
- * events, we need to emit both for each key received */
- if (keycode & SHIFT)
- kbd_put_keycode(SHIFT_CODE);
- if (keycode & CNTRL)
- kbd_put_keycode(CNTRL_CODE);
- if (keycode & ALT)
- kbd_put_keycode(ALT_CODE);
- if (keycode & GREY)
- kbd_put_keycode(GREY_CODE);
- kbd_put_keycode(keycode & KEY_MASK);
- if (keycode & GREY)
- kbd_put_keycode(GREY_CODE);
- kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE);
- if (keycode & ALT)
- kbd_put_keycode(ALT_CODE | KEY_RELEASE);
- if (keycode & CNTRL)
- kbd_put_keycode(CNTRL_CODE | KEY_RELEASE);
- if (keycode & SHIFT)
- kbd_put_keycode(SHIFT_CODE | KEY_RELEASE);
- } else {
- keysym = curses2keysym[chr];
- if (keysym == -1)
- keysym = chr;
-
- kbd_put_keysym(keysym);
- }
- }
-}
-
-static void curses_cleanup(void *opaque)
-{
- endwin();
-}
-
-static void curses_atexit(void)
-{
- curses_cleanup(NULL);
-}
-
-static void curses_setup(void)
-{
- int i, colour_default[8] = {
- COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
- COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE,
- };
-
- /* input as raw as possible, let everything be interpreted
- * by the guest system */
- initscr(); noecho(); intrflush(stdscr, FALSE);
- nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
- start_color(); raw(); scrollok(stdscr, FALSE);
-
- for (i = 0; i < 64; i ++)
- init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
-}
-
-static void curses_keyboard_setup(void)
-{
- int i, keycode, keysym;
-
-#if defined(__APPLE__)
- /* always use generic keymaps */
- if (!keyboard_layout)
- keyboard_layout = "en-us";
-#endif
- if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(keyboard_layout);
- if (!kbd_layout)
- exit(1);
- }
-
- for (i = 0; i < CURSES_KEYS; i ++)
- keycode2keysym[i] = -1;
-
- for (i = 0; i < CURSES_KEYS; i ++) {
- if (curses2keycode[i] == -1)
- continue;
-
- keycode = curses2keycode[i] & KEY_MASK;
- if (keycode2keysym[keycode] >= 0)
- continue;
-
- for (keysym = 0; keysym < CURSES_KEYS; keysym ++)
- if (curses2keycode[keysym] == keycode) {
- keycode2keysym[keycode] = keysym;
- break;
- }
-
- if (keysym >= CURSES_KEYS)
- keycode2keysym[keycode] = i;
- }
-}
-
-void curses_display_init(DisplayState *ds, int full_screen)
-{
-#ifndef _WIN32
- if (!isatty(1)) {
- fprintf(stderr, "We need a terminal output\n");
- exit(1);
- }
-#endif
-
- curses_setup();
- curses_keyboard_setup();
- atexit(curses_atexit);
-
-#ifndef _WIN32
-#if defined(SIGWINCH) && defined(KEY_RESIZE)
- /* some curses implementations provide a handler, but we
- * want to be sure this is handled regardless of the library */
- signal(SIGWINCH, curses_winch_handler);
-#endif
-#endif
-
- ds->data = (void *) screen;
- ds->linesize = 0;
- ds->depth = 0;
- ds->width = 640;
- ds->height = 400;
- ds->dpy_update = curses_update;
- ds->dpy_resize = curses_resize;
- ds->dpy_refresh = curses_refresh;
- ds->dpy_text_cursor = curses_cursor_position;
-
- invalidate = 1;
-
- /* Standard VGA initial text mode dimensions */
- curses_resize(ds, 80, 25);
-}
diff --git a/curses_keys.h b/curses_keys.h
deleted file mode 100644
index 27f9cd8..0000000
--- a/curses_keys.h
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Keycode and keysyms conversion tables for curses
- *
- * Copyright (c) 2005 Andrzej Zaborowski <balrog@zabor.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define KEY_RELEASE 0x80
-#define KEY_MASK 0x7f
-#define SHIFT_CODE 0x2a
-#define SHIFT 0x0080
-#define GREY_CODE 0xe0
-#define GREY 0x0100
-#define CNTRL_CODE 0x1d
-#define CNTRL 0x0200
-#define ALT_CODE 0x38
-#define ALT 0x0400
-
-/* curses won't detect a Control + Alt + 1, so use Alt + 1 */
-#define QEMU_KEY_CONSOLE0 (2 | ALT) /* (curses2keycode['1'] | ALT) */
-
-#define CURSES_KEYS KEY_MAX /* KEY_MAX defined in <curses.h> */
-
-int curses2keycode[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
-
- [0x01b] = 1, /* Escape */
- ['1'] = 2,
- ['2'] = 3,
- ['3'] = 4,
- ['4'] = 5,
- ['5'] = 6,
- ['6'] = 7,
- ['7'] = 8,
- ['8'] = 9,
- ['9'] = 10,
- ['0'] = 11,
- ['-'] = 12,
- ['='] = 13,
- [0x07f] = 14, /* Backspace */
- [0x107] = 14, /* Backspace */
-
- ['\t'] = 15, /* Tab */
- ['q'] = 16,
- ['w'] = 17,
- ['e'] = 18,
- ['r'] = 19,
- ['t'] = 20,
- ['y'] = 21,
- ['u'] = 22,
- ['i'] = 23,
- ['o'] = 24,
- ['p'] = 25,
- ['['] = 26,
- [']'] = 27,
- ['\n'] = 28, /* Return */
- ['\r'] = 28, /* Return */
- [0x157] = 28, /* Return */
-
- ['a'] = 30,
- ['s'] = 31,
- ['d'] = 32,
- ['f'] = 33,
- ['g'] = 34,
- ['h'] = 35,
- ['j'] = 36,
- ['k'] = 37,
- ['l'] = 38,
- [';'] = 39,
- ['\''] = 40, /* Single quote */
- ['`'] = 41,
- ['\\'] = 43, /* Backslash */
-
- ['z'] = 44,
- ['x'] = 45,
- ['c'] = 46,
- ['v'] = 47,
- ['b'] = 48,
- ['n'] = 49,
- ['m'] = 50,
- [','] = 51,
- ['.'] = 52,
- ['/'] = 53,
-
- [' '] = 57,
-
- [0x109] = 59, /* Function Key 1 */
- [0x10a] = 60, /* Function Key 2 */
- [0x10b] = 61, /* Function Key 3 */
- [0x10c] = 62, /* Function Key 4 */
- [0x10d] = 63, /* Function Key 5 */
- [0x10e] = 64, /* Function Key 6 */
- [0x10f] = 65, /* Function Key 7 */
- [0x110] = 66, /* Function Key 8 */
- [0x111] = 67, /* Function Key 9 */
- [0x112] = 68, /* Function Key 10 */
- [0x113] = 87, /* Function Key 11 */
- [0x114] = 88, /* Function Key 12 */
-
- [0x106] = 71 | GREY, /* Home */
- [0x103] = 72 | GREY, /* Up Arrow */
- [0x153] = 73 | GREY, /* Page Up */
- [0x104] = 75 | GREY, /* Left Arrow */
- [0x105] = 77 | GREY, /* Right Arrow */
- [0x168] = 79 | GREY, /* End */
- [0x102] = 80 | GREY, /* Down Arrow */
- [0x152] = 81 | GREY, /* Page Down */
- [0x14b] = 82 | GREY, /* Insert */
- [0x14a] = 83 | GREY, /* Delete */
-
- ['!'] = 2 | SHIFT,
- ['@'] = 3 | SHIFT,
- ['#'] = 4 | SHIFT,
- ['$'] = 5 | SHIFT,
- ['%'] = 6 | SHIFT,
- ['^'] = 7 | SHIFT,
- ['&'] = 8 | SHIFT,
- ['*'] = 9 | SHIFT,
- ['('] = 10 | SHIFT,
- [')'] = 11 | SHIFT,
- ['_'] = 12 | SHIFT,
- ['+'] = 13 | SHIFT,
-
- [0x161] = 15 | SHIFT, /* Shift + Tab */
- ['Q'] = 16 | SHIFT,
- ['W'] = 17 | SHIFT,
- ['E'] = 18 | SHIFT,
- ['R'] = 19 | SHIFT,
- ['T'] = 20 | SHIFT,
- ['Y'] = 21 | SHIFT,
- ['U'] = 22 | SHIFT,
- ['I'] = 23 | SHIFT,
- ['O'] = 24 | SHIFT,
- ['P'] = 25 | SHIFT,
- ['{'] = 26 | SHIFT,
- ['}'] = 27 | SHIFT,
-
- ['A'] = 30 | SHIFT,
- ['S'] = 31 | SHIFT,
- ['D'] = 32 | SHIFT,
- ['F'] = 33 | SHIFT,
- ['G'] = 34 | SHIFT,
- ['H'] = 35 | SHIFT,
- ['J'] = 36 | SHIFT,
- ['K'] = 37 | SHIFT,
- ['L'] = 38 | SHIFT,
- [':'] = 39 | SHIFT,
- ['"'] = 40 | SHIFT,
- ['~'] = 41 | SHIFT,
- ['|'] = 43 | SHIFT,
-
- ['Z'] = 44 | SHIFT,
- ['X'] = 45 | SHIFT,
- ['C'] = 46 | SHIFT,
- ['V'] = 47 | SHIFT,
- ['B'] = 48 | SHIFT,
- ['N'] = 49 | SHIFT,
- ['M'] = 50 | SHIFT,
- ['<'] = 51 | SHIFT,
- ['>'] = 52 | SHIFT,
- ['?'] = 53 | SHIFT,
-
- [0x115] = 59 | SHIFT, /* Shift + Function Key 1 */
- [0x116] = 60 | SHIFT, /* Shift + Function Key 2 */
- [0x117] = 61 | SHIFT, /* Shift + Function Key 3 */
- [0x118] = 62 | SHIFT, /* Shift + Function Key 4 */
- [0x119] = 63 | SHIFT, /* Shift + Function Key 5 */
- [0x11a] = 64 | SHIFT, /* Shift + Function Key 6 */
- [0x11b] = 65 | SHIFT, /* Shift + Function Key 7 */
- [0x11c] = 66 | SHIFT, /* Shift + Function Key 8 */
-
- [0x011] = 16 | CNTRL, /* Control + q */
- [0x017] = 17 | CNTRL, /* Control + w */
- [0x005] = 18 | CNTRL, /* Control + e */
- [0x012] = 19 | CNTRL, /* Control + r */
- [0x014] = 20 | CNTRL, /* Control + t */
- [0x019] = 21 | CNTRL, /* Control + y */
- [0x015] = 22 | CNTRL, /* Control + u */
- [0x009] = 23 | CNTRL, /* Control + i */
- [0x00f] = 24 | CNTRL, /* Control + o */
- [0x010] = 25 | CNTRL, /* Control + p */
-
- [0x001] = 30 | CNTRL, /* Control + a */
- [0x013] = 31 | CNTRL, /* Control + s */
- [0x004] = 32 | CNTRL, /* Control + d */
- [0x006] = 33 | CNTRL, /* Control + f */
- [0x007] = 34 | CNTRL, /* Control + g */
- [0x008] = 35 | CNTRL, /* Control + h */
- [0x00a] = 36 | CNTRL, /* Control + j */
- [0x00b] = 37 | CNTRL, /* Control + k */
- [0x00c] = 38 | CNTRL, /* Control + l */
-
- [0x01a] = 44 | CNTRL, /* Control + z */
- [0x018] = 45 | CNTRL, /* Control + x */
- [0x003] = 46 | CNTRL, /* Control + c */
- [0x016] = 47 | CNTRL, /* Control + v */
- [0x002] = 48 | CNTRL, /* Control + b */
- [0x00e] = 49 | CNTRL, /* Control + n */
- /* Control + m collides with the keycode for Enter */
-
-};
-
-int curses2keysym[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
-
- ['\n'] = '\n',
- ['\r'] = '\n',
-
- [0x07f] = QEMU_KEY_BACKSPACE,
-
- [0x102] = QEMU_KEY_DOWN,
- [0x103] = QEMU_KEY_UP,
- [0x104] = QEMU_KEY_LEFT,
- [0x105] = QEMU_KEY_RIGHT,
- [0x106] = QEMU_KEY_HOME,
- [0x107] = QEMU_KEY_BACKSPACE,
-
- [0x14a] = QEMU_KEY_DELETE,
- [0x152] = QEMU_KEY_PAGEDOWN,
- [0x153] = QEMU_KEY_PAGEUP,
- [0x157] = '\n',
- [0x168] = QEMU_KEY_END,
-
-};
-
-typedef struct {
- const char* name;
- int keysym;
-} name2keysym_t;
-
-static name2keysym_t name2keysym[] = {
- /* Plain ASCII */
- { "space", 0x020 },
- { "exclam", 0x021 },
- { "quotedbl", 0x022 },
- { "numbersign", 0x023 },
- { "dollar", 0x024 },
- { "percent", 0x025 },
- { "ampersand", 0x026 },
- { "apostrophe", 0x027 },
- { "parenleft", 0x028 },
- { "parenright", 0x029 },
- { "asterisk", 0x02a },
- { "plus", 0x02b },
- { "comma", 0x02c },
- { "minus", 0x02d },
- { "period", 0x02e },
- { "slash", 0x02f },
- { "0", 0x030 },
- { "1", 0x031 },
- { "2", 0x032 },
- { "3", 0x033 },
- { "4", 0x034 },
- { "5", 0x035 },
- { "6", 0x036 },
- { "7", 0x037 },
- { "8", 0x038 },
- { "9", 0x039 },
- { "colon", 0x03a },
- { "semicolon", 0x03b },
- { "less", 0x03c },
- { "equal", 0x03d },
- { "greater", 0x03e },
- { "question", 0x03f },
- { "at", 0x040 },
- { "A", 0x041 },
- { "B", 0x042 },
- { "C", 0x043 },
- { "D", 0x044 },
- { "E", 0x045 },
- { "F", 0x046 },
- { "G", 0x047 },
- { "H", 0x048 },
- { "I", 0x049 },
- { "J", 0x04a },
- { "K", 0x04b },
- { "L", 0x04c },
- { "M", 0x04d },
- { "N", 0x04e },
- { "O", 0x04f },
- { "P", 0x050 },
- { "Q", 0x051 },
- { "R", 0x052 },
- { "S", 0x053 },
- { "T", 0x054 },
- { "U", 0x055 },
- { "V", 0x056 },
- { "W", 0x057 },
- { "X", 0x058 },
- { "Y", 0x059 },
- { "Z", 0x05a },
- { "bracketleft", 0x05b },
- { "backslash", 0x05c },
- { "bracketright", 0x05d },
- { "asciicircum", 0x05e },
- { "underscore", 0x05f },
- { "grave", 0x060 },
- { "a", 0x061 },
- { "b", 0x062 },
- { "c", 0x063 },
- { "d", 0x064 },
- { "e", 0x065 },
- { "f", 0x066 },
- { "g", 0x067 },
- { "h", 0x068 },
- { "i", 0x069 },
- { "j", 0x06a },
- { "k", 0x06b },
- { "l", 0x06c },
- { "m", 0x06d },
- { "n", 0x06e },
- { "o", 0x06f },
- { "p", 0x070 },
- { "q", 0x071 },
- { "r", 0x072 },
- { "s", 0x073 },
- { "t", 0x074 },
- { "u", 0x075 },
- { "v", 0x076 },
- { "w", 0x077 },
- { "x", 0x078 },
- { "y", 0x079 },
- { "z", 0x07a },
- { "braceleft", 0x07b },
- { "bar", 0x07c },
- { "braceright", 0x07d },
- { "asciitilde", 0x07e },
-
- /* Latin-1 extensions */
- { "nobreakspace", 0x0a0 },
- { "exclamdown", 0x0a1 },
- { "cent", 0x0a2 },
- { "sterling", 0x0a3 },
- { "currency", 0x0a4 },
- { "yen", 0x0a5 },
- { "brokenbar", 0x0a6 },
- { "section", 0x0a7 },
- { "diaeresis", 0x0a8 },
- { "copyright", 0x0a9 },
- { "ordfeminine", 0x0aa },
- { "guillemotleft", 0x0ab },
- { "notsign", 0x0ac },
- { "hyphen", 0x0ad },
- { "registered", 0x0ae },
- { "macron", 0x0af },
- { "degree", 0x0b0 },
- { "plusminus", 0x0b1 },
- { "twosuperior", 0x0b2 },
- { "threesuperior", 0x0b3 },
- { "acute", 0x0b4 },
- { "mu", 0x0b5 },
- { "paragraph", 0x0b6 },
- { "periodcentered", 0x0b7 },
- { "cedilla", 0x0b8 },
- { "onesuperior", 0x0b9 },
- { "masculine", 0x0ba },
- { "guillemotright", 0x0bb },
- { "onequarter", 0x0bc },
- { "onehalf", 0x0bd },
- { "threequarters", 0x0be },
- { "questiondown", 0x0bf },
- { "Agrave", 0x0c0 },
- { "Aacute", 0x0c1 },
- { "Acircumflex", 0x0c2 },
- { "Atilde", 0x0c3 },
- { "Adiaeresis", 0x0c4 },
- { "Aring", 0x0c5 },
- { "AE", 0x0c6 },
- { "Ccedilla", 0x0c7 },
- { "Egrave", 0x0c8 },
- { "Eacute", 0x0c9 },
- { "Ecircumflex", 0x0ca },
- { "Ediaeresis", 0x0cb },
- { "Igrave", 0x0cc },
- { "Iacute", 0x0cd },
- { "Icircumflex", 0x0ce },
- { "Idiaeresis", 0x0cf },
- { "ETH", 0x0d0 },
- { "Eth", 0x0d0 },
- { "Ntilde", 0x0d1 },
- { "Ograve", 0x0d2 },
- { "Oacute", 0x0d3 },
- { "Ocircumflex", 0x0d4 },
- { "Otilde", 0x0d5 },
- { "Odiaeresis", 0x0d6 },
- { "multiply", 0x0d7 },
- { "Ooblique", 0x0d8 },
- { "Oslash", 0x0d8 },
- { "Ugrave", 0x0d9 },
- { "Uacute", 0x0da },
- { "Ucircumflex", 0x0db },
- { "Udiaeresis", 0x0dc },
- { "Yacute", 0x0dd },
- { "THORN", 0x0de },
- { "Thorn", 0x0de },
- { "ssharp", 0x0df },
- { "agrave", 0x0e0 },
- { "aacute", 0x0e1 },
- { "acircumflex", 0x0e2 },
- { "atilde", 0x0e3 },
- { "adiaeresis", 0x0e4 },
- { "aring", 0x0e5 },
- { "ae", 0x0e6 },
- { "ccedilla", 0x0e7 },
- { "egrave", 0x0e8 },
- { "eacute", 0x0e9 },
- { "ecircumflex", 0x0ea },
- { "ediaeresis", 0x0eb },
- { "igrave", 0x0ec },
- { "iacute", 0x0ed },
- { "icircumflex", 0x0ee },
- { "idiaeresis", 0x0ef },
- { "eth", 0x0f0 },
- { "ntilde", 0x0f1 },
- { "ograve", 0x0f2 },
- { "oacute", 0x0f3 },
- { "ocircumflex", 0x0f4 },
- { "otilde", 0x0f5 },
- { "odiaeresis", 0x0f6 },
- { "division", 0x0f7 },
- { "oslash", 0x0f8 },
- { "ooblique", 0x0f8 },
- { "ugrave", 0x0f9 },
- { "uacute", 0x0fa },
- { "ucircumflex", 0x0fb },
- { "udiaeresis", 0x0fc },
- { "yacute", 0x0fd },
- { "thorn", 0x0fe },
- { "ydiaeresis", 0x0ff },
-
- /* Special keys */
- { "BackSpace", 0x07f },
- { "Tab", '\t' },
- { "Return", '\r' },
- { "Right", 0x105 },
- { "Left", 0x104 },
- { "Up", 0x103 },
- { "Down", 0x102 },
- { "Page_Down", 0x152 },
- { "Page_Up", 0x153 },
- { "Insert", 0x14b },
- { "Delete", 0x14a },
- { "Home", 0x106 },
- { "End", 0x168 },
- { "F1", 0x109 },
- { "F2", 0x10a },
- { "F3", 0x10b },
- { "F4", 0x10c },
- { "F5", 0x10d },
- { "F6", 0x10e },
- { "F7", 0x10f },
- { "F8", 0x110 },
- { "F9", 0x111 },
- { "F10", 0x112 },
- { "F11", 0x113 },
- { "F12", 0x114 },
- { "F13", 0x115 },
- { "F14", 0x116 },
- { "F15", 0x117 },
- { "F16", 0x118 },
- { "F17", 0x119 },
- { "F18", 0x11a },
- { "F19", 0x11b },
- { "F20", 0x11c },
- { "Escape", 27 },
-
- { 0, 0 },
-};
diff --git a/cutils.c b/cutils.c
deleted file mode 100644
index b256286..0000000
--- a/cutils.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Simple C functions to supplement the C library
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-
-void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-/* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
-{
- int len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-int stristart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (toupper(*p) != toupper(*q))
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-time_t mktimegm(struct tm *tm)
-{
- time_t t;
- int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
- if (m < 3) {
- m += 12;
- y--;
- }
- t = 86400 * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
- y / 400 - 719469);
- t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
- return t;
-}
-
-void *get_mmap_addr(unsigned long size)
-{
- return NULL;
-}
-
-void qemu_free(void *ptr)
-{
- free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
- return malloc(size);
-}
-
-void *qemu_mallocz(size_t size)
-{
- void *ptr;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- memset(ptr, 0, size);
- return ptr;
-}
-
-void *qemu_realloc(void* ptr, size_t size)
-{
- return realloc(ptr, size);
-}
-
-char *qemu_strdup(const char *str)
-{
- char *ptr;
- ptr = qemu_malloc(strlen(str) + 1);
- if (!ptr)
- return NULL;
- strcpy(ptr, str);
- return ptr;
-}
diff --git a/d3des.c b/d3des.c
deleted file mode 100644
index 6e8a02e..0000000
--- a/d3des.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * This is D3DES (V5.09) by Richard Outerbridge with the double and
- * triple-length support removed for use in VNC. Also the bytebit[] array
- * has been reversed so that the most significant bit in each byte of the
- * key is ignored, not the least significant.
- *
- * These changes are:
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* D3DES (V5.09) -
- *
- * A portable, public domain, version of the Data Encryption Standard.
- *
- * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
- * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
- * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
- * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
- * for humouring me on.
- *
- * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
- * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
- */
-
-#include "d3des.h"
-
-static void scrunch(unsigned char *, unsigned long *);
-static void unscrun(unsigned long *, unsigned char *);
-static void desfunc(unsigned long *, unsigned long *);
-static void cookey(unsigned long *);
-
-static unsigned long KnL[32] = { 0L };
-
-static const unsigned short bytebit[8] = {
- 01, 02, 04, 010, 020, 040, 0100, 0200 };
-
-static const unsigned long bigbyte[24] = {
- 0x800000L, 0x400000L, 0x200000L, 0x100000L,
- 0x80000L, 0x40000L, 0x20000L, 0x10000L,
- 0x8000L, 0x4000L, 0x2000L, 0x1000L,
- 0x800L, 0x400L, 0x200L, 0x100L,
- 0x80L, 0x40L, 0x20L, 0x10L,
- 0x8L, 0x4L, 0x2L, 0x1L };
-
-/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
-
-static const unsigned char pc1[56] = {
- 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
- 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
- 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
- 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
-
-static const unsigned char totrot[16] = {
- 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
-
-static const unsigned char pc2[48] = {
- 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
- 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
- 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
- 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
-
-void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */
-unsigned char *key;
-int edf;
-{
- register int i, j, l, m, n;
- unsigned char pc1m[56], pcr[56];
- unsigned long kn[32];
-
- for ( j = 0; j < 56; j++ ) {
- l = pc1[j];
- m = l & 07;
- pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
- }
- for( i = 0; i < 16; i++ ) {
- if( edf == DE1 ) m = (15 - i) << 1;
- else m = i << 1;
- n = m + 1;
- kn[m] = kn[n] = 0L;
- for( j = 0; j < 28; j++ ) {
- l = j + totrot[i];
- if( l < 28 ) pcr[j] = pc1m[l];
- else pcr[j] = pc1m[l - 28];
- }
- for( j = 28; j < 56; j++ ) {
- l = j + totrot[i];
- if( l < 56 ) pcr[j] = pc1m[l];
- else pcr[j] = pc1m[l - 28];
- }
- for( j = 0; j < 24; j++ ) {
- if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
- if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
- }
- }
- cookey(kn);
- return;
- }
-
-static void cookey(raw1)
-register unsigned long *raw1;
-{
- register unsigned long *cook, *raw0;
- unsigned long dough[32];
- register int i;
-
- cook = dough;
- for( i = 0; i < 16; i++, raw1++ ) {
- raw0 = raw1++;
- *cook = (*raw0 & 0x00fc0000L) << 6;
- *cook |= (*raw0 & 0x00000fc0L) << 10;
- *cook |= (*raw1 & 0x00fc0000L) >> 10;
- *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
- *cook = (*raw0 & 0x0003f000L) << 12;
- *cook |= (*raw0 & 0x0000003fL) << 16;
- *cook |= (*raw1 & 0x0003f000L) >> 4;
- *cook++ |= (*raw1 & 0x0000003fL);
- }
- usekey(dough);
- return;
- }
-
-void cpkey(into)
-register unsigned long *into;
-{
- register unsigned long *from, *endp;
-
- from = KnL, endp = &KnL[32];
- while( from < endp ) *into++ = *from++;
- return;
- }
-
-void usekey(from)
-register unsigned long *from;
-{
- register unsigned long *to, *endp;
-
- to = KnL, endp = &KnL[32];
- while( to < endp ) *to++ = *from++;
- return;
- }
-
-void des(inblock, outblock)
-unsigned char *inblock, *outblock;
-{
- unsigned long work[2];
-
- scrunch(inblock, work);
- desfunc(work, KnL);
- unscrun(work, outblock);
- return;
- }
-
-static void scrunch(outof, into)
-register unsigned char *outof;
-register unsigned long *into;
-{
- *into = (*outof++ & 0xffL) << 24;
- *into |= (*outof++ & 0xffL) << 16;
- *into |= (*outof++ & 0xffL) << 8;
- *into++ |= (*outof++ & 0xffL);
- *into = (*outof++ & 0xffL) << 24;
- *into |= (*outof++ & 0xffL) << 16;
- *into |= (*outof++ & 0xffL) << 8;
- *into |= (*outof & 0xffL);
- return;
- }
-
-static void unscrun(outof, into)
-register unsigned long *outof;
-register unsigned char *into;
-{
- *into++ = (unsigned char)((*outof >> 24) & 0xffL);
- *into++ = (unsigned char)((*outof >> 16) & 0xffL);
- *into++ = (unsigned char)((*outof >> 8) & 0xffL);
- *into++ = (unsigned char)(*outof++ & 0xffL);
- *into++ = (unsigned char)((*outof >> 24) & 0xffL);
- *into++ = (unsigned char)((*outof >> 16) & 0xffL);
- *into++ = (unsigned char)((*outof >> 8) & 0xffL);
- *into = (unsigned char)(*outof & 0xffL);
- return;
- }
-
-static unsigned long SP1[64] = {
- 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
- 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
- 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
- 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
- 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
- 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
- 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
- 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
- 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
- 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
- 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
- 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
- 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
- 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
- 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
- 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
-
-static unsigned long SP2[64] = {
- 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
- 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
- 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
- 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
- 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
- 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
- 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
- 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
- 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
- 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
- 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
- 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
- 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
- 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
- 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
- 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
-
-static unsigned long SP3[64] = {
- 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
- 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
- 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
- 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
- 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
- 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
- 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
- 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
- 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
- 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
- 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
- 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
- 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
- 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
- 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
- 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
-
-static unsigned long SP4[64] = {
- 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
- 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
- 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
- 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
- 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
- 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
- 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
- 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
- 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
- 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
- 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
- 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
- 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
- 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
- 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
- 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
-
-static unsigned long SP5[64] = {
- 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
- 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
- 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
- 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
- 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
- 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
- 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
- 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
- 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
- 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
- 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
- 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
- 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
- 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
- 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
- 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
-
-static unsigned long SP6[64] = {
- 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
- 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
- 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
- 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
- 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
- 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
- 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
- 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
- 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
- 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
- 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
- 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
- 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
- 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
- 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
- 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
-
-static unsigned long SP7[64] = {
- 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
- 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
- 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
- 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
- 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
- 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
- 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
- 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
- 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
- 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
- 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
- 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
- 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
- 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
- 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
- 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
-
-static unsigned long SP8[64] = {
- 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
- 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
- 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
- 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
- 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
- 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
- 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
- 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
- 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
- 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
- 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
- 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
- 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
- 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
- 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
- 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
-
-static void desfunc(block, keys)
-register unsigned long *block, *keys;
-{
- register unsigned long fval, work, right, leftt;
- register int round;
-
- leftt = block[0];
- right = block[1];
- work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
- right ^= work;
- leftt ^= (work << 4);
- work = ((leftt >> 16) ^ right) & 0x0000ffffL;
- right ^= work;
- leftt ^= (work << 16);
- work = ((right >> 2) ^ leftt) & 0x33333333L;
- leftt ^= work;
- right ^= (work << 2);
- work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
- leftt ^= work;
- right ^= (work << 8);
- right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
- work = (leftt ^ right) & 0xaaaaaaaaL;
- leftt ^= work;
- right ^= work;
- leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
-
- for( round = 0; round < 8; round++ ) {
- work = (right << 28) | (right >> 4);
- work ^= *keys++;
- fval = SP7[ work & 0x3fL];
- fval |= SP5[(work >> 8) & 0x3fL];
- fval |= SP3[(work >> 16) & 0x3fL];
- fval |= SP1[(work >> 24) & 0x3fL];
- work = right ^ *keys++;
- fval |= SP8[ work & 0x3fL];
- fval |= SP6[(work >> 8) & 0x3fL];
- fval |= SP4[(work >> 16) & 0x3fL];
- fval |= SP2[(work >> 24) & 0x3fL];
- leftt ^= fval;
- work = (leftt << 28) | (leftt >> 4);
- work ^= *keys++;
- fval = SP7[ work & 0x3fL];
- fval |= SP5[(work >> 8) & 0x3fL];
- fval |= SP3[(work >> 16) & 0x3fL];
- fval |= SP1[(work >> 24) & 0x3fL];
- work = leftt ^ *keys++;
- fval |= SP8[ work & 0x3fL];
- fval |= SP6[(work >> 8) & 0x3fL];
- fval |= SP4[(work >> 16) & 0x3fL];
- fval |= SP2[(work >> 24) & 0x3fL];
- right ^= fval;
- }
-
- right = (right << 31) | (right >> 1);
- work = (leftt ^ right) & 0xaaaaaaaaL;
- leftt ^= work;
- right ^= work;
- leftt = (leftt << 31) | (leftt >> 1);
- work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
- right ^= work;
- leftt ^= (work << 8);
- work = ((leftt >> 2) ^ right) & 0x33333333L;
- right ^= work;
- leftt ^= (work << 2);
- work = ((right >> 16) ^ leftt) & 0x0000ffffL;
- leftt ^= work;
- right ^= (work << 16);
- work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
- leftt ^= work;
- right ^= (work << 4);
- *block++ = right;
- *block = leftt;
- return;
- }
-
-/* Validation sets:
- *
- * Single-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef
- * Plain : 0123 4567 89ab cde7
- * Cipher : c957 4425 6a5e d31d
- *
- * Double-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
- * Plain : 0123 4567 89ab cde7
- * Cipher : 7f1d 0a77 826b 8aff
- *
- * Double-length key, double-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
- * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
- * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
- *
- * Triple-length key, single-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
- * Plain : 0123 4567 89ab cde7
- * Cipher : de0b 7c06 ae5e 0ed5
- *
- * Triple-length key, double-length plaintext -
- * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
- * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
- * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
- *
- * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
- **********************************************************************/
diff --git a/d3des.h b/d3des.h
deleted file mode 100644
index ea3da44..0000000
--- a/d3des.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This is D3DES (V5.09) by Richard Outerbridge with the double and
- * triple-length support removed for use in VNC.
- *
- * These changes are:
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* d3des.h -
- *
- * Headers and defines for d3des.c
- * Graven Imagery, 1992.
- *
- * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
- * (GEnie : OUTER; CIS : [71755,204])
- */
-
-#define EN0 0 /* MODE == encrypt */
-#define DE1 1 /* MODE == decrypt */
-
-extern void deskey(unsigned char *, int);
-/* hexkey[8] MODE
- * Sets the internal key register according to the hexadecimal
- * key contained in the 8 bytes of hexkey, according to the DES,
- * for encryption or decryption according to MODE.
- */
-
-extern void usekey(unsigned long *);
-/* cookedkey[32]
- * Loads the internal key register with the data in cookedkey.
- */
-
-extern void cpkey(unsigned long *);
-/* cookedkey[32]
- * Copies the contents of the internal key register into the storage
- * located at &cookedkey[0].
- */
-
-extern void des(unsigned char *, unsigned char *);
-/* from[8] to[8]
- * Encrypts/Decrypts (according to the key currently loaded in the
- * internal key register) one block of eight bytes at address 'from'
- * into the block at address 'to'. They can be the same.
- */
-
-/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
- ********************************************************************/
diff --git a/dcache.c b/dcache.c
deleted file mode 100644
index 56426ee..0000000
--- a/dcache.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "dcache.h"
-#include "cpu.h"
-#include "exec-all.h"
-#include "trace.h"
-#include "varint.h"
-
-extern FILE *ftrace_debug;
-
-int dcache_size = 16 * 1024;
-int dcache_ways = 4;
-int dcache_line_size = 32;
-int dcache_replace_policy = kPolicyRandom;
-int dcache_load_miss_penalty = 30;
-int dcache_store_miss_penalty = 5;
-
-typedef struct Dcache {
- int size;
- int ways;
- int line_size;
- int log_line_size;
- int rows;
- uint32_t addr_mask;
- int replace_policy;
- int next_way;
- int extra_increment_counter;
- int *replace;
- uint32_t **table;
- int load_miss_penalty;
- int store_miss_penalty;
- uint64_t load_hits;
- uint64_t load_misses;
- uint64_t store_hits;
- uint64_t store_misses;
-} Dcache;
-
-Dcache dcache;
-
-void dcache_cleanup();
-
-// Returns the log2 of "num" rounded up to the nearest integer.
-int log2_roundup(int num)
-{
- int power2;
- int exp;
-
- for (exp = 0, power2 = 1; power2 < num; power2 <<= 1) {
- exp += 1;
- }
- return exp;
-}
-
-void dcache_init(int size, int ways, int line_size, int replace_policy,
- int load_miss_penalty, int store_miss_penalty)
-{
- int ii;
-
- // Compute the logs of the params, rounded up
- int log_size = log2_roundup(size);
- int log_ways = log2_roundup(ways);
- int log_line_size = log2_roundup(line_size);
-
- // The number of rows in the table = size / (line_size * ways)
- int log_rows = log_size - log_line_size - log_ways;
-
- dcache.size = 1 << log_size;
- dcache.ways = 1 << log_ways;
- dcache.line_size = 1 << log_line_size;
- dcache.log_line_size = log_line_size;
- dcache.rows = 1 << log_rows;
- dcache.addr_mask = (1 << log_rows) - 1;
-
- // Allocate an array of pointers, one for each row
- uint32_t **table = malloc(sizeof(uint32_t *) << log_rows);
-
- // Allocate the data for the whole cache in one call to malloc()
- int data_size = sizeof(uint32_t) << (log_rows + log_ways);
- uint32_t *data = malloc(data_size);
-
- // Fill the cache with invalid addresses
- memset(data, ~0, data_size);
-
- // Assign the pointers into the data array
- int rows = dcache.rows;
- for (ii = 0; ii < rows; ++ii) {
- table[ii] = &data[ii << log_ways];
- }
- dcache.table = table;
- dcache.replace_policy = replace_policy;
- dcache.next_way = 0;
- dcache.extra_increment_counter = 0;
-
- dcache.replace = NULL;
- if (replace_policy == kPolicyRoundRobin) {
- dcache.replace = malloc(sizeof(int) << log_rows);
- memset(dcache.replace, 0, sizeof(int) << log_rows);
- }
- dcache.load_miss_penalty = load_miss_penalty;
- dcache.store_miss_penalty = store_miss_penalty;
- dcache.load_hits = 0;
- dcache.load_misses = 0;
- dcache.store_hits = 0;
- dcache.store_misses = 0;
-
- atexit(dcache_cleanup);
-}
-
-void dcache_stats()
-{
- uint64_t hits = dcache.load_hits + dcache.store_hits;
- uint64_t misses = dcache.load_misses + dcache.store_misses;
- uint64_t total = hits + misses;
- double hit_per = 0;
- double miss_per = 0;
- if (total) {
- hit_per = 100.0 * hits / total;
- miss_per = 100.0 * misses / total;
- }
- printf("\n");
- printf("Dcache hits %10llu %6.2f%%\n", hits, hit_per);
- printf("Dcache misses %10llu %6.2f%%\n", misses, miss_per);
- printf("Dcache total %10llu\n", hits + misses);
-}
-
-void dcache_free()
-{
- free(dcache.table[0]);
- free(dcache.table);
- free(dcache.replace);
- dcache.table = NULL;
-}
-
-void dcache_cleanup()
-{
- dcache_stats();
- dcache_free();
-}
-
-void compress_trace_addresses(TraceAddr *trace_addr)
-{
- AddrRec *ptr;
- char *comp_ptr = trace_addr->compressed_ptr;
- uint32_t prev_addr = trace_addr->prev_addr;
- uint64_t prev_time = trace_addr->prev_time;
- AddrRec *last = &trace_addr->buffer[kMaxNumAddrs];
- for (ptr = trace_addr->buffer; ptr != last; ++ptr) {
- if (comp_ptr >= trace_addr->high_water_ptr) {
- uint32_t size = comp_ptr - trace_addr->compressed;
- fwrite(trace_addr->compressed, sizeof(char), size, trace_addr->fstream);
- comp_ptr = trace_addr->compressed;
- }
-
- int addr_diff = ptr->addr - prev_addr;
- uint64_t time_diff = ptr->time - prev_time;
- prev_addr = ptr->addr;
- prev_time = ptr->time;
-
- comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
- comp_ptr = varint_encode(time_diff, comp_ptr);
- }
- trace_addr->compressed_ptr = comp_ptr;
- trace_addr->prev_addr = prev_addr;
- trace_addr->prev_time = prev_time;
-}
-
-// This function is called by the generated code to simulate
-// a dcache load access.
-void dcache_load(uint32_t addr)
-{
- int ii;
- int ways = dcache.ways;
- uint32_t cache_addr = addr >> dcache.log_line_size;
- int row = cache_addr & dcache.addr_mask;
- //printf("ld %lld 0x%x\n", sim_time, addr);
- for (ii = 0; ii < ways; ++ii) {
- if (cache_addr == dcache.table[row][ii]) {
- dcache.load_hits += 1;
-#if 0
- printf("dcache load hit addr: 0x%x cache_addr: 0x%x row %d way %d\n",
- addr, cache_addr, row, ii);
-#endif
- // If we are tracing all addresses, then include this in the trace.
- if (trace_all_addr) {
- AddrRec *next = trace_load.next;
- next->addr = addr;
- next->time = sim_time;
- next += 1;
- if (next == &trace_load.buffer[kMaxNumAddrs]) {
- // Compress the trace
- compress_trace_addresses(&trace_load);
- next = &trace_load.buffer[0];
- }
- trace_load.next = next;
- }
- return;
- }
- }
- // This is a cache miss
-
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld %08x\n", sim_time, addr);
-#endif
- if (trace_load.fstream) {
- AddrRec *next = trace_load.next;
- next->addr = addr;
- next->time = sim_time;
- next += 1;
- if (next == &trace_load.buffer[kMaxNumAddrs]) {
- // Compress the trace
- compress_trace_addresses(&trace_load);
- next = &trace_load.buffer[0];
- }
- trace_load.next = next;
- }
-
- dcache.load_misses += 1;
- sim_time += dcache.load_miss_penalty;
-
- // Pick a way to replace
- int way;
- if (dcache.replace_policy == kPolicyRoundRobin) {
- // Round robin replacement policy
- way = dcache.replace[row];
- int next_way = way + 1;
- if (next_way == dcache.ways)
- next_way = 0;
- dcache.replace[row] = next_way;
- } else {
- // Random replacement policy
- way = dcache.next_way;
- dcache.next_way += 1;
- if (dcache.next_way >= dcache.ways)
- dcache.next_way = 0;
-
- // Every 13 replacements, add an extra increment to the next way
- dcache.extra_increment_counter += 1;
- if (dcache.extra_increment_counter == 13) {
- dcache.extra_increment_counter = 0;
- dcache.next_way += 1;
- if (dcache.next_way >= dcache.ways)
- dcache.next_way = 0;
- }
- }
-#if 0
- printf("dcache load miss addr: 0x%x cache_addr: 0x%x row %d replacing way %d\n",
- addr, cache_addr, row, way);
-#endif
- dcache.table[row][way] = cache_addr;
-}
-
-// This function is called by the generated code to simulate
-// a dcache store access.
-void dcache_store(uint32_t addr, uint32_t val)
-{
- // Check for a write to a magic address (this is a virtual address)
- //printf("st %lld 0x%08x val 0x%x\n", sim_time, addr, val);
- if ((addr & kMagicBaseMask) == kMagicBaseAddr) {
- uint32_t offset = addr & kMagicOffsetMask;
- switch (offset) {
- case kMethodTraceEnterOffset:
- trace_interpreted_method(val, kMethodEnter);
- break;
- case kMethodTraceExitOffset:
- trace_interpreted_method(val, kMethodExit);
- break;
- case kMethodTraceExceptionOffset:
- trace_interpreted_method(val, kMethodException);
- break;
- }
- }
-
- int ii;
- int ways = dcache.ways;
- uint32_t cache_addr = addr >> dcache.log_line_size;
- int row = cache_addr & dcache.addr_mask;
- for (ii = 0; ii < ways; ++ii) {
- if (cache_addr == dcache.table[row][ii]) {
- dcache.store_hits += 1;
-#if 0
- printf("dcache store hit addr: 0x%x cache_addr: 0x%x row %d way %d\n",
- addr, cache_addr, row, ii);
-#endif
- // If we are tracing all addresses, then include this in the trace.
- if (trace_all_addr) {
- AddrRec *next = trace_store.next;
- next->addr = addr;
- next->time = sim_time;
- next += 1;
- if (next == &trace_store.buffer[kMaxNumAddrs]) {
- // Compress the trace
- compress_trace_addresses(&trace_store);
- next = &trace_store.buffer[0];
- }
- trace_store.next = next;
- }
- return;
- }
- }
- // This is a cache miss
-#if 0
- printf("dcache store miss addr: 0x%x cache_addr: 0x%x row %d\n",
- addr, cache_addr, row);
-#endif
-
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld %08x\n", sim_time, addr);
-#endif
-
- if (trace_store.fstream) {
- AddrRec *next = trace_store.next;
- next->addr = addr;
- next->time = sim_time;
- next += 1;
- if (next == &trace_store.buffer[kMaxNumAddrs]) {
- // Compress the trace
- compress_trace_addresses(&trace_store);
- next = &trace_store.buffer[0];
- }
- trace_store.next = next;
- }
-
- dcache.store_misses += 1;
- sim_time += dcache.store_miss_penalty;
-
- // Assume no write-allocate for now
-}
-
-// This function is called by the generated code to simulate
-// a dcache load and store (swp) access.
-void dcache_swp(uint32_t addr)
-{
- dcache_load(addr);
- dcache_store(addr, 0);
-}
diff --git a/dcache.h b/dcache.h
deleted file mode 100644
index 8857600..0000000
--- a/dcache.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef DCACHE_H
-#define DCACHE_H
-
-#include <inttypes.h>
-
-// Define constants for the replacement policies
-#define kPolicyRoundRobin 1
-#define kPolicyRandom 2
-
-extern int dcache_size;
-extern int dcache_ways;
-extern int dcache_line_size;
-extern int dcache_replace_policy;
-extern int dcache_load_miss_penalty;
-extern int dcache_store_miss_penalty;
-
-extern void dcache_init(int size, int ways, int line_size, int replace_policy,
- int load_miss_penalty, int store_miss_penalty);
-
-#endif /* DCACHE_H */
diff --git a/dis-asm.h b/dis-asm.h
deleted file mode 100644
index 1ba86dd..0000000
--- a/dis-asm.h
+++ /dev/null
@@ -1,478 +0,0 @@
-/* Interface between the opcode library and its callers.
- Written by Cygnus Support, 1993.
-
- The opcode library (libopcodes.a) provides instruction decoders for
- a large variety of instruction sets, callable with an identical
- interface, for making instruction-processing programs more independent
- of the instruction set being processed. */
-
-#ifndef DIS_ASM_H
-#define DIS_ASM_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#define PARAMS(x) x
-typedef void *PTR;
-typedef uint64_t bfd_vma;
-typedef int64_t bfd_signed_vma;
-typedef uint8_t bfd_byte;
-#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x)
-#define snprintf_vma(s,ss,x) snprintf (s, ss, "%0" PRIx64, x)
-
-#define BFD64
-
-enum bfd_flavour {
- bfd_target_unknown_flavour,
- bfd_target_aout_flavour,
- bfd_target_coff_flavour,
- bfd_target_ecoff_flavour,
- bfd_target_elf_flavour,
- bfd_target_ieee_flavour,
- bfd_target_nlm_flavour,
- bfd_target_oasys_flavour,
- bfd_target_tekhex_flavour,
- bfd_target_srec_flavour,
- bfd_target_ihex_flavour,
- bfd_target_som_flavour,
- bfd_target_os9k_flavour,
- bfd_target_versados_flavour,
- bfd_target_msdos_flavour,
- bfd_target_evax_flavour
-};
-
-enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
-
-enum bfd_architecture
-{
- bfd_arch_unknown, /* File arch not known */
- bfd_arch_obscure, /* Arch known, not one of these */
- bfd_arch_m68k, /* Motorola 68xxx */
-#define bfd_mach_m68000 1
-#define bfd_mach_m68008 2
-#define bfd_mach_m68010 3
-#define bfd_mach_m68020 4
-#define bfd_mach_m68030 5
-#define bfd_mach_m68040 6
-#define bfd_mach_m68060 7
-#define bfd_mach_cpu32 8
-#define bfd_mach_mcf5200 9
-#define bfd_mach_mcf5206e 10
-#define bfd_mach_mcf5307 11
-#define bfd_mach_mcf5407 12
-#define bfd_mach_mcf528x 13
-#define bfd_mach_mcfv4e 14
-#define bfd_mach_mcf521x 15
-#define bfd_mach_mcf5249 16
-#define bfd_mach_mcf547x 17
-#define bfd_mach_mcf548x 18
- bfd_arch_vax, /* DEC Vax */
- bfd_arch_i960, /* Intel 960 */
- /* The order of the following is important.
- lower number indicates a machine type that
- only accepts a subset of the instructions
- available to machines with higher numbers.
- The exception is the "ca", which is
- incompatible with all other machines except
- "core". */
-
-#define bfd_mach_i960_core 1
-#define bfd_mach_i960_ka_sa 2
-#define bfd_mach_i960_kb_sb 3
-#define bfd_mach_i960_mc 4
-#define bfd_mach_i960_xa 5
-#define bfd_mach_i960_ca 6
-#define bfd_mach_i960_jx 7
-#define bfd_mach_i960_hx 8
-
- bfd_arch_a29k, /* AMD 29000 */
- bfd_arch_sparc, /* SPARC */
-#define bfd_mach_sparc 1
-/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
-#define bfd_mach_sparc_sparclet 2
-#define bfd_mach_sparc_sparclite 3
-#define bfd_mach_sparc_v8plus 4
-#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
-#define bfd_mach_sparc_sparclite_le 6
-#define bfd_mach_sparc_v9 7
-#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
-#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
-#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
-/* Nonzero if MACH has the v9 instruction set. */
-#define bfd_mach_sparc_v9_p(mach) \
- ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
- && (mach) != bfd_mach_sparc_sparclite_le)
- bfd_arch_mips, /* MIPS Rxxxx */
-#define bfd_mach_mips3000 3000
-#define bfd_mach_mips3900 3900
-#define bfd_mach_mips4000 4000
-#define bfd_mach_mips4010 4010
-#define bfd_mach_mips4100 4100
-#define bfd_mach_mips4300 4300
-#define bfd_mach_mips4400 4400
-#define bfd_mach_mips4600 4600
-#define bfd_mach_mips4650 4650
-#define bfd_mach_mips5000 5000
-#define bfd_mach_mips6000 6000
-#define bfd_mach_mips8000 8000
-#define bfd_mach_mips10000 10000
-#define bfd_mach_mips16 16
- bfd_arch_i386, /* Intel 386 */
-#define bfd_mach_i386_i386 0
-#define bfd_mach_i386_i8086 1
-#define bfd_mach_i386_i386_intel_syntax 2
-#define bfd_mach_x86_64 3
-#define bfd_mach_x86_64_intel_syntax 4
- bfd_arch_we32k, /* AT&T WE32xxx */
- bfd_arch_tahoe, /* CCI/Harris Tahoe */
- bfd_arch_i860, /* Intel 860 */
- bfd_arch_romp, /* IBM ROMP PC/RT */
- bfd_arch_alliant, /* Alliant */
- bfd_arch_convex, /* Convex */
- bfd_arch_m88k, /* Motorola 88xxx */
- bfd_arch_pyramid, /* Pyramid Technology */
- bfd_arch_h8300, /* Hitachi H8/300 */
-#define bfd_mach_h8300 1
-#define bfd_mach_h8300h 2
-#define bfd_mach_h8300s 3
- bfd_arch_powerpc, /* PowerPC */
-#define bfd_mach_ppc 0
-#define bfd_mach_ppc64 1
-#define bfd_mach_ppc_403 403
-#define bfd_mach_ppc_403gc 4030
-#define bfd_mach_ppc_505 505
-#define bfd_mach_ppc_601 601
-#define bfd_mach_ppc_602 602
-#define bfd_mach_ppc_603 603
-#define bfd_mach_ppc_ec603e 6031
-#define bfd_mach_ppc_604 604
-#define bfd_mach_ppc_620 620
-#define bfd_mach_ppc_630 630
-#define bfd_mach_ppc_750 750
-#define bfd_mach_ppc_860 860
-#define bfd_mach_ppc_a35 35
-#define bfd_mach_ppc_rs64ii 642
-#define bfd_mach_ppc_rs64iii 643
-#define bfd_mach_ppc_7400 7400
- bfd_arch_rs6000, /* IBM RS/6000 */
- bfd_arch_hppa, /* HP PA RISC */
-#define bfd_mach_hppa10 10
-#define bfd_mach_hppa11 11
-#define bfd_mach_hppa20 20
-#define bfd_mach_hppa20w 25
- bfd_arch_d10v, /* Mitsubishi D10V */
- bfd_arch_z8k, /* Zilog Z8000 */
-#define bfd_mach_z8001 1
-#define bfd_mach_z8002 2
- bfd_arch_h8500, /* Hitachi H8/500 */
- bfd_arch_sh, /* Hitachi SH */
-#define bfd_mach_sh 1
-#define bfd_mach_sh2 0x20
-#define bfd_mach_sh_dsp 0x2d
-#define bfd_mach_sh2a 0x2a
-#define bfd_mach_sh2a_nofpu 0x2b
-#define bfd_mach_sh2e 0x2e
-#define bfd_mach_sh3 0x30
-#define bfd_mach_sh3_nommu 0x31
-#define bfd_mach_sh3_dsp 0x3d
-#define bfd_mach_sh3e 0x3e
-#define bfd_mach_sh4 0x40
-#define bfd_mach_sh4_nofpu 0x41
-#define bfd_mach_sh4_nommu_nofpu 0x42
-#define bfd_mach_sh4a 0x4a
-#define bfd_mach_sh4a_nofpu 0x4b
-#define bfd_mach_sh4al_dsp 0x4d
-#define bfd_mach_sh5 0x50
- bfd_arch_alpha, /* Dec Alpha */
-#define bfd_mach_alpha 1
- bfd_arch_arm, /* Advanced Risc Machines ARM */
-#define bfd_mach_arm_unknown 0
-#define bfd_mach_arm_2 1
-#define bfd_mach_arm_2a 2
-#define bfd_mach_arm_3 3
-#define bfd_mach_arm_3M 4
-#define bfd_mach_arm_4 5
-#define bfd_mach_arm_4T 6
-#define bfd_mach_arm_5 7
-#define bfd_mach_arm_5T 8
-#define bfd_mach_arm_5TE 9
-#define bfd_mach_arm_XScale 10
-#define bfd_mach_arm_ep9312 11
-#define bfd_mach_arm_iWMMXt 12
-#define bfd_mach_arm_iWMMXt2 13
- bfd_arch_ns32k, /* National Semiconductors ns32000 */
- bfd_arch_w65, /* WDC 65816 */
- bfd_arch_tic30, /* Texas Instruments TMS320C30 */
- bfd_arch_v850, /* NEC V850 */
-#define bfd_mach_v850 0
- bfd_arch_arc, /* Argonaut RISC Core */
-#define bfd_mach_arc_base 0
- bfd_arch_m32r, /* Mitsubishi M32R/D */
-#define bfd_mach_m32r 0 /* backwards compatibility */
- bfd_arch_mn10200, /* Matsushita MN10200 */
- bfd_arch_mn10300, /* Matsushita MN10300 */
- bfd_arch_cris, /* Axis CRIS */
-#define bfd_mach_cris_v0_v10 255
-#define bfd_mach_cris_v32 32
-#define bfd_mach_cris_v10_v32 1032
- bfd_arch_last
- };
-#define bfd_mach_s390_31 31
-#define bfd_mach_s390_64 64
-
-typedef struct symbol_cache_entry
-{
- const char *name;
- union
- {
- PTR p;
- bfd_vma i;
- } udata;
-} asymbol;
-
-typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
-
-enum dis_insn_type {
- dis_noninsn, /* Not a valid instruction */
- dis_nonbranch, /* Not a branch instruction */
- dis_branch, /* Unconditional branch */
- dis_condbranch, /* Conditional branch */
- dis_jsr, /* Jump to subroutine */
- dis_condjsr, /* Conditional jump to subroutine */
- dis_dref, /* Data reference instruction */
- dis_dref2 /* Two data references in instruction */
-};
-
-/* This struct is passed into the instruction decoding routine,
- and is passed back out into each callback. The various fields are used
- for conveying information from your main routine into your callbacks,
- for passing information into the instruction decoders (such as the
- addresses of the callback functions), or for passing information
- back from the instruction decoders to their callers.
-
- It must be initialized before it is first passed; this can be done
- by hand, or using one of the initialization macros below. */
-
-typedef struct disassemble_info {
- fprintf_ftype fprintf_func;
- FILE *stream;
- PTR application_data;
-
- /* Target description. We could replace this with a pointer to the bfd,
- but that would require one. There currently isn't any such requirement
- so to avoid introducing one we record these explicitly. */
- /* The bfd_flavour. This can be bfd_target_unknown_flavour. */
- enum bfd_flavour flavour;
- /* The bfd_arch value. */
- enum bfd_architecture arch;
- /* The bfd_mach value. */
- unsigned long mach;
- /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
- enum bfd_endian endian;
-
- /* An array of pointers to symbols either at the location being disassembled
- or at the start of the function being disassembled. The array is sorted
- so that the first symbol is intended to be the one used. The others are
- present for any misc. purposes. This is not set reliably, but if it is
- not NULL, it is correct. */
- asymbol **symbols;
- /* Number of symbols in array. */
- int num_symbols;
-
- /* For use by the disassembler.
- The top 16 bits are reserved for public use (and are documented here).
- The bottom 16 bits are for the internal use of the disassembler. */
- unsigned long flags;
-#define INSN_HAS_RELOC 0x80000000
- PTR private_data;
-
- /* Function used to get bytes to disassemble. MEMADDR is the
- address of the stuff to be disassembled, MYADDR is the address to
- put the bytes in, and LENGTH is the number of bytes to read.
- INFO is a pointer to this struct.
- Returns an errno value or 0 for success. */
- int (*read_memory_func)
- PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
- struct disassemble_info *info));
-
- /* Function which should be called if we get an error that we can't
- recover from. STATUS is the errno value from read_memory_func and
- MEMADDR is the address that we were trying to read. INFO is a
- pointer to this struct. */
- void (*memory_error_func)
- PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
-
- /* Function called to print ADDR. */
- void (*print_address_func)
- PARAMS ((bfd_vma addr, struct disassemble_info *info));
-
- /* Function called to determine if there is a symbol at the given ADDR.
- If there is, the function returns 1, otherwise it returns 0.
- This is used by ports which support an overlay manager where
- the overlay number is held in the top part of an address. In
- some circumstances we want to include the overlay number in the
- address, (normally because there is a symbol associated with
- that address), but sometimes we want to mask out the overlay bits. */
- int (* symbol_at_address_func)
- PARAMS ((bfd_vma addr, struct disassemble_info * info));
-
- /* These are for buffer_read_memory. */
- bfd_byte *buffer;
- bfd_vma buffer_vma;
- int buffer_length;
-
- /* This variable may be set by the instruction decoder. It suggests
- the number of bytes objdump should display on a single line. If
- the instruction decoder sets this, it should always set it to
- the same value in order to get reasonable looking output. */
- int bytes_per_line;
-
- /* the next two variables control the way objdump displays the raw data */
- /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
- /* output will look like this:
- 00: 00000000 00000000
- with the chunks displayed according to "display_endian". */
- int bytes_per_chunk;
- enum bfd_endian display_endian;
-
- /* Results from instruction decoders. Not all decoders yet support
- this information. This info is set each time an instruction is
- decoded, and is only valid for the last such instruction.
-
- To determine whether this decoder supports this information, set
- insn_info_valid to 0, decode an instruction, then check it. */
-
- char insn_info_valid; /* Branch info has been set. */
- char branch_delay_insns; /* How many sequential insn's will run before
- a branch takes effect. (0 = normal) */
- char data_size; /* Size of data reference in insn, in bytes */
- enum dis_insn_type insn_type; /* Type of instruction */
- bfd_vma target; /* Target address of branch or dref, if known;
- zero if unknown. */
- bfd_vma target2; /* Second target address for dref2 */
-
- /* Command line options specific to the target disassembler. */
- char * disassembler_options;
-
-} disassemble_info;
-
-
-/* Standard disassemblers. Disassemble one instruction at the given
- target address. Return number of bytes processed. */
-typedef int (*disassembler_ftype)
- PARAMS((bfd_vma, disassemble_info *));
-
-extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
-extern disassembler_ftype arc_get_disassembler PARAMS ((int, int));
-extern int print_insn_arm PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_shl PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_ppc PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_s390 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_crisv32 PARAMS ((bfd_vma, disassemble_info*));
-
-#if 0
-/* Fetch the disassembler for a given BFD, if that support is available. */
-extern disassembler_ftype disassembler PARAMS ((bfd *));
-#endif
-
-
-/* This block of definitions is for particular callers who read instructions
- into a buffer before calling the instruction decoder. */
-
-/* Here is a function which callers may wish to use for read_memory_func.
- It gets bytes from a buffer. */
-extern int buffer_read_memory
- PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
-
-/* This function goes with buffer_read_memory.
- It prints a message using info->fprintf_func and info->stream. */
-extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
-
-
-/* Just print the address in hex. This is included for completeness even
- though both GDB and objdump provide their own (to print symbolic
- addresses). */
-extern void generic_print_address
- PARAMS ((bfd_vma, struct disassemble_info *));
-
-/* Always true. */
-extern int generic_symbol_at_address
- PARAMS ((bfd_vma, struct disassemble_info *));
-
-/* Macro to initialize a disassemble_info struct. This should be called
- by all applications creating such a struct. */
-#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
- (INFO).flavour = bfd_target_unknown_flavour, \
- (INFO).arch = bfd_arch_unknown, \
- (INFO).mach = 0, \
- (INFO).endian = BFD_ENDIAN_UNKNOWN, \
- INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC)
-
-/* Call this macro to initialize only the internal variables for the
- disassembler. Architecture dependent things such as byte order, or machine
- variant are not touched by this macro. This makes things much easier for
- GDB which must initialize these things separately. */
-
-#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
- (INFO).fprintf_func = (FPRINTF_FUNC), \
- (INFO).stream = (STREAM), \
- (INFO).symbols = NULL, \
- (INFO).num_symbols = 0, \
- (INFO).private_data = NULL, \
- (INFO).buffer = NULL, \
- (INFO).buffer_vma = 0, \
- (INFO).buffer_length = 0, \
- (INFO).read_memory_func = buffer_read_memory, \
- (INFO).memory_error_func = perror_memory, \
- (INFO).print_address_func = generic_print_address, \
- (INFO).symbol_at_address_func = generic_symbol_at_address, \
- (INFO).flags = 0, \
- (INFO).bytes_per_line = 0, \
- (INFO).bytes_per_chunk = 0, \
- (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \
- (INFO).disassembler_options = NULL, \
- (INFO).insn_info_valid = 0
-
-#define _(x) x
-#define ATTRIBUTE_UNUSED __attribute__((unused))
-
-/* from libbfd */
-
-bfd_vma bfd_getl32 (const bfd_byte *addr);
-bfd_vma bfd_getb32 (const bfd_byte *addr);
-bfd_vma bfd_getl16 (const bfd_byte *addr);
-bfd_vma bfd_getb16 (const bfd_byte *addr);
-typedef enum bfd_boolean {false, true} boolean;
-typedef boolean bfd_boolean;
-
-#endif /* ! defined (DIS_ASM_H) */
diff --git a/disas.c b/disas.c
deleted file mode 100644
index a8bc8ad..0000000
--- a/disas.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/* General "disassemble this chunk" code. Used for debugging. */
-#include "config.h"
-#include "dis-asm.h"
-#include "elf.h"
-#include <errno.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-
-/* Filled in by elfload.c. Simplistic, but will do for now. */
-struct syminfo *syminfos = NULL;
-
-/* Get LENGTH bytes from info's buffer, at target address memaddr.
- Transfer them to myaddr. */
-int
-buffer_read_memory (memaddr, myaddr, length, info)
- bfd_vma memaddr;
- bfd_byte *myaddr;
- int length;
- struct disassemble_info *info;
-{
- if (memaddr < info->buffer_vma
- || memaddr + length > info->buffer_vma + info->buffer_length)
- /* Out of bounds. Use EIO because GDB uses it. */
- return EIO;
- memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
- return 0;
-}
-
-/* Get LENGTH bytes from info's buffer, at target address memaddr.
- Transfer them to myaddr. */
-static int
-target_read_memory (bfd_vma memaddr,
- bfd_byte *myaddr,
- int length,
- struct disassemble_info *info)
-{
- int i;
- for(i = 0; i < length; i++) {
- myaddr[i] = ldub_code(memaddr + i);
- }
- return 0;
-}
-
-/* Print an error message. We can assume that this is in response to
- an error return from buffer_read_memory. */
-void
-perror_memory (status, memaddr, info)
- int status;
- bfd_vma memaddr;
- struct disassemble_info *info;
-{
- if (status != EIO)
- /* Can't happen. */
- (*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
- else
- /* Actually, address between memaddr and memaddr + len was
- out of bounds. */
- (*info->fprintf_func) (info->stream,
- "Address 0x%" PRIx64 " is out of bounds.\n", memaddr);
-}
-
-/* This could be in a separate file, to save miniscule amounts of space
- in statically linked executables. */
-
-/* Just print the address is hex. This is included for completeness even
- though both GDB and objdump provide their own (to print symbolic
- addresses). */
-
-void
-generic_print_address (addr, info)
- bfd_vma addr;
- struct disassemble_info *info;
-{
- (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
-}
-
-/* Just return the given address. */
-
-int
-generic_symbol_at_address (addr, info)
- bfd_vma addr;
- struct disassemble_info * info;
-{
- return 1;
-}
-
-bfd_vma bfd_getl32 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0];
- v |= (unsigned long) addr[1] << 8;
- v |= (unsigned long) addr[2] << 16;
- v |= (unsigned long) addr[3] << 24;
- return (bfd_vma) v;
-}
-
-bfd_vma bfd_getb32 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0] << 24;
- v |= (unsigned long) addr[1] << 16;
- v |= (unsigned long) addr[2] << 8;
- v |= (unsigned long) addr[3];
- return (bfd_vma) v;
-}
-
-bfd_vma bfd_getl16 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0];
- v |= (unsigned long) addr[1] << 8;
- return (bfd_vma) v;
-}
-
-bfd_vma bfd_getb16 (const bfd_byte *addr)
-{
- unsigned long v;
-
- v = (unsigned long) addr[0] << 24;
- v |= (unsigned long) addr[1] << 16;
- return (bfd_vma) v;
-}
-
-#ifdef TARGET_ARM
-static int
-print_insn_thumb1(bfd_vma pc, disassemble_info *info)
-{
- return print_insn_arm(pc | 1, info);
-}
-#endif
-
-/* Disassemble this for me please... (debugging). 'flags' has the following
- values:
- i386 - nonzero means 16 bit code
- arm - nonzero means thumb code
- ppc - nonzero means little endian
- other targets - unused
- */
-void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
-{
- target_ulong pc;
- int count;
- struct disassemble_info disasm_info;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
-
- INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
-
- disasm_info.read_memory_func = target_read_memory;
- disasm_info.buffer_vma = code;
- disasm_info.buffer_length = size;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- disasm_info.endian = BFD_ENDIAN_BIG;
-#else
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#endif
-#if defined(TARGET_I386)
- if (flags == 2)
- disasm_info.mach = bfd_mach_x86_64;
- else if (flags == 1)
- disasm_info.mach = bfd_mach_i386_i8086;
- else
- disasm_info.mach = bfd_mach_i386_i386;
- print_insn = print_insn_i386;
-#elif defined(TARGET_ARM)
- if (flags)
- print_insn = print_insn_thumb1;
- else
- print_insn = print_insn_arm;
-#elif defined(TARGET_SPARC)
- print_insn = print_insn_sparc;
-#ifdef TARGET_SPARC64
- disasm_info.mach = bfd_mach_sparc_v9b;
-#endif
-#elif defined(TARGET_PPC)
- if (flags >> 16)
- disasm_info.endian = BFD_ENDIAN_LITTLE;
- if (flags & 0xFFFF) {
- /* If we have a precise definitions of the instructions set, use it */
- disasm_info.mach = flags & 0xFFFF;
- } else {
-#ifdef TARGET_PPC64
- disasm_info.mach = bfd_mach_ppc64;
-#else
- disasm_info.mach = bfd_mach_ppc;
-#endif
- }
- print_insn = print_insn_ppc;
-#elif defined(TARGET_M68K)
- print_insn = print_insn_m68k;
-#elif defined(TARGET_MIPS)
-#ifdef TARGET_WORDS_BIGENDIAN
- print_insn = print_insn_big_mips;
-#else
- print_insn = print_insn_little_mips;
-#endif
-#elif defined(TARGET_SH4)
- disasm_info.mach = bfd_mach_sh4;
- print_insn = print_insn_sh;
-#elif defined(TARGET_ALPHA)
- disasm_info.mach = bfd_mach_alpha;
- print_insn = print_insn_alpha;
-#elif defined(TARGET_CRIS)
- disasm_info.mach = bfd_mach_cris_v32;
- print_insn = print_insn_crisv32;
-#else
- fprintf(out, "0x" TARGET_FMT_lx
- ": Asm output not supported on this arch\n", code);
- return;
-#endif
-
- for (pc = code; pc < code + size; pc += count) {
- fprintf(out, "0x" TARGET_FMT_lx ": ", pc);
- count = print_insn(pc, &disasm_info);
-#if 0
- {
- int i;
- uint8_t b;
- fprintf(out, " {");
- for(i = 0; i < count; i++) {
- target_read_memory(pc + i, &b, 1, &disasm_info);
- fprintf(out, " %02x", b);
- }
- fprintf(out, " }");
- }
-#endif
- fprintf(out, "\n");
- if (count < 0)
- break;
- }
-}
-
-/* Disassemble this for me please... (debugging). */
-void disas(FILE *out, void *code, unsigned long size)
-{
- unsigned long pc;
- int count;
- struct disassemble_info disasm_info;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
-
- INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
-
- disasm_info.buffer = code;
- disasm_info.buffer_vma = (unsigned long)code;
- disasm_info.buffer_length = size;
-
-#ifdef WORDS_BIGENDIAN
- disasm_info.endian = BFD_ENDIAN_BIG;
-#else
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#endif
-#if defined(__i386__)
- disasm_info.mach = bfd_mach_i386_i386;
- print_insn = print_insn_i386;
-#elif defined(__x86_64__)
- disasm_info.mach = bfd_mach_x86_64;
- print_insn = print_insn_i386;
-#elif defined(__powerpc__)
- print_insn = print_insn_ppc;
-#elif defined(__alpha__)
- print_insn = print_insn_alpha;
-#elif defined(__sparc__)
- print_insn = print_insn_sparc;
-#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
- disasm_info.mach = bfd_mach_sparc_v9b;
-#endif
-#elif defined(__arm__)
- print_insn = print_insn_arm;
-#elif defined(__MIPSEB__)
- print_insn = print_insn_big_mips;
-#elif defined(__MIPSEL__)
- print_insn = print_insn_little_mips;
-#elif defined(__m68k__)
- print_insn = print_insn_m68k;
-#elif defined(__s390__)
- print_insn = print_insn_s390;
-#elif defined(__hppa__)
- print_insn = print_insn_hppa;
-#else
- fprintf(out, "0x%lx: Asm output not supported on this arch\n",
- (long) code);
- return;
-#endif
- for (pc = (unsigned long)code; pc < (unsigned long)code + size; pc += count) {
- fprintf(out, "0x%08lx: ", pc);
-#ifdef __arm__
- /* since data is included in the code, it is better to
- display code data too */
- fprintf(out, "%08x ", (int)bfd_getl32((const bfd_byte *)pc));
-#endif
- count = print_insn(pc, &disasm_info);
- fprintf(out, "\n");
- if (count < 0)
- break;
- }
-}
-
-/* Look up symbol for debugging purpose. Returns "" if unknown. */
-const char *lookup_symbol(target_ulong orig_addr)
-{
- unsigned int i;
- /* Hack, because we know this is x86. */
- Elf32_Sym *sym;
- struct syminfo *s;
- target_ulong addr;
-
- for (s = syminfos; s; s = s->next) {
- sym = s->disas_symtab;
- for (i = 0; i < s->disas_num_syms; i++) {
- if (sym[i].st_shndx == SHN_UNDEF
- || sym[i].st_shndx >= SHN_LORESERVE)
- continue;
-
- if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
- continue;
-
- addr = sym[i].st_value;
-#if defined(TARGET_ARM) || defined (TARGET_MIPS)
- /* The bottom address bit marks a Thumb or MIPS16 symbol. */
- addr &= ~(target_ulong)1;
-#endif
- if (orig_addr >= addr
- && orig_addr < addr + sym[i].st_size)
- return s->disas_strtab + sym[i].st_name;
- }
- }
- return "";
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...);
-
-static int monitor_disas_is_physical;
-static CPUState *monitor_disas_env;
-
-static int
-monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
- struct disassemble_info *info)
-{
- if (monitor_disas_is_physical) {
- cpu_physical_memory_rw(memaddr, myaddr, length, 0);
- } else {
- cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
- }
- return 0;
-}
-
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
- return 0;
-}
-
-void monitor_disas(CPUState *env,
- target_ulong pc, int nb_insn, int is_physical, int flags)
-{
- int count, i;
- struct disassemble_info disasm_info;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
-
- INIT_DISASSEMBLE_INFO(disasm_info, NULL, monitor_fprintf);
-
- monitor_disas_env = env;
- monitor_disas_is_physical = is_physical;
- disasm_info.read_memory_func = monitor_read_memory;
-
- disasm_info.buffer_vma = pc;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- disasm_info.endian = BFD_ENDIAN_BIG;
-#else
- disasm_info.endian = BFD_ENDIAN_LITTLE;
-#endif
-#if defined(TARGET_I386)
- if (flags == 2)
- disasm_info.mach = bfd_mach_x86_64;
- else if (flags == 1)
- disasm_info.mach = bfd_mach_i386_i8086;
- else
- disasm_info.mach = bfd_mach_i386_i386;
- print_insn = print_insn_i386;
-#elif defined(TARGET_ARM)
- print_insn = print_insn_arm;
-#elif defined(TARGET_ALPHA)
- print_insn = print_insn_alpha;
-#elif defined(TARGET_SPARC)
- print_insn = print_insn_sparc;
-#ifdef TARGET_SPARC64
- disasm_info.mach = bfd_mach_sparc_v9b;
-#endif
-#elif defined(TARGET_PPC)
-#ifdef TARGET_PPC64
- disasm_info.mach = bfd_mach_ppc64;
-#else
- disasm_info.mach = bfd_mach_ppc;
-#endif
- print_insn = print_insn_ppc;
-#elif defined(TARGET_M68K)
- print_insn = print_insn_m68k;
-#elif defined(TARGET_MIPS)
-#ifdef TARGET_WORDS_BIGENDIAN
- print_insn = print_insn_big_mips;
-#else
- print_insn = print_insn_little_mips;
-#endif
-#else
- term_printf("0x" TARGET_FMT_lx
- ": Asm output not supported on this arch\n", pc);
- return;
-#endif
-
- for(i = 0; i < nb_insn; i++) {
- term_printf("0x" TARGET_FMT_lx ": ", pc);
- count = print_insn(pc, &disasm_info);
- term_printf("\n");
- if (count < 0)
- break;
- pc += count;
- }
-}
-#endif
diff --git a/disas.h b/disas.h
deleted file mode 100644
index ee0a79c..0000000
--- a/disas.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _QEMU_DISAS_H
-#define _QEMU_DISAS_H
-
-/* Disassemble this for me please... (debugging). */
-void disas(FILE *out, void *code, unsigned long size);
-void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
-void monitor_disas(CPUState *env,
- target_ulong pc, int nb_insn, int is_physical, int flags);
-
-/* Look up symbol for debugging purpose. Returns "" if unknown. */
-const char *lookup_symbol(target_ulong orig_addr);
-
-/* Filled in by elfload.c. Simplistic, but will do for now. */
-extern struct syminfo {
- unsigned int disas_num_syms;
- void *disas_symtab;
- const char *disas_strtab;
- struct syminfo *next;
-} *syminfos;
-
-#endif /* _QEMU_DISAS_H */
diff --git a/distrib/Makefile b/distrib/Makefile
deleted file mode 100644
index 677b0bb..0000000
--- a/distrib/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-ZLIB_VERSION := zlib-1.2.3
-LIBPNG_VERSION := libpng-1.2.19
-
-ZLIB_DIR = $(SRC_PATH)/distrib/$(ZLIB_VERSION)
-LIBPNG_DIR := $(SRC_PATH)/distrib/$(LIBPNG_VERSION)
-
-include $(ZLIB_DIR)/Makefile
-include $(LIBPNG_DIR)/Makefile
diff --git a/distrib/README b/distrib/README
deleted file mode 100644
index 8a2cf52..0000000
--- a/distrib/README
+++ /dev/null
@@ -1,50 +0,0 @@
-This is source release of the Android emulator. simply run the "build-emulator.sh" script to
-generate a statically linked "emulator" binary in the current directory.
-
-you can also use the "--target=<path>" option to install the executable into a different location,
-
-At the moment, only Linux and Mac OS X are supported.
-
-This emulator is probably not usable without other support files provided by the Android project,
-like a specific kernel image, ramdisk, system and user disk images. Please go to the Android web
-site for more details.
-
-This emulator is licensed under the GNU General Public License (GPL) version 2, which can be
-found in the file "qemu/COPYING".
-
-it is based on QEMU 0.8.2 with many changes used to support the following features:
-
- - additionnal hardware support for some Android reference boards.
-
- - various OS-X related patches to make everything compile cleanly with GCC 4.1 and
- beyond. this includes better support for the Mach-O binary format
-
- - support for instruction-level profiling and data cache simulation. this allows the
- emulator to generate "profile" files that can later be analyzed with external tools
- to provide accurate information about what's happening in the system
-
- - changes in the dynamic code generators, mainly to support concurrent generators in
- a single binary (this allows us to use different generators for profiling and
- non-profiling modes, and switch between them dynamically at runtime when needed)
-
- - support for network throttling and latency simulation, used to better emulate the
- network conditions of radio networks.
-
- - a new graphical user interface capable of displaying and rotating "device skins"
-
- - an optional (and disabled by default) "polling" runtime mode that doesn't use
- SIGALRM signals to implement timers. this makes for much better timing accuracy
- when using "old" emukated Linux kernels, at the cost of using 100% CPU, even when
- the guest system is idle. This is now disabled since Linux 2.6.21 and beyond use
- "dynamic ticks" that make this mode un-necessary for Android.
-
-
-it also uses a patched version of LibSDL-1.2.12 which implements the following:
-
- - prevent a fatal bug in Quartz Extreme's QuickDraw emulation to crash the program
- whenever SDL_WINDOW_POS is set in the environment before starting the program.
- the patch implements a simple workaround to this system-level problem.
-
- - new APIs: SDL_WM_GetPos() and SDL_WM_SetPos() are used to retrieve and set the emulator
- window position. this allows us to implement a simple-yet-useful feature: the emulator remembers
- its position among restarts.
diff --git a/distrib/build-emulator.sh b/distrib/build-emulator.sh
deleted file mode 100755
index b2722cf..0000000
--- a/distrib/build-emulator.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-#
-# this script is used to build a static version of the Android emulator
-# from our distribution package.
-#
-cd $(dirname $0)
-CURDIR=$(pwd)
-
-show_help=
-TARGET=emulator
-for opt; do
- optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
- case "$opt" in
- --help|-h|-\?) show_help=yes
- ;;
- --target=*) TARGET=$optarg
- ;;
- esac
-done
-
-if [ -n "$show_help" ] ; then
- echo "usage: build-emulator [--target=FILEPATH]"
- exit 1
-fi
-
-# directory where we'll place the temporary SDL binaries
-LOCAL=$CURDIR/local
-
-cd $CURDIR/sdl
-if ! (./android-configure --prefix=$LOCAL && make && make install); then
- echo "ERROR: could not build SDL library, please check their sources"
-fi
-
-cd $CURDIR/qemu
-if ! (./android-rebuild.sh --sdl-config=$LOCAL/bin/sdl-config); then
- echo "ERROR: could not build the emulator, please check the sources"
-fi
-
-cp objs/emulator $CURDIR/emulator
diff --git a/distrib/build_gcc_qemu_darwin.sh b/distrib/build_gcc_qemu_darwin.sh
deleted file mode 100755
index 4c82af4..0000000
--- a/distrib/build_gcc_qemu_darwin.sh
+++ /dev/null
@@ -1,482 +0,0 @@
-#!/bin/sh
-# APPLE LOCAL file B&I
-
-set -x
-
-# set BUILD_CPLUSPLUS to 'true' if you want to compile support for C++
-BUILD_CPLUSPLUS=false
-
-# set BUILD_DOCS to 'true' to build and install the documentation
-BUILD_DOCS=false
-
-# set BUILD_SYM to 'true' to build and install symbolic binaries
-BUILD_SYM=false
-
-# -arch arguments are different than configure arguments. We need to
-# translate them.
-
-TRANSLATE_ARCH="sed -e s/ppc/powerpc/ -e s/i386/i686/"
-
-# Build GCC the "Apple way".
-# Parameters:
-
-# The first parameter is a space-separated list of the architectures
-# the compilers will run on. For instance, "ppc i386". If the
-# current machine isn't in the list, it will (effectively) be added.
-#HOSTS=`echo $1 | $TRANSLATE_ARCH `
-HOSTS=i686
-
-# The second parameter is a space-separated list of the architectures the
-# compilers will generate code for. If the current machine isn't in
-# the list, a compiler for it will get built anyway, but won't be
-# installed.
-#TARGETS=`echo $2 | $TRANSLATE_ARCH`
-TARGETS=i686
-
-# The GNU makefile target ('bootstrap' by default).
-BOOTSTRAP=${BOOTSTRAP-bootstrap}
-
-# The B&I build srcript (~rc/bin/buildit) accepts an '-othercflags'
-# command-line flag, and captures the argument to that flag in
-# $RC_NONARCH_CFLAGS (and mysteriously prepends '-pipe' thereto).
-# We will allow this to override the default $CFLAGS and $CXXFLAGS.
-
-CFLAGS="-g -O2 ${RC_NONARCH_CFLAGS/-pipe/}"
-
-# This isn't a parameter; it is the architecture of the current machine.
-BUILD=`arch | $TRANSLATE_ARCH`
-
-# The third parameter is the path to the compiler sources. There should
-# be a shell script named 'configure' in this directory. This script
-# makes a copy...
-#ORIG_SRC_DIR="$3"
-ORIG_SRC_DIR=`dirname $0`
-ORIG_SRC_DIR=`pwd`/$ORIG_SRC_DIR
-
-# The fourth parameter is the location where the compiler will be installed,
-# normally "/usr". You can move it once it's built, so this mostly controls
-# the layout of $DEST_DIR.
-#DEST_ROOT="$4"
-DEST_ROOT=/
-
-# The fifth parameter is the place where the compiler will be copied once
-# it's built.
-#DEST_DIR="$5"
-DEST_DIR=/Volumes/Android/device/prebuilt/darwin-x86/gcc-qemu
-
-# The sixth parameter is a directory in which to place information (like
-# unstripped executables and generated source files) helpful in debugging
-# the resulting compiler.
-#SYM_DIR="$6"
-SYM_DIR=`pwd`/sym
-
-# The current working directory is where the build will happen.
-# It may already contain a partial result of an interrupted build,
-# in which case this script will continue where it left off.
-DIR=`pwd`
-
-# This isn't a parameter; it's the version of the compiler that we're
-# about to build. It's included in the names of various files and
-# directories in the installed image.
-VERS=`sed -n -e '/version_string/s/.*\"\([^ \"]*\)[ \"].*/\1/p' \
- < $ORIG_SRC_DIR/gcc/version.c || exit 1`
-
-# This isn't a parameter either, it's the major version of the compiler
-# to be built. It's VERS but only up to the second '.' (if there is one).
-MAJ_VERS=`echo $VERS | sed 's/\([0-9]*\.[0-9]*\)[.-].*/\1/'`
-
-# This is the default architecture for i386 configurations.
-I386_CPU="--with-arch=pentium-m --with-tune=prescott"
-
-# This is the libstdc++ version to use.
-LIBSTDCXX_VERSION=4.0.0
-
-# Sniff to see if we can do ppc64 building.
-DARWIN_VERS=8
-if [ x"`file /usr/lib/crt1.o | grep 'architecture ppc64'`" == x ]; then
- DARWIN_VERS=7
-fi
-
-echo DARWIN_VERS = $DARWIN_VERS
-
-########################################
-# Run the build.
-
-# Create the source tree we'll actually use to build, deleting
-# tcl since it doesn't actually build properly in a cross environment
-# and we don't really need it.
-SRC_DIR=$DIR/src
-rm -rf $SRC_DIR || exit 1
-mkdir $SRC_DIR || exit 1
-ln -s $ORIG_SRC_DIR/* $SRC_DIR/ || exit 1
-rm -rf $SRC_DIR/tcl $SRC_DIR/expect $SRC_DIR/dejagnu || exit 1
-# Also remove libstdc++ since it is built from a separate project.
-rm -rf $SRC_DIR/libstdc++-v3 || exit 1
-# Clean out old specs files
-rm -f /usr/lib/gcc/*/4.0.0/specs
-
-ENABLE_LANGUAGES="--enable-languages=c,objc"
-if [ $BUILD_CPLUSPLUS = true ] ; then
- ENABLE_LANGUAGES="$ENABLE_LANGUAGES,c++,obj-c++"
-fi
-
-# These are the configure and build flags that are used.
-CONFIGFLAGS="--disable-checking -enable-werror \
- --prefix=$DEST_ROOT \
- --mandir=\${prefix}/share/man \
- $ENABLE_LANGUAGES \
- --program-transform-name=/^[cg][^.-]*$/s/$/-$MAJ_VERS/ \
- --with-gxx-include-dir=\${prefix}/include/c++/$LIBSTDCXX_VERSION \
- --with-slibdir=/usr/lib \
- --build=$BUILD-apple-darwin$DARWIN_VERS
- --disable-nls"
-
-# Figure out how many make processes to run.
-SYSCTL=`sysctl -n hw.activecpu`
-
-# hw.activecpu only available in 10.2.6 and later
-if [ -z "$SYSCTL" ]; then
- SYSCTL=`sysctl -n hw.ncpu`
-fi
-
-# sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot.
-# Builders can default to 2, since even if they are single processor,
-# nothing else is running on the machine.
-if [ -z "$SYSCTL" ]; then
- SYSCTL=2
-fi
-
-# The $LOCAL_MAKEFLAGS variable can be used to override $MAKEFLAGS.
-MAKEFLAGS=${LOCAL_MAKEFLAGS-"-j $SYSCTL"}
-
-# Build the native GCC. Do this even if the user didn't ask for it
-# because it'll be needed for the bootstrap.
-mkdir -p $DIR/obj-$BUILD-$BUILD $DIR/dst-$BUILD-$BUILD || exit 1
-cd $DIR/obj-$BUILD-$BUILD || exit 1
-if [ \! -f Makefile ]; then
- $SRC_DIR/configure $CONFIGFLAGS \
- `if [ $BUILD = i686 ] ; then echo $I386_CPU ; fi` \
- --host=$BUILD-apple-darwin$DARWIN_VERS --target=$BUILD-apple-darwin$DARWIN_VERS || exit 1
-fi
-make $MAKEFLAGS $BOOTSTRAP CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
-if [ $BUILD_DOCS = "true" ] ; then
-make $MAKEFLAGS html CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
-fi
-make $MAKEFLAGS DESTDIR=$DIR/dst-$BUILD-$BUILD install-gcc install-target \
- CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
-
-# Add the compiler we just built to the path, giving it appropriate names.
-D=$DIR/dst-$BUILD-$BUILD/$DEST_ROOT/bin
-ln -f $D/gcc-$MAJ_VERS $D/gcc || exit 1
-ln -f $D/gcc $D/$BUILD-apple-darwin$DARWIN_VERS-gcc || exit 1
-PATH=$DIR/dst-$BUILD-$BUILD/$DEST_ROOT/bin:$PATH
-
-# The cross-tools' build process expects to find certain programs
-# under names like 'i386-apple-darwin$DARWIN_VERS-ar'; so make them.
-# Annoyingly, ranlib changes behaviour depending on what you call it,
-# so we have to use a shell script for indirection, grrr.
-rm -rf $DIR/bin || exit 1
-mkdir $DIR/bin || exit 1
-for prog in ar nm ranlib strip lipo ; do
- for t in `echo $TARGETS $HOSTS | sort -u`; do
- P=$DIR/bin/${t}-apple-darwin$DARWIN_VERS-${prog}
- echo '#!/bin/sh' > $P || exit 1
- echo 'exec /usr/bin/'${prog}' $*' >> $P || exit 1
- chmod a+x $P || exit 1
- done
-done
-for t in `echo $1 $2 | sort -u`; do
- gt=`echo $t | $TRANSLATE_ARCH`
- P=$DIR/bin/${gt}-apple-darwin$DARWIN_VERS-as
- echo '#!/bin/sh' > $P || exit 1
- echo 'exec /usr/bin/as -arch '${t}' $*' >> $P || exit 1
- chmod a+x $P || exit 1
-done
-PATH=$DIR/bin:$PATH
-
-# Build the cross-compilers, using the compiler we just built.
-for t in $TARGETS ; do
- if [ $t != $BUILD ] ; then
- mkdir -p $DIR/obj-$BUILD-$t $DIR/dst-$BUILD-$t || exit 1
- cd $DIR/obj-$BUILD-$t || exit 1
- if [ \! -f Makefile ]; then
- $SRC_DIR/configure $CONFIGFLAGS --enable-werror-always \
- `if [ $t = i686 ] ; then echo $I386_CPU ; fi` \
- --program-prefix=$t-apple-darwin$DARWIN_VERS- \
- --host=$BUILD-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1
- fi
- make $MAKEFLAGS all CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
- make $MAKEFLAGS DESTDIR=$DIR/dst-$BUILD-$t install-gcc install-target \
- CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
-
- # Add the compiler we just built to the path.
- PATH=$DIR/dst-$BUILD-$t/$DEST_ROOT/bin:$PATH
- fi
-done
-
-# Rearrange various libraries, for no really good reason.
-for t in $TARGETS ; do
- DT=$DIR/dst-$BUILD-$t
- D=`echo $DT/$DEST_ROOT/lib/gcc/$t-apple-darwin$DARWIN_VERS/$VERS`
- mv $D/static/libgcc.a $D/libgcc_static.a || exit 1
- mv $D/kext/libgcc.a $D/libcc_kext.a || exit 1
- rm -r $D/static $D/kext || exit 1
-done
-
-# Build the cross-hosted compilers.
-for h in $HOSTS ; do
- if [ $h != $BUILD ] ; then
- for t in $TARGETS ; do
- mkdir -p $DIR/obj-$h-$t $DIR/dst-$h-$t || exit 1
- cd $DIR/obj-$h-$t || exit 1
- if [ $h = $t ] ; then
- pp=
- else
- pp=$t-apple-darwin$DARWIN_VERS-
- fi
-
- if [ \! -f Makefile ]; then
- $SRC_DIR/configure $CONFIGFLAGS \
- `if [ $t = i686 ] ; then echo $I386_CPU ; fi` \
- --program-prefix=$pp \
- --host=$h-apple-darwin$DARWIN_VERS --target=$t-apple-darwin$DARWIN_VERS || exit 1
- fi
- make $MAKEFLAGS all-gcc CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
- make $MAKEFLAGS DESTDIR=$DIR/dst-$h-$t install-gcc \
- CFLAGS="$CFLAGS" CXXFLAGS="$CFLAGS" || exit 1
- done
- fi
-done
-
-########################################
-# Construct the actual destination root, by copying stuff from
-# $DIR/dst-* to $DEST_DIR, with occasional 'lipo' commands.
-
-cd $DEST_DIR || exit 1
-
-# Clean out DEST_DIR in case -noclean was passed to buildit.
-rm -rf * || exit 1
-
-if [ $BUILD_DOCS = "true" ] ; then
-# HTML documentation
-HTMLDIR="/Developer/ADC Reference Library/documentation/DeveloperTools"
-mkdir -p ".$HTMLDIR" || exit 1
-cp -Rp $DIR/obj-$BUILD-$BUILD/gcc/HTML/* ".$HTMLDIR/" || exit 1
-
-# Manual pages
-mkdir -p .$DEST_ROOT/share || exit 1
-cp -Rp $DIR/dst-$BUILD-$BUILD$DEST_ROOT/share/man .$DEST_ROOT/share/ \
- || exit 1
-fi
-
-# libexec
-cd $DIR/dst-$BUILD-$BUILD$DEST_ROOT/libexec/gcc/$BUILD-apple-darwin$DARWIN_VERS/$VERS \
- || exit 1
-LIBEXEC_FILES=`find . -type f -print || exit 1`
-LIBEXEC_DIRS=`find . -type d -print || exit 1`
-cd $DEST_DIR || exit 1
-for t in $TARGETS ; do
- DL=$DEST_ROOT/libexec/gcc/$t-apple-darwin$DARWIN_VERS/$VERS
- for d in $LIBEXEC_DIRS ; do
- mkdir -p .$DL/$d || exit 1
- done
- for f in $LIBEXEC_FILES ; do
- if file $DIR/dst-*-$t$DL/$f | grep -q 'Mach-O executable' ; then
- lipo -output .$DL/$f -create $DIR/dst-*-$t$DL/$f || exit 1
- else
- cp -p $DIR/dst-$BUILD-$t$DL/$f .$DL/$f || exit 1
- fi
- done
-done
-
-# bin
-# The native drivers ('native' is different in different architectures).
-BIN_FILES=`ls $DIR/dst-$BUILD-$BUILD$DEST_ROOT/bin | grep '^[^-]*-[0-9.]*$' \
- | grep -v gccbug | grep -v gcov || exit 1`
-mkdir .$DEST_ROOT/bin
-for f in $BIN_FILES ; do
- lipo -output .$DEST_ROOT/bin/$f -create $DIR/dst-*$DEST_ROOT/bin/$f || exit 1
-done
-# gcov, which is special only because it gets built multiple times and lipo
-# will complain if we try to add two architectures into the same output.
-TARG0=`echo $TARGETS | cut -d ' ' -f 1`
-lipo -output .$DEST_ROOT/bin/gcov-$MAJ_VERS -create \
- $DIR/dst-*-$TARG0$DEST_ROOT/bin/*gcov* || exit 1
-# The fully-named drivers, which have the same target on every host.
-for t in $TARGETS ; do
- lipo -output .$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-gcc-$VERS -create \
- $DIR/dst-*-$t$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-gcc-$VERS || exit 1
- if [ $BUILD_CPLUSPLUS = "true" ] ; then
- lipo -output .$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-g++-$VERS -create \
- $DIR/dst-*-$t$DEST_ROOT/bin/$t-apple-darwin$DARWIN_VERS-g++* || exit 1
- fi
-done
-
-# lib
-mkdir -p .$DEST_ROOT/lib/gcc || exit 1
-for t in $TARGETS ; do
- cp -Rp $DIR/dst-$BUILD-$t$DEST_ROOT/lib/gcc/$t-apple-darwin$DARWIN_VERS \
- .$DEST_ROOT/lib/gcc || exit 1
-done
-
-SHARED_LIBS="libgcc_s.1.dylib libgcc_s.10.4.dylib libgcc_s.10.5.dylib"
-if echo $HOSTS | grep -q powerpc ; then
- SHARED_LIBS="${SHARED_LIBS} libgcc_s_ppc64.1.dylib"
-fi
-for l in $SHARED_LIBS ; do
- CANDIDATES=()
- for t in $TARGETS ; do
- if [ -e $DIR/dst-$t-$t$DEST_ROOT/lib/$l ] ; then
- CANDIDATES[${#CANDIDATES[*]}]=$DIR/dst-$t-$t$DEST_ROOT/lib/$l
- fi
- done
- if [ -L ${CANDIDATES[0]} ] ; then
- ln -s `readlink ${CANDIDATES[0]}` .$DEST_ROOT/lib/$l || exit 1
- else
- lipo -output .$DEST_ROOT/lib/$l -create "${CANDIDATES[@]}" || exit 1
- fi
-done
-
-if [ $BUILD_CPLUSPLUS = "true" ] ; then
-for t in $TARGETS ; do
- ln -s ../../../libstdc++.6.dylib \
- .$DEST_ROOT/lib/gcc/$t-apple-darwin$DARWIN_VERS/$VERS/libstdc++.dylib \
- || exit 1
-done
-fi
-
-# include
-HEADERPATH=$DEST_ROOT/include/gcc/darwin/$MAJ_VERS
-mkdir -p .$HEADERPATH || exit 1
-
-# Some headers are installed from more-hdrs/. They all share
-# one common feature: they shouldn't be installed here. Sometimes,
-# they should be part of FSF GCC and installed from there; sometimes,
-# they should be installed by some completely different package; sometimes,
-# they only exist for codewarrior compatibility and codewarrior should provide
-# its own. We take care not to install the headers if Libc is already
-# providing them.
-cd $SRC_DIR/more-hdrs
-for h in `echo *.h` ; do
- if [ ! -f /usr/include/$h -o -L /usr/include/$h ] ; then
- cp -R $h $DEST_DIR$HEADERPATH/$h || exit 1
- for t in $TARGETS ; do
- THEADERPATH=$DEST_DIR$DEST_ROOT/lib/gcc/${t}-apple-darwin$DARWIN_VERS/$VERS/include
- [ -f $THEADERPATH/$h ] || \
- ln -s ../../../../../include/gcc/darwin/$MAJ_VERS/$h $THEADERPATH/$h || \
- exit 1
- done
- fi
-done
-mkdir -p $DEST_DIR$HEADERPATH/machine
-for h in `echo */*.h` ; do
- if [ ! -f /usr/include/$h -o -L /usr/include/$h ] ; then
- cp -R $h $DEST_DIR$HEADERPATH/$h || exit 1
- for t in $TARGETS ; do
- THEADERPATH=$DEST_DIR$DEST_ROOT/lib/gcc/${t}-apple-darwin$DARWIN_VERS/$VERS/include
- mkdir -p $THEADERPATH/machine
- # In fixincludes/fixinc.in we created this file... always link for now
- [ -f /disable/$THEADERPATH/$h ] || \
- ln -f -s ../../../../../../include/gcc/darwin/$MAJ_VERS/$h $THEADERPATH/$h || \
- exit 1
- done
- fi
-done
-
-if [ $BUILD_DOCS = "true" ] ; then
-if [ $BUILD_CPLUSPLUS = "true" ] ; then
-# Add extra man page symlinks for 'c++' and for arch-specific names.
-MDIR=$DEST_DIR$DEST_ROOT/share/man/man1
-ln -f $MDIR/g++-$MAJ_VERS.1 $MDIR/c++-$MAJ_VERS.1 || exit 1
-for t in $TARGETS ; do
- ln -f $MDIR/gcc-$MAJ_VERS.1 $MDIR/$t-apple-darwin$DARWIN_VERS-gcc-$VERS.1 \
- || exit 1
- ln -f $MDIR/g++-$MAJ_VERS.1 $MDIR/$t-apple-darwin$DARWIN_VERS-g++-$VERS.1 \
- || exit 1
-done
-fi
-fi
-
-# Build driver-driver using fully-named drivers
-for h in $HOSTS ; do
- $DEST_DIR$DEST_ROOT/bin/$h-apple-darwin$DARWIN_VERS-gcc-$VERS \
- $ORIG_SRC_DIR/gcc/config/darwin-driver.c \
- -DPDN="\"-apple-darwin$DARWIN_VERS-gcc-$VERS\"" \
- -DIL="\"$DEST_ROOT/bin/\"" -I $ORIG_SRC_DIR/include \
- -I $ORIG_SRC_DIR/gcc -I $ORIG_SRC_DIR/gcc/config \
- -liberty -L$DIR/dst-$BUILD-$h$DEST_ROOT/lib/ \
- -L$DIR/dst-$BUILD-$h$DEST_ROOT/$h-apple-darwin$DARWIN_VERS/lib/ \
- -L$DIR/obj-$h-$BUILD/libiberty/ \
- -o $DEST_DIR/$DEST_ROOT/bin/tmp-$h-gcc-$MAJ_VERS || exit 1
-
- if [ $BUILD_CPLUSPLUS = "true" ] ; then
- $DEST_DIR$DEST_ROOT/bin/$h-apple-darwin$DARWIN_VERS-gcc-$VERS \
- $ORIG_SRC_DIR/gcc/config/darwin-driver.c \
- -DPDN="\"-apple-darwin$DARWIN_VERS-g++-$VERS\"" \
- -DIL="\"$DEST_ROOT/bin/\"" -I $ORIG_SRC_DIR/include \
- -I $ORIG_SRC_DIR/gcc -I $ORIG_SRC_DIR/gcc/config \
- -liberty -L$DIR/dst-$BUILD-$h$DEST_ROOT/lib/ \
- -L$DIR/dst-$BUILD-$h$DEST_ROOT/$h-apple-darwin$DARWIN_VERS/lib/ \
- -L$DIR/obj-$h-$BUILD/libiberty/ \
- -o $DEST_DIR/$DEST_ROOT/bin/tmp-$h-g++-$MAJ_VERS || exit 1
- fi
-done
-
-lipo -output $DEST_DIR/$DEST_ROOT/bin/gcc-$MAJ_VERS -create \
- $DEST_DIR/$DEST_ROOT/bin/tmp-*-gcc-$MAJ_VERS || exit 1
-
-if [ $BUILD_CPLUSPLUS = "true" ] ; then
-lipo -output $DEST_DIR/$DEST_ROOT/bin/g++-$MAJ_VERS -create \
- $DEST_DIR/$DEST_ROOT/bin/tmp-*-g++-$MAJ_VERS || exit 1
-
-ln -f $DEST_DIR/$DEST_ROOT/bin/g++-$MAJ_VERS $DEST_DIR/$DEST_ROOT/bin/c++-$MAJ_VERS || exit 1
-fi
-
-rm $DEST_DIR/$DEST_ROOT/bin/tmp-*-gcc-$MAJ_VERS || exit 1
-if [ $BUILD_CPLUPLUS = "true" ] ; then
-rm $DEST_DIR/$DEST_ROOT/bin/tmp-*-g++-$MAJ_VERS || exit 1
-fi
-
-########################################
-# Save the source files and objects needed for debugging
-if [ $BUILD_SYM = "true" ] ; then
-cd $SYM_DIR || exit 1
-
-# Clean out SYM_DIR in case -noclean was passed to buildit.
-rm -rf * || exit 1
-
-# Save executables and libraries.
-cd $DEST_DIR || exit 1
-find . \( -perm -0111 -or -name \*.a -or -name \*.dylib \) -type f -print \
- | cpio -pdml $SYM_DIR || exit 1
-# Save source files.
-mkdir $SYM_DIR/src || exit 1
-cd $DIR || exit 1
-find obj-* -name \*.\[chy\] -print | cpio -pdml $SYM_DIR/src || exit 1
-fi
-
-########################################
-# Strip the executables and libraries
-find $DEST_DIR -perm -0111 \! -name \*.dylib \! -name fixinc.sh \
- \! -name mkheaders -type f -print \
- | xargs strip || exit 1
-find $DEST_DIR \( -name \*.a -or -name \*.dylib \) \
- \! -name libgcc_s.10.*.dylib -type f -print \
- | xargs strip -SX || exit 1
-find $DEST_DIR -name \*.a -type f -print \
- | xargs ranlib || exit 1
-chgrp -h -R wheel $DEST_DIR
-chgrp -R wheel $DEST_DIR
-
-#########################################3
-# Rename the executables
-FILES="gcc cpp"
-if [ $BUILD_CPLUSPLUS = "true" ] ; then
- FILES="$FILES g++"
-fi
-for ff in $FILES; do
- ln -f $DEST_DIR/bin/$ff-$MAJ_VERS $DEST_DIR/bin/$ff || exit 1
-done
-
-# Done!
-exit 0
diff --git a/distrib/libpng-1.2.19/Makefile b/distrib/libpng-1.2.19/Makefile
deleted file mode 100644
index ba59f45..0000000
--- a/distrib/libpng-1.2.19/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# Makefile used to compile libpng statically
-# you need to define ZLIB_INCLUDE to the Zlib include path
-# and PREFIX to the installation path
-#
-LIBPNG_LIB := $(SRC_PATH)/libpng.a
-LIBPNG_CFLAGS := -I$(LIBPNG_DIR)
-
-HOST_ARCH := $(shell uname -p)
-HOST_OS := $(shell uname -s)
-ifeq ($(HOST_OS),Darwin)
- HOST_OS := darwin
-endif
-
-include $(LIBPNG_DIR)/sources.make
-
-LIBPNG_OBJS := $(LIBPNG_SOURCES:%.c=%.o)
-
-$(LIBPNG_LIB): $(LIBPNG_OBJS)
- ar ru $@ $(LIBPNG_OBJS)
-
-$(LIBPNG_OBJS): CFLAGS += $(ZLIB_CFLAGS) $(LIBPNG_CFLAGS)
-
-clean-libpng:
- rm -f $(LIBPNG_OBJS) $(LIBPNG_LIB)
-
diff --git a/distrib/libpng-1.2.19/png.c b/distrib/libpng-1.2.19/png.c
deleted file mode 100644
index 8aa4131..0000000
--- a/distrib/libpng-1.2.19/png.c
+++ /dev/null
@@ -1,895 +0,0 @@
-
-/* png.c - location for general purpose libpng functions
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-#define PNG_INTERNAL
-#define PNG_NO_EXTERN
-#include "png.h"
-
-/* Generate a compiler error if there is an old png.h in the search path. */
-typedef version_1_2_19 Your_png_h_is_not_version_1_2_19;
-
-/* Version information for C files. This had better match the version
- * string defined in png.h. */
-
-#ifdef PNG_USE_GLOBAL_ARRAYS
-/* png_libpng_ver was changed to a function in version 1.0.5c */
-PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
-
-#ifdef PNG_READ_SUPPORTED
-
-/* png_sig was changed to a function in version 1.0.5c */
-/* Place to hold the signature string for a PNG file. */
-PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
-#endif /* PNG_READ_SUPPORTED */
-
-/* Invoke global declarations for constant strings for known chunk types */
-PNG_IHDR;
-PNG_IDAT;
-PNG_IEND;
-PNG_PLTE;
-PNG_bKGD;
-PNG_cHRM;
-PNG_gAMA;
-PNG_hIST;
-PNG_iCCP;
-PNG_iTXt;
-PNG_oFFs;
-PNG_pCAL;
-PNG_sCAL;
-PNG_pHYs;
-PNG_sBIT;
-PNG_sPLT;
-PNG_sRGB;
-PNG_tEXt;
-PNG_tIME;
-PNG_tRNS;
-PNG_zTXt;
-
-#ifdef PNG_READ_SUPPORTED
-/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
-/* start of interlace block */
-PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
-/* offset to next interlace block */
-PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
-/* start of interlace block in the y direction */
-PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
-/* offset to next interlace block in the y direction */
-PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
-/* width of interlace block (used in assembler routines only) */
-#if defined(PNG_HAVE_MMX_COMBINE_ROW) || defined(PNG_OPTIMIZED_CODE_SUPPORTED)
-PNG_CONST int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
-#endif
-
-/* Height of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
-PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
-*/
-
-/* Mask to determine which pixels are valid in a pass */
-PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
-
-/* Mask to determine which pixels to overwrite while displaying */
-PNG_CONST int FARDATA png_pass_dsp_mask[]
- = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
-
-#endif /* PNG_READ_SUPPORTED */
-#endif /* PNG_USE_GLOBAL_ARRAYS */
-
-/* Tells libpng that we have already handled the first "num_bytes" bytes
- * of the PNG file signature. If the PNG data is embedded into another
- * stream we can set num_bytes = 8 so that libpng will not attempt to read
- * or write any of the magic bytes before it starts on the IHDR.
- */
-
-#ifdef PNG_READ_SUPPORTED
-void PNGAPI
-png_set_sig_bytes(png_structp png_ptr, int num_bytes)
-{
- if(png_ptr == NULL) return;
- png_debug(1, "in png_set_sig_bytes\n");
- if (num_bytes > 8)
- png_error(png_ptr, "Too many bytes for PNG signature.");
-
- png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
-}
-
-/* Checks whether the supplied bytes match the PNG signature. We allow
- * checking less than the full 8-byte signature so that those apps that
- * already read the first few bytes of a file to determine the file type
- * can simply check the remaining bytes for extra assurance. Returns
- * an integer less than, equal to, or greater than zero if sig is found,
- * respectively, to be less than, to match, or be greater than the correct
- * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
- */
-int PNGAPI
-png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
-{
- png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
- if (num_to_check > 8)
- num_to_check = 8;
- else if (num_to_check < 1)
- return (-1);
-
- if (start > 7)
- return (-1);
-
- if (start + num_to_check > 8)
- num_to_check = 8 - start;
-
- return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
-}
-
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-/* (Obsolete) function to check signature bytes. It does not allow one
- * to check a partial signature. This function might be removed in the
- * future - use png_sig_cmp(). Returns true (nonzero) if the file is PNG.
- */
-int PNGAPI
-png_check_sig(png_bytep sig, int num)
-{
- return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
-}
-#endif
-#endif /* PNG_READ_SUPPORTED */
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-/* Function to allocate memory for zlib and clear it to 0. */
-#ifdef PNG_1_0_X
-voidpf PNGAPI
-#else
-voidpf /* private */
-#endif
-png_zalloc(voidpf png_ptr, uInt items, uInt size)
-{
- png_voidp ptr;
- png_structp p=(png_structp)png_ptr;
- png_uint_32 save_flags=p->flags;
- png_uint_32 num_bytes;
-
- if(png_ptr == NULL) return (NULL);
- if (items > PNG_UINT_32_MAX/size)
- {
- png_warning (p, "Potential overflow in png_zalloc()");
- return (NULL);
- }
- num_bytes = (png_uint_32)items * size;
-
- p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
- ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
- p->flags=save_flags;
-
-#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
- if (ptr == NULL)
- return ((voidpf)ptr);
-
- if (num_bytes > (png_uint_32)0x8000L)
- {
- png_memset(ptr, 0, (png_size_t)0x8000L);
- png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
- (png_size_t)(num_bytes - (png_uint_32)0x8000L));
- }
- else
- {
- png_memset(ptr, 0, (png_size_t)num_bytes);
- }
-#endif
- return ((voidpf)ptr);
-}
-
-/* function to free memory for zlib */
-#ifdef PNG_1_0_X
-void PNGAPI
-#else
-void /* private */
-#endif
-png_zfree(voidpf png_ptr, voidpf ptr)
-{
- png_free((png_structp)png_ptr, (png_voidp)ptr);
-}
-
-/* Reset the CRC variable to 32 bits of 1's. Care must be taken
- * in case CRC is > 32 bits to leave the top bits 0.
- */
-void /* PRIVATE */
-png_reset_crc(png_structp png_ptr)
-{
- png_ptr->crc = crc32(0, Z_NULL, 0);
-}
-
-/* Calculate the CRC over a section of data. We can only pass as
- * much data to this routine as the largest single buffer size. We
- * also check that this data will actually be used before going to the
- * trouble of calculating it.
- */
-void /* PRIVATE */
-png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
-{
- int need_crc = 1;
-
- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
- else /* critical */
- {
- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
- need_crc = 0;
- }
-
- if (need_crc)
- png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
-}
-
-/* Allocate the memory for an info_struct for the application. We don't
- * really need the png_ptr, but it could potentially be useful in the
- * future. This should be used in favour of malloc(png_sizeof(png_info))
- * and png_info_init() so that applications that want to use a shared
- * libpng don't have to be recompiled if png_info changes size.
- */
-png_infop PNGAPI
-png_create_info_struct(png_structp png_ptr)
-{
- png_infop info_ptr;
-
- png_debug(1, "in png_create_info_struct\n");
- if(png_ptr == NULL) return (NULL);
-#ifdef PNG_USER_MEM_SUPPORTED
- info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
- png_ptr->malloc_fn, png_ptr->mem_ptr);
-#else
- info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
-#endif
- if (info_ptr != NULL)
- png_info_init_3(&info_ptr, png_sizeof(png_info));
-
- return (info_ptr);
-}
-
-/* This function frees the memory associated with a single info struct.
- * Normally, one would use either png_destroy_read_struct() or
- * png_destroy_write_struct() to free an info struct, but this may be
- * useful for some applications.
- */
-void PNGAPI
-png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
-{
- png_infop info_ptr = NULL;
- if(png_ptr == NULL) return;
-
- png_debug(1, "in png_destroy_info_struct\n");
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (info_ptr != NULL)
- {
- png_info_destroy(png_ptr, info_ptr);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
- png_ptr->mem_ptr);
-#else
- png_destroy_struct((png_voidp)info_ptr);
-#endif
- *info_ptr_ptr = NULL;
- }
-}
-
-/* Initialize the info structure. This is now an internal function (0.89)
- * and applications using it are urged to use png_create_info_struct()
- * instead.
- */
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-#undef png_info_init
-void PNGAPI
-png_info_init(png_infop info_ptr)
-{
- /* We only come here via pre-1.0.12-compiled applications */
- png_info_init_3(&info_ptr, 0);
-}
-#endif
-
-void PNGAPI
-png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
-{
- png_infop info_ptr = *ptr_ptr;
-
- if(info_ptr == NULL) return;
-
- png_debug(1, "in png_info_init_3\n");
-
- if(png_sizeof(png_info) > png_info_struct_size)
- {
- png_destroy_struct(info_ptr);
- info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
- *ptr_ptr = info_ptr;
- }
-
- /* set everything to 0 */
- png_memset(info_ptr, 0, png_sizeof (png_info));
-}
-
-#ifdef PNG_FREE_ME_SUPPORTED
-void PNGAPI
-png_data_freer(png_structp png_ptr, png_infop info_ptr,
- int freer, png_uint_32 mask)
-{
- png_debug(1, "in png_data_freer\n");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- if(freer == PNG_DESTROY_WILL_FREE_DATA)
- info_ptr->free_me |= mask;
- else if(freer == PNG_USER_WILL_FREE_DATA)
- info_ptr->free_me &= ~mask;
- else
- png_warning(png_ptr,
- "Unknown freer parameter in png_data_freer.");
-}
-#endif
-
-void PNGAPI
-png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
- int num)
-{
- png_debug(1, "in png_free_data\n");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
-#if defined(PNG_TEXT_SUPPORTED)
-/* free text item num or (if num == -1) all text items */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_TEXT)
-#endif
-{
- if (num != -1)
- {
- if (info_ptr->text && info_ptr->text[num].key)
- {
- png_free(png_ptr, info_ptr->text[num].key);
- info_ptr->text[num].key = NULL;
- }
- }
- else
- {
- int i;
- for (i = 0; i < info_ptr->num_text; i++)
- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
- png_free(png_ptr, info_ptr->text);
- info_ptr->text = NULL;
- info_ptr->num_text=0;
- }
-}
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED)
-/* free any tRNS entry */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
-#else
-if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
-#endif
-{
- png_free(png_ptr, info_ptr->trans);
- info_ptr->valid &= ~PNG_INFO_tRNS;
-#ifndef PNG_FREE_ME_SUPPORTED
- png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
-#endif
- info_ptr->trans = NULL;
-}
-#endif
-
-#if defined(PNG_sCAL_SUPPORTED)
-/* free any sCAL entry */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_SCAL)
-#endif
-{
-#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, info_ptr->scal_s_width);
- png_free(png_ptr, info_ptr->scal_s_height);
- info_ptr->scal_s_width = NULL;
- info_ptr->scal_s_height = NULL;
-#endif
- info_ptr->valid &= ~PNG_INFO_sCAL;
-}
-#endif
-
-#if defined(PNG_pCAL_SUPPORTED)
-/* free any pCAL entry */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_PCAL)
-#endif
-{
- png_free(png_ptr, info_ptr->pcal_purpose);
- png_free(png_ptr, info_ptr->pcal_units);
- info_ptr->pcal_purpose = NULL;
- info_ptr->pcal_units = NULL;
- if (info_ptr->pcal_params != NULL)
- {
- int i;
- for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
- {
- png_free(png_ptr, info_ptr->pcal_params[i]);
- info_ptr->pcal_params[i]=NULL;
- }
- png_free(png_ptr, info_ptr->pcal_params);
- info_ptr->pcal_params = NULL;
- }
- info_ptr->valid &= ~PNG_INFO_pCAL;
-}
-#endif
-
-#if defined(PNG_iCCP_SUPPORTED)
-/* free any iCCP entry */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_ICCP)
-#endif
-{
- png_free(png_ptr, info_ptr->iccp_name);
- png_free(png_ptr, info_ptr->iccp_profile);
- info_ptr->iccp_name = NULL;
- info_ptr->iccp_profile = NULL;
- info_ptr->valid &= ~PNG_INFO_iCCP;
-}
-#endif
-
-#if defined(PNG_sPLT_SUPPORTED)
-/* free a given sPLT entry, or (if num == -1) all sPLT entries */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_SPLT)
-#endif
-{
- if (num != -1)
- {
- if(info_ptr->splt_palettes)
- {
- png_free(png_ptr, info_ptr->splt_palettes[num].name);
- png_free(png_ptr, info_ptr->splt_palettes[num].entries);
- info_ptr->splt_palettes[num].name = NULL;
- info_ptr->splt_palettes[num].entries = NULL;
- }
- }
- else
- {
- if(info_ptr->splt_palettes_num)
- {
- int i;
- for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
- png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
-
- png_free(png_ptr, info_ptr->splt_palettes);
- info_ptr->splt_palettes = NULL;
- info_ptr->splt_palettes_num = 0;
- }
- info_ptr->valid &= ~PNG_INFO_sPLT;
- }
-}
-#endif
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_ptr->unknown_chunk.data)
- {
- png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
- }
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_UNKN)
-#endif
-{
- if (num != -1)
- {
- if(info_ptr->unknown_chunks)
- {
- png_free(png_ptr, info_ptr->unknown_chunks[num].data);
- info_ptr->unknown_chunks[num].data = NULL;
- }
- }
- else
- {
- int i;
-
- if(info_ptr->unknown_chunks_num)
- {
- for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
- png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
-
- png_free(png_ptr, info_ptr->unknown_chunks);
- info_ptr->unknown_chunks = NULL;
- info_ptr->unknown_chunks_num = 0;
- }
- }
-}
-#endif
-
-#if defined(PNG_hIST_SUPPORTED)
-/* free any hIST entry */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
-#else
-if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
-#endif
-{
- png_free(png_ptr, info_ptr->hist);
- info_ptr->hist = NULL;
- info_ptr->valid &= ~PNG_INFO_hIST;
-#ifndef PNG_FREE_ME_SUPPORTED
- png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
-#endif
-}
-#endif
-
-/* free any PLTE entry that was internally allocated */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
-#else
-if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
-#endif
-{
- png_zfree(png_ptr, info_ptr->palette);
- info_ptr->palette = NULL;
- info_ptr->valid &= ~PNG_INFO_PLTE;
-#ifndef PNG_FREE_ME_SUPPORTED
- png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
-#endif
- info_ptr->num_palette = 0;
-}
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-/* free any image bits attached to the info structure */
-#ifdef PNG_FREE_ME_SUPPORTED
-if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
-#else
-if (mask & PNG_FREE_ROWS)
-#endif
-{
- if(info_ptr->row_pointers)
- {
- int row;
- for (row = 0; row < (int)info_ptr->height; row++)
- {
- png_free(png_ptr, info_ptr->row_pointers[row]);
- info_ptr->row_pointers[row]=NULL;
- }
- png_free(png_ptr, info_ptr->row_pointers);
- info_ptr->row_pointers=NULL;
- }
- info_ptr->valid &= ~PNG_INFO_IDAT;
-}
-#endif
-
-#ifdef PNG_FREE_ME_SUPPORTED
- if(num == -1)
- info_ptr->free_me &= ~mask;
- else
- info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
-#endif
-}
-
-/* This is an internal routine to free any memory that the info struct is
- * pointing to before re-using it or freeing the struct itself. Recall
- * that png_free() checks for NULL pointers for us.
- */
-void /* PRIVATE */
-png_info_destroy(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_info_destroy\n");
-
- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->num_chunk_list)
- {
- png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list=NULL;
- png_ptr->num_chunk_list=0;
- }
-#endif
-
- png_info_init_3(&info_ptr, png_sizeof(png_info));
-}
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
-/* This function returns a pointer to the io_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy() or png_read_destroy() are called.
- */
-png_voidp PNGAPI
-png_get_io_ptr(png_structp png_ptr)
-{
- if(png_ptr == NULL) return (NULL);
- return (png_ptr->io_ptr);
-}
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-#if !defined(PNG_NO_STDIO)
-/* Initialize the default input/output functions for the PNG file. If you
- * use your own read or write routines, you can call either png_set_read_fn()
- * or png_set_write_fn() instead of png_init_io(). If you have defined
- * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
- * necessarily available.
- */
-void PNGAPI
-png_init_io(png_structp png_ptr, png_FILE_p fp)
-{
- png_debug(1, "in png_init_io\n");
- if(png_ptr == NULL) return;
- png_ptr->io_ptr = (png_voidp)fp;
-}
-#endif
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
-/* Convert the supplied time into an RFC 1123 string suitable for use in
- * a "Creation Time" or other text-based time string.
- */
-png_charp PNGAPI
-png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
-{
- static PNG_CONST char short_months[12][4] =
- {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- if(png_ptr == NULL) return (NULL);
- if (png_ptr->time_buffer == NULL)
- {
- png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
- png_sizeof(char)));
- }
-
-#if defined(_WIN32_WCE)
- {
- wchar_t time_buf[29];
- wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
- WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
- NULL, NULL);
- }
-#else
-#ifdef USE_FAR_KEYWORD
- {
- char near_time_buf[29];
- png_snprintf6(near_time_buf,29,"%d %s %d %02d:%02d:%02d +0000",
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
- png_memcpy(png_ptr->time_buffer, near_time_buf,
- 29*png_sizeof(char));
- }
-#else
- png_snprintf6(png_ptr->time_buffer,29,"%d %s %d %02d:%02d:%02d +0000",
- ptime->day % 32, short_months[(ptime->month - 1) % 12],
- ptime->year, ptime->hour % 24, ptime->minute % 60,
- ptime->second % 61);
-#endif
-#endif /* _WIN32_WCE */
- return ((png_charp)png_ptr->time_buffer);
-}
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
-
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
-png_charp PNGAPI
-png_get_copyright(png_structp png_ptr)
-{
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) "\n libpng version 1.2.19 - August 18, 2007\n\
- Copyright (c) 1998-2007 Glenn Randers-Pehrson\n\
- Copyright (c) 1996-1997 Andreas Dilger\n\
- Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
-}
-
-/* The following return the library version as a short string in the
- * format 1.0.0 through 99.99.99zz. To get the version of *.h files
- * used with your application, print out PNG_LIBPNG_VER_STRING, which
- * is defined in png.h.
- * Note: now there is no difference between png_get_libpng_ver() and
- * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
- * it is guaranteed that png.c uses the correct version of png.h.
- */
-png_charp PNGAPI
-png_get_libpng_ver(png_structp png_ptr)
-{
- /* Version of *.c files used when building libpng */
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) PNG_LIBPNG_VER_STRING);
-}
-
-png_charp PNGAPI
-png_get_header_ver(png_structp png_ptr)
-{
- /* Version of *.h files used when building libpng */
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) PNG_LIBPNG_VER_STRING);
-}
-
-png_charp PNGAPI
-png_get_header_version(png_structp png_ptr)
-{
- /* Returns longer string containing both version and date */
- png_ptr = png_ptr; /* silence compiler warning about unused png_ptr */
- return ((png_charp) PNG_HEADER_VERSION_STRING
-#ifdef PNG_READ_SUPPORTED
-# ifdef PNG_USE_PNGGCCRD
-# ifdef __x86_64__
-# ifdef __PIC__
- " (PNGGCRD x86_64, PIC)\n"
-# else
-# ifdef PNG_THREAD_UNSAFE_OK
- " (PNGGCRD x86_64, Thread unsafe)\n"
-# else
- " (PNGGCRD x86_64, Thread safe)\n"
-# endif
-# endif
-# else
-# ifdef PNG_THREAD_UNSAFE_OK
- " (PNGGCRD, Thread unsafe)\n"
-# else
- " (PNGGCRD, Thread safe)\n"
-# endif
-# endif
-# else
-# ifdef PNG_USE_PNGVCRD
-# ifdef __x86_64__
- " (x86_64 PNGVCRD)\n"
-# else
- " (PNGVCRD)\n"
-# endif
-# else
-# ifdef __x86_64__
-# ifdef PNG_OPTIMIZED_CODE_SUPPORTED
- " (x86_64 OPTIMIZED)\n"
-# else
- " (x86_64 NOT OPTIMIZED)\n"
-# endif
-# else
-# ifdef PNG_OPTIMIZED_CODE_SUPPORTED
- " (OPTIMIZED)\n"
-# else
- " (NOT OPTIMIZED)\n"
-# endif
-# endif
-# endif
-# endif
-#else
- " (NO READ SUPPORT)\n"
-#endif
- );
-}
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-int PNGAPI
-png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
-{
- /* check chunk_name and return "keep" value if it's on the list, else 0 */
- int i;
- png_bytep p;
- if(png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
- return 0;
- p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
- for (i = png_ptr->num_chunk_list; i; i--, p-=5)
- if (!png_memcmp(chunk_name, p, 4))
- return ((int)*(p+4));
- return 0;
-}
-#endif
-
-/* This function, added to libpng-1.0.6g, is untested. */
-int PNGAPI
-png_reset_zstream(png_structp png_ptr)
-{
- if (png_ptr == NULL) return Z_STREAM_ERROR;
- return (inflateReset(&png_ptr->zstream));
-}
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
-
-/* This function was added to libpng-1.0.7 */
-png_uint_32 PNGAPI
-png_access_version_number(void)
-{
- /* Version of *.c files used when building libpng */
- return((png_uint_32) PNG_LIBPNG_VER);
-}
-
-
-#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
-#if !defined(PNG_1_0_X)
-#if defined(PNG_MMX_CODE_SUPPORTED)
-/* this INTERNAL function was added to libpng 1.2.0 */
-void /* PRIVATE */
-png_init_mmx_flags (png_structp png_ptr)
-{
- if(png_ptr == NULL) return;
- png_ptr->mmx_rowbytes_threshold = 0;
- png_ptr->mmx_bitdepth_threshold = 0;
-
-# if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))
-
- png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
-
- if (png_mmx_support() > 0) {
- png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
-# ifdef PNG_HAVE_MMX_COMBINE_ROW
- | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
-# endif
-# ifdef PNG_HAVE_MMX_READ_INTERLACE
- | PNG_ASM_FLAG_MMX_READ_INTERLACE
-# endif
-# ifndef PNG_HAVE_MMX_READ_FILTER_ROW
- ;
-# else
- | PNG_ASM_FLAG_MMX_READ_FILTER_SUB
- | PNG_ASM_FLAG_MMX_READ_FILTER_UP
- | PNG_ASM_FLAG_MMX_READ_FILTER_AVG
- | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
-
- png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
- png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
-# endif
- } else {
- png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
- | PNG_MMX_READ_FLAGS
- | PNG_MMX_WRITE_FLAGS );
- }
-
-# else /* !(PNGVCRD || PNGGCCRD) */
-
- /* clear all MMX flags; no support is compiled in */
- png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );
-
-# endif /* ?(PNGVCRD || PNGGCCRD) */
-}
-
-#endif /* !(PNG_MMX_CODE_SUPPORTED) */
-
-/* this function was added to libpng 1.2.0 */
-#if !defined(PNG_USE_PNGGCCRD) && \
- !(defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
-int PNGAPI
-png_mmx_support(void)
-{
- return -1;
-}
-#endif
-#endif /* PNG_1_0_X */
-#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-#ifdef PNG_SIZE_T
-/* Added at libpng version 1.2.6 */
- PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
-png_size_t PNGAPI
-png_convert_size(size_t size)
-{
- if (size > (png_size_t)-1)
- PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
- return ((png_size_t)size);
-}
-#endif /* PNG_SIZE_T */
-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
diff --git a/distrib/libpng-1.2.19/png.h b/distrib/libpng-1.2.19/png.h
deleted file mode 100644
index 04f786d..0000000
--- a/distrib/libpng-1.2.19/png.h
+++ /dev/null
@@ -1,3525 +0,0 @@
-
-/* png.h - header file for PNG reference library
- *
- * libpng version 1.2.19 - August 18, 2007
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * Authors and maintainers:
- * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
- * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.2.19 - August 18, 2007: Glenn
- * See also "Contributing Authors", below.
- *
- * Note about libpng version numbers:
- *
- * Due to various miscommunications, unforeseen code incompatibilities
- * and occasional factors outside the authors' control, version numbering
- * on the library has not always been consistent and straightforward.
- * The following table summarizes matters since version 0.89c, which was
- * the first widely used release:
- *
- * source png.h png.h shared-lib
- * version string int version
- * ------- ------ ----- ----------
- * 0.89c "1.0 beta 3" 0.89 89 1.0.89
- * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
- * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
- * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
- * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
- * 0.97c 0.97 97 2.0.97
- * 0.98 0.98 98 2.0.98
- * 0.99 0.99 98 2.0.99
- * 0.99a-m 0.99 99 2.0.99
- * 1.00 1.00 100 2.1.0 [100 should be 10000]
- * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
- * 1.0.1 png.h string is 10001 2.1.0
- * 1.0.1a-e identical to the 10002 from here on, the shared library
- * 1.0.2 source version) 10002 is 2.V where V is the source code
- * 1.0.2a-b 10003 version, except as noted.
- * 1.0.3 10003
- * 1.0.3a-d 10004
- * 1.0.4 10004
- * 1.0.4a-f 10005
- * 1.0.5 (+ 2 patches) 10005
- * 1.0.5a-d 10006
- * 1.0.5e-r 10100 (not source compatible)
- * 1.0.5s-v 10006 (not binary compatible)
- * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
- * 1.0.6d-f 10007 (still binary incompatible)
- * 1.0.6g 10007
- * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
- * 1.0.6i 10007 10.6i
- * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
- * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
- * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
- * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
- * 1.0.7 1 10007 (still compatible)
- * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
- * 1.0.8rc1 1 10008 2.1.0.8rc1
- * 1.0.8 1 10008 2.1.0.8
- * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
- * 1.0.9rc1 1 10009 2.1.0.9rc1
- * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
- * 1.0.9rc2 1 10009 2.1.0.9rc2
- * 1.0.9 1 10009 2.1.0.9
- * 1.0.10beta1 1 10010 2.1.0.10beta1
- * 1.0.10rc1 1 10010 2.1.0.10rc1
- * 1.0.10 1 10010 2.1.0.10
- * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
- * 1.0.11rc1 1 10011 2.1.0.11rc1
- * 1.0.11 1 10011 2.1.0.11
- * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
- * 1.0.12rc1 2 10012 2.1.0.12rc1
- * 1.0.12 2 10012 2.1.0.12
- * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
- * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
- * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
- * 1.2.0rc1 3 10200 3.1.2.0rc1
- * 1.2.0 3 10200 3.1.2.0
- * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
- * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
- * 1.2.1 3 10201 3.1.2.1
- * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
- * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
- * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
- * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
- * 1.0.13 10 10013 10.so.0.1.0.13
- * 1.2.2 12 10202 12.so.0.1.2.2
- * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
- * 1.2.3 12 10203 12.so.0.1.2.3
- * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
- * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
- * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
- * 1.0.14 10 10014 10.so.0.1.0.14
- * 1.2.4 13 10204 12.so.0.1.2.4
- * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
- * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
- * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
- * 1.0.15 10 10015 10.so.0.1.0.15
- * 1.2.5 13 10205 12.so.0.1.2.5
- * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
- * 1.0.16 10 10016 10.so.0.1.0.16
- * 1.2.6 13 10206 12.so.0.1.2.6
- * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
- * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1
- * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
- * 1.0.17 10 10017 10.so.0.1.0.17
- * 1.2.7 13 10207 12.so.0.1.2.7
- * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
- * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5
- * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
- * 1.0.18 10 10018 10.so.0.1.0.18
- * 1.2.8 13 10208 12.so.0.1.2.8
- * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3
- * 1.2.9beta4-11 13 10209 12.so.0.9[.0]
- * 1.2.9rc1 13 10209 12.so.0.9[.0]
- * 1.2.9 13 10209 12.so.0.9[.0]
- * 1.2.10beta1-8 13 10210 12.so.0.10[.0]
- * 1.2.10rc1-3 13 10210 12.so.0.10[.0]
- * 1.2.10 13 10210 12.so.0.10[.0]
- * 1.2.11beta1-4 13 10211 12.so.0.11[.0]
- * 1.0.19rc1-5 10 10019 10.so.0.19[.0]
- * 1.2.11rc1-5 13 10211 12.so.0.11[.0]
- * 1.0.19 10 10019 10.so.0.19[.0]
- * 1.2.11 13 10211 12.so.0.11[.0]
- * 1.0.20 10 10020 10.so.0.20[.0]
- * 1.2.12 13 10212 12.so.0.12[.0]
- * 1.2.13beta1 13 10213 12.so.0.13[.0]
- * 1.0.21 10 10021 10.so.0.21[.0]
- * 1.2.13 13 10213 12.so.0.13[.0]
- * 1.2.14beta1-2 13 10214 12.so.0.14[.0]
- * 1.0.22rc1 10 10022 10.so.0.22[.0]
- * 1.2.14rc1 13 10214 12.so.0.14[.0]
- * 1.0.22 10 10022 10.so.0.22[.0]
- * 1.2.14 13 10214 12.so.0.14[.0]
- * 1.2.15beta1-6 13 10215 12.so.0.15[.0]
- * 1.0.23rc1-5 10 10023 10.so.0.23[.0]
- * 1.2.15rc1-5 13 10215 12.so.0.15[.0]
- * 1.0.23 10 10023 10.so.0.23[.0]
- * 1.2.15 13 10215 12.so.0.15[.0]
- * 1.2.16beta1-2 13 10216 12.so.0.16[.0]
- * 1.2.16rc1 13 10216 12.so.0.16[.0]
- * 1.0.24 10 10024 10.so.0.24[.0]
- * 1.2.16 13 10216 12.so.0.16[.0]
- * 1.2.17beta1-2 13 10217 12.so.0.17[.0]
- * 1.0.25rc1 10 10025 10.so.0.25[.0]
- * 1.2.17rc1-3 13 10217 12.so.0.17[.0]
- * 1.0.25 10 10025 10.so.0.25[.0]
- * 1.2.17 13 10217 12.so.0.17[.0]
- * 1.0.26 10 10026 10.so.0.26[.0]
- * 1.2.18 13 10218 12.so.0.18[.0]
- * 1.2.19beta1-31 13 10219 12.so.0.19[.0]
- * 1.0.27rc1-6 10 10027 10.so.0.27[.0]
- * 1.2.19rc1-6 13 10219 12.so.0.19[.0]
- * 1.0.27 10 10027 10.so.0.27[.0]
- * 1.2.19 13 10219 12.so.0.19[.0]
- *
- * Henceforth the source version will match the shared-library major
- * and minor numbers; the shared-library major version number will be
- * used for changes in backward compatibility, as it is intended. The
- * PNG_LIBPNG_VER macro, which is not used within libpng but is available
- * for applications, is an unsigned integer of the form xyyzz corresponding
- * to the source version x.y.z (leading zeros in y and z). Beta versions
- * were given the previous public release number plus a letter, until
- * version 1.0.6j; from then on they were given the upcoming public
- * release number plus "betaNN" or "rcN".
- *
- * Binary incompatibility exists only when applications make direct access
- * to the info_ptr or png_ptr members through png.h, and the compiled
- * application is loaded with a different version of the library.
- *
- * DLLNUM will change each time there are forward or backward changes
- * in binary compatibility (e.g., when a new feature is added).
- *
- * See libpng.txt or libpng.3 for more information. The PNG specification
- * is available as a W3C Recommendation and as an ISO Specification,
- * <http://www.w3.org/TR/2003/REC-PNG-20031110/
- */
-
-/*
- * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
- *
- * If you modify libpng you may insert additional notices immediately following
- * this sentence.
- *
- * libpng versions 1.2.6, August 15, 2004, through 1.2.19, August 18, 2007, are
- * Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-1.2.5
- * with the following individual added to the list of Contributing Authors:
- *
- * Cosmin Truta
- *
- * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
- * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-1.0.6
- * with the following individuals added to the list of Contributing Authors:
- *
- * Simon-Pierre Cadieux
- * Eric S. Raymond
- * Gilles Vollant
- *
- * and with the following additions to the disclaimer:
- *
- * There is no warranty against interference with your enjoyment of the
- * library or against infringement. There is no warranty that our
- * efforts or the library will fulfill any of your particular purposes
- * or needs. This library is provided with all faults, and the entire
- * risk of satisfactory quality, performance, accuracy, and effort is with
- * the user.
- *
- * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
- * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
- * distributed according to the same disclaimer and license as libpng-0.96,
- * with the following individuals added to the list of Contributing Authors:
- *
- * Tom Lane
- * Glenn Randers-Pehrson
- * Willem van Schaik
- *
- * libpng versions 0.89, June 1996, through 0.96, May 1997, are
- * Copyright (c) 1996, 1997 Andreas Dilger
- * Distributed according to the same disclaimer and license as libpng-0.88,
- * with the following individuals added to the list of Contributing Authors:
- *
- * John Bowler
- * Kevin Bracey
- * Sam Bushell
- * Magnus Holmgren
- * Greg Roelofs
- * Tom Tanner
- *
- * libpng versions 0.5, May 1995, through 0.88, January 1996, are
- * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
- *
- * For the purposes of this copyright and license, "Contributing Authors"
- * is defined as the following set of individuals:
- *
- * Andreas Dilger
- * Dave Martindale
- * Guy Eric Schalnat
- * Paul Schmidt
- * Tim Wegner
- *
- * The PNG Reference Library is supplied "AS IS". The Contributing Authors
- * and Group 42, Inc. disclaim all warranties, expressed or implied,
- * including, without limitation, the warranties of merchantability and of
- * fitness for any purpose. The Contributing Authors and Group 42, Inc.
- * assume no liability for direct, indirect, incidental, special, exemplary,
- * or consequential damages, which may result from the use of the PNG
- * Reference Library, even if advised of the possibility of such damage.
- *
- * Permission is hereby granted to use, copy, modify, and distribute this
- * source code, or portions hereof, for any purpose, without fee, subject
- * to the following restrictions:
- *
- * 1. The origin of this source code must not be misrepresented.
- *
- * 2. Altered versions must be plainly marked as such and
- * must not be misrepresented as being the original source.
- *
- * 3. This Copyright notice may not be removed or altered from
- * any source or altered source distribution.
- *
- * The Contributing Authors and Group 42, Inc. specifically permit, without
- * fee, and encourage the use of this source code as a component to
- * supporting the PNG file format in commercial products. If you use this
- * source code in a product, acknowledgment is not required but would be
- * appreciated.
- */
-
-/*
- * A "png_get_copyright" function is available, for convenient use in "about"
- * boxes and the like:
- *
- * printf("%s",png_get_copyright(NULL));
- *
- * Also, the PNG logo (in PNG format, of course) is supplied in the
- * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
- */
-
-/*
- * Libpng is OSI Certified Open Source Software. OSI Certified is a
- * certification mark of the Open Source Initiative.
- */
-
-/*
- * The contributing authors would like to thank all those who helped
- * with testing, bug fixes, and patience. This wouldn't have been
- * possible without all of you.
- *
- * Thanks to Frank J. T. Wojcik for helping with the documentation.
- */
-
-/*
- * Y2K compliance in libpng:
- * =========================
- *
- * August 18, 2007
- *
- * Since the PNG Development group is an ad-hoc body, we can't make
- * an official declaration.
- *
- * This is your unofficial assurance that libpng from version 0.71 and
- * upward through 1.2.19 are Y2K compliant. It is my belief that earlier
- * versions were also Y2K compliant.
- *
- * Libpng only has three year fields. One is a 2-byte unsigned integer
- * that will hold years up to 65535. The other two hold the date in text
- * format, and will hold years up to 9999.
- *
- * The integer is
- * "png_uint_16 year" in png_time_struct.
- *
- * The strings are
- * "png_charp time_buffer" in png_struct and
- * "near_time_buffer", which is a local character string in png.c.
- *
- * There are seven time-related functions:
- * png.c: png_convert_to_rfc_1123() in png.c
- * (formerly png_convert_to_rfc_1152() in error)
- * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- * png_convert_from_time_t() in pngwrite.c
- * png_get_tIME() in pngget.c
- * png_handle_tIME() in pngrutil.c, called in pngread.c
- * png_set_tIME() in pngset.c
- * png_write_tIME() in pngwutil.c, called in pngwrite.c
- *
- * All handle dates properly in a Y2K environment. The
- * png_convert_from_time_t() function calls gmtime() to convert from system
- * clock time, which returns (year - 1900), which we properly convert to
- * the full 4-digit year. There is a possibility that applications using
- * libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- * function, or that they are incorrectly passing only a 2-digit year
- * instead of "year - 1900" into the png_convert_from_struct_tm() function,
- * but this is not under our control. The libpng documentation has always
- * stated that it works with 4-digit years, and the APIs have been
- * documented as such.
- *
- * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
- * integer to hold the year, and can hold years as large as 65535.
- *
- * zlib, upon which libpng depends, is also Y2K compliant. It contains
- * no date-related code.
- *
- * Glenn Randers-Pehrson
- * libpng maintainer
- * PNG Development Group
- */
-
-#ifndef PNG_H
-#define PNG_H
-
-/* This is not the place to learn how to use libpng. The file libpng.txt
- * describes how to use libpng, and the file example.c summarizes it
- * with some code on which to build. This file is useful for looking
- * at the actual function definitions and structure components.
- */
-
-/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.2.19"
-#define PNG_HEADER_VERSION_STRING \
- " libpng version 1.2.19 - August 18, 2007\n"
-
-#define PNG_LIBPNG_VER_SONUM 0
-#define PNG_LIBPNG_VER_DLLNUM 13
-
-/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
-#define PNG_LIBPNG_VER_MAJOR 1
-#define PNG_LIBPNG_VER_MINOR 2
-#define PNG_LIBPNG_VER_RELEASE 19
-/* This should match the numeric part of the final component of
- * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
-
-#define PNG_LIBPNG_VER_BUILD 0
-
-/* Release Status */
-#define PNG_LIBPNG_BUILD_ALPHA 1
-#define PNG_LIBPNG_BUILD_BETA 2
-#define PNG_LIBPNG_BUILD_RC 3
-#define PNG_LIBPNG_BUILD_STABLE 4
-#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
-
-/* Release-Specific Flags */
-#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
- PNG_LIBPNG_BUILD_STABLE only */
-#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
- PNG_LIBPNG_BUILD_SPECIAL */
-#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
- PNG_LIBPNG_BUILD_PRIVATE */
-
-#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
-
-/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
- * We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
- * version 1.0.0 was mis-numbered 100 instead of 10000). From
- * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */
-#define PNG_LIBPNG_VER 10219 /* 1.2.19 */
-
-#ifndef PNG_VERSION_INFO_ONLY
-/* include the compression library's header */
-#include "zlib.h"
-#endif
-
-/* include all user configurable info, including optional assembler routines */
-#include "pngconf.h"
-
-/*
- * Added at libpng-1.2.8 */
-/* Ref MSDN: Private as priority over Special
- * VS_FF_PRIVATEBUILD File *was not* built using standard release
- * procedures. If this value is given, the StringFileInfo block must
- * contain a PrivateBuild string.
- *
- * VS_FF_SPECIALBUILD File *was* built by the original company using
- * standard release procedures but is a variation of the standard
- * file of the same version number. If this value is given, the
- * StringFileInfo block must contain a SpecialBuild string.
- */
-
-#if defined(PNG_USER_PRIVATEBUILD)
-# define PNG_LIBPNG_BUILD_TYPE \
- (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
-#else
-# if defined(PNG_LIBPNG_SPECIALBUILD)
-# define PNG_LIBPNG_BUILD_TYPE \
- (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
-# else
-# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
-# endif
-#endif
-
-#ifndef PNG_VERSION_INFO_ONLY
-
-/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* This file is arranged in several sections. The first section contains
- * structure and type definitions. The second section contains the external
- * library functions, while the third has the internal library functions,
- * which applications aren't expected to use directly.
- */
-
-#ifndef PNG_NO_TYPECAST_NULL
-#define int_p_NULL (int *)NULL
-#define png_bytep_NULL (png_bytep)NULL
-#define png_bytepp_NULL (png_bytepp)NULL
-#define png_doublep_NULL (png_doublep)NULL
-#define png_error_ptr_NULL (png_error_ptr)NULL
-#define png_flush_ptr_NULL (png_flush_ptr)NULL
-#define png_free_ptr_NULL (png_free_ptr)NULL
-#define png_infopp_NULL (png_infopp)NULL
-#define png_malloc_ptr_NULL (png_malloc_ptr)NULL
-#define png_read_status_ptr_NULL (png_read_status_ptr)NULL
-#define png_rw_ptr_NULL (png_rw_ptr)NULL
-#define png_structp_NULL (png_structp)NULL
-#define png_uint_16p_NULL (png_uint_16p)NULL
-#define png_voidp_NULL (png_voidp)NULL
-#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
-#else
-#define int_p_NULL NULL
-#define png_bytep_NULL NULL
-#define png_bytepp_NULL NULL
-#define png_doublep_NULL NULL
-#define png_error_ptr_NULL NULL
-#define png_flush_ptr_NULL NULL
-#define png_free_ptr_NULL NULL
-#define png_infopp_NULL NULL
-#define png_malloc_ptr_NULL NULL
-#define png_read_status_ptr_NULL NULL
-#define png_rw_ptr_NULL NULL
-#define png_structp_NULL NULL
-#define png_uint_16p_NULL NULL
-#define png_voidp_NULL NULL
-#define png_write_status_ptr_NULL NULL
-#endif
-
-/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
-#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
-/* Version information for C files, stored in png.c. This had better match
- * the version above.
- */
-#ifdef PNG_USE_GLOBAL_ARRAYS
-PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18];
- /* need room for 99.99.99beta99z */
-#else
-#define png_libpng_ver png_get_header_ver(NULL)
-#endif
-
-#ifdef PNG_USE_GLOBAL_ARRAYS
-/* This was removed in version 1.0.5c */
-/* Structures to facilitate easy interlacing. See png.c for more details */
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7];
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7];
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7];
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7];
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7];
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7];
-#if defined(PNG_HAVE_MMX_COMBINE_ROW) || defined(PNG_OPTIMIZED_CODE_SUPPORTED)
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_width[7];
-#endif
-/* This isn't currently used. If you need it, see png.c for more details.
-PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7];
-*/
-#endif
-
-#endif /* PNG_NO_EXTERN */
-
-/* Three color definitions. The order of the red, green, and blue, (and the
- * exact size) is not important, although the size of the fields need to
- * be png_byte or png_uint_16 (as defined below).
- */
-typedef struct png_color_struct
-{
- png_byte red;
- png_byte green;
- png_byte blue;
-} png_color;
-typedef png_color FAR * png_colorp;
-typedef png_color FAR * FAR * png_colorpp;
-
-typedef struct png_color_16_struct
-{
- png_byte index; /* used for palette files */
- png_uint_16 red; /* for use in red green blue files */
- png_uint_16 green;
- png_uint_16 blue;
- png_uint_16 gray; /* for use in grayscale files */
-} png_color_16;
-typedef png_color_16 FAR * png_color_16p;
-typedef png_color_16 FAR * FAR * png_color_16pp;
-
-typedef struct png_color_8_struct
-{
- png_byte red; /* for use in red green blue files */
- png_byte green;
- png_byte blue;
- png_byte gray; /* for use in grayscale files */
- png_byte alpha; /* for alpha channel files */
-} png_color_8;
-typedef png_color_8 FAR * png_color_8p;
-typedef png_color_8 FAR * FAR * png_color_8pp;
-
-/*
- * The following two structures are used for the in-core representation
- * of sPLT chunks.
- */
-typedef struct png_sPLT_entry_struct
-{
- png_uint_16 red;
- png_uint_16 green;
- png_uint_16 blue;
- png_uint_16 alpha;
- png_uint_16 frequency;
-} png_sPLT_entry;
-typedef png_sPLT_entry FAR * png_sPLT_entryp;
-typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
-
-/* When the depth of the sPLT palette is 8 bits, the color and alpha samples
- * occupy the LSB of their respective members, and the MSB of each member
- * is zero-filled. The frequency member always occupies the full 16 bits.
- */
-
-typedef struct png_sPLT_struct
-{
- png_charp name; /* palette name */
- png_byte depth; /* depth of palette samples */
- png_sPLT_entryp entries; /* palette entries */
- png_int_32 nentries; /* number of palette entries */
-} png_sPLT_t;
-typedef png_sPLT_t FAR * png_sPLT_tp;
-typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
-
-#ifdef PNG_TEXT_SUPPORTED
-/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
- * and whether that contents is compressed or not. The "key" field
- * points to a regular zero-terminated C string. The "text", "lang", and
- * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
- * However, the * structure returned by png_get_text() will always contain
- * regular zero-terminated C strings (possibly empty), never NULL pointers,
- * so they can be safely used in printf() and other string-handling functions.
- */
-typedef struct png_text_struct
-{
- int compression; /* compression value:
- -1: tEXt, none
- 0: zTXt, deflate
- 1: iTXt, none
- 2: iTXt, deflate */
- png_charp key; /* keyword, 1-79 character description of "text" */
- png_charp text; /* comment, may be an empty string (ie "")
- or a NULL pointer */
- png_size_t text_length; /* length of the text string */
-#ifdef PNG_iTXt_SUPPORTED
- png_size_t itxt_length; /* length of the itxt string */
- png_charp lang; /* language code, 0-79 characters
- or a NULL pointer */
- png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
- chars or a NULL pointer */
-#endif
-} png_text;
-typedef png_text FAR * png_textp;
-typedef png_text FAR * FAR * png_textpp;
-#endif
-
-/* Supported compression types for text in PNG files (tEXt, and zTXt).
- * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
-#define PNG_TEXT_COMPRESSION_NONE_WR -3
-#define PNG_TEXT_COMPRESSION_zTXt_WR -2
-#define PNG_TEXT_COMPRESSION_NONE -1
-#define PNG_TEXT_COMPRESSION_zTXt 0
-#define PNG_ITXT_COMPRESSION_NONE 1
-#define PNG_ITXT_COMPRESSION_zTXt 2
-#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
-
-/* png_time is a way to hold the time in an machine independent way.
- * Two conversions are provided, both from time_t and struct tm. There
- * is no portable way to convert to either of these structures, as far
- * as I know. If you know of a portable way, send it to me. As a side
- * note - PNG has always been Year 2000 compliant!
- */
-typedef struct png_time_struct
-{
- png_uint_16 year; /* full year, as in, 1995 */
- png_byte month; /* month of year, 1 - 12 */
- png_byte day; /* day of month, 1 - 31 */
- png_byte hour; /* hour of day, 0 - 23 */
- png_byte minute; /* minute of hour, 0 - 59 */
- png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
-} png_time;
-typedef png_time FAR * png_timep;
-typedef png_time FAR * FAR * png_timepp;
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-/* png_unknown_chunk is a structure to hold queued chunks for which there is
- * no specific support. The idea is that we can use this to queue
- * up private chunks for output even though the library doesn't actually
- * know about their semantics.
- */
-typedef struct png_unknown_chunk_t
-{
- png_byte name[5];
- png_byte *data;
- png_size_t size;
-
- /* libpng-using applications should NOT directly modify this byte. */
- png_byte location; /* mode of operation at read time */
-}
-png_unknown_chunk;
-typedef png_unknown_chunk FAR * png_unknown_chunkp;
-typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
-#endif
-
-/* png_info is a structure that holds the information in a PNG file so
- * that the application can find out the characteristics of the image.
- * If you are reading the file, this structure will tell you what is
- * in the PNG file. If you are writing the file, fill in the information
- * you want to put into the PNG file, then call png_write_info().
- * The names chosen should be very close to the PNG specification, so
- * consult that document for information about the meaning of each field.
- *
- * With libpng < 0.95, it was only possible to directly set and read the
- * the values in the png_info_struct, which meant that the contents and
- * order of the values had to remain fixed. With libpng 0.95 and later,
- * however, there are now functions that abstract the contents of
- * png_info_struct from the application, so this makes it easier to use
- * libpng with dynamic libraries, and even makes it possible to use
- * libraries that don't have all of the libpng ancillary chunk-handing
- * functionality.
- *
- * In any case, the order of the parameters in png_info_struct should NOT
- * be changed for as long as possible to keep compatibility with applications
- * that use the old direct-access method with png_info_struct.
- *
- * The following members may have allocated storage attached that should be
- * cleaned up before the structure is discarded: palette, trans, text,
- * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
- * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
- * are automatically freed when the info structure is deallocated, if they were
- * allocated internally by libpng. This behavior can be changed by means
- * of the png_data_freer() function.
- *
- * More allocation details: all the chunk-reading functions that
- * change these members go through the corresponding png_set_*
- * functions. A function to clear these members is available: see
- * png_free_data(). The png_set_* functions do not depend on being
- * able to point info structure members to any of the storage they are
- * passed (they make their own copies), EXCEPT that the png_set_text
- * functions use the same storage passed to them in the text_ptr or
- * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
- * functions do not make their own copies.
- */
-typedef struct png_info_struct
-{
- /* the following are necessary for every PNG file */
- png_uint_32 width; /* width of image in pixels (from IHDR) */
- png_uint_32 height; /* height of image in pixels (from IHDR) */
- png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
- png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */
- png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
- png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
- png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
- png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
- png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
- /* The following three should have been named *_method not *_type */
- png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
- png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
- png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
-
- /* The following is informational only on read, and not used on writes. */
- png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
- png_byte pixel_depth; /* number of bits per pixel */
- png_byte spare_byte; /* to align the data, and for future use */
- png_byte signature[8]; /* magic bytes read by libpng from start of file */
-
- /* The rest of the data is optional. If you are reading, check the
- * valid field to see if the information in these are valid. If you
- * are writing, set the valid field to those chunks you want written,
- * and initialize the appropriate fields below.
- */
-
-#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
- /* The gAMA chunk describes the gamma characteristics of the system
- * on which the image was created, normally in the range [1.0, 2.5].
- * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
- */
- float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
-#endif
-
-#if defined(PNG_sRGB_SUPPORTED)
- /* GR-P, 0.96a */
- /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
- png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
-#endif
-
-#if defined(PNG_TEXT_SUPPORTED)
- /* The tEXt, and zTXt chunks contain human-readable textual data in
- * uncompressed, compressed, and optionally compressed forms, respectively.
- * The data in "text" is an array of pointers to uncompressed,
- * null-terminated C strings. Each chunk has a keyword that describes the
- * textual data contained in that chunk. Keywords are not required to be
- * unique, and the text string may be empty. Any number of text chunks may
- * be in an image.
- */
- int num_text; /* number of comments read/to write */
- int max_text; /* current size of text array */
- png_textp text; /* array of comments read/to write */
-#endif /* PNG_TEXT_SUPPORTED */
-
-#if defined(PNG_tIME_SUPPORTED)
- /* The tIME chunk holds the last time the displayed image data was
- * modified. See the png_time struct for the contents of this struct.
- */
- png_time mod_time;
-#endif
-
-#if defined(PNG_sBIT_SUPPORTED)
- /* The sBIT chunk specifies the number of significant high-order bits
- * in the pixel data. Values are in the range [1, bit_depth], and are
- * only specified for the channels in the pixel data. The contents of
- * the low-order bits is not specified. Data is valid if
- * (valid & PNG_INFO_sBIT) is non-zero.
- */
- png_color_8 sig_bit; /* significant bits in color channels */
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
-defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* The tRNS chunk supplies transparency data for paletted images and
- * other image types that don't need a full alpha channel. There are
- * "num_trans" transparency values for a paletted image, stored in the
- * same order as the palette colors, starting from index 0. Values
- * for the data are in the range [0, 255], ranging from fully transparent
- * to fully opaque, respectively. For non-paletted images, there is a
- * single color specified that should be treated as fully transparent.
- * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
- */
- png_bytep trans; /* transparent values for paletted image */
- png_color_16 trans_values; /* transparent color for non-palette image */
-#endif
-
-#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* The bKGD chunk gives the suggested image background color if the
- * display program does not have its own background color and the image
- * is needs to composited onto a background before display. The colors
- * in "background" are normally in the same color space/depth as the
- * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
- */
- png_color_16 background;
-#endif
-
-#if defined(PNG_oFFs_SUPPORTED)
- /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
- * and downwards from the top-left corner of the display, page, or other
- * application-specific co-ordinate space. See the PNG_OFFSET_ defines
- * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
- */
- png_int_32 x_offset; /* x offset on page */
- png_int_32 y_offset; /* y offset on page */
- png_byte offset_unit_type; /* offset units type */
-#endif
-
-#if defined(PNG_pHYs_SUPPORTED)
- /* The pHYs chunk gives the physical pixel density of the image for
- * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
- * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
- */
- png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
- png_uint_32 y_pixels_per_unit; /* vertical pixel density */
- png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
-#endif
-
-#if defined(PNG_hIST_SUPPORTED)
- /* The hIST chunk contains the relative frequency or importance of the
- * various palette entries, so that a viewer can intelligently select a
- * reduced-color palette, if required. Data is an array of "num_palette"
- * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
- * is non-zero.
- */
- png_uint_16p hist;
-#endif
-
-#ifdef PNG_cHRM_SUPPORTED
- /* The cHRM chunk describes the CIE color characteristics of the monitor
- * on which the PNG was created. This data allows the viewer to do gamut
- * mapping of the input image to ensure that the viewer sees the same
- * colors in the image as the creator. Values are in the range
- * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
- */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- float x_white;
- float y_white;
- float x_red;
- float y_red;
- float x_green;
- float y_green;
- float x_blue;
- float y_blue;
-#endif
-#endif
-
-#if defined(PNG_pCAL_SUPPORTED)
- /* The pCAL chunk describes a transformation between the stored pixel
- * values and original physical data values used to create the image.
- * The integer range [0, 2^bit_depth - 1] maps to the floating-point
- * range given by [pcal_X0, pcal_X1], and are further transformed by a
- * (possibly non-linear) transformation function given by "pcal_type"
- * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
- * defines below, and the PNG-Group's PNG extensions document for a
- * complete description of the transformations and how they should be
- * implemented, and for a description of the ASCII parameter strings.
- * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
- */
- png_charp pcal_purpose; /* pCAL chunk description string */
- png_int_32 pcal_X0; /* minimum value */
- png_int_32 pcal_X1; /* maximum value */
- png_charp pcal_units; /* Latin-1 string giving physical units */
- png_charpp pcal_params; /* ASCII strings containing parameter values */
- png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
- png_byte pcal_nparams; /* number of parameters given in pcal_params */
-#endif
-
-/* New members added in libpng-1.0.6 */
-#ifdef PNG_FREE_ME_SUPPORTED
- png_uint_32 free_me; /* flags items libpng is responsible for freeing */
-#endif
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- /* storage for unknown chunks that the library doesn't recognize. */
- png_unknown_chunkp unknown_chunks;
- png_size_t unknown_chunks_num;
-#endif
-
-#if defined(PNG_iCCP_SUPPORTED)
- /* iCCP chunk data. */
- png_charp iccp_name; /* profile name */
- png_charp iccp_profile; /* International Color Consortium profile data */
- /* Note to maintainer: should be png_bytep */
- png_uint_32 iccp_proflen; /* ICC profile data length */
- png_byte iccp_compression; /* Always zero */
-#endif
-
-#if defined(PNG_sPLT_SUPPORTED)
- /* data on sPLT chunks (there may be more than one). */
- png_sPLT_tp splt_palettes;
- png_uint_32 splt_palettes_num;
-#endif
-
-#if defined(PNG_sCAL_SUPPORTED)
- /* The sCAL chunk describes the actual physical dimensions of the
- * subject matter of the graphic. The chunk contains a unit specification
- * a byte value, and two ASCII strings representing floating-point
- * values. The values are width and height corresponsing to one pixel
- * in the image. This external representation is converted to double
- * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
- */
- png_byte scal_unit; /* unit of physical scale */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- double scal_pixel_width; /* width of one pixel */
- double scal_pixel_height; /* height of one pixel */
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_charp scal_s_width; /* string containing height */
- png_charp scal_s_height; /* string containing width */
-#endif
-#endif
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
- /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
- /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
- png_bytepp row_pointers; /* the image bits */
-#endif
-
-#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
- png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
- png_fixed_point int_x_white;
- png_fixed_point int_y_white;
- png_fixed_point int_x_red;
- png_fixed_point int_y_red;
- png_fixed_point int_x_green;
- png_fixed_point int_y_green;
- png_fixed_point int_x_blue;
- png_fixed_point int_y_blue;
-#endif
-
-} png_info;
-
-typedef png_info FAR * png_infop;
-typedef png_info FAR * FAR * png_infopp;
-
-/* Maximum positive integer used in PNG is (2^31)-1 */
-#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
-#define PNG_UINT_32_MAX ((png_uint_32)(-1))
-#define PNG_SIZE_MAX ((png_size_t)(-1))
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
-#define PNG_MAX_UINT PNG_UINT_31_MAX
-#endif
-
-/* These describe the color_type field in png_info. */
-/* color type masks */
-#define PNG_COLOR_MASK_PALETTE 1
-#define PNG_COLOR_MASK_COLOR 2
-#define PNG_COLOR_MASK_ALPHA 4
-
-/* color types. Note that not all combinations are legal */
-#define PNG_COLOR_TYPE_GRAY 0
-#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
-#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
-#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
-#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
-/* aliases */
-#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
-#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
-
-/* This is for compression type. PNG 1.0-1.2 only define the single type. */
-#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
-#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
-
-/* This is for filter type. PNG 1.0-1.2 only define the single type. */
-#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
-#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
-#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
-
-/* These are for the interlacing type. These values should NOT be changed. */
-#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
-#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
-#define PNG_INTERLACE_LAST 2 /* Not a valid value */
-
-/* These are for the oFFs chunk. These values should NOT be changed. */
-#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
-#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
-#define PNG_OFFSET_LAST 2 /* Not a valid value */
-
-/* These are for the pCAL chunk. These values should NOT be changed. */
-#define PNG_EQUATION_LINEAR 0 /* Linear transformation */
-#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
-#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
-#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
-#define PNG_EQUATION_LAST 4 /* Not a valid value */
-
-/* These are for the sCAL chunk. These values should NOT be changed. */
-#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
-#define PNG_SCALE_METER 1 /* meters per pixel */
-#define PNG_SCALE_RADIAN 2 /* radians per pixel */
-#define PNG_SCALE_LAST 3 /* Not a valid value */
-
-/* These are for the pHYs chunk. These values should NOT be changed. */
-#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
-#define PNG_RESOLUTION_METER 1 /* pixels/meter */
-#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
-
-/* These are for the sRGB chunk. These values should NOT be changed. */
-#define PNG_sRGB_INTENT_PERCEPTUAL 0
-#define PNG_sRGB_INTENT_RELATIVE 1
-#define PNG_sRGB_INTENT_SATURATION 2
-#define PNG_sRGB_INTENT_ABSOLUTE 3
-#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
-
-/* This is for text chunks */
-#define PNG_KEYWORD_MAX_LENGTH 79
-
-/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
-#define PNG_MAX_PALETTE_LENGTH 256
-
-/* These determine if an ancillary chunk's data has been successfully read
- * from the PNG header, or if the application has filled in the corresponding
- * data in the info_struct to be written into the output file. The values
- * of the PNG_INFO_<chunk> defines should NOT be changed.
- */
-#define PNG_INFO_gAMA 0x0001
-#define PNG_INFO_sBIT 0x0002
-#define PNG_INFO_cHRM 0x0004
-#define PNG_INFO_PLTE 0x0008
-#define PNG_INFO_tRNS 0x0010
-#define PNG_INFO_bKGD 0x0020
-#define PNG_INFO_hIST 0x0040
-#define PNG_INFO_pHYs 0x0080
-#define PNG_INFO_oFFs 0x0100
-#define PNG_INFO_tIME 0x0200
-#define PNG_INFO_pCAL 0x0400
-#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
-#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
-#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
-#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
-#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
-
-/* This is used for the transformation routines, as some of them
- * change these values for the row. It also should enable using
- * the routines for other purposes.
- */
-typedef struct png_row_info_struct
-{
- png_uint_32 width; /* width of row */
- png_uint_32 rowbytes; /* number of bytes in row */
- png_byte color_type; /* color type of row */
- png_byte bit_depth; /* bit depth of row */
- png_byte channels; /* number of channels (1, 2, 3, or 4) */
- png_byte pixel_depth; /* bits per pixel (depth * channels) */
-} png_row_info;
-
-typedef png_row_info FAR * png_row_infop;
-typedef png_row_info FAR * FAR * png_row_infopp;
-
-/* These are the function types for the I/O functions and for the functions
- * that allow the user to override the default I/O functions with his or her
- * own. The png_error_ptr type should match that of user-supplied warning
- * and error functions, while the png_rw_ptr type should match that of the
- * user read/write data functions.
- */
-typedef struct png_struct_def png_struct;
-typedef png_struct FAR * png_structp;
-
-typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
-typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
-typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
-typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
- int));
-typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
- int));
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
-typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
-typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
- png_uint_32, int));
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
-typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
- png_row_infop, png_bytep));
-#endif
-
-#if defined(PNG_USER_CHUNKS_SUPPORTED)
-typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
-#endif
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
-#endif
-
-/* Transform masks for the high-level interface */
-#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
-#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
-#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
-#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
-#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
-#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
-#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
-#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
-#define PNG_TRANSFORM_BGR 0x0080 /* read and write */
-#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
-#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
-#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
-#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */
-
-/* Flags for MNG supported features */
-#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
-#define PNG_FLAG_MNG_FILTER_64 0x04
-#define PNG_ALL_MNG_FEATURES 0x05
-
-typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
-typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
-
-/* The structure that holds the information to read and write PNG files.
- * The only people who need to care about what is inside of this are the
- * people who will be modifying the library for their own special needs.
- * It should NOT be accessed directly by an application, except to store
- * the jmp_buf.
- */
-
-struct png_struct_def
-{
-#ifdef PNG_SETJMP_SUPPORTED
- jmp_buf jmpbuf; /* used in png_error */
-#endif
- png_error_ptr error_fn; /* function for printing errors and aborting */
- png_error_ptr warning_fn; /* function for printing warnings */
- png_voidp error_ptr; /* user supplied struct for error functions */
- png_rw_ptr write_data_fn; /* function for writing output data */
- png_rw_ptr read_data_fn; /* function for reading input data */
- png_voidp io_ptr; /* ptr to application struct for I/O functions */
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- png_user_transform_ptr read_user_transform_fn; /* user read transform */
-#endif
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- png_user_transform_ptr write_user_transform_fn; /* user write transform */
-#endif
-
-/* These were added in libpng-1.0.2 */
-#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- png_voidp user_transform_ptr; /* user supplied struct for user transform */
- png_byte user_transform_depth; /* bit depth of user transformed pixels */
- png_byte user_transform_channels; /* channels in user transformed pixels */
-#endif
-#endif
-
- png_uint_32 mode; /* tells us where we are in the PNG file */
- png_uint_32 flags; /* flags indicating various things to libpng */
- png_uint_32 transformations; /* which transformations to perform */
-
- z_stream zstream; /* pointer to decompression structure (below) */
- png_bytep zbuf; /* buffer for zlib */
- png_size_t zbuf_size; /* size of zbuf */
- int zlib_level; /* holds zlib compression level */
- int zlib_method; /* holds zlib compression method */
- int zlib_window_bits; /* holds zlib compression window bits */
- int zlib_mem_level; /* holds zlib compression memory level */
- int zlib_strategy; /* holds zlib compression strategy */
-
- png_uint_32 width; /* width of image in pixels */
- png_uint_32 height; /* height of image in pixels */
- png_uint_32 num_rows; /* number of rows in current pass */
- png_uint_32 usr_width; /* width of row at start of write */
- png_uint_32 rowbytes; /* size of row in bytes */
- png_uint_32 irowbytes; /* size of current interlaced row in bytes */
- png_uint_32 iwidth; /* width of current interlaced row in pixels */
- png_uint_32 row_number; /* current row in interlace pass */
- png_bytep prev_row; /* buffer to save previous (unfiltered) row */
- png_bytep row_buf; /* buffer to save current (unfiltered) row */
- png_bytep sub_row; /* buffer to save "sub" row when filtering */
- png_bytep up_row; /* buffer to save "up" row when filtering */
- png_bytep avg_row; /* buffer to save "avg" row when filtering */
- png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
- png_row_info row_info; /* used for transformation routines */
-
- png_uint_32 idat_size; /* current IDAT size for read */
- png_uint_32 crc; /* current chunk CRC value */
- png_colorp palette; /* palette from the input file */
- png_uint_16 num_palette; /* number of color entries in palette */
- png_uint_16 num_trans; /* number of transparency values */
- png_byte chunk_name[5]; /* null-terminated name of current chunk */
- png_byte compression; /* file compression type (always 0) */
- png_byte filter; /* file filter type (always 0) */
- png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
- png_byte pass; /* current interlace pass (0 - 6) */
- png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
- png_byte color_type; /* color type of file */
- png_byte bit_depth; /* bit depth of file */
- png_byte usr_bit_depth; /* bit depth of users row */
- png_byte pixel_depth; /* number of bits per pixel */
- png_byte channels; /* number of channels in file */
- png_byte usr_channels; /* channels at start of write */
- png_byte sig_bytes; /* magic bytes read/written from start of file */
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-#ifdef PNG_LEGACY_SUPPORTED
- png_byte filler; /* filler byte for pixel expansion */
-#else
- png_uint_16 filler; /* filler bytes for pixel expansion */
-#endif
-#endif
-
-#if defined(PNG_bKGD_SUPPORTED)
- png_byte background_gamma_type;
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- float background_gamma;
-# endif
- png_color_16 background; /* background color in screen gamma space */
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- png_color_16 background_1; /* background normalized to gamma 1.0 */
-#endif
-#endif /* PNG_bKGD_SUPPORTED */
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_flush_ptr output_flush_fn;/* Function for flushing output */
- png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
- png_uint_32 flush_rows; /* number of rows written since last flush */
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- int gamma_shift; /* number of "insignificant" bits 16-bit gamma */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- float gamma; /* file gamma value */
- float screen_gamma; /* screen gamma value (display_exponent) */
-#endif
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_bytep gamma_table; /* gamma table for 8-bit depth files */
- png_bytep gamma_from_1; /* converts from 1.0 to screen */
- png_bytep gamma_to_1; /* converts from file to 1.0 */
- png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
- png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
- png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
- png_color_8 sig_bit; /* significant bits in each available channel */
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
- png_color_8 shift; /* shift for significant bit tranformation */
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
- || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_bytep trans; /* transparency values for paletted files */
- png_color_16 trans_values; /* transparency values for non-paletted files */
-#endif
-
- png_read_status_ptr read_row_fn; /* called after each row is decoded */
- png_write_status_ptr write_row_fn; /* called after each row is encoded */
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- png_progressive_info_ptr info_fn; /* called after header data fully read */
- png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */
- png_progressive_end_ptr end_fn; /* called after image is complete */
- png_bytep save_buffer_ptr; /* current location in save_buffer */
- png_bytep save_buffer; /* buffer for previously read data */
- png_bytep current_buffer_ptr; /* current location in current_buffer */
- png_bytep current_buffer; /* buffer for recently used data */
- png_uint_32 push_length; /* size of current input chunk */
- png_uint_32 skip_length; /* bytes to skip in input data */
- png_size_t save_buffer_size; /* amount of data now in save_buffer */
- png_size_t save_buffer_max; /* total size of save_buffer */
- png_size_t buffer_size; /* total amount of available input data */
- png_size_t current_buffer_size; /* amount of data now in current_buffer */
- int process_mode; /* what push library is currently doing */
- int cur_palette; /* current push library palette index */
-
-# if defined(PNG_TEXT_SUPPORTED)
- png_size_t current_text_size; /* current size of text input data */
- png_size_t current_text_left; /* how much text left to read in input */
- png_charp current_text; /* current text chunk buffer */
- png_charp current_text_ptr; /* current location in current_text */
-# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */
-
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* for the Borland special 64K segment handler */
- png_bytepp offset_table_ptr;
- png_bytep offset_table;
- png_uint_16 offset_table_number;
- png_uint_16 offset_table_count;
- png_uint_16 offset_table_count_free;
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
- png_bytep palette_lookup; /* lookup table for dithering */
- png_bytep dither_index; /* index translation for palette files */
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
- png_uint_16p hist; /* histogram */
-#endif
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_byte heuristic_method; /* heuristic for row filter selection */
- png_byte num_prev_filters; /* number of weights for previous rows */
- png_bytep prev_filters; /* filter type(s) of previous row(s) */
- png_uint_16p filter_weights; /* weight(s) for previous line(s) */
- png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
- png_uint_16p filter_costs; /* relative filter calculation cost */
- png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
-#endif
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_charp time_buffer; /* String to hold RFC 1123 time text */
-#endif
-
-/* New members added in libpng-1.0.6 */
-
-#ifdef PNG_FREE_ME_SUPPORTED
- png_uint_32 free_me; /* flags items libpng is responsible for freeing */
-#endif
-
-#if defined(PNG_USER_CHUNKS_SUPPORTED)
- png_voidp user_chunk_ptr;
- png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
-#endif
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- int num_chunk_list;
- png_bytep chunk_list;
-#endif
-
-/* New members added in libpng-1.0.3 */
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- png_byte rgb_to_gray_status;
- /* These were changed from png_byte in libpng-1.0.6 */
- png_uint_16 rgb_to_gray_red_coeff;
- png_uint_16 rgb_to_gray_green_coeff;
- png_uint_16 rgb_to_gray_blue_coeff;
-#endif
-
-/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
-#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
- defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
-/* changed from png_byte to png_uint_32 at version 1.2.0 */
-#ifdef PNG_1_0_X
- png_byte mng_features_permitted;
-#else
- png_uint_32 mng_features_permitted;
-#endif /* PNG_1_0_X */
-#endif
-
-/* New member added in libpng-1.0.7 */
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_fixed_point int_gamma;
-#endif
-
-/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_byte filter_type;
-#endif
-
-#if defined(PNG_1_0_X)
-/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
- png_uint_32 row_buf_size;
-#endif
-
-/* New members added in libpng-1.2.0 */
-#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
-# if !defined(PNG_1_0_X)
-# if defined(PNG_MMX_CODE_SUPPORTED)
- png_byte mmx_bitdepth_threshold;
- png_uint_32 mmx_rowbytes_threshold;
-# endif
- png_uint_32 asm_flags;
-# endif
-#endif
-
-/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
-#ifdef PNG_USER_MEM_SUPPORTED
- png_voidp mem_ptr; /* user supplied struct for mem functions */
- png_malloc_ptr malloc_fn; /* function for allocating memory */
- png_free_ptr free_fn; /* function for freeing memory */
-#endif
-
-/* New member added in libpng-1.0.13 and 1.2.0 */
- png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-/* The following three members were added at version 1.0.14 and 1.2.4 */
- png_bytep dither_sort; /* working sort array */
- png_bytep index_to_palette; /* where the original index currently is */
- /* in the palette */
- png_bytep palette_to_index; /* which original index points to this */
- /* palette color */
-#endif
-
-/* New members added in libpng-1.0.16 and 1.2.6 */
- png_byte compression_type;
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_uint_32 user_width_max;
- png_uint_32 user_height_max;
-#endif
-
-/* New member added in libpng-1.0.25 and 1.2.17 */
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- /* storage for unknown chunk that the library doesn't recognize. */
- png_unknown_chunk unknown_chunk;
-#endif
-};
-
-
-/* This triggers a compiler error in png.c, if png.c and png.h
- * do not agree upon the version number.
- */
-typedef png_structp version_1_2_19;
-
-typedef png_struct FAR * FAR * png_structpp;
-
-/* Here are the function definitions most commonly used. This is not
- * the place to find out how to use libpng. See libpng.txt for the
- * full explanation, see example.c for the summary. This just provides
- * a simple one line description of the use of each function.
- */
-
-/* Returns the version number of the library */
-extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
-
-/* Tell lib we have already handled the first <num_bytes> magic bytes.
- * Handling more than 8 bytes from the beginning of the file is an error.
- */
-extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
- int num_bytes));
-
-/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
- * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
- * signature, and non-zero otherwise. Having num_to_check == 0 or
- * start > 7 will always fail (ie return non-zero).
- */
-extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
- png_size_t num_to_check));
-
-/* Simple signature checking function. This is the same as calling
- * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
- */
-extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
-
-/* Allocate and initialize png_ptr struct for reading, and any other memory. */
-extern PNG_EXPORT(png_structp,png_create_read_struct)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn));
-
-/* Allocate and initialize png_ptr struct for writing, and any other memory */
-extern PNG_EXPORT(png_structp,png_create_write_struct)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn));
-
-#ifdef PNG_WRITE_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
- PNGARG((png_structp png_ptr));
-#endif
-
-#ifdef PNG_WRITE_SUPPORTED
-extern PNG_EXPORT(void,png_set_compression_buffer_size)
- PNGARG((png_structp png_ptr, png_uint_32 size));
-#endif
-
-/* Reset the compression stream */
-extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
-
-/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
-#ifdef PNG_USER_MEM_SUPPORTED
-extern PNG_EXPORT(png_structp,png_create_read_struct_2)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-extern PNG_EXPORT(png_structp,png_create_write_struct_2)
- PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-#endif
-
-/* Write a PNG chunk - size, type, (optional) data, CRC. */
-extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
- png_bytep chunk_name, png_bytep data, png_size_t length));
-
-/* Write the start of a PNG chunk - length and chunk name. */
-extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
- png_bytep chunk_name, png_uint_32 length));
-
-/* Write the data of a PNG chunk started with png_write_chunk_start(). */
-extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
-/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
-extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
-
-/* Allocate and initialize the info structure */
-extern PNG_EXPORT(png_infop,png_create_info_struct)
- PNGARG((png_structp png_ptr));
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* Initialize the info structure (old interface - DEPRECATED) */
-extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr));
-#undef png_info_init
-#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\
- png_sizeof(png_info));
-#endif
-
-extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
- png_size_t png_info_struct_size));
-
-/* Writes all the PNG information before the image. */
-extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* read the information before the actual image data. */
-extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
-extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
- PNGARG((png_structp png_ptr, png_timep ptime));
-#endif
-
-#if !defined(_WIN32_WCE)
-/* "time.h" functions are not supported on WindowsCE */
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-/* convert from a struct tm to png_time */
-extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
- struct tm FAR * ttime));
-
-/* convert from time_t to png_time. Uses gmtime() */
-extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
- time_t ttime));
-#endif /* PNG_WRITE_tIME_SUPPORTED */
-#endif /* _WIN32_WCE */
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
-extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
-#if !defined(PNG_1_0_X)
-extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp
- png_ptr));
-#endif
-extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
-extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* Deprecated */
-extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
-#endif
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* Use blue, green, red order for pixels. */
-extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-/* Expand the grayscale to 24-bit RGB if necessary. */
-extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-/* Reduce RGB to grayscale. */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
- int error_action, double red, double green ));
-#endif
-extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
- int error_action, png_fixed_point red, png_fixed_point green ));
-extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
- png_ptr));
-#endif
-
-extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
- png_colorp palette));
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
-extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
- png_uint_32 filler, int flags));
-/* The values of the PNG_FILLER_ defines should NOT be changed */
-#define PNG_FILLER_BEFORE 0
-#define PNG_FILLER_AFTER 1
-/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
-#if !defined(PNG_1_0_X)
-extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr,
- png_uint_32 filler, int flags));
-#endif
-#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swap bytes in 16-bit depth files. */
-extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
-extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-/* Swap packing order of pixels in bytes. */
-extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-/* Converts files to legal bit depths. */
-extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
- png_color_8p true_bits));
-#endif
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
- defined(PNG_WRITE_INTERLACING_SUPPORTED)
-/* Have the code handle the interlacing. Returns the number of passes. */
-extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-/* Invert monochrome files */
-extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-/* Handle alpha and tRNS by replacing with a background color. */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
- png_color_16p background_color, int background_gamma_code,
- int need_expand, double background_gamma));
-#endif
-#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
-#define PNG_BACKGROUND_GAMMA_SCREEN 1
-#define PNG_BACKGROUND_GAMMA_FILE 2
-#define PNG_BACKGROUND_GAMMA_UNIQUE 3
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* strip the second byte of information from a 16-bit depth file. */
-extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-/* Turn on dithering, and reduce the palette to the number of colors available. */
-extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
- png_colorp palette, int num_palette, int maximum_colors,
- png_uint_16p histogram, int full_dither));
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-/* Handle gamma correction. Screen_gamma=(display_exponent) */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
- double screen_gamma, double default_file_gamma));
-#endif
-#endif
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
-/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
-/* Deprecated and will be removed. Use png_permit_mng_features() instead. */
-extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
- int empty_plte_permitted));
-#endif
-#endif
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-/* Set how many lines between output flushes - 0 for no flushing */
-extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
-/* Flush the current PNG output buffer */
-extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
-#endif
-
-/* optional update palette with requested transformations */
-extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
-
-/* optional call to update the users info structure */
-extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* read one or more rows of image data. */
-extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
- png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
-#endif
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* read a row of data. */
-extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
- png_bytep row,
- png_bytep display_row));
-#endif
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* read the whole image into memory at once. */
-extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
- png_bytepp image));
-#endif
-
-/* write a row of image data */
-extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
- png_bytep row));
-
-/* write a few rows of image data */
-extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
- png_bytepp row, png_uint_32 num_rows));
-
-/* write the image data */
-extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
- png_bytepp image));
-
-/* writes the end of the PNG file. */
-extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* read the end of the PNG file. */
-extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-
-/* free any memory associated with the png_info_struct */
-extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
- png_infopp info_ptr_ptr));
-
-/* free any memory associated with the png_struct and the png_info_structs */
-extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
- png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
-
-/* free all memory used by the read (old method - NOT DLL EXPORTED) */
-extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_infop end_info_ptr));
-
-/* free any memory associated with the png_struct and the png_info_structs */
-extern PNG_EXPORT(void,png_destroy_write_struct)
- PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
-
-/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
-extern void png_write_destroy PNGARG((png_structp png_ptr));
-
-/* set the libpng method of handling chunk CRC errors */
-extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
- int crit_action, int ancil_action));
-
-/* Values for png_set_crc_action() to say how to handle CRC errors in
- * ancillary and critical chunks, and whether to use the data contained
- * therein. Note that it is impossible to "discard" data in a critical
- * chunk. For versions prior to 0.90, the action was always error/quit,
- * whereas in version 0.90 and later, the action for CRC errors in ancillary
- * chunks is warn/discard. These values should NOT be changed.
- *
- * value action:critical action:ancillary
- */
-#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
-#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
-#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
-#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
-#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
-#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
-
-/* These functions give the user control over the scan-line filtering in
- * libpng and the compression methods used by zlib. These functions are
- * mainly useful for testing, as the defaults should work with most users.
- * Those users who are tight on memory or want faster performance at the
- * expense of compression can modify them. See the compression library
- * header file (zlib.h) for an explination of the compression functions.
- */
-
-/* set the filtering method(s) used by libpng. Currently, the only valid
- * value for "method" is 0.
- */
-extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
- int filters));
-
-/* Flags for png_set_filter() to say which filters to use. The flags
- * are chosen so that they don't conflict with real filter types
- * below, in case they are supplied instead of the #defined constants.
- * These values should NOT be changed.
- */
-#define PNG_NO_FILTERS 0x00
-#define PNG_FILTER_NONE 0x08
-#define PNG_FILTER_SUB 0x10
-#define PNG_FILTER_UP 0x20
-#define PNG_FILTER_AVG 0x40
-#define PNG_FILTER_PAETH 0x80
-#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
- PNG_FILTER_AVG | PNG_FILTER_PAETH)
-
-/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
- * These defines should NOT be changed.
- */
-#define PNG_FILTER_VALUE_NONE 0
-#define PNG_FILTER_VALUE_SUB 1
-#define PNG_FILTER_VALUE_UP 2
-#define PNG_FILTER_VALUE_AVG 3
-#define PNG_FILTER_VALUE_PAETH 4
-#define PNG_FILTER_VALUE_LAST 5
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
-/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
- * defines, either the default (minimum-sum-of-absolute-differences), or
- * the experimental method (weighted-minimum-sum-of-absolute-differences).
- *
- * Weights are factors >= 1.0, indicating how important it is to keep the
- * filter type consistent between rows. Larger numbers mean the current
- * filter is that many times as likely to be the same as the "num_weights"
- * previous filters. This is cumulative for each previous row with a weight.
- * There needs to be "num_weights" values in "filter_weights", or it can be
- * NULL if the weights aren't being specified. Weights have no influence on
- * the selection of the first row filter. Well chosen weights can (in theory)
- * improve the compression for a given image.
- *
- * Costs are factors >= 1.0 indicating the relative decoding costs of a
- * filter type. Higher costs indicate more decoding expense, and are
- * therefore less likely to be selected over a filter with lower computational
- * costs. There needs to be a value in "filter_costs" for each valid filter
- * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
- * setting the costs. Costs try to improve the speed of decompression without
- * unduly increasing the compressed image size.
- *
- * A negative weight or cost indicates the default value is to be used, and
- * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
- * The default values for both weights and costs are currently 1.0, but may
- * change if good general weighting/cost heuristics can be found. If both
- * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
- * to the UNWEIGHTED method, but with added encoding time/computation.
- */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
- int heuristic_method, int num_weights, png_doublep filter_weights,
- png_doublep filter_costs));
-#endif
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
-/* Heuristic used for row filter selection. These defines should NOT be
- * changed.
- */
-#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
-#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
-#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
-#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
-
-/* Set the library compression level. Currently, valid values range from
- * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
- * (0 - no compression, 9 - "maximal" compression). Note that tests have
- * shown that zlib compression levels 3-6 usually perform as well as level 9
- * for PNG images, and do considerably fewer caclulations. In the future,
- * these values may not correspond directly to the zlib compression levels.
- */
-extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
- int level));
-
-extern PNG_EXPORT(void,png_set_compression_mem_level)
- PNGARG((png_structp png_ptr, int mem_level));
-
-extern PNG_EXPORT(void,png_set_compression_strategy)
- PNGARG((png_structp png_ptr, int strategy));
-
-extern PNG_EXPORT(void,png_set_compression_window_bits)
- PNGARG((png_structp png_ptr, int window_bits));
-
-extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
- int method));
-
-/* These next functions are called for input/output, memory, and error
- * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
- * and call standard C I/O routines such as fread(), fwrite(), and
- * fprintf(). These functions can be made to use other I/O routines
- * at run time for those applications that need to handle I/O in a
- * different manner by calling png_set_???_fn(). See libpng.txt for
- * more information.
- */
-
-#if !defined(PNG_NO_STDIO)
-/* Initialize the input/output for the PNG file to the default functions. */
-extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
-#endif
-
-/* Replace the (error and abort), and warning functions with user
- * supplied functions. If no messages are to be printed you must still
- * write and use replacement functions. The replacement error_fn should
- * still do a longjmp to the last setjmp location if you are using this
- * method of error handling. If error_fn or warning_fn is NULL, the
- * default function will be used.
- */
-
-extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
-
-/* Return the user pointer associated with the error functions */
-extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
-
-/* Replace the default data output functions with a user supplied one(s).
- * If buffered output is not used, then output_flush_fn can be set to NULL.
- * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
- * output_flush_fn will be ignored (and thus can be NULL).
- */
-extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
- png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
-
-/* Replace the default data input function with a user supplied one. */
-extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
- png_voidp io_ptr, png_rw_ptr read_data_fn));
-
-/* Return the user pointer associated with the I/O functions */
-extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
-
-extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
- png_read_status_ptr read_row_fn));
-
-extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
- png_write_status_ptr write_row_fn));
-
-#ifdef PNG_USER_MEM_SUPPORTED
-/* Replace the default memory allocation functions with user supplied one(s). */
-extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
- png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-/* Return the user pointer associated with the memory functions */
-extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
-extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
- png_ptr, png_user_transform_ptr read_user_transform_fn));
-#endif
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
-extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
- png_ptr, png_user_transform_ptr write_user_transform_fn));
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
-extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
- png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
- int user_transform_channels));
-/* Return the user pointer associated with the user transform functions */
-extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
- PNGARG((png_structp png_ptr));
-#endif
-
-#ifdef PNG_USER_CHUNKS_SUPPORTED
-extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
- png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
-extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
- png_ptr));
-#endif
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-/* Sets the function callbacks for the push reader, and a pointer to a
- * user-defined structure available to the callback functions.
- */
-extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
- png_voidp progressive_ptr,
- png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
- png_progressive_end_ptr end_fn));
-
-/* returns the user pointer associated with the push read functions */
-extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
- PNGARG((png_structp png_ptr));
-
-/* function to be called when data becomes available */
-extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
-
-/* function that combines rows. Not very much different than the
- * png_combine_row() call. Is this even used?????
- */
-extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
- png_bytep old_row, png_bytep new_row));
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-
-#if defined(PNG_1_0_X)
-# define png_malloc_warn png_malloc
-#else
-/* Added at libpng version 1.2.4 */
-extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-#endif
-
-/* frees a pointer allocated by png_malloc() */
-extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
-
-#if defined(PNG_1_0_X)
-/* Function to allocate memory for zlib. */
-extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
- uInt size));
-
-/* Function to free memory for zlib */
-extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
-#endif
-
-/* Free data that was allocated internally */
-extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 free_me, int num));
-#ifdef PNG_FREE_ME_SUPPORTED
-/* Reassign responsibility for freeing existing data, whether allocated
- * by libpng or by the application */
-extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int freer, png_uint_32 mask));
-#endif
-/* assignments for png_data_freer */
-#define PNG_DESTROY_WILL_FREE_DATA 1
-#define PNG_SET_WILL_FREE_DATA 1
-#define PNG_USER_WILL_FREE_DATA 2
-/* Flags for png_ptr->free_me and info_ptr->free_me */
-#define PNG_FREE_HIST 0x0008
-#define PNG_FREE_ICCP 0x0010
-#define PNG_FREE_SPLT 0x0020
-#define PNG_FREE_ROWS 0x0040
-#define PNG_FREE_PCAL 0x0080
-#define PNG_FREE_SCAL 0x0100
-#define PNG_FREE_UNKN 0x0200
-#define PNG_FREE_LIST 0x0400
-#define PNG_FREE_PLTE 0x1000
-#define PNG_FREE_TRNS 0x2000
-#define PNG_FREE_TEXT 0x4000
-#define PNG_FREE_ALL 0x7fff
-#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
-
-#ifdef PNG_USER_MEM_SUPPORTED
-extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
- png_uint_32 size));
-extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
- png_voidp ptr));
-#endif
-
-extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
- png_voidp s1, png_voidp s2, png_uint_32 size));
-
-extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
- png_voidp s1, int value, png_uint_32 size));
-
-#if defined(USE_FAR_KEYWORD) /* memory model conversion function */
-extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
- int check));
-#endif /* USE_FAR_KEYWORD */
-
-/* Fatal error in PNG image of libpng - can't continue */
-extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
- png_const_charp error_message));
-
-/* The same, but the chunk name is prepended to the error string. */
-extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
- png_const_charp error_message));
-
-#ifndef PNG_NO_WARNINGS
-/* Non-fatal error in libpng. Can continue, but may have a problem. */
-extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
- png_const_charp warning_message));
-
-#ifdef PNG_READ_SUPPORTED
-/* Non-fatal error in libpng, chunk name is prepended to message. */
-extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
- png_const_charp warning_message));
-#endif /* PNG_READ_SUPPORTED */
-#endif /* PNG_NO_WARNINGS */
-
-/* The png_set_<chunk> functions are for storing values in the png_info_struct.
- * Similarly, the png_get_<chunk> calls are used to read values from the
- * png_info_struct, either storing the parameters in the passed variables, or
- * setting pointers into the png_info_struct where the data is stored. The
- * png_get_<chunk> functions return a non-zero value if the data was available
- * in info_ptr, or return zero and do not change any of the parameters if the
- * data was not available.
- *
- * These functions should be used instead of directly accessing png_info
- * to avoid problems with future changes in the size and internal layout of
- * png_info_struct.
- */
-/* Returns "flag" if chunk data is valid in info_ptr. */
-extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
-png_infop info_ptr, png_uint_32 flag));
-
-/* Returns number of bytes needed to hold a transformed row. */
-extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-/* Returns row_pointers, which is an array of pointers to scanlines that was
-returned from png_read_png(). */
-extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-/* Set row_pointers, which is an array of pointers to scanlines for use
-by png_write_png(). */
-extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytepp row_pointers));
-#endif
-
-/* Returns number of color channels in image. */
-extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
-/* Returns image width in pixels. */
-extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image height in pixels. */
-extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image bit_depth. */
-extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image color_type. */
-extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image filter_type. */
-extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image interlace_type. */
-extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image compression_type. */
-extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns image resolution in pixels per meter, from pHYs chunk data. */
-extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-/* Returns pixel aspect ratio, computed from pHYs chunk data. */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-#endif
-
-/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
-extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
-png_ptr, png_infop info_ptr));
-
-#endif /* PNG_EASY_ACCESS_SUPPORTED */
-
-/* Returns pointer to signature string read from PNG header */
-extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-#if defined(PNG_bKGD_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_16p *background));
-#endif
-
-#if defined(PNG_bKGD_SUPPORTED)
-extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_16p background));
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double *white_x, double *white_y, double *red_x,
- double *red_y, double *green_x, double *green_y, double *blue_x,
- double *blue_y));
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
- *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
- png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
- *int_blue_x, png_fixed_point *int_blue_y));
-#endif
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double white_x, double white_y, double red_x,
- double red_y, double green_x, double green_y, double blue_x, double blue_y));
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
- png_fixed_point int_blue_y));
-#endif
-#endif
-
-#if defined(PNG_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double *file_gamma));
-#endif
-extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point *int_file_gamma));
-#endif
-
-#if defined(PNG_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
- png_infop info_ptr, double file_gamma));
-#endif
-extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_fixed_point int_file_gamma));
-#endif
-
-#if defined(PNG_hIST_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_16p *hist));
-#endif
-
-#if defined(PNG_hIST_SUPPORTED)
-extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_16p hist));
-#endif
-
-extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
- int *bit_depth, int *color_type, int *interlace_method,
- int *compression_method, int *filter_method));
-
-extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_method, int compression_method,
- int filter_method));
-
-#if defined(PNG_oFFs_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
- int *unit_type));
-#endif
-
-#if defined(PNG_oFFs_SUPPORTED)
-extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
- int unit_type));
-#endif
-
-#if defined(PNG_pCAL_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
- int *type, int *nparams, png_charp *units, png_charpp *params));
-#endif
-
-#if defined(PNG_pCAL_SUPPORTED)
-extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
- int type, int nparams, png_charp units, png_charpp params));
-#endif
-
-#if defined(PNG_pHYs_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-#endif
-
-#if defined(PNG_pHYs_SUPPORTED)
-extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
-#endif
-
-extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_colorp *palette, int *num_palette));
-
-extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_colorp palette, int num_palette));
-
-#if defined(PNG_sBIT_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_8p *sig_bit));
-#endif
-
-#if defined(PNG_sBIT_SUPPORTED)
-extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_color_8p sig_bit));
-#endif
-
-#if defined(PNG_sRGB_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *intent));
-#endif
-
-#if defined(PNG_sRGB_SUPPORTED)
-extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int intent));
-extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int intent));
-#endif
-
-#if defined(PNG_iCCP_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charpp name, int *compression_type,
- png_charpp profile, png_uint_32 *proflen));
- /* Note to maintainer: profile should be png_bytepp */
-#endif
-
-#if defined(PNG_iCCP_SUPPORTED)
-extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_charp name, int compression_type,
- png_charp profile, png_uint_32 proflen));
- /* Note to maintainer: profile should be png_bytep */
-#endif
-
-#if defined(PNG_sPLT_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_sPLT_tpp entries));
-#endif
-
-#if defined(PNG_sPLT_SUPPORTED)
-extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_sPLT_tp entries, int nentries));
-#endif
-
-#if defined(PNG_TEXT_SUPPORTED)
-/* png_get_text also returns the number of text chunks in *num_text */
-extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp *text_ptr, int *num_text));
-#endif
-
-/*
- * Note while png_set_text() will accept a structure whose text,
- * language, and translated keywords are NULL pointers, the structure
- * returned by png_get_text will always contain regular
- * zero-terminated C strings. They might be empty strings but
- * they will never be NULL pointers.
- */
-
-#if defined(PNG_TEXT_SUPPORTED)
-extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp text_ptr, int num_text));
-#endif
-
-#if defined(PNG_tIME_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_timep *mod_time));
-#endif
-
-#if defined(PNG_tIME_SUPPORTED)
-extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_timep mod_time));
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED)
-extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep *trans, int *num_trans,
- png_color_16p *trans_values));
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED)
-extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_bytep trans, int num_trans,
- png_color_16p trans_values));
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED)
-#endif
-
-#if defined(PNG_sCAL_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *unit, double *width, double *height));
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
-#endif
-#endif
-#endif /* PNG_sCAL_SUPPORTED */
-
-#if defined(PNG_sCAL_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int unit, double width, double height));
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
-extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
-#endif
-#endif
-#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-/* provide a list of chunks and how they are to be handled, if the built-in
- handling or default unknown chunk handling is not desired. Any chunks not
- listed will be handled in the default manner. The IHDR and IEND chunks
- must not be listed.
- keep = 0: follow default behaviour
- = 1: do not keep
- = 2: keep only if safe-to-copy
- = 3: keep even if unsafe-to-copy
-*/
-extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
- png_ptr, int keep, png_bytep chunk_list, int num_chunks));
-extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
-extern PNG_EXPORT(void, png_set_unknown_chunk_location)
- PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
-extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
- png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
-#endif
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
- chunk_name));
-#endif
-
-/* Png_free_data() will turn off the "valid" flag for anything it frees.
- If you need to turn it off for a chunk that your application has freed,
- you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
-extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
- png_infop info_ptr, int mask));
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-/* The "params" pointer is currently not used and is for future expansion. */
-extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
- png_infop info_ptr,
- int transforms,
- png_voidp params));
-extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
- png_infop info_ptr,
- int transforms,
- png_voidp params));
-#endif
-
-/* Define PNG_DEBUG at compile time for debugging information. Higher
- * numbers for PNG_DEBUG mean more debugging information. This has
- * only been added since version 0.95 so it is not implemented throughout
- * libpng yet, but more support will be added as needed.
- */
-#ifdef PNG_DEBUG
-#if (PNG_DEBUG > 0)
-#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
-#include <crtdbg.h>
-#if (PNG_DEBUG > 1)
-#define png_debug(l,m) _RPT0(_CRT_WARN,m)
-#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1)
-#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
-#endif
-#else /* PNG_DEBUG_FILE || !_MSC_VER */
-#ifndef PNG_DEBUG_FILE
-#define PNG_DEBUG_FILE stderr
-#endif /* PNG_DEBUG_FILE */
-#if (PNG_DEBUG > 1)
-#define png_debug(l,m) \
-{ \
- int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
-}
-#define png_debug1(l,m,p1) \
-{ \
- int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
-}
-#define png_debug2(l,m,p1,p2) \
-{ \
- int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
-}
-#endif /* (PNG_DEBUG > 1) */
-#endif /* _MSC_VER */
-#endif /* (PNG_DEBUG > 0) */
-#endif /* PNG_DEBUG */
-#ifndef png_debug
-#define png_debug(l, m)
-#endif
-#ifndef png_debug1
-#define png_debug1(l, m, p1)
-#endif
-#ifndef png_debug2
-#define png_debug2(l, m, p1, p2)
-#endif
-
-extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
-extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
-extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
-extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
- png_ptr, png_uint_32 mng_features_permitted));
-#endif
-
-/* For use in png_set_keep_unknown, added to version 1.2.6 */
-#define PNG_HANDLE_CHUNK_AS_DEFAULT 0
-#define PNG_HANDLE_CHUNK_NEVER 1
-#define PNG_HANDLE_CHUNK_IF_SAFE 2
-#define PNG_HANDLE_CHUNK_ALWAYS 3
-
-/* Added to version 1.2.0 */
-#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
-#if defined(PNG_MMX_CODE_SUPPORTED)
-#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */
-#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */
-#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04
-#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08
-#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10
-#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20
-#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40
-#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
-#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */
-
-#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
- | PNG_ASM_FLAG_MMX_READ_INTERLACE \
- | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
- | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
- | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
- | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
-#define PNG_MMX_WRITE_FLAGS ( 0 )
-
-#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
- | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \
- | PNG_MMX_READ_FLAGS \
- | PNG_MMX_WRITE_FLAGS )
-
-#define PNG_SELECT_READ 1
-#define PNG_SELECT_WRITE 2
-#endif /* PNG_MMX_CODE_SUPPORTED */
-
-#if !defined(PNG_1_0_X)
-/* pngget.c */
-extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask)
- PNGARG((int flag_select, int *compilerID));
-
-/* pngget.c */
-extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask)
- PNGARG((int flag_select));
-
-/* pngget.c */
-extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
- PNGARG((png_structp png_ptr));
-
-/* pngget.c */
-extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
- PNGARG((png_structp png_ptr));
-
-/* pngget.c */
-extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
- PNGARG((png_structp png_ptr));
-
-/* pngset.c */
-extern PNG_EXPORT(void,png_set_asm_flags)
- PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
-
-/* pngset.c */
-extern PNG_EXPORT(void,png_set_mmx_thresholds)
- PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
- png_uint_32 mmx_rowbytes_threshold));
-
-#endif /* PNG_1_0_X */
-
-#if !defined(PNG_1_0_X)
-/* png.c, pnggccrd.c, or pngvcrd.c */
-extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
-#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
-
-/* Strip the prepended error numbers ("#nnn ") from error and warning
- * messages before passing them to the error or warning handler. */
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
- png_ptr, png_uint_32 strip_mode));
-#endif
-
-#endif /* PNG_1_0_X */
-
-/* Added at libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp
- png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max));
-extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp
- png_ptr));
-extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp
- png_ptr));
-#endif
-
-/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
-
-#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
-/* With these routines we avoid an integer divide, which will be slower on
- * most machines. However, it does take more operations than the corresponding
- * divide method, so it may be slower on a few RISC systems. There are two
- * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
- *
- * Note that the rounding factors are NOT supposed to be the same! 128 and
- * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
- * standard method.
- *
- * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
- */
-
- /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
-
-# define png_composite(composite, fg, alpha, bg) \
- { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
- + (png_uint_16)(bg)*(png_uint_16)(255 - \
- (png_uint_16)(alpha)) + (png_uint_16)128); \
- (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
-
-# define png_composite_16(composite, fg, alpha, bg) \
- { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
- + (png_uint_32)(bg)*(png_uint_32)(65535L - \
- (png_uint_32)(alpha)) + (png_uint_32)32768L); \
- (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
-
-#else /* standard method using integer division */
-
-# define png_composite(composite, fg, alpha, bg) \
- (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
- (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
- (png_uint_16)127) / 255)
-
-# define png_composite_16(composite, fg, alpha, bg) \
- (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
- (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
- (png_uint_32)32767) / (png_uint_32)65535L)
-
-#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
-
-/* Inline macros to do direct reads of bytes from the input buffer. These
- * require that you are using an architecture that uses PNG byte ordering
- * (MSB first) and supports unaligned data storage. I think that PowerPC
- * in big-endian mode and 680x0 are the only ones that will support this.
- * The x86 line of processors definitely do not. The png_get_int_32()
- * routine also assumes we are using two's complement format for negative
- * values, which is almost certainly true.
- */
-#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
-# define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
-# define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
-# define png_get_int_32(buf) ( *((png_int_32p) (buf)))
-#else
-extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf));
-extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf));
-extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf));
-#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
-extern PNG_EXPORT(png_uint_32,png_get_uint_31)
- PNGARG((png_structp png_ptr, png_bytep buf));
-/* No png_get_int_16 -- may be added if there's a real need for it. */
-
-/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
- */
-extern PNG_EXPORT(void,png_save_uint_32)
- PNGARG((png_bytep buf, png_uint_32 i));
-extern PNG_EXPORT(void,png_save_int_32)
- PNGARG((png_bytep buf, png_int_32 i));
-
-/* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
-extern PNG_EXPORT(void,png_save_uint_16)
- PNGARG((png_bytep buf, unsigned int i));
-/* No png_save_int_16 -- may be added if there's a real need for it. */
-
-/* ************************************************************************* */
-
-/* These next functions are used internally in the code. They generally
- * shouldn't be used unless you are writing code to add or replace some
- * functionality in libpng. More information about most functions can
- * be found in the files where the functions are located.
- */
-
-
-/* Various modes of operation, that are visible to applications because
- * they are used for unknown chunk location.
- */
-#define PNG_HAVE_IHDR 0x01
-#define PNG_HAVE_PLTE 0x02
-#define PNG_HAVE_IDAT 0x04
-#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */
-#define PNG_HAVE_IEND 0x10
-
-#if defined(PNG_INTERNAL)
-
-/* More modes of operation. Note that after an init, mode is set to
- * zero automatically when the structure is created.
- */
-#define PNG_HAVE_gAMA 0x20
-#define PNG_HAVE_cHRM 0x40
-#define PNG_HAVE_sRGB 0x80
-#define PNG_HAVE_CHUNK_HEADER 0x100
-#define PNG_WROTE_tIME 0x200
-#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
-#define PNG_BACKGROUND_IS_GRAY 0x800
-#define PNG_HAVE_PNG_SIGNATURE 0x1000
-#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
-
-/* flags for the transformations the PNG library does on the image data */
-#define PNG_BGR 0x0001
-#define PNG_INTERLACE 0x0002
-#define PNG_PACK 0x0004
-#define PNG_SHIFT 0x0008
-#define PNG_SWAP_BYTES 0x0010
-#define PNG_INVERT_MONO 0x0020
-#define PNG_DITHER 0x0040
-#define PNG_BACKGROUND 0x0080
-#define PNG_BACKGROUND_EXPAND 0x0100
- /* 0x0200 unused */
-#define PNG_16_TO_8 0x0400
-#define PNG_RGBA 0x0800
-#define PNG_EXPAND 0x1000
-#define PNG_GAMMA 0x2000
-#define PNG_GRAY_TO_RGB 0x4000
-#define PNG_FILLER 0x8000L
-#define PNG_PACKSWAP 0x10000L
-#define PNG_SWAP_ALPHA 0x20000L
-#define PNG_STRIP_ALPHA 0x40000L
-#define PNG_INVERT_ALPHA 0x80000L
-#define PNG_USER_TRANSFORM 0x100000L
-#define PNG_RGB_TO_GRAY_ERR 0x200000L
-#define PNG_RGB_TO_GRAY_WARN 0x400000L
-#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
- /* 0x800000L Unused */
-#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
- /* 0x4000000L unused */
- /* 0x8000000L unused */
- /* 0x10000000L unused */
- /* 0x20000000L unused */
- /* 0x40000000L unused */
-
-/* flags for png_create_struct */
-#define PNG_STRUCT_PNG 0x0001
-#define PNG_STRUCT_INFO 0x0002
-
-/* Scaling factor for filter heuristic weighting calculations */
-#define PNG_WEIGHT_SHIFT 8
-#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
-#define PNG_COST_SHIFT 3
-#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
-
-/* flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
-#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
-#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
-#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
-#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
-#define PNG_FLAG_ZLIB_FINISHED 0x0020
-#define PNG_FLAG_ROW_INIT 0x0040
-#define PNG_FLAG_FILLER_AFTER 0x0080
-#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
-#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
-#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
-#define PNG_FLAG_FREE_PLTE 0x1000
-#define PNG_FLAG_FREE_TRNS 0x2000
-#define PNG_FLAG_FREE_HIST 0x4000
-#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
-#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
-#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
-#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
-#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
-#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
-#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
-#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
- /* 0x800000L unused */
- /* 0x1000000L unused */
- /* 0x2000000L unused */
- /* 0x4000000L unused */
- /* 0x8000000L unused */
- /* 0x10000000L unused */
- /* 0x20000000L unused */
- /* 0x40000000L unused */
-
-#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
- PNG_FLAG_CRC_ANCILLARY_NOWARN)
-
-#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
- PNG_FLAG_CRC_CRITICAL_IGNORE)
-
-#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
- PNG_FLAG_CRC_CRITICAL_MASK)
-
-/* save typing and make code easier to understand */
-
-#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
- abs((int)((c1).green) - (int)((c2).green)) + \
- abs((int)((c1).blue) - (int)((c2).blue)))
-
-/* Added to libpng-1.2.6 JB */
-#define PNG_ROWBYTES(pixel_bits, width) \
- ((pixel_bits) >= 8 ? \
- ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \
- (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) )
-
-/* PNG_OUT_OF_RANGE returns true if value is outside the range
- ideal-delta..ideal+delta. Each argument is evaluated twice.
- "ideal" and "delta" should be constants, normally simple
- integers, "value" a variable. Added to libpng-1.2.6 JB */
-#define PNG_OUT_OF_RANGE(value, ideal, delta) \
- ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
-
-/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
-#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
-/* place to hold the signature string for a PNG file. */
-#ifdef PNG_USE_GLOBAL_ARRAYS
- PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8];
-#else
-#endif
-#endif /* PNG_NO_EXTERN */
-
-/* Constant strings for known chunk types. If you need to add a chunk,
- * define the name here, and add an invocation of the macro in png.c and
- * wherever it's needed.
- */
-#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
-#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
-#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
-#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
-#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
-#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
-#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
-#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
-#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
-#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
-#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
-#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
-#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
-#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
-#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
-#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
-#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
-#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
-#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
-#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
-#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
-
-#ifdef PNG_USE_GLOBAL_ARRAYS
-PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
-PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
-#endif /* PNG_USE_GLOBAL_ARRAYS */
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* Initialize png_ptr struct for reading, and allocate any other memory.
- * (old interface - DEPRECATED - use png_create_read_struct instead).
- */
-extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
-#undef png_read_init
-#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
- PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
-#endif
-
-extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size));
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
- png_info_size));
-#endif
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* Initialize png_ptr struct for writing, and allocate any other memory.
- * (old interface - DEPRECATED - use png_create_write_struct instead).
- */
-extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
-#undef png_write_init
-#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
- PNG_LIBPNG_VER_STRING, png_sizeof(png_struct));
-#endif
-
-extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size));
-extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
- png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
- png_info_size));
-
-/* Allocate memory for an internal libpng struct */
-PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
-
-/* Free memory from internal libpng struct */
-PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
-
-PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
- malloc_fn, png_voidp mem_ptr));
-PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
- png_free_ptr free_fn, png_voidp mem_ptr));
-
-/* Free any memory that info_ptr points to and reset struct. */
-PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-#ifndef PNG_1_0_X
-/* Function to allocate memory for zlib. */
-PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
-
-/* Function to free memory for zlib */
-PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
-
-#ifdef PNG_SIZE_T
-/* Function to convert a sizeof an item to png_sizeof item */
- PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
-#endif
-
-/* Next four functions are used internally as callbacks. PNGAPI is required
- * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */
-
-PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t length));
-#endif
-
-PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
- png_bytep data, png_size_t length));
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-#if !defined(PNG_NO_STDIO)
-PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
-#endif
-#endif
-#else /* PNG_1_0_X */
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t length));
-#endif
-#endif /* PNG_1_0_X */
-
-/* Reset the CRC variable */
-PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
-
-/* Write the "data" buffer to whatever output you are using. */
-PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
-/* Read data from whatever input you are using into the "data" buffer */
-PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
-/* Read bytes into buf, and update png_ptr->crc */
-PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
- png_size_t length));
-
-/* Decompress data in a chunk that uses compression */
-#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
- defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
-PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
- int comp_type, png_charp chunkdata, png_size_t chunklength,
- png_size_t prefix_length, png_size_t *data_length));
-#endif
-
-/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
-PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
-
-/* Read the CRC from the file and compare it to the libpng calculated CRC */
-PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
-
-/* Calculate the CRC over a section of data. Note that we are only
- * passing a maximum of 64K on systems that have this as a memory limit,
- * since this is the maximum buffer size we can specify.
- */
-PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
- png_size_t length));
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
-#endif
-
-/* simple function to write the signature */
-PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
-
-/* write various chunks */
-
-/* Write the IHDR chunk, and update the png_struct with the necessary
- * information.
- */
-PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
- png_uint_32 height,
- int bit_depth, int color_type, int compression_method, int filter_method,
- int interlace_method));
-
-PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
- png_uint_32 num_pal));
-
-PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
- png_size_t length));
-
-PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
-
-#if defined(PNG_WRITE_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
- file_gamma));
-#endif
-#endif
-
-#if defined(PNG_WRITE_sBIT_SUPPORTED)
-PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
- int color_type));
-#endif
-
-#if defined(PNG_WRITE_cHRM_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
- double white_x, double white_y,
- double red_x, double red_y, double green_x, double green_y,
- double blue_x, double blue_y));
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
- png_fixed_point int_white_x, png_fixed_point int_white_y,
- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
- png_fixed_point int_blue_y));
-#endif
-#endif
-
-#if defined(PNG_WRITE_sRGB_SUPPORTED)
-PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
- int intent));
-#endif
-
-#if defined(PNG_WRITE_iCCP_SUPPORTED)
-PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
- png_charp name, int compression_type,
- png_charp profile, int proflen));
- /* Note to maintainer: profile should be png_bytep */
-#endif
-
-#if defined(PNG_WRITE_sPLT_SUPPORTED)
-PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
- png_sPLT_tp palette));
-#endif
-
-#if defined(PNG_WRITE_tRNS_SUPPORTED)
-PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
- png_color_16p values, int number, int color_type));
-#endif
-
-#if defined(PNG_WRITE_bKGD_SUPPORTED)
-PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
- png_color_16p values, int color_type));
-#endif
-
-#if defined(PNG_WRITE_hIST_SUPPORTED)
-PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
- int num_hist));
-#endif
-
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
-PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
- png_charp key, png_charpp new_key));
-#endif
-
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
-PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
- png_charp text, png_size_t text_len));
-#endif
-
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
-PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
- png_charp text, png_size_t text_len, int compression));
-#endif
-
-#if defined(PNG_WRITE_iTXt_SUPPORTED)
-PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
- int compression, png_charp key, png_charp lang, png_charp lang_key,
- png_charp text));
-#endif
-
-#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */
-PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_textp text_ptr, int num_text));
-#endif
-
-#if defined(PNG_WRITE_oFFs_SUPPORTED)
-PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
- png_int_32 x_offset, png_int_32 y_offset, int unit_type));
-#endif
-
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
-PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
- png_int_32 X0, png_int_32 X1, int type, int nparams,
- png_charp units, png_charpp params));
-#endif
-
-#if defined(PNG_WRITE_pHYs_SUPPORTED)
-PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
- png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
- int unit_type));
-#endif
-
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
- png_timep mod_time));
-#endif
-
-#if defined(PNG_WRITE_sCAL_SUPPORTED)
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
-PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
- int unit, double width, double height));
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
-PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
- int unit, png_charp width, png_charp height));
-#endif
-#endif
-#endif
-
-/* Called when finished processing a row of data */
-PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
-
-/* Internal use only. Called before first row of data */
-PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
-#endif
-
-/* combine a row of data, dealing with alpha, etc. if requested */
-PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
- int mask));
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-/* expand an interlaced row */
-/* OLD pre-1.0.9 interface:
-PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
- png_bytep row, int pass, png_uint_32 transformations));
- */
-PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
-#endif
-
-/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
-
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
-/* grab pixels out of a row for an interlaced pass */
-PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
- png_bytep row, int pass));
-#endif
-
-/* unfilter a row */
-PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
- png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
-
-/* Choose the best filter to use and filter the row data */
-PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
- png_row_infop row_info));
-
-/* Write out the filtered row. */
-PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
- png_bytep filtered_row));
-/* finish a row while reading, dealing with interlacing passes, etc. */
-PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
-
-/* initialize the row buffers, etc. */
-PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
-/* optional call to update the users info structure */
-PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-
-/* these are the functions that do the transformations */
-#if defined(PNG_READ_FILLER_SUPPORTED)
-PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 filler, png_uint_32 flags));
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
- defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 flags));
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
- row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED)
-PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
-PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
- png_color_8p sig_bits));
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
- png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
-
-# if defined(PNG_CORRECT_PALETTE_SUPPORTED)
-PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
- png_colorp palette, int num_palette));
-# endif
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
-#endif
-
-#if defined(PNG_WRITE_PACK_SUPPORTED)
-PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
- png_bytep row, png_uint_32 bit_depth));
-#endif
-
-#if defined(PNG_WRITE_SHIFT_SUPPORTED)
-PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
- png_color_8p bit_depth));
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background,
- png_color_16p background_1,
- png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
- png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
- png_uint_16pp gamma_16_to_1, int gamma_shift));
-#else
-PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background));
-#endif
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
- png_bytep gamma_table, png_uint_16pp gamma_16_table,
- int gamma_shift));
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
- png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
-PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
- png_bytep row, png_color_16p trans_value));
-#endif
-
-/* The following decodes the appropriate chunks, and does error correction,
- * then calls the appropriate callback for the chunk if it is valid.
- */
-
-/* decode the IHDR chunk */
-PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-
-#if defined(PNG_READ_bKGD_SUPPORTED)
-PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED)
-PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_gAMA_SUPPORTED)
-PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_hIST_SUPPORTED)
-PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_iCCP_SUPPORTED)
-extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif /* PNG_READ_iCCP_SUPPORTED */
-
-#if defined(PNG_READ_iTXt_SUPPORTED)
-PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_oFFs_SUPPORTED)
-PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_sCAL_SUPPORTED)
-PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_sPLT_SUPPORTED)
-extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif /* PNG_READ_sPLT_SUPPORTED */
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
-PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_tEXt_SUPPORTED)
-PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_tIME_SUPPORTED)
-PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
-PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-#if defined(PNG_READ_zTXt_SUPPORTED)
-PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
- png_uint_32 length));
-#endif
-
-PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-
-PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
- png_bytep chunk_name));
-
-/* handle the transformations for reading and writing */
-PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
-
-PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
- png_uint_32 length));
-PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t buffer_length));
-PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
- png_bytep buffer, png_size_t buffer_length));
-PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
-PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
-PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
-#if defined(PNG_READ_tEXt_SUPPORTED)
-PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
-PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
-PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr, png_uint_32 length));
-PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
- png_infop info_ptr));
-#endif
-
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
- png_bytep row));
-PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
- png_bytep row));
-#endif
-
-#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
-#if defined(PNG_MMX_CODE_SUPPORTED)
-/* png.c */ /* PRIVATE */
-PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr));
-#endif
-#endif
-
-#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
-PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr,
-png_infop info_ptr));
-
-#if defined(PNG_pHYs_SUPPORTED)
-PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr,
-png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-#endif /* PNG_pHYs_SUPPORTED */
-#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
-
-/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
-
-#endif /* PNG_INTERNAL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PNG_VERSION_INFO_ONLY */
-/* do not put anything past this line */
-#endif /* PNG_H */
diff --git a/distrib/libpng-1.2.19/pngconf.h b/distrib/libpng-1.2.19/pngconf.h
deleted file mode 100644
index 43dfe04..0000000
--- a/distrib/libpng-1.2.19/pngconf.h
+++ /dev/null
@@ -1,1535 +0,0 @@
-
-/* pngconf.h - machine configurable file for libpng
- *
- * libpng version 1.2.19 - August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-/* Any machine specific code is near the front of this file, so if you
- * are configuring libpng for a machine, you may want to read the section
- * starting here down to where it starts to typedef png_color, png_text,
- * and png_info.
- */
-
-#ifndef PNGCONF_H
-#define PNGCONF_H
-
-#define PNG_1_2_X
-
-/*
- * PNG_USER_CONFIG has to be defined on the compiler command line. This
- * includes the resource compiler for Windows DLL configurations.
- */
-#ifdef PNG_USER_CONFIG
-# ifndef PNG_USER_PRIVATEBUILD
-# define PNG_USER_PRIVATEBUILD
-# endif
-#include "pngusr.h"
-#endif
-
-/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */
-#ifdef PNG_CONFIGURE_LIBPNG
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#endif
-
-/*
- * Added at libpng-1.2.8
- *
- * If you create a private DLL you need to define in "pngusr.h" the followings:
- * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of
- * the DLL was built>
- * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
- * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
- * distinguish your DLL from those of the official release. These
- * correspond to the trailing letters that come after the version
- * number and must match your private DLL name>
- * e.g. // private DLL "libpng13gx.dll"
- * #define PNG_USER_DLLFNAME_POSTFIX "gx"
- *
- * The following macros are also at your disposal if you want to complete the
- * DLL VERSIONINFO structure.
- * - PNG_USER_VERSIONINFO_COMMENTS
- * - PNG_USER_VERSIONINFO_COMPANYNAME
- * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
- */
-
-#ifdef __STDC__
-#ifdef SPECIALBUILD
-# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\
- are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.")
-#endif
-
-#ifdef PRIVATEBUILD
-# pragma message("PRIVATEBUILD is deprecated.\
- Use PNG_USER_PRIVATEBUILD instead.")
-# define PNG_USER_PRIVATEBUILD PRIVATEBUILD
-#endif
-#endif /* __STDC__ */
-
-#ifndef PNG_VERSION_INFO_ONLY
-
-/* End of material added to libpng-1.2.8 */
-
-/* Added at libpng-1.2.19 */
-#ifndef PNG_NO_WARN_UNINITIALIZED_ROW
-# ifndef PNG_WARN_UNINITIALIZED_ROW
-# define PNG_WARN_UNINITIALIZED_ROW 1 /* 0: warning; 1: error */
-# endif
-#endif
-/* End of material added at libpng-1.2.19 */
-
-/* This is the size of the compression buffer, and thus the size of
- * an IDAT chunk. Make this whatever size you feel is best for your
- * machine. One of these will be allocated per png_struct. When this
- * is full, it writes the data to the disk, and does some other
- * calculations. Making this an extremely small size will slow
- * the library down, but you may want to experiment to determine
- * where it becomes significant, if you are concerned with memory
- * usage. Note that zlib allocates at least 32Kb also. For readers,
- * this describes the size of the buffer available to read the data in.
- * Unless this gets smaller than the size of a row (compressed),
- * it should not make much difference how big this is.
- */
-
-#ifndef PNG_ZBUF_SIZE
-# define PNG_ZBUF_SIZE 8192
-#endif
-
-/* Enable if you want a write-only libpng */
-
-#ifndef PNG_NO_READ_SUPPORTED
-# define PNG_READ_SUPPORTED
-#endif
-
-/* Enable if you want a read-only libpng */
-
-#ifndef PNG_NO_WRITE_SUPPORTED
-# define PNG_WRITE_SUPPORTED
-#endif
-
-/* Enabled by default in 1.2.0. You can disable this if you don't need to
- support PNGs that are embedded in MNG datastreams */
-#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
-# ifndef PNG_MNG_FEATURES_SUPPORTED
-# define PNG_MNG_FEATURES_SUPPORTED
-# endif
-#endif
-
-#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
-# ifndef PNG_FLOATING_POINT_SUPPORTED
-# define PNG_FLOATING_POINT_SUPPORTED
-# endif
-#endif
-
-/* If you are running on a machine where you cannot allocate more
- * than 64K of memory at once, uncomment this. While libpng will not
- * normally need that much memory in a chunk (unless you load up a very
- * large file), zlib needs to know how big of a chunk it can use, and
- * libpng thus makes sure to check any memory allocation to verify it
- * will fit into memory.
-#define PNG_MAX_MALLOC_64K
- */
-#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
-# define PNG_MAX_MALLOC_64K
-#endif
-
-/* Special munging to support doing things the 'cygwin' way:
- * 'Normal' png-on-win32 defines/defaults:
- * PNG_BUILD_DLL -- building dll
- * PNG_USE_DLL -- building an application, linking to dll
- * (no define) -- building static library, or building an
- * application and linking to the static lib
- * 'Cygwin' defines/defaults:
- * PNG_BUILD_DLL -- (ignored) building the dll
- * (no define) -- (ignored) building an application, linking to the dll
- * PNG_STATIC -- (ignored) building the static lib, or building an
- * application that links to the static lib.
- * ALL_STATIC -- (ignored) building various static libs, or building an
- * application that links to the static libs.
- * Thus,
- * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
- * this bit of #ifdefs will define the 'correct' config variables based on
- * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
- * unnecessary.
- *
- * Also, the precedence order is:
- * ALL_STATIC (since we can't #undef something outside our namespace)
- * PNG_BUILD_DLL
- * PNG_STATIC
- * (nothing) == PNG_USE_DLL
- *
- * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
- * of auto-import in binutils, we no longer need to worry about
- * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore,
- * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
- * to __declspec() stuff. However, we DO need to worry about
- * PNG_BUILD_DLL and PNG_STATIC because those change some defaults
- * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
- */
-#if defined(__CYGWIN__)
-# if defined(ALL_STATIC)
-# if defined(PNG_BUILD_DLL)
-# undef PNG_BUILD_DLL
-# endif
-# if defined(PNG_USE_DLL)
-# undef PNG_USE_DLL
-# endif
-# if defined(PNG_DLL)
-# undef PNG_DLL
-# endif
-# if !defined(PNG_STATIC)
-# define PNG_STATIC
-# endif
-# else
-# if defined (PNG_BUILD_DLL)
-# if defined(PNG_STATIC)
-# undef PNG_STATIC
-# endif
-# if defined(PNG_USE_DLL)
-# undef PNG_USE_DLL
-# endif
-# if !defined(PNG_DLL)
-# define PNG_DLL
-# endif
-# else
-# if defined(PNG_STATIC)
-# if defined(PNG_USE_DLL)
-# undef PNG_USE_DLL
-# endif
-# if defined(PNG_DLL)
-# undef PNG_DLL
-# endif
-# else
-# if !defined(PNG_USE_DLL)
-# define PNG_USE_DLL
-# endif
-# if !defined(PNG_DLL)
-# define PNG_DLL
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* This protects us against compilers that run on a windowing system
- * and thus don't have or would rather us not use the stdio types:
- * stdin, stdout, and stderr. The only one currently used is stderr
- * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
- * prevent these from being compiled and used. #defining PNG_NO_STDIO
- * will also prevent these, plus will prevent the entire set of stdio
- * macros and functions (FILE *, printf, etc.) from being compiled and used,
- * unless (PNG_DEBUG > 0) has been #defined.
- *
- * #define PNG_NO_CONSOLE_IO
- * #define PNG_NO_STDIO
- */
-
-#if defined(_WIN32_WCE)
-# include <windows.h>
- /* Console I/O functions are not supported on WindowsCE */
-# define PNG_NO_CONSOLE_IO
-# ifdef PNG_DEBUG
-# undef PNG_DEBUG
-# endif
-#endif
-
-#ifdef PNG_BUILD_DLL
-# ifndef PNG_CONSOLE_IO_SUPPORTED
-# ifndef PNG_NO_CONSOLE_IO
-# define PNG_NO_CONSOLE_IO
-# endif
-# endif
-#endif
-
-# ifdef PNG_NO_STDIO
-# ifndef PNG_NO_CONSOLE_IO
-# define PNG_NO_CONSOLE_IO
-# endif
-# ifdef PNG_DEBUG
-# if (PNG_DEBUG > 0)
-# include <stdio.h>
-# endif
-# endif
-# else
-# if !defined(_WIN32_WCE)
-/* "stdio.h" functions are not supported on WindowsCE */
-# include <stdio.h>
-# endif
-# endif
-
-/* This macro protects us against machines that don't have function
- * prototypes (ie K&R style headers). If your compiler does not handle
- * function prototypes, define this macro and use the included ansi2knr.
- * I've always been able to use _NO_PROTO as the indicator, but you may
- * need to drag the empty declaration out in front of here, or change the
- * ifdef to suit your own needs.
- */
-#ifndef PNGARG
-
-#ifdef OF /* zlib prototype munger */
-# define PNGARG(arglist) OF(arglist)
-#else
-
-#ifdef _NO_PROTO
-# define PNGARG(arglist) ()
-# ifndef PNG_TYPECAST_NULL
-# define PNG_TYPECAST_NULL
-# endif
-#else
-# define PNGARG(arglist) arglist
-#endif /* _NO_PROTO */
-
-
-#endif /* OF */
-
-#endif /* PNGARG */
-
-/* Try to determine if we are compiling on a Mac. Note that testing for
- * just __MWERKS__ is not good enough, because the Codewarrior is now used
- * on non-Mac platforms.
- */
-#ifndef MACOS
-# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
- defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-# define MACOS
-# endif
-#endif
-
-/* enough people need this for various reasons to include it here */
-#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
-# include <sys/types.h>
-#endif
-
-#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
-# define PNG_SETJMP_SUPPORTED
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* This is an attempt to force a single setjmp behaviour on Linux. If
- * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
- */
-
-# ifdef __linux__
-# ifdef _BSD_SOURCE
-# define PNG_SAVE_BSD_SOURCE
-# undef _BSD_SOURCE
-# endif
-# ifdef _SETJMP_H
- /* If you encounter a compiler error here, see the explanation
- * near the end of INSTALL.
- */
- __png.h__ already includes setjmp.h;
- __dont__ include it again.;
-# endif
-# endif /* __linux__ */
-
- /* include setjmp.h for error handling */
-# include <setjmp.h>
-
-# ifdef __linux__
-# ifdef PNG_SAVE_BSD_SOURCE
-# define _BSD_SOURCE
-# undef PNG_SAVE_BSD_SOURCE
-# endif
-# endif /* __linux__ */
-#endif /* PNG_SETJMP_SUPPORTED */
-
-#ifdef BSD
-# include <strings.h>
-#else
-# include <string.h>
-#endif
-
-/* Other defines for things like memory and the like can go here. */
-#ifdef PNG_INTERNAL
-
-#include <stdlib.h>
-
-/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
- * aren't usually used outside the library (as far as I know), so it is
- * debatable if they should be exported at all. In the future, when it is
- * possible to have run-time registry of chunk-handling functions, some of
- * these will be made available again.
-#define PNG_EXTERN extern
- */
-#define PNG_EXTERN
-
-/* Other defines specific to compilers can go here. Try to keep
- * them inside an appropriate ifdef/endif pair for portability.
- */
-
-#if defined(PNG_FLOATING_POINT_SUPPORTED)
-# if defined(MACOS)
- /* We need to check that <math.h> hasn't already been included earlier
- * as it seems it doesn't agree with <fp.h>, yet we should really use
- * <fp.h> if possible.
- */
-# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
-# include <fp.h>
-# endif
-# else
-# include <math.h>
-# endif
-# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
- /* Amiga SAS/C: We must include builtin FPU functions when compiling using
- * MATH=68881
- */
-# include <m68881.h>
-# endif
-#endif
-
-/* Codewarrior on NT has linking problems without this. */
-#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
-# define PNG_ALWAYS_EXTERN
-#endif
-
-/* This provides the non-ANSI (far) memory allocation routines. */
-#if defined(__TURBOC__) && defined(__MSDOS__)
-# include <mem.h>
-# include <alloc.h>
-#endif
-
-/* I have no idea why is this necessary... */
-#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
- defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
-# include <malloc.h>
-#endif
-
-/* This controls how fine the dithering gets. As this allocates
- * a largish chunk of memory (32K), those who are not as concerned
- * with dithering quality can decrease some or all of these.
- */
-#ifndef PNG_DITHER_RED_BITS
-# define PNG_DITHER_RED_BITS 5
-#endif
-#ifndef PNG_DITHER_GREEN_BITS
-# define PNG_DITHER_GREEN_BITS 5
-#endif
-#ifndef PNG_DITHER_BLUE_BITS
-# define PNG_DITHER_BLUE_BITS 5
-#endif
-
-/* This controls how fine the gamma correction becomes when you
- * are only interested in 8 bits anyway. Increasing this value
- * results in more memory being used, and more pow() functions
- * being called to fill in the gamma tables. Don't set this value
- * less then 8, and even that may not work (I haven't tested it).
- */
-
-#ifndef PNG_MAX_GAMMA_8
-# define PNG_MAX_GAMMA_8 11
-#endif
-
-/* This controls how much a difference in gamma we can tolerate before
- * we actually start doing gamma conversion.
- */
-#ifndef PNG_GAMMA_THRESHOLD
-# define PNG_GAMMA_THRESHOLD 0.05
-#endif
-
-#endif /* PNG_INTERNAL */
-
-/* The following uses const char * instead of char * for error
- * and warning message functions, so some compilers won't complain.
- * If you do not want to use const, define PNG_NO_CONST here.
- */
-
-#ifndef PNG_NO_CONST
-# define PNG_CONST const
-#else
-# define PNG_CONST
-#endif
-
-/* The following defines give you the ability to remove code from the
- * library that you will not be using. I wish I could figure out how to
- * automate this, but I can't do that without making it seriously hard
- * on the users. So if you are not using an ability, change the #define
- * to and #undef, and that part of the library will not be compiled. If
- * your linker can't find a function, you may want to make sure the
- * ability is defined here. Some of these depend upon some others being
- * defined. I haven't figured out all the interactions here, so you may
- * have to experiment awhile to get everything to compile. If you are
- * creating or using a shared library, you probably shouldn't touch this,
- * as it will affect the size of the structures, and this will cause bad
- * things to happen if the library and/or application ever change.
- */
-
-/* Any features you will not be using can be undef'ed here */
-
-/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
- * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
- * on the compile line, then pick and choose which ones to define without
- * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
- * if you only want to have a png-compliant reader/writer but don't need
- * any of the extra transformations. This saves about 80 kbytes in a
- * typical installation of the library. (PNG_NO_* form added in version
- * 1.0.1c, for consistency)
- */
-
-/* The size of the png_text structure changed in libpng-1.0.6 when
- * iTXt support was added. iTXt support was turned off by default through
- * libpng-1.2.x, to support old apps that malloc the png_text structure
- * instead of calling png_set_text() and letting libpng malloc it. It
- * was turned on by default in libpng-1.3.0.
- */
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-# ifndef PNG_NO_iTXt_SUPPORTED
-# define PNG_NO_iTXt_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_iTXt
-# define PNG_NO_READ_iTXt
-# endif
-# ifndef PNG_NO_WRITE_iTXt
-# define PNG_NO_WRITE_iTXt
-# endif
-#endif
-
-#if !defined(PNG_NO_iTXt_SUPPORTED)
-# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
-# define PNG_READ_iTXt
-# endif
-# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
-# define PNG_WRITE_iTXt
-# endif
-#endif
-
-/* The following support, added after version 1.0.0, can be turned off here en
- * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
- * with old applications that require the length of png_struct and png_info
- * to remain unchanged.
- */
-
-#ifdef PNG_LEGACY_SUPPORTED
-# define PNG_NO_FREE_ME
-# define PNG_NO_READ_UNKNOWN_CHUNKS
-# define PNG_NO_WRITE_UNKNOWN_CHUNKS
-# define PNG_NO_READ_USER_CHUNKS
-# define PNG_NO_READ_iCCP
-# define PNG_NO_WRITE_iCCP
-# define PNG_NO_READ_iTXt
-# define PNG_NO_WRITE_iTXt
-# define PNG_NO_READ_sCAL
-# define PNG_NO_WRITE_sCAL
-# define PNG_NO_READ_sPLT
-# define PNG_NO_WRITE_sPLT
-# define PNG_NO_INFO_IMAGE
-# define PNG_NO_READ_RGB_TO_GRAY
-# define PNG_NO_READ_USER_TRANSFORM
-# define PNG_NO_WRITE_USER_TRANSFORM
-# define PNG_NO_USER_MEM
-# define PNG_NO_READ_EMPTY_PLTE
-# define PNG_NO_MNG_FEATURES
-# define PNG_NO_FIXED_POINT_SUPPORTED
-#endif
-
-/* Ignore attempt to turn off both floating and fixed point support */
-#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
- !defined(PNG_NO_FIXED_POINT_SUPPORTED)
-# define PNG_FIXED_POINT_SUPPORTED
-#endif
-
-#ifndef PNG_NO_FREE_ME
-# define PNG_FREE_ME_SUPPORTED
-#endif
-
-#if defined(PNG_READ_SUPPORTED)
-
-#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
- !defined(PNG_NO_READ_TRANSFORMS)
-# define PNG_READ_TRANSFORMS_SUPPORTED
-#endif
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-# ifndef PNG_NO_READ_EXPAND
-# define PNG_READ_EXPAND_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_SHIFT
-# define PNG_READ_SHIFT_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_PACK
-# define PNG_READ_PACK_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_BGR
-# define PNG_READ_BGR_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_SWAP
-# define PNG_READ_SWAP_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_PACKSWAP
-# define PNG_READ_PACKSWAP_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_INVERT
-# define PNG_READ_INVERT_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_DITHER
-# define PNG_READ_DITHER_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_BACKGROUND
-# define PNG_READ_BACKGROUND_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_16_TO_8
-# define PNG_READ_16_TO_8_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_FILLER
-# define PNG_READ_FILLER_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_GAMMA
-# define PNG_READ_GAMMA_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_GRAY_TO_RGB
-# define PNG_READ_GRAY_TO_RGB_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_SWAP_ALPHA
-# define PNG_READ_SWAP_ALPHA_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_INVERT_ALPHA
-# define PNG_READ_INVERT_ALPHA_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_STRIP_ALPHA
-# define PNG_READ_STRIP_ALPHA_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_USER_TRANSFORM
-# define PNG_READ_USER_TRANSFORM_SUPPORTED
-# endif
-# ifndef PNG_NO_READ_RGB_TO_GRAY
-# define PNG_READ_RGB_TO_GRAY_SUPPORTED
-# endif
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#if !defined(PNG_NO_PROGRESSIVE_READ) && \
- !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */
-# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */
-#endif /* about interlacing capability! You'll */
- /* still have interlacing unless you change the following line: */
-
-#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */
-
-#ifndef PNG_NO_READ_COMPOSITE_NODIV
-# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */
-# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */
-# endif
-#endif
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* Deprecated, will be removed from version 2.0.0.
- Use PNG_MNG_FEATURES_SUPPORTED instead. */
-#ifndef PNG_NO_READ_EMPTY_PLTE
-# define PNG_READ_EMPTY_PLTE_SUPPORTED
-#endif
-#endif
-
-#endif /* PNG_READ_SUPPORTED */
-
-#if defined(PNG_WRITE_SUPPORTED)
-
-# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
- !defined(PNG_NO_WRITE_TRANSFORMS)
-# define PNG_WRITE_TRANSFORMS_SUPPORTED
-#endif
-
-#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-# ifndef PNG_NO_WRITE_SHIFT
-# define PNG_WRITE_SHIFT_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_PACK
-# define PNG_WRITE_PACK_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_BGR
-# define PNG_WRITE_BGR_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_SWAP
-# define PNG_WRITE_SWAP_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_PACKSWAP
-# define PNG_WRITE_PACKSWAP_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_INVERT
-# define PNG_WRITE_INVERT_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_FILLER
-# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */
-# endif
-# ifndef PNG_NO_WRITE_SWAP_ALPHA
-# define PNG_WRITE_SWAP_ALPHA_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_INVERT_ALPHA
-# define PNG_WRITE_INVERT_ALPHA_SUPPORTED
-# endif
-# ifndef PNG_NO_WRITE_USER_TRANSFORM
-# define PNG_WRITE_USER_TRANSFORM_SUPPORTED
-# endif
-#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
-
-#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \
- !defined(PNG_WRITE_INTERLACING_SUPPORTED)
-#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
- encoders, but can cause trouble
- if left undefined */
-#endif
-
-#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
- !defined(PNG_WRITE_WEIGHTED_FILTER) && \
- defined(PNG_FLOATING_POINT_SUPPORTED)
-# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
-#endif
-
-#ifndef PNG_NO_WRITE_FLUSH
-# define PNG_WRITE_FLUSH_SUPPORTED
-#endif
-
-#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
-/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
-#ifndef PNG_NO_WRITE_EMPTY_PLTE
-# define PNG_WRITE_EMPTY_PLTE_SUPPORTED
-#endif
-#endif
-
-#endif /* PNG_WRITE_SUPPORTED */
-
-#ifndef PNG_1_0_X
-# ifndef PNG_NO_ERROR_NUMBERS
-# define PNG_ERROR_NUMBERS_SUPPORTED
-# endif
-#endif /* PNG_1_0_X */
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-# ifndef PNG_NO_USER_TRANSFORM_PTR
-# define PNG_USER_TRANSFORM_PTR_SUPPORTED
-# endif
-#endif
-
-#ifndef PNG_NO_STDIO
-# define PNG_TIME_RFC1123_SUPPORTED
-#endif
-
-/* This adds extra functions in pngget.c for accessing data from the
- * info pointer (added in version 0.99)
- * png_get_image_width()
- * png_get_image_height()
- * png_get_bit_depth()
- * png_get_color_type()
- * png_get_compression_type()
- * png_get_filter_type()
- * png_get_interlace_type()
- * png_get_pixel_aspect_ratio()
- * png_get_pixels_per_meter()
- * png_get_x_offset_pixels()
- * png_get_y_offset_pixels()
- * png_get_x_offset_microns()
- * png_get_y_offset_microns()
- */
-#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
-# define PNG_EASY_ACCESS_SUPPORTED
-#endif
-
-/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0
- * even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined.
- *
- * PNG_NO_ASSEMBLER_CODE disables use of all assembler code,
- * and removes several functions from the API.
- *
- * PNG_NO_MMX_CODE disables the use of MMX code without changing the API.
- * When MMX code is off, then optimized C replacement functions are used,
- * if PNG_NO_OPTIMIZED_CODE is not enabled. This was added in version
- * 1.2.19.
-*/
-
-#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE)
-# ifndef PNG_OPTIMIZED_CODE_SUPPORTED
-# define PNG_OPTIMIZED_CODE_SUPPORTED
-# endif
-#endif
-
-#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
-# ifndef PNG_ASSEMBLER_CODE_SUPPORTED
-# define PNG_ASSEMBLER_CODE_SUPPORTED
-# endif
-
-# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
-# define PNG_MMX_CODE_SUPPORTED
-# endif
-
-# if !defined(PNG_USE_PNGVCRD) && defined(PNG_MMX_CODE_SUPPORTED) && \
- defined(_MSC_VER)
-# define PNG_USE_PNGVCRD
-# endif
-
-# if !defined(PNG_USE_PNGGCCRD) && defined(PNG_MMX_CODE_SUPPORTED) && \
- !defined(PNG_USE_PNGVCRD)
-# define PNG_USE_PNGGCCRD
- /* If you are sure that you don't need thread safety and you are compiling
- with PNG_USE_PNGCCRD for an MMX application, you can define this for
- faster execution. See pnggccrd.c.
-# define PNG_THREAD_UNSAFE_OK
- */
-# endif
-
-#endif
-
-#if !defined(PNG_1_0_X)
-#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
-# define PNG_USER_MEM_SUPPORTED
-#endif
-#endif /* PNG_1_0_X */
-
-/* Added at libpng-1.2.6 */
-#if !defined(PNG_1_0_X)
-#ifndef PNG_SET_USER_LIMITS_SUPPORTED
-#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED)
-# define PNG_SET_USER_LIMITS_SUPPORTED
-#endif
-#endif
-#endif /* PNG_1_0_X */
-
-/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter
- * how large, set these limits to 0x7fffffffL
- */
-#ifndef PNG_USER_WIDTH_MAX
-# define PNG_USER_WIDTH_MAX 1000000L
-#endif
-#ifndef PNG_USER_HEIGHT_MAX
-# define PNG_USER_HEIGHT_MAX 1000000L
-#endif
-
-/* These are currently experimental features, define them if you want */
-
-/* very little testing */
-/*
-#ifdef PNG_READ_SUPPORTED
-# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
-# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
-# endif
-#endif
-*/
-
-/* This is only for PowerPC big-endian and 680x0 systems */
-/* some testing */
-/*
-#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
-# define PNG_READ_BIG_ENDIAN_SUPPORTED
-#endif
-*/
-
-/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
-/*
-#define PNG_NO_POINTER_INDEXING
-*/
-
-/* These functions are turned off by default, as they will be phased out. */
-/*
-#define PNG_USELESS_TESTS_SUPPORTED
-#define PNG_CORRECT_PALETTE_SUPPORTED
-*/
-
-/* Any chunks you are not interested in, you can undef here. The
- * ones that allocate memory may be expecially important (hIST,
- * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
- * a bit smaller.
- */
-
-#if defined(PNG_READ_SUPPORTED) && \
- !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
- !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
-# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
-#endif
-
-#if defined(PNG_WRITE_SUPPORTED) && \
- !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
- !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
-# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
-#endif
-
-#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
-
-#ifdef PNG_NO_READ_TEXT
-# define PNG_NO_READ_iTXt
-# define PNG_NO_READ_tEXt
-# define PNG_NO_READ_zTXt
-#endif
-#ifndef PNG_NO_READ_bKGD
-# define PNG_READ_bKGD_SUPPORTED
-# define PNG_bKGD_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_cHRM
-# define PNG_READ_cHRM_SUPPORTED
-# define PNG_cHRM_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_gAMA
-# define PNG_READ_gAMA_SUPPORTED
-# define PNG_gAMA_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_hIST
-# define PNG_READ_hIST_SUPPORTED
-# define PNG_hIST_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_iCCP
-# define PNG_READ_iCCP_SUPPORTED
-# define PNG_iCCP_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_iTXt
-# ifndef PNG_READ_iTXt_SUPPORTED
-# define PNG_READ_iTXt_SUPPORTED
-# endif
-# ifndef PNG_iTXt_SUPPORTED
-# define PNG_iTXt_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_READ_oFFs
-# define PNG_READ_oFFs_SUPPORTED
-# define PNG_oFFs_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_pCAL
-# define PNG_READ_pCAL_SUPPORTED
-# define PNG_pCAL_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_sCAL
-# define PNG_READ_sCAL_SUPPORTED
-# define PNG_sCAL_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_pHYs
-# define PNG_READ_pHYs_SUPPORTED
-# define PNG_pHYs_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_sBIT
-# define PNG_READ_sBIT_SUPPORTED
-# define PNG_sBIT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_sPLT
-# define PNG_READ_sPLT_SUPPORTED
-# define PNG_sPLT_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_sRGB
-# define PNG_READ_sRGB_SUPPORTED
-# define PNG_sRGB_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_tEXt
-# define PNG_READ_tEXt_SUPPORTED
-# define PNG_tEXt_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_tIME
-# define PNG_READ_tIME_SUPPORTED
-# define PNG_tIME_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_tRNS
-# define PNG_READ_tRNS_SUPPORTED
-# define PNG_tRNS_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_zTXt
-# define PNG_READ_zTXt_SUPPORTED
-# define PNG_zTXt_SUPPORTED
-#endif
-#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
-# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
-# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
-# define PNG_UNKNOWN_CHUNKS_SUPPORTED
-# endif
-# ifndef PNG_NO_HANDLE_AS_UNKNOWN
-# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-# endif
-#endif
-#if !defined(PNG_NO_READ_USER_CHUNKS) && \
- defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
-# define PNG_READ_USER_CHUNKS_SUPPORTED
-# define PNG_USER_CHUNKS_SUPPORTED
-# ifdef PNG_NO_READ_UNKNOWN_CHUNKS
-# undef PNG_NO_READ_UNKNOWN_CHUNKS
-# endif
-# ifdef PNG_NO_HANDLE_AS_UNKNOWN
-# undef PNG_NO_HANDLE_AS_UNKNOWN
-# endif
-#endif
-#ifndef PNG_NO_READ_OPT_PLTE
-# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
-#endif /* optional PLTE chunk in RGB and RGBA images */
-#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
- defined(PNG_READ_zTXt_SUPPORTED)
-# define PNG_READ_TEXT_SUPPORTED
-# define PNG_TEXT_SUPPORTED
-#endif
-
-#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
-
-#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
-
-#ifdef PNG_NO_WRITE_TEXT
-# define PNG_NO_WRITE_iTXt
-# define PNG_NO_WRITE_tEXt
-# define PNG_NO_WRITE_zTXt
-#endif
-#ifndef PNG_NO_WRITE_bKGD
-# define PNG_WRITE_bKGD_SUPPORTED
-# ifndef PNG_bKGD_SUPPORTED
-# define PNG_bKGD_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_cHRM
-# define PNG_WRITE_cHRM_SUPPORTED
-# ifndef PNG_cHRM_SUPPORTED
-# define PNG_cHRM_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_gAMA
-# define PNG_WRITE_gAMA_SUPPORTED
-# ifndef PNG_gAMA_SUPPORTED
-# define PNG_gAMA_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_hIST
-# define PNG_WRITE_hIST_SUPPORTED
-# ifndef PNG_hIST_SUPPORTED
-# define PNG_hIST_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_iCCP
-# define PNG_WRITE_iCCP_SUPPORTED
-# ifndef PNG_iCCP_SUPPORTED
-# define PNG_iCCP_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_iTXt
-# ifndef PNG_WRITE_iTXt_SUPPORTED
-# define PNG_WRITE_iTXt_SUPPORTED
-# endif
-# ifndef PNG_iTXt_SUPPORTED
-# define PNG_iTXt_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_oFFs
-# define PNG_WRITE_oFFs_SUPPORTED
-# ifndef PNG_oFFs_SUPPORTED
-# define PNG_oFFs_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_pCAL
-# define PNG_WRITE_pCAL_SUPPORTED
-# ifndef PNG_pCAL_SUPPORTED
-# define PNG_pCAL_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_sCAL
-# define PNG_WRITE_sCAL_SUPPORTED
-# ifndef PNG_sCAL_SUPPORTED
-# define PNG_sCAL_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_pHYs
-# define PNG_WRITE_pHYs_SUPPORTED
-# ifndef PNG_pHYs_SUPPORTED
-# define PNG_pHYs_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_sBIT
-# define PNG_WRITE_sBIT_SUPPORTED
-# ifndef PNG_sBIT_SUPPORTED
-# define PNG_sBIT_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_sPLT
-# define PNG_WRITE_sPLT_SUPPORTED
-# ifndef PNG_sPLT_SUPPORTED
-# define PNG_sPLT_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_sRGB
-# define PNG_WRITE_sRGB_SUPPORTED
-# ifndef PNG_sRGB_SUPPORTED
-# define PNG_sRGB_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_tEXt
-# define PNG_WRITE_tEXt_SUPPORTED
-# ifndef PNG_tEXt_SUPPORTED
-# define PNG_tEXt_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_tIME
-# define PNG_WRITE_tIME_SUPPORTED
-# ifndef PNG_tIME_SUPPORTED
-# define PNG_tIME_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_tRNS
-# define PNG_WRITE_tRNS_SUPPORTED
-# ifndef PNG_tRNS_SUPPORTED
-# define PNG_tRNS_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_zTXt
-# define PNG_WRITE_zTXt_SUPPORTED
-# ifndef PNG_zTXt_SUPPORTED
-# define PNG_zTXt_SUPPORTED
-# endif
-#endif
-#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
-# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
-# define PNG_UNKNOWN_CHUNKS_SUPPORTED
-# endif
-# ifndef PNG_NO_HANDLE_AS_UNKNOWN
-# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-# endif
-# endif
-#endif
-#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
- defined(PNG_WRITE_zTXt_SUPPORTED)
-# define PNG_WRITE_TEXT_SUPPORTED
-# ifndef PNG_TEXT_SUPPORTED
-# define PNG_TEXT_SUPPORTED
-# endif
-#endif
-
-#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
-
-/* Turn this off to disable png_read_png() and
- * png_write_png() and leave the row_pointers member
- * out of the info structure.
- */
-#ifndef PNG_NO_INFO_IMAGE
-# define PNG_INFO_IMAGE_SUPPORTED
-#endif
-
-/* need the time information for reading tIME chunks */
-#if defined(PNG_tIME_SUPPORTED)
-# if !defined(_WIN32_WCE)
- /* "time.h" functions are not supported on WindowsCE */
-# include <time.h>
-# endif
-#endif
-
-/* Some typedefs to get us started. These should be safe on most of the
- * common platforms. The typedefs should be at least as large as the
- * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
- * don't have to be exactly that size. Some compilers dislike passing
- * unsigned shorts as function parameters, so you may be better off using
- * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
- * want to have unsigned int for png_uint_32 instead of unsigned long.
- */
-
-typedef unsigned long png_uint_32;
-typedef long png_int_32;
-typedef unsigned short png_uint_16;
-typedef short png_int_16;
-typedef unsigned char png_byte;
-
-/* This is usually size_t. It is typedef'ed just in case you need it to
- change (I'm not sure if you will or not, so I thought I'd be safe) */
-#ifdef PNG_SIZE_T
- typedef PNG_SIZE_T png_size_t;
-# define png_sizeof(x) png_convert_size(sizeof (x))
-#else
- typedef size_t png_size_t;
-# define png_sizeof(x) sizeof (x)
-#endif
-
-/* The following is needed for medium model support. It cannot be in the
- * PNG_INTERNAL section. Needs modification for other compilers besides
- * MSC. Model independent support declares all arrays and pointers to be
- * large using the far keyword. The zlib version used must also support
- * model independent data. As of version zlib 1.0.4, the necessary changes
- * have been made in zlib. The USE_FAR_KEYWORD define triggers other
- * changes that are needed. (Tim Wegner)
- */
-
-/* Separate compiler dependencies (problem here is that zlib.h always
- defines FAR. (SJT) */
-#ifdef __BORLANDC__
-# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
-# define LDATA 1
-# else
-# define LDATA 0
-# endif
- /* GRR: why is Cygwin in here? Cygwin is not Borland C... */
-# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
-# define PNG_MAX_MALLOC_64K
-# if (LDATA != 1)
-# ifndef FAR
-# define FAR __far
-# endif
-# define USE_FAR_KEYWORD
-# endif /* LDATA != 1 */
- /* Possibly useful for moving data out of default segment.
- * Uncomment it if you want. Could also define FARDATA as
- * const if your compiler supports it. (SJT)
-# define FARDATA FAR
- */
-# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
-#endif /* __BORLANDC__ */
-
-
-/* Suggest testing for specific compiler first before testing for
- * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
- * making reliance oncertain keywords suspect. (SJT)
- */
-
-/* MSC Medium model */
-#if defined(FAR)
-# if defined(M_I86MM)
-# define USE_FAR_KEYWORD
-# define FARDATA FAR
-# include <dos.h>
-# endif
-#endif
-
-/* SJT: default case */
-#ifndef FAR
-# define FAR
-#endif
-
-/* At this point FAR is always defined */
-#ifndef FARDATA
-# define FARDATA
-#endif
-
-/* Typedef for floating-point numbers that are converted
- to fixed-point with a multiple of 100,000, e.g., int_gamma */
-typedef png_int_32 png_fixed_point;
-
-/* Add typedefs for pointers */
-typedef void FAR * png_voidp;
-typedef png_byte FAR * png_bytep;
-typedef png_uint_32 FAR * png_uint_32p;
-typedef png_int_32 FAR * png_int_32p;
-typedef png_uint_16 FAR * png_uint_16p;
-typedef png_int_16 FAR * png_int_16p;
-typedef PNG_CONST char FAR * png_const_charp;
-typedef char FAR * png_charp;
-typedef png_fixed_point FAR * png_fixed_point_p;
-
-#ifndef PNG_NO_STDIO
-#if defined(_WIN32_WCE)
-typedef HANDLE png_FILE_p;
-#else
-typedef FILE * png_FILE_p;
-#endif
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-typedef double FAR * png_doublep;
-#endif
-
-/* Pointers to pointers; i.e. arrays */
-typedef png_byte FAR * FAR * png_bytepp;
-typedef png_uint_32 FAR * FAR * png_uint_32pp;
-typedef png_int_32 FAR * FAR * png_int_32pp;
-typedef png_uint_16 FAR * FAR * png_uint_16pp;
-typedef png_int_16 FAR * FAR * png_int_16pp;
-typedef PNG_CONST char FAR * FAR * png_const_charpp;
-typedef char FAR * FAR * png_charpp;
-typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-typedef double FAR * FAR * png_doublepp;
-#endif
-
-/* Pointers to pointers to pointers; i.e., pointer to array */
-typedef char FAR * FAR * FAR * png_charppp;
-
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-/* SPC - Is this stuff deprecated? */
-/* It'll be removed as of libpng-1.3.0 - GR-P */
-/* libpng typedefs for types in zlib. If zlib changes
- * or another compression library is used, then change these.
- * Eliminates need to change all the source files.
- */
-typedef charf * png_zcharp;
-typedef charf * FAR * png_zcharpp;
-typedef z_stream FAR * png_zstreamp;
-#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */
-
-/*
- * Define PNG_BUILD_DLL if the module being built is a Windows
- * LIBPNG DLL.
- *
- * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
- * It is equivalent to Microsoft predefined macro _DLL that is
- * automatically defined when you compile using the share
- * version of the CRT (C Run-Time library)
- *
- * The cygwin mods make this behavior a little different:
- * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
- * Define PNG_STATIC if you are building a static library for use with cygwin,
- * -or- if you are building an application that you want to link to the
- * static library.
- * PNG_USE_DLL is defined by default (no user action needed) unless one of
- * the other flags is defined.
- */
-
-#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
-# define PNG_DLL
-#endif
-/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
- * When building a static lib, default to no GLOBAL ARRAYS, but allow
- * command-line override
- */
-#if defined(__CYGWIN__)
-# if !defined(PNG_STATIC)
-# if defined(PNG_USE_GLOBAL_ARRAYS)
-# undef PNG_USE_GLOBAL_ARRAYS
-# endif
-# if !defined(PNG_USE_LOCAL_ARRAYS)
-# define PNG_USE_LOCAL_ARRAYS
-# endif
-# else
-# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
-# if defined(PNG_USE_GLOBAL_ARRAYS)
-# undef PNG_USE_GLOBAL_ARRAYS
-# endif
-# endif
-# endif
-# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
-# define PNG_USE_LOCAL_ARRAYS
-# endif
-#endif
-
-/* Do not use global arrays (helps with building DLL's)
- * They are no longer used in libpng itself, since version 1.0.5c,
- * but might be required for some pre-1.0.5c applications.
- */
-#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
-# if defined(PNG_NO_GLOBAL_ARRAYS) || \
- (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER)
-# define PNG_USE_LOCAL_ARRAYS
-# else
-# define PNG_USE_GLOBAL_ARRAYS
-# endif
-#endif
-
-#if defined(__CYGWIN__)
-# undef PNGAPI
-# define PNGAPI __cdecl
-# undef PNG_IMPEXP
-# define PNG_IMPEXP
-#endif
-
-/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
- * you may get warnings regarding the linkage of png_zalloc and png_zfree.
- * Don't ignore those warnings; you must also reset the default calling
- * convention in your compiler to match your PNGAPI, and you must build
- * zlib and your applications the same way you build libpng.
- */
-
-#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
-# ifndef PNG_NO_MODULEDEF
-# define PNG_NO_MODULEDEF
-# endif
-#endif
-
-#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
-# define PNG_IMPEXP
-#endif
-
-#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
- (( defined(_Windows) || defined(_WINDOWS) || \
- defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
-
-# ifndef PNGAPI
-# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
-# define PNGAPI __cdecl
-# else
-# define PNGAPI _cdecl
-# endif
-# endif
-
-# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
- 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
-# define PNG_IMPEXP
-# endif
-
-# if !defined(PNG_IMPEXP)
-
-# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol
-# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol
-
- /* Borland/Microsoft */
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
-# define PNG_EXPORT PNG_EXPORT_TYPE1
-# else
-# define PNG_EXPORT PNG_EXPORT_TYPE2
-# if defined(PNG_BUILD_DLL)
-# define PNG_IMPEXP __export
-# else
-# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
- VC++ */
-# endif /* Exists in Borland C++ for
- C++ classes (== huge) */
-# endif
-# endif
-
-# if !defined(PNG_IMPEXP)
-# if defined(PNG_BUILD_DLL)
-# define PNG_IMPEXP __declspec(dllexport)
-# else
-# define PNG_IMPEXP __declspec(dllimport)
-# endif
-# endif
-# endif /* PNG_IMPEXP */
-#else /* !(DLL || non-cygwin WINDOWS) */
-# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
-# ifndef PNGAPI
-# define PNGAPI _System
-# endif
-# else
-# if 0 /* ... other platforms, with other meanings */
-# endif
-# endif
-#endif
-
-#ifndef PNGAPI
-# define PNGAPI
-#endif
-#ifndef PNG_IMPEXP
-# define PNG_IMPEXP
-#endif
-
-#ifdef PNG_BUILDSYMS
-# ifndef PNG_EXPORT
-# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END
-# endif
-# ifdef PNG_USE_GLOBAL_ARRAYS
-# ifndef PNG_EXPORT_VAR
-# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT
-# endif
-# endif
-#endif
-
-#ifndef PNG_EXPORT
-# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
-#endif
-
-#ifdef PNG_USE_GLOBAL_ARRAYS
-# ifndef PNG_EXPORT_VAR
-# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
-# endif
-#endif
-
-/* User may want to use these so they are not in PNG_INTERNAL. Any library
- * functions that are passed far data must be model independent.
- */
-
-#ifndef PNG_ABORT
-# define PNG_ABORT() abort()
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
-#else
-# define png_jmpbuf(png_ptr) \
- (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
-#endif
-
-#if defined(USE_FAR_KEYWORD) /* memory model independent fns */
-/* use this to make far-to-near assignments */
-# define CHECK 1
-# define NOCHECK 0
-# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
-# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
-# define png_snprintf _fsnprintf /* Added to v 1.2.19 */
-# define png_strcpy _fstrcpy
-# define png_strncpy _fstrncpy /* Added to v 1.2.6 */
-# define png_strlen _fstrlen
-# define png_memcmp _fmemcmp /* SJT: added */
-# define png_memcpy _fmemcpy
-# define png_memset _fmemset
-#else /* use the usual functions */
-# define CVT_PTR(ptr) (ptr)
-# define CVT_PTR_NOCHECK(ptr) (ptr)
-# ifndef PNG_NO_SNPRINTF
-# ifdef _MSC_VER
-# define png_snprintf _snprintf /* Added to v 1.2.19 */
-# define png_snprintf2 _snprintf
-# define png_snprintf6 _snprintf
-# else
-# define png_snprintf snprintf /* Added to v 1.2.19 */
-# define png_snprintf2 snprintf
-# define png_snprintf6 snprintf
-# endif
-# else
- /* You don't have or don't want to use snprintf(). Caution: Using
- * sprintf instead of snprintf exposes your application to accidental
- * or malevolent buffer overflows. If you don't have snprintf()
- * as a general rule you should provide one (you can get one from
- * Portable OpenSSH). */
-# define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1)
-# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2)
-# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \
- sprintf(s1,fmt,x1,x2,x3,x4,x5,x6)
-# endif
-# define png_strcpy strcpy
-# define png_strncpy strncpy /* Added to v 1.2.6 */
-# define png_strlen strlen
-# define png_memcmp memcmp /* SJT: added */
-# define png_memcpy memcpy
-# define png_memset memset
-#endif
-/* End of memory model independent support */
-
-/* Just a little check that someone hasn't tried to define something
- * contradictory.
- */
-#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
-# undef PNG_ZBUF_SIZE
-# define PNG_ZBUF_SIZE 65536L
-#endif
-
-#ifdef PNG_READ_SUPPORTED
-/* Prior to libpng-1.0.9, this block was in pngasmrd.h */
-#if defined(PNG_INTERNAL)
-
-#if defined(PNG_USE_PNGGCCRD) || defined(PNG_USE_PNGVCRD)
- /* Platform must be Pentium. Makefile must assemble and load
- * pnggccrd.c or pngvcrd.c. MMX will be detected at run time and
- * used if present.
- */
-# ifndef PNG_NO_MMX_COMBINE_ROW
-# define PNG_HAVE_MMX_COMBINE_ROW
-# endif
-# ifndef PNG_NO_MMX_READ_INTERLACE
-# define PNG_HAVE_MMX_READ_INTERLACE
-# endif
-# ifndef PNG_NO_MMX_READ_FILTER_ROW
-# define PNG_HAVE_MMX_READ_FILTER_ROW
-# ifndef PNG_NO_MMX_FILTER_SUB
-# define PNG_MMX_READ_FILTER_SUB_SUPPORTED
-# endif
-# if !(defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4))
- /* work around 64-bit gcc compiler bugs in gcc-3.x */
-# ifndef PNG_NO_MMX_FILTER_UP
-# define PNG_MMX_READ_FILTER_UP_SUPPORTED
-# endif
-# ifndef PNG_NO_MMX_FILTER_AVG
-# define PNG_MMX_READ_FILTER_AVG_SUPPORTED
-# endif
-# ifndef PNG_NO_MMX_FILTER_PAETH
-# define PNG_MMX_READ_FILTER_PAETH_SUPPORTED
-# endif
-# endif /* !((__x86_64__) && (GNUC < 4)) */
-# endif
- /* These are the default thresholds before the MMX code kicks in; if either
- * rowbytes or bitdepth is below the threshold, plain C code is used. These
- * can be overridden at runtime via the png_set_mmx_thresholds() call in
- * libpng 1.2.0 and later. The values below were chosen by Intel.
- */
-# ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT
-# define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */
-# endif
-# ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT
-# define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */
-# endif
-#endif /* PNG_USE_PNGGCCRD || PNG_USE_PNGVCRD */
-/* - see pngvcrd.c or pnggccrd.c for info about what is currently enabled */
-
-#endif /* PNG_INTERNAL */
-#endif /* PNG_READ_SUPPORTED */
-
-/* Added at libpng-1.2.8 */
-#endif /* PNG_VERSION_INFO_ONLY */
-
-#endif /* PNGCONF_H */
diff --git a/distrib/libpng-1.2.19/pngerror.c b/distrib/libpng-1.2.19/pngerror.c
deleted file mode 100644
index b1d5fbe..0000000
--- a/distrib/libpng-1.2.19/pngerror.c
+++ /dev/null
@@ -1,326 +0,0 @@
-
-/* pngerror.c - stub functions for i/o and memory allocation
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all error handling. Users who
- * need special error handling are expected to write replacement functions
- * and use png_set_error_fn() to use those functions. See the instructions
- * at each function.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-static void /* PRIVATE */
-png_default_error PNGARG((png_structp png_ptr,
- png_const_charp error_message));
-#ifndef PNG_NO_WARNINGS
-static void /* PRIVATE */
-png_default_warning PNGARG((png_structp png_ptr,
- png_const_charp warning_message));
-#endif /* PNG_NO_WARNINGS */
-
-/* This function is called whenever there is a fatal error. This function
- * should not be changed. If there is a need to handle errors differently,
- * you should supply a replacement error function and use png_set_error_fn()
- * to replace the error function at run-time.
- */
-void PNGAPI
-png_error(png_structp png_ptr, png_const_charp error_message)
-{
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- char msg[16];
- if (png_ptr != NULL)
- {
- if (png_ptr->flags&
- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
- {
- if (*error_message == '#')
- {
- int offset;
- for (offset=1; offset<15; offset++)
- if (*(error_message+offset) == ' ')
- break;
- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
- {
- int i;
- for (i=0; i<offset-1; i++)
- msg[i]=error_message[i+1];
- msg[i]='\0';
- error_message=msg;
- }
- else
- error_message+=offset;
- }
- else
- {
- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
- {
- msg[0]='0';
- msg[1]='\0';
- error_message=msg;
- }
- }
- }
- }
-#endif
- if (png_ptr != NULL && png_ptr->error_fn != NULL)
- (*(png_ptr->error_fn))(png_ptr, error_message);
-
- /* If the custom handler doesn't exist, or if it returns,
- use the default handler, which will not return. */
- png_default_error(png_ptr, error_message);
-}
-
-#ifndef PNG_NO_WARNINGS
-/* This function is called whenever there is a non-fatal error. This function
- * should not be changed. If there is a need to handle warnings differently,
- * you should supply a replacement warning function and use
- * png_set_error_fn() to replace the warning function at run-time.
- */
-void PNGAPI
-png_warning(png_structp png_ptr, png_const_charp warning_message)
-{
- int offset = 0;
- if (png_ptr != NULL)
- {
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- if (png_ptr->flags&
- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
-#endif
- {
- if (*warning_message == '#')
- {
- for (offset=1; offset<15; offset++)
- if (*(warning_message+offset) == ' ')
- break;
- }
- }
- if (png_ptr != NULL && png_ptr->warning_fn != NULL)
- (*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
- }
- else
- png_default_warning(png_ptr, warning_message+offset);
-}
-#endif /* PNG_NO_WARNINGS */
-
-
-/* These utilities are used internally to build an error message that relates
- * to the current chunk. The chunk name comes from png_ptr->chunk_name,
- * this is used to prefix the message. The message is limited in length
- * to 63 bytes, the name characters are output as hex digits wrapped in []
- * if the character is invalid.
- */
-#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-static PNG_CONST char png_digit[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-static void /* PRIVATE */
-png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
- error_message)
-{
- int iout = 0, iin = 0;
-
- while (iin < 4)
- {
- int c = png_ptr->chunk_name[iin++];
- if (isnonalpha(c))
- {
- buffer[iout++] = '[';
- buffer[iout++] = png_digit[(c & 0xf0) >> 4];
- buffer[iout++] = png_digit[c & 0x0f];
- buffer[iout++] = ']';
- }
- else
- {
- buffer[iout++] = (png_byte)c;
- }
- }
-
- if (error_message == NULL)
- buffer[iout] = 0;
- else
- {
- buffer[iout++] = ':';
- buffer[iout++] = ' ';
- png_strncpy(buffer+iout, error_message, 63);
- buffer[iout+63] = 0;
- }
-}
-
-#ifdef PNG_READ_SUPPORTED
-void PNGAPI
-png_chunk_error(png_structp png_ptr, png_const_charp error_message)
-{
- char msg[18+64];
- if (png_ptr == NULL)
- png_error(png_ptr, error_message);
- else
- {
- png_format_buffer(png_ptr, msg, error_message);
- png_error(png_ptr, msg);
- }
-}
-
-#ifndef PNG_NO_WARNINGS
-void PNGAPI
-png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
-{
- char msg[18+64];
- if (png_ptr == NULL)
- png_warning(png_ptr, warning_message);
- else
- {
- png_format_buffer(png_ptr, msg, warning_message);
- png_warning(png_ptr, msg);
- }
-}
-#endif /* PNG_NO_WARNINGS */
-
-#endif /* PNG_READ_SUPPORTED */
-
-/* This is the default error handling function. Note that replacements for
- * this function MUST NOT RETURN, or the program will likely crash. This
- * function is used by default, or if the program supplies NULL for the
- * error function pointer in png_set_error_fn().
- */
-static void /* PRIVATE */
-png_default_error(png_structp png_ptr, png_const_charp error_message)
-{
-#ifndef PNG_NO_CONSOLE_IO
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- if (*error_message == '#')
- {
- int offset;
- char error_number[16];
- for (offset=0; offset<15; offset++)
- {
- error_number[offset] = *(error_message+offset+1);
- if (*(error_message+offset) == ' ')
- break;
- }
- if((offset > 1) && (offset < 15))
- {
- error_number[offset-1]='\0';
- fprintf(stderr, "libpng error no. %s: %s\n", error_number,
- error_message+offset);
- }
- else
- fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
- }
- else
-#endif
- fprintf(stderr, "libpng error: %s\n", error_message);
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
- if (png_ptr)
- {
-# ifdef USE_FAR_KEYWORD
- {
- jmp_buf jmpbuf;
- png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
- longjmp(jmpbuf, 1);
- }
-# else
- longjmp(png_ptr->jmpbuf, 1);
-# endif
- }
-#else
- PNG_ABORT();
-#endif
-#ifdef PNG_NO_CONSOLE_IO
- error_message = error_message; /* make compiler happy */
-#endif
-}
-
-#ifndef PNG_NO_WARNINGS
-/* This function is called when there is a warning, but the library thinks
- * it can continue anyway. Replacement functions don't have to do anything
- * here if you don't want them to. In the default configuration, png_ptr is
- * not used, but it is passed in case it may be useful.
- */
-static void /* PRIVATE */
-png_default_warning(png_structp png_ptr, png_const_charp warning_message)
-{
-#ifndef PNG_NO_CONSOLE_IO
-# ifdef PNG_ERROR_NUMBERS_SUPPORTED
- if (*warning_message == '#')
- {
- int offset;
- char warning_number[16];
- for (offset=0; offset<15; offset++)
- {
- warning_number[offset]=*(warning_message+offset+1);
- if (*(warning_message+offset) == ' ')
- break;
- }
- if((offset > 1) && (offset < 15))
- {
- warning_number[offset-1]='\0';
- fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
- warning_message+offset);
- }
- else
- fprintf(stderr, "libpng warning: %s\n", warning_message);
- }
- else
-# endif
- fprintf(stderr, "libpng warning: %s\n", warning_message);
-#else
- warning_message = warning_message; /* make compiler happy */
-#endif
- png_ptr = png_ptr; /* make compiler happy */
-}
-#endif /* PNG_NO_WARNINGS */
-
-/* This function is called when the application wants to use another method
- * of handling errors and warnings. Note that the error function MUST NOT
- * return to the calling routine or serious problems will occur. The return
- * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
- */
-void PNGAPI
-png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warning_fn)
-{
- if (png_ptr == NULL)
- return;
- png_ptr->error_ptr = error_ptr;
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
-}
-
-
-/* This function returns a pointer to the error_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
-png_voidp PNGAPI
-png_get_error_ptr(png_structp png_ptr)
-{
- if (png_ptr == NULL)
- return NULL;
- return ((png_voidp)png_ptr->error_ptr);
-}
-
-
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-void PNGAPI
-png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
-{
- if(png_ptr != NULL)
- {
- png_ptr->flags &=
- ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
- }
-}
-#endif
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pnggccrd.c b/distrib/libpng-1.2.19/pnggccrd.c
deleted file mode 100644
index f63867c..0000000
--- a/distrib/libpng-1.2.19/pnggccrd.c
+++ /dev/null
@@ -1,6041 +0,0 @@
-
-/* pnggccrd.c - mixed C/assembler version of utilities to read a PNG file
- *
- * For Intel/AMD x86 or x86-64 CPU (Pentium-MMX or later) and GNU C compiler.
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998 Intel Corporation
- * Copyright (c) 1999-2002,2007 Greg Roelofs
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- *
- * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998.
- * Interface to libpng contributed by Gilles Vollant, 1999.
- * GNU C port by Greg Roelofs, 1999-2001.
- *
- * References:
- *
- * http://www.intel.com/drg/pentiumII/appnotes/916/916.htm
- * http://www.intel.com/drg/pentiumII/appnotes/923/923.htm
- * [Intel's performance analysis of the MMX vs. non-MMX code;
- * moved/deleted as of 2006, but text and some graphs still
- * available via WayBack Machine at archive.org]
- *
- * http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
- * http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
- * http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
- * http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
- * http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
- * AMD64 Architecture Programmer's Manual, volumes 1 and 5
- * [http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_739_7044,00.html]
- * Intel 64 and IA-32 Software Developer's Manuals
- * [http://developer.intel.com/products/processor/manuals/]
- *
- * png_read_filter_row_mmx_*() were converted in place with intel2gas 1.3.1:
- *
- * intel2gas -mdI pnggccrd.c.partially-msvc -o pnggccrd.c
- *
- * and then cleaned up by hand. See http://hermes.terminal.at/intel2gas/ .
- *
- * NOTE: A sufficiently recent version of GNU as (or as.exe under DOS/Windows)
- * is required to assemble the newer asm instructions such as movq. (Version
- * 2.5.2l.15 is definitely too old.) See ftp://ftp.gnu.org/pub/gnu/binutils/ .
- */
-
-/*
- * PORTING NOTES AND CHANGELOG (mostly by Greg Roelofs)
- * ===========================
- *
- * 19991006:
- * - fixed sign error in post-MMX cleanup code (16- & 32-bit cases)
- *
- * 19991007:
- * - additional optimizations (possible or definite):
- * x [DONE] write MMX code for 64-bit case (pixel_bytes == 8) [not tested]
- * - write MMX code for 48-bit case (pixel_bytes == 6)
- * - figure out what's up with 24-bit case (pixel_bytes == 3):
- * why subtract 8 from width_mmx in the pass 4/5 case?
- * (only width_mmx case) (near line 2335)
- * x [DONE] replace pixel_bytes within each block with the true
- * constant value (or are compilers smart enough to do that?)
- * - rewrite all MMX interlacing code so it's aligned with
- * the *beginning* of the row buffer, not the end. This
- * would not only allow one to eliminate half of the memory
- * writes for odd passes (that is, pass == odd), it may also
- * eliminate some unaligned-data-access exceptions (assuming
- * there's a penalty for not aligning 64-bit accesses on
- * 64-bit boundaries). The only catch is that the "leftover"
- * pixel(s) at the end of the row would have to be saved,
- * but there are enough unused MMX registers in every case,
- * so this is not a problem. A further benefit is that the
- * post-MMX cleanup code (C code) in at least some of the
- * cases could be done within the assembler block.
- * x [DONE] the "v3 v2 v1 v0 v7 v6 v5 v4" comments are confusing,
- * inconsistent, and don't match the MMX Programmer's Reference
- * Manual conventions anyway. They should be changed to
- * "b7 b6 b5 b4 b3 b2 b1 b0," where b0 indicates the byte that
- * was lowest in memory (i.e., corresponding to a left pixel)
- * and b7 is the byte that was highest (i.e., a right pixel).
- *
- * 19991016:
- * - Brennan's Guide notwithstanding, gcc under Linux does *not*
- * want globals prefixed by underscores when referencing them--
- * i.e., if the variable is const4, then refer to it as const4,
- * not _const4. This seems to be a djgpp-specific requirement.
- * Also, such variables apparently *must* be declared outside
- * of functions; neither static nor automatic variables work if
- * defined within the scope of a single function, but both
- * static and truly global (multi-module) variables work fine.
- *
- * 19991017:
- * - replaced pixel_bytes in each png_memcpy() call with constant value for
- * inlining (png_do_read_interlace() "non-MMX/modified C code" block)
- *
- * 19991023:
- * - fixed png_combine_row() non-MMX replication bug (odd passes only?)
- * - switched from string-concatenation-with-macros to cleaner method of
- * renaming global variables for djgpp--i.e., always use prefixes in
- * inlined assembler code (== strings) and conditionally rename the
- * variables, not the other way around. Hence _const4, _mask8_0, etc.
- *
- * 19991024:
- * - fixed mmxsupport()/png_do_read_interlace() first-row bug
- * This one was severely weird: even though mmxsupport() doesn't touch
- * ebx (where "row" pointer was stored), it nevertheless managed to zero
- * the register (even in static/non-fPIC code--see below), which in turn
- * caused png_do_read_interlace() to return prematurely on the first row of
- * interlaced images (i.e., without expanding the interlaced pixels).
- * Inspection of the generated assembly code didn't turn up any clues,
- * although it did point at a minor optimization (i.e., get rid of
- * mmx_supported_local variable and just use eax). Possibly the CPUID
- * instruction is more destructive than it looks? (Not yet checked.)
- * - "info gcc" was next to useless, so compared fPIC and non-fPIC assembly
- * listings... Apparently register spillage has to do with ebx, since
- * it's used to index the global offset table. Commenting it out of the
- * input-reg lists in png_combine_row() eliminated compiler barfage, so
- * ifdef'd with __PIC__ macro: if defined, use a global for unmask
- *
- * 19991107:
- * - verified CPUID clobberage: 12-char string constant ("GenuineIntel",
- * "AuthenticAMD", etc.) placed in ebx:ecx:edx. Still need to polish.
- *
- * 19991120:
- * - made "diff" variable (now "_dif") global to simplify conversion of
- * filtering routines (running out of regs, sigh). "diff" is still used
- * in interlacing routines, however.
- * - fixed up both versions of mmxsupport() (ORIG_THAT_USED_TO_CLOBBER_EBX
- * macro determines which is used); original not yet tested.
- *
- * 20000213:
- * - when compiling with gcc, be sure to use -fomit-frame-pointer
- *
- * 20000319:
- * - fixed a register-name typo in png_do_read_interlace(), default (MMX) case,
- * pass == 4 or 5, that caused visible corruption of interlaced images
- *
- * 20000623:
- * - Various problems were reported with gcc 2.95.2 in the Cygwin environment,
- * many of the form "forbidden register 0 (ax) was spilled for class AREG."
- * This is explained at http://gcc.gnu.org/fom_serv/cache/23.html, and
- * Chuck Wilson supplied a patch involving dummy output registers. See
- * http://sourceforge.net/bugs/?func=detailbug&bug_id=108741&group_id=5624
- * for the original (anonymous) SourceForge bug report.
- *
- * 20000706:
- * - Chuck Wilson passed along these remaining gcc 2.95.2 errors:
- * pnggccrd.c: In function `png_combine_row':
- * pnggccrd.c:525: more than 10 operands in `asm'
- * pnggccrd.c:669: more than 10 operands in `asm'
- * pnggccrd.c:828: more than 10 operands in `asm'
- * pnggccrd.c:994: more than 10 operands in `asm'
- * pnggccrd.c:1177: more than 10 operands in `asm'
- * They are all the same problem and can be worked around by using the
- * global _unmask variable unconditionally, not just in the -fPIC case.
- * Reportedly earlier versions of gcc also have the problem with more than
- * 10 operands; they just don't report it. Much strangeness ensues, etc.
- *
- * 20000729:
- * - enabled png_read_filter_row_mmx_up() (shortest remaining unconverted
- * MMX routine); began converting png_read_filter_row_mmx_sub()
- * - to finish remaining sections:
- * - clean up indentation and comments
- * - preload local variables
- * - add output and input regs (order of former determines numerical
- * mapping of latter)
- * - avoid all usage of ebx (including bx, bh, bl) register [20000823]
- * - remove "$" from addressing of Shift and Mask variables [20000823]
- *
- * 20000731:
- * - global union vars causing segfaults in png_read_filter_row_mmx_sub()?
- *
- * 20000822:
- * - ARGH, stupid png_read_filter_row_mmx_sub() segfault only happens with
- * shared-library (-fPIC) version! Code works just fine as part of static
- * library. Should have tested that sooner.
- * ebx is getting clobbered again (explicitly this time); need to save it
- * on stack or rewrite asm code to avoid using it altogether. Blargh!
- *
- * 20000823:
- * - first section was trickiest; all remaining sections have ebx -> edx now.
- * (-fPIC works again.) Also added missing underscores to various Shift*
- * and *Mask* globals and got rid of leading "$" signs.
- *
- * 20000826:
- * - added visual separators to help navigate microscopic printed copies
- * (http://pobox.com/~newt/code/gpr-latest.zip, mode 10); started working
- * on png_read_filter_row_mmx_avg()
- *
- * 20000828:
- * - finished png_read_filter_row_mmx_avg(): only Paeth left! (930 lines...)
- * What the hell, did png_read_filter_row_mmx_paeth(), too. Comments not
- * cleaned up/shortened in either routine, but functionality is complete
- * and seems to be working fine.
- *
- * 20000829:
- * - ahhh, figured out last(?) bit of gcc/gas asm-fu: if register is listed
- * as an input reg (with dummy output variables, etc.), then it *cannot*
- * also appear in the clobber list or gcc 2.95.2 will barf. The solution
- * is simple enough...
- *
- * 20000914:
- * - bug in png_read_filter_row_mmx_avg(): 16-bit grayscale not handled
- * correctly (but 48-bit RGB just fine)
- *
- * 20000916:
- * - fixed bug in png_read_filter_row_mmx_avg(), bpp == 2 case; three errors:
- * - "_ShiftBpp.use = 24;" should have been "_ShiftBpp.use = 16;"
- * - "_ShiftRem.use = 40;" should have been "_ShiftRem.use = 48;"
- * - "psllq _ShiftRem, %%mm2" should have been "psrlq _ShiftRem, %%mm2"
- *
- * 20010101:
- * - added new png_init_mmx_flags() function (here only because it needs to
- * call mmxsupport(), which should probably become global png_mmxsupport());
- * modified other MMX routines to run conditionally (png_ptr->asm_flags)
- *
- * 20010103:
- * - renamed mmxsupport() to png_mmx_support(), with auto-set of mmx_supported,
- * and made it public; moved png_init_mmx_flags() to png.c as internal func
- *
- * 20010104:
- * - removed dependency on png_read_filter_row_c() (C code already duplicated
- * within MMX version of png_read_filter_row()) so no longer necessary to
- * compile it into pngrutil.o
- *
- * 20010310:
- * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX)
- *
- * 20010808:
- * - added PNG_THREAD_UNSAFE_OK around code using global variables [GR-P]
- *
- * 20011124:
- * - fixed missing save of Eflag in png_mmx_support() [Maxim Sobolev]
- *
- * 20020304:
- * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case
- *
- * 20020407:
- * - fixed insufficient preservation of ebx register [Sami Farin]
- *
- * 20040724:
- * - more tinkering with clobber list at lines 4529 and 5033 to get it to
- * compile with gcc 3.4 [GR-P]
- *
- * 20040809:
- * - added "rim" definitions for CONST4 and CONST6 [GR-P]
- *
- * 20060303:
- * - added "OS2" to list of systems that don't need leading underscores [GR-P]
- *
- * 20060320:
- * - made PIC-compliant [Christian Aichinger]
- *
- * 20070313:
- * - finally applied Giuseppe Ghibò's 64-bit patch of 20060803 (completely
- * overlooked Dylan Alex Simon's similar patch of 20060414, oops...)
- *
- * 20070524:
- * - fixed link failure caused by asm-only variables being optimized out
- * (identified by Dimitri of Trolltech) with __attribute__((used)), which
- * also gets rid of warnings => nuked ugly png_squelch_warnings() hack
- * - dropped redundant ifdef
- * - moved png_mmx_support() back up where originally intended (as in
- * pngvcrd.c), using __attribute__((noinline)) in extra prototype
- *
- * 20070527:
- * - revised png_combine_row() to reuse mask in lieu of external _unmask
- * - moved 32-bit (RGBA) case to top of png_combine_row(): most common
- * - just about ready to give up on x86-64 -fPIC mode; can't even access 16
- * _mask*_* constants without triggering link error on shared library:
- * /usr/bin/ld: pnggccrd.pic.o: relocation R_X86_64_32S against `a local
- * symbol' can not be used when making a shared object; recompile with
- * -fPIC
- * pnggccrd.pic.o: could not read symbols: Bad value
- * ("objdump -x pnggccrd.pic.o | grep rodata" to verify)
- * [might be able to work around by doing within assembly code whatever
- * -fPIC does, but given problems to date, seems like long shot...]
- * [relevant ifdefs: __x86_64__ && __PIC__ => C code only]
- * - changed #if 0 to #ifdef PNG_CLOBBER_MMX_REGS_SUPPORTED in case gcc ever
- * supports MMX regs (%mm0, etc.) in clobber list (not supported by gcc
- * 2.7.2.3, 2.91.66 (egcs 1.1.2), 3.x, or 4.1.2)
- *
- * 20070603:
- * - revised png_combine_row() to use @GOTPCREL(%%rip) addressing on _c64
- * struct of _mask*_* constants for x86-64 -fPIC; see sam.zoy.org link
- * above for details
- * - moved _const4 and _const6 into _c64 struct, renamed to _amask5_3_0 and
- * _amask7_1_0, respectively
- * - can't figure out how to use _c64._mask*_* vars within asm code, so still
- * need single variables for non-x86-64/-fPIC half :-(
- * - replaced various __PIC__ ifdefs with *_GOT_ebx macros
- * - moved _LBCarryMask and _HBClearMask into _c64 struct
- * - conditionally replaced _p*temp variables with %r11d-%r13d (via p*_TEMP
- * and CLOBBER_r1*d macros)
- *
- * 20070604:
- * - replaced all _ActiveMask and _ActiveMaskEnd with new _amask*_*_* consts
- * (_amask naming convention: numbers of 00-bytes, ff-bytes, 00-bytes)
- * - _ActiveMask // (10) // avg/paeth/sub; read-only; consts; movq/pand
- * 0x0000000000ffffffLL (bpp 3, avg) _amask5_3_0
- * 0xffffffffffffffffLL (bpp 4, 6, avg) _amask0_8_0
- * 0x000000000000ffffLL (bpp 2, avg) _amask6_2_0
- * 0x0000000000ffffffLL (bpp 3, paeth) _amask5_3_0
- * 0x00000000ffffffffLL (bpp 6, paeth) _amask4_4_0
- * 0x00000000ffffffffLL (bpp 4, paeth) _amask4_4_0
- * 0x00000000ffffffffLL (bpp 8, paeth) _amask4_4_0
- * 0x0000ffffff000000LL (bpp 3, sub) _amask2_3_3
- * 0x00000000ffff0000LL (bpp 2, sub) _amask4_2_2
- * - _ActiveMaskEnd // (1) // paeth only; read-only; const; pand
- * 0xffff000000000000LL (bpp 3, paeth) _amask0_2_6
- * - changed all "#if defined(__x86_64__) // later // && defined(__PIC__)"
- * lines to "#ifdef PNG_x86_64_USE_GOTPCREL" for easier/safer testing
- *
- * 20070605:
- * - merged PNG_x86_64_USE_GOTPCREL, non-PNG_x86_64_USE_GOTPCREL code via
- * *MASK* and LOAD/RESTORE macros
- *
- * 20070607:
- * - replaced all constant instances of _ShiftBpp, _ShiftRem with immediates
- * (still have two shared cases in avg, sub routines)
- *
- * 20070609:
- * - replaced remaining instances of _ShiftBpp, _ShiftRem with immediates
- * (split sub and avg 4/6-bpp cases into separate blocks)
- * - fixed paeth bug due to clobbered r11/r12/r13 regs
- *
- * 20070610:
- * - made global "_dif" variable (avg/paeth/sub routines) local again (now
- * "diff"--see 19991120 entry above), using register constraints
- * - note that %ebp in clobber list doesn't actually work, at least for 32-bit
- * version and gcc 4.1.2; must save and restore manually. (Seems to work
- * OK for 64-bit version and gcc 3.4.3, but gcc may not be using ebp/rbp
- * in that case.)
- * - started replacing direct _MMXLength accesses with register constraints
- *
- * 20070612:
- * - continued replacing direct _MMXLength accesses with register constraints
- *
- * 20070613:
- * - finished replacing direct _MMXLength accesses with register constraints;
- * switched to local variable (and renamed back to MMXLength)
- *
- * 20070614:
- * - fixed sub bpp = 1 bug
- * - started replacing direct _FullLength accesses with register constraints
- *
- * 20070615:
- * - fixed 64-bit paeth bpp 3 crash bug (misplaced LOAD_GOT_rbp)
- * - fixed 64-bit paeth bpp 1/2 and cleanup-block crash bugs (misplaced
- * RESTORE_r11_r12_r13)
- * - slightly optimized avg/paeth cleanup blocks and paeth bpp 1/2 block
- * (save/restore ebx only if needed)
- * - continued replacing direct _FullLength accesses with register constraints
- *
- * 20070616:
- * - finished replacing direct _FullLength accesses with register constraints
- * (*ugly* conditional clobber-separator macros for avg and paeth, sigh)
- *
- * 20070618:
- * - fixed misplaced PNG_THREAD_UNSAFE_OK endif (was missing LOAD_GOT_rbp/
- * RESTORE_rbp in 32-bit thread-safe case)
- * - changed all "ifdef *" to "if defined(*)" [GR-P]
- *
- * 20070619:
- * - rearranged most bitdepth-related case statements to put most frequent
- * cases at top (24-bit, 32-bit, 8-bit, rest)
- *
- * 20070623:
- * - cleaned up png_debug() warnings/formatting
- * - removed PNG_MMX_CODE_SUPPORTED ifdefs and added outer __GNUC__ ifdef
- * (module no longer used by non-x86/non-GCC builds as of libpng 1.2.19)
- * - removed single libpng-1.2.x PNG_DEBUG dependency on 1.0.x png_struct
- * member (row_buf_size)
- * - rearranged pass-related if-blocks in png_do_read_interlace() to put most
- * frequent cases (4, 5) at top [GR-P suggestion]
- *
- * 20070624-29:
- * - fixed 64-bit crash bug: pointers -> rsi/rdi, not esi/edi (switched to
- * %0/%1/%2/%3/%4 notation; eliminated size suffixes from relevant add/
- * inc/sub/mov instructions; changed dummy vars to pointers)
- * - png_combine_row()
- * - png_do_read_interlace()
- * - png_read_filter_row_mmx_avg()
- * - png_read_filter_row_mmx_paeth()
- * - png_read_filter_row_mmx_sub()
- * - png_read_filter_row_mmx_up()
- * - NOTE: this fix makes use of the fact that modifying a 32-bit reg (e.g.,
- * %%ebx) clears the top half of its corresponding 64-bit reg (%%rbx), so
- * it's safe to mix 32-bit operations with 64-bit base/index addressing
- * (see new PSI/PAX/PBX/PDX/PBP/etc. "pointer-register" macros); applies
- * also to clobber lists
- *
- * 20070630:
- * - cleaned up formatting, macros, minor png_read_filter_row_mmx_sub() 8-bpp
- * register-usage inefficiency
- * - fixed 32-bit png_do_read_interlace() bug (was using pointer size for
- * 64-bit dummy values)
- *
- * 20070703:
- * - added check for (manual) PIC macro to fix OpenBSD crash bug
- *
- * 20070717:
- * - fixed 48-bit png_combine_row() bug (was acting like 32-bit): copy 6
- * bytes per pixel, not 4, and use stride of 6, not 4, in the second loop
- * of interlace processing of 48-bit pixels [GR-P]
- *
- * 20070722:
- * - fixed 64-bit png_uint_32 bug with MMXLength/FullLength temp vars
- *
- * [still broken: tops of all row-filter blocks (input/output constraints);
- * shows up on 64-bit dynamic (-fPIC) version with -O2, especially if debug-
- * printfs enabled, but at right edge of odd-width images even if disabled]
- *
- *
- * STILL TO DO:
- * - fix final thread-unsafe code using stack vars and pointer? (paeth top,
- * default, bottom only: default, bottom already 5 reg constraints; could
- * replace bpp with pointer and group bpp/patemp/pbtemp/pctemp in array)
- * - fix ebp/no-reg-constraint inefficiency (avg/paeth/sub top)
- * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8)
- * - write MMX code for 48-bit case (pixel_bytes == 6)
- * - figure out what's up with 24-bit case (pixel_bytes == 3):
- * why subtract 8 from width_mmx in the pass 4/5 case? due to
- * odd number of bytes? (only width_mmx case) (near line 2335)
- * - rewrite all MMX interlacing code so it's aligned with beginning
- * of the row buffer, not the end (see 19991007 for details)
- * - add error messages to any remaining bogus default cases
- * - enable pixel_depth == 8 cases in png_read_filter_row()? (test speed)
- * - try =r, etc., as reg constraints? (would gcc use 64-bit ones on x86-64?)
- * - need full, non-graphical, CRC-based test suite... maybe autogenerate
- * random data of various height/width/depth, compute CRCs, write (C
- * funcs), read (asm/MMX), recompute CRCs, and compare?
- * - write true x86-64 version using 128-bit "media instructions", %xmm0-15,
- * and extra general-purpose registers
- */
-
-#if defined(__GNUC__)
-
-#define PNG_INTERNAL
-#include "png.h"
-
-
-/* for some inexplicable reason, gcc 3.3.5 on OpenBSD (and elsewhere?) does
- * *not* define __PIC__ when the -fPIC option is used, so we have to rely on
- * makefiles and whatnot to define the PIC macro explicitly */
-#if defined(PIC) && !defined(__PIC__) // (this can/should move to pngconf.h)
-# define __PIC__
-#endif
-
-#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGGCCRD)
-
-/* if you want/need full thread-safety on x86-64 even when linking statically,
- * comment out the "&& defined(__PIC__)" part here: */
-#if defined(__x86_64__) && defined(__PIC__)
-# define PNG_x86_64_USE_GOTPCREL // GOTPCREL => full thread-safety
-# define PNG_CLOBBER_x86_64_REGS_SUPPORTED // works as of gcc 3.4.3 ...
-#endif
-
-int PNGAPI png_mmx_support(void);
-
-#if defined(PNG_USE_LOCAL_ARRAYS)
-static PNG_CONST int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-static PNG_CONST int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-static PNG_CONST int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1};
-#endif
-
-/* djgpp, Win32, Cygwin, and OS2 add their own underscores to global variables,
- * so define them without: */
-#if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__) || \
- defined(__OS2__)
-# define _mmx_supported mmx_supported
-# define _mask8_0 mask8_0
-# define _mask16_1 mask16_1
-# define _mask16_0 mask16_0
-# define _mask24_2 mask24_2
-# define _mask24_1 mask24_1
-# define _mask24_0 mask24_0
-# define _mask32_3 mask32_3
-# define _mask32_2 mask32_2
-# define _mask32_1 mask32_1
-# define _mask32_0 mask32_0
-# define _mask48_5 mask48_5
-# define _mask48_4 mask48_4
-# define _mask48_3 mask48_3
-# define _mask48_2 mask48_2
-# define _mask48_1 mask48_1
-# define _mask48_0 mask48_0
-# define _amask5_3_0 amask5_3_0
-# define _amask7_1_0 amask7_1_0
-# define _LBCarryMask LBCarryMask
-# define _HBClearMask HBClearMask
-# define _amask0_8_0 amask0_8_0
-# define _amask6_2_0 amask6_2_0
-# define _amask4_4_0 amask4_4_0
-# define _amask0_2_6 amask0_2_6
-# define _amask2_3_3 amask2_3_3
-# define _amask4_2_2 amask4_2_2
-# if defined(PNG_THREAD_UNSAFE_OK)
-# define _patemp patemp
-# define _pbtemp pbtemp
-# define _pctemp pctemp
-# endif
-#endif // djgpp, Win32, Cygwin, OS2
-
-
-/* These constants are used in the inlined MMX assembly code. */
-
-typedef unsigned long long ull;
-
-#if defined(PNG_x86_64_USE_GOTPCREL)
-static PNG_CONST struct {
- //ull _mask_array[26];
-
- // png_combine_row() constants:
- ull _mask8_0;
- ull _mask16_0, _mask16_1;
- ull _mask24_0, _mask24_1, _mask24_2;
- ull _mask32_0, _mask32_1, _mask32_2, _mask32_3;
- ull _mask48_0, _mask48_1, _mask48_2, _mask48_3, _mask48_4, _mask48_5;
-
- // png_do_read_interlace() constants:
- ull _amask5_3_0, _amask7_1_0; // was _const4 and _const6, respectively
-
- // png_read_filter_row_mmx_avg() constants (also uses _amask5_3_0):
- ull _LBCarryMask, _HBClearMask;
- ull _amask0_8_0, _amask6_2_0; // was ActiveMask for bpp 4/6 and 2 cases
-
- // png_read_filter_row_mmx_paeth() constants (also uses _amask5_3_0):
- ull _amask4_4_0, _amask0_2_6; // was ActiveMask{,End} for bpp 6/4/8 and 3
-
- // png_read_filter_row_mmx_sub() constants:
- ull _amask2_3_3, _amask4_2_2; // was ActiveMask for bpp 3 and 2 cases
-
-} _c64 __attribute__((used, aligned(8))) = {
-
- // png_combine_row() constants:
- 0x0102040810204080LL, // _mask8_0 offset 0
-
- 0x1010202040408080LL, // _mask16_0 offset 8
- 0x0101020204040808LL, // _mask16_1 offset 16
-
- 0x2020404040808080LL, // _mask24_0 offset 24
- 0x0408080810101020LL, // _mask24_1 offset 32
- 0x0101010202020404LL, // _mask24_2 offset 40
-
- 0x4040404080808080LL, // _mask32_0 offset 48
- 0x1010101020202020LL, // _mask32_1 offset 56
- 0x0404040408080808LL, // _mask32_2 offset 64
- 0x0101010102020202LL, // _mask32_3 offset 72
-
- 0x4040808080808080LL, // _mask48_0 offset 80
- 0x2020202040404040LL, // _mask48_1 offset 88
- 0x1010101010102020LL, // _mask48_2 offset 96
- 0x0404080808080808LL, // _mask48_3 offset 104
- 0x0202020204040404LL, // _mask48_4 offset 112
- 0x0101010101010202LL, // _mask48_5 offset 120
-
- // png_do_read_interlace() constants:
- 0x0000000000FFFFFFLL, // _amask5_3_0 offset 128 (bpp 3, avg/paeth) const4
- 0x00000000000000FFLL, // _amask7_1_0 offset 136 const6
-
- // png_read_filter_row_mmx_avg() constants:
- 0x0101010101010101LL, // _LBCarryMask offset 144
- 0x7F7F7F7F7F7F7F7FLL, // _HBClearMask offset 152
- 0xFFFFFFFFFFFFFFFFLL, // _amask0_8_0 offset 160 (bpp 4/6, avg)
- 0x000000000000FFFFLL, // _amask6_2_0 offset 168 (bpp 2, avg)
-
- // png_read_filter_row_mmx_paeth() constants:
- 0x00000000FFFFFFFFLL, // _amask4_4_0 offset 176 (bpp 6/4/8, paeth)
- 0xFFFF000000000000LL, // _amask0_2_6 offset 184 (bpp 3, paeth) A.M.End
-
- // png_read_filter_row_mmx_sub() constants:
- 0x0000FFFFFF000000LL, // _amask2_3_3 offset 192 (bpp 3, sub)
- 0x00000000FFFF0000LL, // _amask4_2_2 offset 200 (bpp 2, sub)
-
-};
-
-#define MASK8_0 "(%%rbp)"
-#define MASK16_0 "8(%%rbp)"
-#define MASK16_1 "16(%%rbp)"
-#define MASK24_0 "24(%%rbp)"
-#define MASK24_1 "32(%%rbp)"
-#define MASK24_2 "40(%%rbp)"
-#define MASK32_0 "48(%%rbp)"
-#define MASK32_1 "56(%%rbp)"
-#define MASK32_2 "64(%%rbp)"
-#define MASK32_3 "72(%%rbp)"
-#define MASK48_0 "80(%%rbp)"
-#define MASK48_1 "88(%%rbp)"
-#define MASK48_2 "96(%%rbp)"
-#define MASK48_3 "104(%%rbp)"
-#define MASK48_4 "112(%%rbp)"
-#define MASK48_5 "120(%%rbp)"
-#define AMASK5_3_0 "128(%%rbp)"
-#define AMASK7_1_0 "136(%%rbp)"
-#define LB_CARRY_MASK "144(%%rbp)"
-#define HB_CLEAR_MASK "152(%%rbp)"
-#define AMASK0_8_0 "160(%%rbp)"
-#define AMASK6_2_0 "168(%%rbp)"
-#define AMASK4_4_0 "176(%%rbp)"
-#define AMASK0_2_6 "184(%%rbp)"
-#define AMASK2_3_3 "192(%%rbp)"
-#define AMASK4_2_2 "200(%%rbp)"
-
-#else // !PNG_x86_64_USE_GOTPCREL
-
-static PNG_CONST ull _mask8_0 __attribute__((used, aligned(8))) = 0x0102040810204080LL;
-
-static PNG_CONST ull _mask16_1 __attribute__((used, aligned(8))) = 0x0101020204040808LL;
-static PNG_CONST ull _mask16_0 __attribute__((used, aligned(8))) = 0x1010202040408080LL;
-
-static PNG_CONST ull _mask24_2 __attribute__((used, aligned(8))) = 0x0101010202020404LL;
-static PNG_CONST ull _mask24_1 __attribute__((used, aligned(8))) = 0x0408080810101020LL;
-static PNG_CONST ull _mask24_0 __attribute__((used, aligned(8))) = 0x2020404040808080LL;
-
-static PNG_CONST ull _mask32_3 __attribute__((used, aligned(8))) = 0x0101010102020202LL;
-static PNG_CONST ull _mask32_2 __attribute__((used, aligned(8))) = 0x0404040408080808LL;
-static PNG_CONST ull _mask32_1 __attribute__((used, aligned(8))) = 0x1010101020202020LL;
-static PNG_CONST ull _mask32_0 __attribute__((used, aligned(8))) = 0x4040404080808080LL;
-
-static PNG_CONST ull _mask48_5 __attribute__((used, aligned(8))) = 0x0101010101010202LL;
-static PNG_CONST ull _mask48_4 __attribute__((used, aligned(8))) = 0x0202020204040404LL;
-static PNG_CONST ull _mask48_3 __attribute__((used, aligned(8))) = 0x0404080808080808LL;
-static PNG_CONST ull _mask48_2 __attribute__((used, aligned(8))) = 0x1010101010102020LL;
-static PNG_CONST ull _mask48_1 __attribute__((used, aligned(8))) = 0x2020202040404040LL;
-static PNG_CONST ull _mask48_0 __attribute__((used, aligned(8))) = 0x4040808080808080LL;
-
-// png_do_read_interlace() constants:
-static PNG_CONST ull _amask5_3_0 __attribute__((aligned(8))) = 0x0000000000FFFFFFLL; // was _const4
-static PNG_CONST ull _amask7_1_0 __attribute__((aligned(8))) = 0x00000000000000FFLL; // was _const6
-
-// png_read_filter_row_mmx_avg() constants:
-static PNG_CONST ull _LBCarryMask __attribute__((used, aligned(8))) = 0x0101010101010101LL;
-static PNG_CONST ull _HBClearMask __attribute__((used, aligned(8))) = 0x7f7f7f7f7f7f7f7fLL;
-static PNG_CONST ull _amask0_8_0 __attribute__((used, aligned(8))) = 0xFFFFFFFFFFFFFFFFLL;
-static PNG_CONST ull _amask6_2_0 __attribute__((used, aligned(8))) = 0x000000000000FFFFLL;
-
-// png_read_filter_row_mmx_paeth() constants:
-static PNG_CONST ull _amask4_4_0 __attribute__((used, aligned(8))) = 0x00000000FFFFFFFFLL;
-static PNG_CONST ull _amask0_2_6 __attribute__((used, aligned(8))) = 0xFFFF000000000000LL;
-
-// png_read_filter_row_mmx_sub() constants:
-static PNG_CONST ull _amask2_3_3 __attribute__((used, aligned(8))) = 0x0000FFFFFF000000LL;
-static PNG_CONST ull _amask4_2_2 __attribute__((used, aligned(8))) = 0x00000000FFFF0000LL;
-
-#define MASK8_0 "_mask8_0"
-#define MASK16_0 "_mask16_0"
-#define MASK16_1 "_mask16_1"
-#define MASK24_0 "_mask24_0"
-#define MASK24_1 "_mask24_1"
-#define MASK24_2 "_mask24_2"
-#define MASK32_0 "_mask32_0"
-#define MASK32_1 "_mask32_1"
-#define MASK32_2 "_mask32_2"
-#define MASK32_3 "_mask32_3"
-#define MASK48_0 "_mask48_0"
-#define MASK48_1 "_mask48_1"
-#define MASK48_2 "_mask48_2"
-#define MASK48_3 "_mask48_3"
-#define MASK48_4 "_mask48_4"
-#define MASK48_5 "_mask48_5"
-#define AMASK5_3_0 "_amask5_3_0"
-#define AMASK7_1_0 "_amask7_1_0"
-#define LB_CARRY_MASK "_LBCarryMask"
-#define HB_CLEAR_MASK "_HBClearMask"
-#define AMASK0_8_0 "_amask0_8_0"
-#define AMASK6_2_0 "_amask6_2_0"
-#define AMASK4_4_0 "_amask4_4_0"
-#define AMASK0_2_6 "_amask0_2_6"
-#define AMASK2_3_3 "_amask2_3_3"
-#define AMASK4_2_2 "_amask4_2_2"
-
-#endif // ?PNG_x86_64_USE_GOTPCREL
-
-
-#if defined(PNG_HAVE_MMX_READ_FILTER_ROW) || defined(PNG_HAVE_MMX_COMBINE_ROW)
-
-// this block is specific to png_read_filter_row_mmx_paeth() except for
-// LOAD_GOT_rbp and RESTORE_rbp, which are also used in png_combine_row()
-#if defined(PNG_x86_64_USE_GOTPCREL)
-# define pa_TEMP "%%r11d"
-# define pb_TEMP "%%r12d"
-# define pc_TEMP "%%r13d"
-# if defined(PNG_CLOBBER_x86_64_REGS_SUPPORTED) // works as of gcc 3.4.3 ...
-# define SAVE_r11_r12_r13
-# define RESTORE_r11_r12_r13
-# define _CLOBBER_r11_r12_r13 ,"%r11", "%r12", "%r13"
-# define CLOBBER_r11_r12_r13 "%r11", "%r12", "%r13"
-# else // !PNG_CLOBBER_x86_64_REGS_SUPPORTED
-# define SAVE_r11_r12_r13 "pushq %%r11 \n\t" \
- "pushq %%r12 \n\t" \
- "pushq %%r13 \n\t" // "normally 0-extended"
-# define RESTORE_r11_r12_r13 "popq %%r13 \n\t" \
- "popq %%r12 \n\t" \
- "popq %%r11 \n\t"
-# define _CLOBBER_r11_r12_r13
-# define CLOBBER_r11_r12_r13
-# endif
-# define LOAD_GOT_rbp "pushq %%rbp \n\t" \
- "movq _c64@GOTPCREL(%%rip), %%rbp \n\t"
-# define RESTORE_rbp "popq %%rbp \n\t"
-#else // 32-bit and/or non-PIC
-# if defined(PNG_THREAD_UNSAFE_OK)
- // These variables are used in png_read_filter_row_mmx_paeth() and would be
- // local variables if not for gcc-inline-assembly addressing limitations
- // (some apparently related to ELF format, others to CPU type).
- //
- // WARNING: Their presence defeats the thread-safety of libpng.
- static int _patemp __attribute__((used));
- static int _pbtemp __attribute__((used));
- static int _pctemp __attribute__((used));
-# define pa_TEMP "_patemp"
-# define pb_TEMP "_pbtemp" // temp variables for
-# define pc_TEMP "_pctemp" // Paeth routine
-# define SAVE_r11_r12_r13
-# define RESTORE_r11_r12_r13
-# define _CLOBBER_r11_r12_r13 // not using regs => not clobbering
-# define CLOBBER_r11_r12_r13
-# endif // PNG_THREAD_UNSAFE_OK
-# define LOAD_GOT_rbp
-# define RESTORE_rbp
-#endif
-
-#if defined(__x86_64__)
-# define SAVE_ebp
-# define RESTORE_ebp
-# define _CLOBBER_ebp ,"%ebp"
-# define CLOBBER_ebp "%ebp"
-# define SAVE_FullLength "movl %%eax, %%r15d \n\t"
-# define RESTORE_FullLength "movl %%r15d, " // may go into eax or ecx
-# if defined(PNG_CLOBBER_x86_64_REGS_SUPPORTED) // works as of gcc 3.4.3 ...
-# define SAVE_r15
-# define RESTORE_r15
-# define _CLOBBER_r15 ,"%r15"
-# else
-# define SAVE_r15 "pushq %%r15 \n\t"
-# define RESTORE_r15 "popq %%r15 \n\t"
-# define _CLOBBER_r15
-# endif
-# define PBP "%%rbp" // regs used for 64-bit
-# define PAX "%%rax" // pointers or in
-# define PBX "%%rbx" // combination with
-# define PCX "%%rcx" // 64-bit pointer-regs
-# define PDX "%%rdx" // (base/index pairs,
-# define PSI "%%rsi" // add/sub/mov pairs)
-# define CLEAR_BOTTOM_3_BITS "and $0xfffffffffffffff8, "
-#else
-# define SAVE_ebp "pushl %%ebp \n\t" // clobber list doesn't work
-# define RESTORE_ebp "popl %%ebp \n\t" // for %ebp on 32-bit; not
-# define _CLOBBER_ebp // clear why not
-# define CLOBBER_ebp
-# define SAVE_FullLength "pushl %%eax \n\t"
-# define RESTORE_FullLength "popl " // eax (avg) or ecx (paeth)
-# define SAVE_r15
-# define RESTORE_r15
-# define _CLOBBER_r15
-# define PBP "%%ebp" // regs used for or in
-# define PAX "%%eax" // combination with
-# define PBX "%%ebx" // "normal," 32-bit
-# define PCX "%%ecx" // pointers
-# define PDX "%%edx"
-# define PSI "%%esi"
-# define CLEAR_BOTTOM_3_BITS "and $0xfffffff8, "
-#endif
-
-// CLOB_COMMA_ebx_ebp: need comma ONLY if both CLOBBER_ebp and CLOBBER_GOT_ebx
-// have values, i.e., only if __x86_64__ AND !__PIC__
-#if defined(__x86_64__) && !defined(__PIC__)
-# define CLOB_COMMA_ebx_ebp , // clobbering both ebp and ebx => need comma
-#else
-# define CLOB_COMMA_ebx_ebp
-#endif
-
-// CLOB_COMMA_ebX_r1X: need comma UNLESS both CLOBBER_ebp and CLOBBER_GOT_ebx
-// are empty OR CLOBBER_r11_r12_r13 is empty--i.e., NO comma
-// if (!__x86_64__ AND __PIC__) OR !(PNG_x86_64_USE_GOTPCREL
-// AND PNG_CLOBBER_x86_64_REGS_SUPPORTED) (double sigh...)
-#if (!defined(__x86_64__) && defined(__PIC__)) || \
- !defined(PNG_x86_64_USE_GOTPCREL) || \
- !defined(PNG_CLOBBER_x86_64_REGS_SUPPORTED)
-# define CLOB_COMMA_ebX_r1X
-#else
-# define CLOB_COMMA_ebX_r1X , // clobbering (ebp OR ebx) AND r11_r12_r13
-#endif
-
-// CLOB_COLON_ebx_ebp: need colon unless CLOBBER_ebp and CLOBBER_GOT_ebx are
-// BOTH empty--i.e., NO colon if (!__x86_64__ AND __PIC__)
-// CLOB_COLON_ebx_ebp_r1X: if, in addition, CLOBBER_r11_r12_r13 is empty, then
-// no colon for Paeth blocks, either--i.e., NO colon
-// if !(PNG_x86_64_USE_GOTPCREL AND
-// PNG_CLOBBER_x86_64_REGS_SUPPORTED)
-#if (!defined(__x86_64__) && defined(__PIC__))
-# define CLOB_COLON_ebx_ebp
-# if !(defined(PNG_x86_64_USE_GOTPCREL) && \
- defined(PNG_CLOBBER_x86_64_REGS_SUPPORTED))
-# define CLOB_COLON_ebx_ebp_r1X
-# else
-# define CLOB_COLON_ebx_ebp_r1X : // clobbering ebp OR ebx OR r11_r12_r13
-# endif
-#else
-# define CLOB_COLON_ebx_ebp : // clobbering ebp OR ebx
-# define CLOB_COLON_ebx_ebp_r1X : // clobbering ebp OR ebx OR r11_r12_r13
-#endif
-
-#endif // PNG_HAVE_MMX_READ_FILTER_ROW
-
-#if defined(__PIC__) // macros to save, restore index to Global Offset Table
-# if defined(__x86_64__)
-# define SAVE_GOT_ebx "pushq %%rbx \n\t"
-# define RESTORE_GOT_ebx "popq %%rbx \n\t"
-# else
-# define SAVE_GOT_ebx "pushl %%ebx \n\t"
-# define RESTORE_GOT_ebx "popl %%ebx \n\t"
-# endif
-# define _CLOBBER_GOT_ebx // explicitly saved, restored => not clobbered
-# define CLOBBER_GOT_ebx
-#else
-# define SAVE_GOT_ebx
-# define RESTORE_GOT_ebx
-# define _CLOBBER_GOT_ebx ,"%ebx"
-# define CLOBBER_GOT_ebx "%ebx"
-#endif
-
-#if defined(PNG_HAVE_MMX_COMBINE_ROW) || defined(PNG_HAVE_MMX_READ_INTERLACE)
-# define BPP2 2
-# define BPP3 3 // bytes per pixel (a.k.a. pixel_bytes)
-# define BPP4 4 // (defined only to help avoid cut-and-paste errors)
-# define BPP6 6
-# define BPP8 8
-#endif
-
-
-
-static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
-
-/*===========================================================================*/
-/* */
-/* P N G _ M M X _ S U P P O R T */
-/* */
-/*===========================================================================*/
-
-// GRR NOTES: (1) the following code assumes 386 or better (pushfl/popfl)
-// (2) all instructions compile with gcc 2.7.2.3 and later
-// x (3) the function is moved down here to prevent gcc from
-// x inlining it in multiple places and then barfing be-
-// x cause the ".NOT_SUPPORTED" label is multiply defined
-// [need to retest with gcc 2.7.2.3]
-
-// GRR 20070524: This declaration apparently is compatible with but supersedes
-// the one in png.h; in any case, the generated object file is slightly
-// smaller. It is unnecessary with gcc 4.1.2, but gcc 2.x apparently
-// replicated the ".NOT_SUPPORTED" label in each location the function was
-// inlined, leading to compilation errors due to the "multiply defined"
-// label. Old workaround was to leave the function at the end of this
-// file; new one (still testing) is to use a gcc-specific function attribute
-// to prevent local inlining.
-int PNGAPI
-png_mmx_support(void) __attribute__((noinline));
-
-int PNGAPI
-png_mmx_support(void)
-{
-#if defined(PNG_MMX_CODE_SUPPORTED) // superfluous, but what the heck
- int result;
- __asm__ __volatile__ (
-#if defined(__x86_64__)
- "pushq %%rbx \n\t" // rbx gets clobbered by CPUID instruction
- "pushq %%rcx \n\t" // so does rcx...
- "pushq %%rdx \n\t" // ...and rdx (but rcx & rdx safe on Linux)
- "pushfq \n\t" // save Eflag to stack
- "popq %%rax \n\t" // get Eflag from stack into rax
- "movq %%rax, %%rcx \n\t" // make another copy of Eflag in rcx
- "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
- "pushq %%rax \n\t" // save modified Eflag back to stack
- "popfq \n\t" // restore modified value to Eflag reg
- "pushfq \n\t" // save Eflag to stack
- "popq %%rax \n\t" // get Eflag from stack
- "pushq %%rcx \n\t" // save original Eflag to stack
- "popfq \n\t" // restore original Eflag
-#else
- "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction
- "pushl %%ecx \n\t" // so does ecx...
- "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux)
- "pushfl \n\t" // save Eflag to stack
- "popl %%eax \n\t" // get Eflag from stack into eax
- "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx
- "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
- "pushl %%eax \n\t" // save modified Eflag back to stack
- "popfl \n\t" // restore modified value to Eflag reg
- "pushfl \n\t" // save Eflag to stack
- "popl %%eax \n\t" // get Eflag from stack
- "pushl %%ecx \n\t" // save original Eflag to stack
- "popfl \n\t" // restore original Eflag
-#endif
- "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag
- "jz 0f \n\t" // if same, CPUID instr. is not supported
-
- "xorl %%eax, %%eax \n\t" // set eax to zero
-// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode)
- "cpuid \n\t" // get the CPU identification info
- "cmpl $1, %%eax \n\t" // make sure eax return non-zero value
- "jl 0f \n\t" // if eax is zero, MMX is not supported
-
- "xorl %%eax, %%eax \n\t" // set eax to zero and...
- "incl %%eax \n\t" // ...increment eax to 1. This pair is
- // faster than the instruction "mov eax, 1"
- "cpuid \n\t" // get the CPU identification info again
- "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
- "cmpl $0, %%edx \n\t" // 0 = MMX not supported
- "jz 0f \n\t" // non-zero = yes, MMX IS supported
-
- "movl $1, %%eax \n\t" // set return value to 1
- "jmp 1f \n\t" // DONE: have MMX support
-
- "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions
- "movl $0, %%eax \n\t" // set return value to 0
- "1: \n\t" // .RETURN: target label for jump instructions
-#if defined(__x86_64__)
- "popq %%rdx \n\t" // restore rdx
- "popq %%rcx \n\t" // restore rcx
- "popq %%rbx \n\t" // restore rbx
-#else
- "popl %%edx \n\t" // restore edx
- "popl %%ecx \n\t" // restore ecx
- "popl %%ebx \n\t" // restore ebx
-#endif
-
-// "ret \n\t" // DONE: no MMX support
- // (fall through to standard C "ret")
-
- : "=a" (result) // output list
-
- : // any variables used on input (none)
-
- // no clobber list
-// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually
-// , "memory" // if write to a variable gcc thought was in a reg
-// , "cc" // "condition codes" (flag bits)
- );
- _mmx_supported = result;
-#else
- _mmx_supported = 0;
-#endif /* PNG_MMX_CODE_SUPPORTED */
-
- return _mmx_supported;
-}
-
-
-/*===========================================================================*/
-/* */
-/* P N G _ C O M B I N E _ R O W */
-/* */
-/*===========================================================================*/
-
-#if defined(PNG_HAVE_MMX_COMBINE_ROW)
-
-/* Combines the row recently read in with the previous row.
- This routine takes care of alpha and transparency if requested.
- This routine also handles the two methods of progressive display
- of interlaced images, depending on the mask value.
- The mask value describes which pixels are to be combined with
- the row. The pattern always repeats every 8 pixels, so just 8
- bits are needed. A one indicates the pixel is to be combined; a
- zero indicates the pixel is to be skipped. This is in addition
- to any alpha or transparency value associated with the pixel.
- If you want all pixels to be combined, pass 0xff (255) in mask. */
-
-/* Use this routine for the x86 platform - it uses a faster MMX routine
- if the machine supports MMX. */
-
-void /* PRIVATE */
-png_combine_row(png_structp png_ptr, png_bytep row, int mask)
-{
- int dummy_value_a; // fix 'forbidden register spilled' error
- int dummy_value_c;
- int dummy_value_d;
- png_bytep dummy_value_S;
- png_bytep dummy_value_D;
-
- png_debug(1, "in png_combine_row (pnggccrd.c)\n");
-
- if (_mmx_supported == 2) {
-#if !defined(PNG_1_0_X)
- /* this should have happened in png_init_mmx_flags() already */
- png_warning(png_ptr, "asm_flags may not have been initialized");
-#endif
- png_mmx_support();
- }
-
- if (mask == 0xff)
- {
- png_debug(2,"mask == 0xff: doing single png_memcpy()\n");
- png_memcpy(row, png_ptr->row_buf + 1,
- (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width));
- }
- else /* (png_combine_row() is never called with mask == 0) */
- {
- switch (png_ptr->row_info.pixel_depth)
- {
- case 24: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
-#if !defined(PNG_1_0_X)
- if (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
-#else
- if (_mmx_supported)
-#endif
- {
- png_uint_32 len;
- int diff;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
- len = png_ptr->width & ~7; // reduce to multiple of 8
- diff = (int) (png_ptr->width & 7); // amount lost
-
- __asm__ __volatile__ (
- "not %%edx \n\t" // mask => unmask
- "movd %%edx, %%mm7 \n\t" // load bit pattern
- "not %%edx \n\t" // unmask => mask for later
- "psubb %%mm6, %%mm6 \n\t" // zero mm6
- "punpcklbw %%mm7, %%mm7 \n\t"
- "punpcklwd %%mm7, %%mm7 \n\t"
- "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
-
- LOAD_GOT_rbp
- "movq " MASK24_0 ", %%mm0 \n\t" // _mask24_0 -> mm0
- "movq " MASK24_1 ", %%mm1 \n\t" // _mask24_1 -> mm1
- "movq " MASK24_2 ", %%mm2 \n\t" // _mask24_2 -> mm2
- RESTORE_rbp
-
- "pand %%mm7, %%mm0 \n\t"
- "pand %%mm7, %%mm1 \n\t"
- "pand %%mm7, %%mm2 \n\t"
-
- "pcmpeqb %%mm6, %%mm0 \n\t"
- "pcmpeqb %%mm6, %%mm1 \n\t"
- "pcmpeqb %%mm6, %%mm2 \n\t"
-
-// preload "movl len, %%ecx \n\t" // load length of line
-// preload "movl srcptr, %3 \n\t" // load source
-// preload "movl dstptr, %4 \n\t" // load dest
-
- "cmpl $0, %%ecx \n\t"
- "jz mainloop24end \n\t"
-
- "mainloop24: \n\t"
- "movq (%3), %%mm4 \n\t"
- "pand %%mm0, %%mm4 \n\t"
- "movq %%mm0, %%mm6 \n\t"
- "movq (%4), %%mm7 \n\t"
- "pandn %%mm7, %%mm6 \n\t"
- "por %%mm6, %%mm4 \n\t"
- "movq %%mm4, (%4) \n\t"
-
- "movq 8(%3), %%mm5 \n\t"
- "pand %%mm1, %%mm5 \n\t"
- "movq %%mm1, %%mm7 \n\t"
- "movq 8(%4), %%mm6 \n\t"
- "pandn %%mm6, %%mm7 \n\t"
- "por %%mm7, %%mm5 \n\t"
- "movq %%mm5, 8(%4) \n\t"
-
- "movq 16(%3), %%mm6 \n\t"
- "pand %%mm2, %%mm6 \n\t"
- "movq %%mm2, %%mm4 \n\t"
- "movq 16(%4), %%mm7 \n\t"
- "pandn %%mm7, %%mm4 \n\t"
- "por %%mm4, %%mm6 \n\t"
- "movq %%mm6, 16(%4) \n\t"
-
- "add $24, %3 \n\t" // inc by 24 bytes processed
- "add $24, %4 \n\t"
- "subl $8, %%ecx \n\t" // dec by 8 pixels processed
-
- "ja mainloop24 \n\t"
-
- "mainloop24end: \n\t"
-// preload "movl diff, %%ecx \n\t" // (diff is in eax)
- "movl %%eax, %%ecx \n\t"
- "cmpl $0, %%ecx \n\t"
- "jz end24 \n\t"
-// preload "movl mask, %%edx \n\t"
- "sall $24, %%edx \n\t" // make low byte, high byte
-
- "secondloop24: \n\t"
- "sall %%edx \n\t" // move high bit to CF
- "jnc skip24 \n\t" // if CF = 0
- "movw (%3), %%ax \n\t"
- "movw %%ax, (%4) \n\t"
- "xorl %%eax, %%eax \n\t"
- "movb 2(%3), %%al \n\t"
- "movb %%al, 2(%4) \n\t"
-
- "skip24: \n\t"
- "add $3, %3 \n\t"
- "add $3, %4 \n\t"
- "decl %%ecx \n\t"
- "jnz secondloop24 \n\t"
-
- "end24: \n\t"
- "EMMS \n\t" // DONE
-
- : "=a" (dummy_value_a), // output regs (dummy)
- "=d" (dummy_value_d),
- "=c" (dummy_value_c),
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (diff), // eax // input regs
- "1" (mask), // edx
- "2" (len), // ecx
-// was (unmask) "b" RESERVED // ebx // Global Offset Table idx
- "3" (srcptr), // esi/rsi
- "4" (dstptr) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- else /* not _mmx_supported - use modified C routine */
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP3 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP3;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 24 bpp */
-
- // formerly claimed to be most common case (combining 32-bit RGBA),
- // but almost certainly less common than 24-bit RGB case
- case 32: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
-#if !defined(PNG_1_0_X)
- if (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
-#else
- if (_mmx_supported)
-#endif
- {
- png_uint_32 len;
- int diff;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
- len = png_ptr->width & ~7; // reduce to multiple of 8
- diff = (int) (png_ptr->width & 7); // amount lost
-
- __asm__ __volatile__ (
- "not %%edx \n\t" // mask => unmask
- "movd %%edx, %%mm7 \n\t" // load bit pattern
- "not %%edx \n\t" // unmask => mask for later
- "psubb %%mm6, %%mm6 \n\t" // zero mm6
- "punpcklbw %%mm7, %%mm7 \n\t"
- "punpcklwd %%mm7, %%mm7 \n\t"
- "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
-
- LOAD_GOT_rbp
- "movq " MASK32_0 ", %%mm0 \n\t" // _mask32_0
- "movq " MASK32_1 ", %%mm1 \n\t" // _mask32_1
- "movq " MASK32_2 ", %%mm2 \n\t" // _mask32_2
- "movq " MASK32_3 ", %%mm3 \n\t" // _mask32_3
- RESTORE_rbp
-
- "pand %%mm7, %%mm0 \n\t"
- "pand %%mm7, %%mm1 \n\t"
- "pand %%mm7, %%mm2 \n\t"
- "pand %%mm7, %%mm3 \n\t"
-
- "pcmpeqb %%mm6, %%mm0 \n\t"
- "pcmpeqb %%mm6, %%mm1 \n\t"
- "pcmpeqb %%mm6, %%mm2 \n\t"
- "pcmpeqb %%mm6, %%mm3 \n\t"
-
-// preload "movl len, %%ecx \n\t" // load length of line
-// preload "movl srcptr, %3 \n\t" // load source
-// preload "movl dstptr, %4 \n\t" // load dest
-
- "cmpl $0, %%ecx \n\t" // lcr
- "jz mainloop32end \n\t"
-
- "mainloop32: \n\t"
- "movq (%3), %%mm4 \n\t"
- "pand %%mm0, %%mm4 \n\t"
- "movq %%mm0, %%mm6 \n\t"
- "movq (%4), %%mm7 \n\t"
- "pandn %%mm7, %%mm6 \n\t"
- "por %%mm6, %%mm4 \n\t"
- "movq %%mm4, (%4) \n\t"
-
- "movq 8(%3), %%mm5 \n\t"
- "pand %%mm1, %%mm5 \n\t"
- "movq %%mm1, %%mm7 \n\t"
- "movq 8(%4), %%mm6 \n\t"
- "pandn %%mm6, %%mm7 \n\t"
- "por %%mm7, %%mm5 \n\t"
- "movq %%mm5, 8(%4) \n\t"
-
- "movq 16(%3), %%mm6 \n\t"
- "pand %%mm2, %%mm6 \n\t"
- "movq %%mm2, %%mm4 \n\t"
- "movq 16(%4), %%mm7 \n\t"
- "pandn %%mm7, %%mm4 \n\t"
- "por %%mm4, %%mm6 \n\t"
- "movq %%mm6, 16(%4) \n\t"
-
- "movq 24(%3), %%mm7 \n\t"
- "pand %%mm3, %%mm7 \n\t"
- "movq %%mm3, %%mm5 \n\t"
- "movq 24(%4), %%mm4 \n\t"
- "pandn %%mm4, %%mm5 \n\t"
- "por %%mm5, %%mm7 \n\t"
- "movq %%mm7, 24(%4) \n\t"
-
- "add $32, %3 \n\t" // inc by 32 bytes processed
- "add $32, %4 \n\t"
- "subl $8, %%ecx \n\t" // dec by 8 pixels processed
- "ja mainloop32 \n\t"
-
- "mainloop32end: \n\t"
-// preload "movl diff, %%ecx \n\t" // (diff is in eax)
- "movl %%eax, %%ecx \n\t"
- "cmpl $0, %%ecx \n\t"
- "jz end32 \n\t"
-// preload "movl mask, %%edx \n\t"
- "sall $24, %%edx \n\t" // low byte => high byte
-
- "secondloop32: \n\t"
- "sall %%edx \n\t" // move high bit to CF
- "jnc skip32 \n\t" // if CF = 0
- "movl (%3), %%eax \n\t"
- "movl %%eax, (%4) \n\t"
-
- "skip32: \n\t"
- "add $4, %3 \n\t"
- "add $4, %4 \n\t"
- "decl %%ecx \n\t"
- "jnz secondloop32 \n\t"
-
- "end32: \n\t"
- "EMMS \n\t" // DONE
-
- : "=a" (dummy_value_a), // output regs (dummy)
- "=d" (dummy_value_d),
- "=c" (dummy_value_c),
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (diff), // eax // input regs
- "1" (mask), // edx
- "2" (len), // ecx
-// was (unmask) "b" RESERVED // ebx // Global Offset Table idx
- "3" (srcptr), // esi/rsi
- "4" (dstptr) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- else /* not _mmx_supported - use modified C routine */
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP4 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP4;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 32 bpp */
-
- case 8: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
-#if !defined(PNG_1_0_X)
- if (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
-#else
- if (_mmx_supported)
-#endif
- {
- png_uint_32 len;
- int diff;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
- len = png_ptr->width & ~7; // reduce to multiple of 8
- diff = (int) (png_ptr->width & 7); // amount lost
-
- __asm__ __volatile__ (
- "not %%edx \n\t" // mask => unmask
- "movd %%edx, %%mm7 \n\t" // load bit pattern
- "not %%edx \n\t" // unmask => mask for later
- "psubb %%mm6, %%mm6 \n\t" // zero mm6
- "punpcklbw %%mm7, %%mm7 \n\t"
- "punpcklwd %%mm7, %%mm7 \n\t"
- "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
-
- LOAD_GOT_rbp
- "movq " MASK8_0 ", %%mm0 \n\t" // _mask8_0 -> mm0
- RESTORE_rbp
-
- "pand %%mm7, %%mm0 \n\t" // nonzero if keep byte
- "pcmpeqb %%mm6, %%mm0 \n\t" // zeros->1s, v versa
-
-// preload "movl len, %%ecx \n\t" // load length of line
-// preload "movl srcptr, %3 \n\t" // load source
-// preload "movl dstptr, %4 \n\t" // load dest
-
- "cmpl $0, %%ecx \n\t" // len == 0 ?
- "je mainloop8end \n\t"
-
- "mainloop8: \n\t"
- "movq (%3), %%mm4 \n\t" // *srcptr
- "pand %%mm0, %%mm4 \n\t"
- "movq %%mm0, %%mm6 \n\t"
- "pandn (%4), %%mm6 \n\t" // *dstptr
- "por %%mm6, %%mm4 \n\t"
- "movq %%mm4, (%4) \n\t"
- "add $8, %3 \n\t" // inc by 8 bytes processed
- "add $8, %4 \n\t"
- "subl $8, %%ecx \n\t" // dec by 8 pixels processed
- "ja mainloop8 \n\t"
-
- "mainloop8end: \n\t"
-// preload "movl diff, %%ecx \n\t" // (diff is in eax)
- "movl %%eax, %%ecx \n\t"
- "cmpl $0, %%ecx \n\t"
- "jz end8 \n\t"
-// preload "movl mask, %%edx \n\t"
- "sall $24, %%edx \n\t" // make low byte, high byte
-
- "secondloop8: \n\t"
- "sall %%edx \n\t" // move high bit to CF
- "jnc skip8 \n\t" // if CF = 0
- "movb (%3), %%al \n\t"
- "movb %%al, (%4) \n\t"
-
- "skip8: \n\t"
- "inc %3 \n\t"
- "inc %4 \n\t"
- "decl %%ecx \n\t"
- "jnz secondloop8 \n\t"
-
- "end8: \n\t"
- "EMMS \n\t" // DONE
-
- : "=a" (dummy_value_a), // output regs (dummy)
- "=d" (dummy_value_d),
- "=c" (dummy_value_c),
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (diff), // eax // input regs
- "1" (mask), // edx
- "2" (len), // ecx
-// was (unmask) "b" RESERVED // ebx // Global Offset Table idx
- "3" (srcptr), // esi/rsi
- "4" (dstptr) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm4", "%mm6", "%mm7" // clobber list
-#endif
- );
- }
- else /* not _mmx_supported - use modified C routine */
- {
- register png_uint_32 i;
- png_uint_32 initial_val = png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff /* *BPP1 */ ;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
-
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 8 bpp */
-
- case 1: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep sp;
- png_bytep dp;
- int s_inc, s_start, s_end;
- int m;
- int shift;
- png_uint_32 i;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
- else
-#endif
- {
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- int value;
-
- value = (*sp >> shift) & 0x1;
- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- } /* end 1 bpp */
-
- case 2: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep sp;
- png_bytep dp;
- int s_start, s_end, s_inc;
- int m;
- int shift;
- png_uint_32 i;
- int value;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
- else
-#endif
- {
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0x3;
- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- } /* end 2 bpp */
-
- case 4: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep sp;
- png_bytep dp;
- int s_start, s_end, s_inc;
- int m;
- int shift;
- png_uint_32 i;
- int value;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
- else
-#endif
- {
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0xf;
- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- } /* end 4 bpp */
-
- case 16: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
-#if !defined(PNG_1_0_X)
- if (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
-#else
- if (_mmx_supported)
-#endif
- {
- png_uint_32 len;
- int diff;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
- len = png_ptr->width & ~7; // reduce to multiple of 8
- diff = (int) (png_ptr->width & 7); // amount lost
-
- __asm__ __volatile__ (
- "not %%edx \n\t" // mask => unmask
- "movd %%edx, %%mm7 \n\t" // load bit pattern
- "not %%edx \n\t" // unmask => mask for later
- "psubb %%mm6, %%mm6 \n\t" // zero mm6
- "punpcklbw %%mm7, %%mm7 \n\t"
- "punpcklwd %%mm7, %%mm7 \n\t"
- "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
-
- LOAD_GOT_rbp
- "movq " MASK16_0 ", %%mm0 \n\t" // _mask16_0 -> mm0
- "movq " MASK16_1 ", %%mm1 \n\t" // _mask16_1 -> mm1
- RESTORE_rbp
-
- "pand %%mm7, %%mm0 \n\t"
- "pand %%mm7, %%mm1 \n\t"
-
- "pcmpeqb %%mm6, %%mm0 \n\t"
- "pcmpeqb %%mm6, %%mm1 \n\t"
-
-// preload "movl len, %%ecx \n\t" // load length of line
-// preload "movl srcptr, %3 \n\t" // load source
-// preload "movl dstptr, %4 \n\t" // load dest
-
- "cmpl $0, %%ecx \n\t"
- "jz mainloop16end \n\t"
-
- "mainloop16: \n\t"
- "movq (%3), %%mm4 \n\t"
- "pand %%mm0, %%mm4 \n\t"
- "movq %%mm0, %%mm6 \n\t"
- "movq (%4), %%mm7 \n\t"
- "pandn %%mm7, %%mm6 \n\t"
- "por %%mm6, %%mm4 \n\t"
- "movq %%mm4, (%4) \n\t"
-
- "movq 8(%3), %%mm5 \n\t"
- "pand %%mm1, %%mm5 \n\t"
- "movq %%mm1, %%mm7 \n\t"
- "movq 8(%4), %%mm6 \n\t"
- "pandn %%mm6, %%mm7 \n\t"
- "por %%mm7, %%mm5 \n\t"
- "movq %%mm5, 8(%4) \n\t"
-
- "add $16, %3 \n\t" // inc by 16 bytes processed
- "add $16, %4 \n\t"
- "subl $8, %%ecx \n\t" // dec by 8 pixels processed
- "ja mainloop16 \n\t"
-
- "mainloop16end: \n\t"
-// preload "movl diff, %%ecx \n\t" // (diff is in eax)
- "movl %%eax, %%ecx \n\t"
- "cmpl $0, %%ecx \n\t"
- "jz end16 \n\t"
-// preload "movl mask, %%edx \n\t"
- "sall $24, %%edx \n\t" // make low byte, high byte
-
- "secondloop16: \n\t"
- "sall %%edx \n\t" // move high bit to CF
- "jnc skip16 \n\t" // if CF = 0
- "movw (%3), %%ax \n\t"
- "movw %%ax, (%4) \n\t"
-
- "skip16: \n\t"
- "add $2, %3 \n\t"
- "add $2, %4 \n\t"
- "decl %%ecx \n\t"
- "jnz secondloop16 \n\t"
-
- "end16: \n\t"
- "EMMS \n\t" // DONE
-
- : "=a" (dummy_value_a), // output regs (dummy)
- "=d" (dummy_value_d),
- "=c" (dummy_value_c),
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (diff), // eax // input regs
- "1" (mask), // edx
- "2" (len), // ecx
-// was (unmask) "b" RESERVED // ebx // Global Offset Table idx
- "3" (srcptr), // esi/rsi
- "4" (dstptr) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm4" // clobber list
- , "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- else /* not _mmx_supported - use modified C routine */
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP2 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP2;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 16 bpp */
-
- case 48: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
-#if !defined(PNG_1_0_X)
- if (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
-#else
- if (_mmx_supported)
-#endif
- {
- png_uint_32 len;
- int diff;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
- len = png_ptr->width & ~7; // reduce to multiple of 8
- diff = (int) (png_ptr->width & 7); // amount lost
-
- __asm__ __volatile__ (
- "not %%edx \n\t" // mask => unmask
- "movd %%edx, %%mm7 \n\t" // load bit pattern
- "not %%edx \n\t" // unmask => mask for later
- "psubb %%mm6, %%mm6 \n\t" // zero mm6
- "punpcklbw %%mm7, %%mm7 \n\t"
- "punpcklwd %%mm7, %%mm7 \n\t"
- "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
-
- LOAD_GOT_rbp
- "movq " MASK48_0 ", %%mm0 \n\t" // _mask48_0 -> mm0
- "movq " MASK48_1 ", %%mm1 \n\t" // _mask48_1 -> mm1
- "movq " MASK48_2 ", %%mm2 \n\t" // _mask48_2 -> mm2
- "movq " MASK48_3 ", %%mm3 \n\t" // _mask48_3 -> mm3
- "movq " MASK48_4 ", %%mm4 \n\t" // _mask48_4 -> mm4
- "movq " MASK48_5 ", %%mm5 \n\t" // _mask48_5 -> mm5
- RESTORE_rbp
-
- "pand %%mm7, %%mm0 \n\t"
- "pand %%mm7, %%mm1 \n\t"
- "pand %%mm7, %%mm2 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pand %%mm7, %%mm4 \n\t"
- "pand %%mm7, %%mm5 \n\t"
-
- "pcmpeqb %%mm6, %%mm0 \n\t"
- "pcmpeqb %%mm6, %%mm1 \n\t"
- "pcmpeqb %%mm6, %%mm2 \n\t"
- "pcmpeqb %%mm6, %%mm3 \n\t"
- "pcmpeqb %%mm6, %%mm4 \n\t"
- "pcmpeqb %%mm6, %%mm5 \n\t"
-
-// preload "movl len, %%ecx \n\t" // load length of line
-// preload "movl srcptr, %3 \n\t" // load source
-// preload "movl dstptr, %4 \n\t" // load dest
-
- "cmpl $0, %%ecx \n\t"
- "jz mainloop48end \n\t"
-
- "mainloop48: \n\t"
- "movq (%3), %%mm7 \n\t"
- "pand %%mm0, %%mm7 \n\t"
- "movq %%mm0, %%mm6 \n\t"
- "pandn (%4), %%mm6 \n\t"
- "por %%mm6, %%mm7 \n\t"
- "movq %%mm7, (%4) \n\t"
-
- "movq 8(%3), %%mm6 \n\t"
- "pand %%mm1, %%mm6 \n\t"
- "movq %%mm1, %%mm7 \n\t"
- "pandn 8(%4), %%mm7 \n\t"
- "por %%mm7, %%mm6 \n\t"
- "movq %%mm6, 8(%4) \n\t"
-
- "movq 16(%3), %%mm6 \n\t"
- "pand %%mm2, %%mm6 \n\t"
- "movq %%mm2, %%mm7 \n\t"
- "pandn 16(%4), %%mm7 \n\t"
- "por %%mm7, %%mm6 \n\t"
- "movq %%mm6, 16(%4) \n\t"
-
- "movq 24(%3), %%mm7 \n\t"
- "pand %%mm3, %%mm7 \n\t"
- "movq %%mm3, %%mm6 \n\t"
- "pandn 24(%4), %%mm6 \n\t"
- "por %%mm6, %%mm7 \n\t"
- "movq %%mm7, 24(%4) \n\t"
-
- "movq 32(%3), %%mm6 \n\t"
- "pand %%mm4, %%mm6 \n\t"
- "movq %%mm4, %%mm7 \n\t"
- "pandn 32(%4), %%mm7 \n\t"
- "por %%mm7, %%mm6 \n\t"
- "movq %%mm6, 32(%4) \n\t"
-
- "movq 40(%3), %%mm7 \n\t"
- "pand %%mm5, %%mm7 \n\t"
- "movq %%mm5, %%mm6 \n\t"
- "pandn 40(%4), %%mm6 \n\t"
- "por %%mm6, %%mm7 \n\t"
- "movq %%mm7, 40(%4) \n\t"
-
- "add $48, %3 \n\t" // inc by 48 bytes processed
- "add $48, %4 \n\t"
- "subl $8, %%ecx \n\t" // dec by 8 pixels processed
-
- "ja mainloop48 \n\t"
-
- "mainloop48end: \n\t"
-// preload "movl diff, %%ecx \n\t" // (diff is in eax)
- "movl %%eax, %%ecx \n\t"
- "cmpl $0, %%ecx \n\t"
- "jz end48 \n\t"
-// preload "movl mask, %%edx \n\t"
- "sall $24, %%edx \n\t" // make low byte, high byte
-
- "secondloop48: \n\t"
- "sall %%edx \n\t" // move high bit to CF
- "jnc skip48 \n\t" // if CF = 0
- "movl (%3), %%eax \n\t"
- "movl %%eax, (%4) \n\t"
- "movw 4(%3), %%ax \n\t" // GR-P bugfix 20070717
- "movw %%ax, 4(%4) \n\t" // GR-P bugfix 20070717
-
- "skip48: \n\t"
- "add $6, %3 \n\t" // GR-P bugfix 20070717
- "add $6, %4 \n\t" // GR-P bugfix 20070717
- "decl %%ecx \n\t"
- "jnz secondloop48 \n\t"
-
- "end48: \n\t"
- "EMMS \n\t" // DONE
-
- : "=a" (dummy_value_a), // output regs (dummy)
- "=d" (dummy_value_d),
- "=c" (dummy_value_c),
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (diff), // eax // input regs
- "1" (mask), // edx
- "2" (len), // ecx
-// was (unmask) "b" RESERVED // ebx // Global Offset Table idx
- "3" (srcptr), // esi/rsi
- "4" (dstptr) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- else /* not _mmx_supported - use modified C routine */
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP6 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP6;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 48 bpp */
-
- case 64: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
- register png_uint_32 i;
- png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP8 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP8;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
-
- break;
- } /* end 64 bpp */
-
- default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */
- {
- // ERROR: SHOULD NEVER BE REACHED
-#if defined(PNG_DEBUG)
- png_debug(1, "Internal libpng logic error (GCC "
- "png_combine_row() pixel_depth)\n");
-#endif
- break;
- }
- } /* end switch (png_ptr->row_info.pixel_depth) */
-
- } /* end if (non-trivial mask) */
-
-} /* end png_combine_row() */
-
-#endif /* PNG_HAVE_MMX_COMBINE_ROW */
-
-
-
-
-/*===========================================================================*/
-/* */
-/* P N G _ D O _ R E A D _ I N T E R L A C E */
-/* */
-/*===========================================================================*/
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-#if defined(PNG_HAVE_MMX_READ_INTERLACE)
-
-/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion
- * has taken place. [GRR: what other steps come before and/or after?]
- */
-
-void /* PRIVATE */
-png_do_read_interlace(png_structp png_ptr)
-{
- png_row_infop row_info = &(png_ptr->row_info);
- png_bytep row = png_ptr->row_buf + 1;
- int pass = png_ptr->pass;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- png_uint_32 transformations = png_ptr->transformations;
-#endif
-
- png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n");
-
- if (_mmx_supported == 2) {
-#if !defined(PNG_1_0_X)
- /* this should have happened in png_init_mmx_flags() already */
- png_warning(png_ptr, "asm_flags may not have been initialized");
-#endif
- png_mmx_support();
- }
-
- if (row != NULL && row_info != NULL)
- {
- png_uint_32 final_width;
-
- final_width = row_info->width * png_pass_inc[pass];
-
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_byte v;
- png_uint_32 i;
- int j;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 3);
- dp = row + (png_size_t)((final_width - 1) >> 3);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)((row_info->width + 7) & 7);
- dshift = (int)((final_width + 7) & 7);
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
- else
-#endif
- {
- sshift = 7 - (int)((row_info->width + 7) & 7);
- dshift = 7 - (int)((final_width + 7) & 7);
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
-
- for (i = row_info->width; i; i--)
- {
- v = (png_byte)((*sp >> sshift) & 0x1);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- case 2:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 2);
- dp = row + (png_size_t)((final_width - 1) >> 2);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
- dshift = (png_size_t)(((final_width + 3) & 3) << 1);
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
- else
-#endif
- {
- sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
- dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
-
- for (i = row_info->width; i; i--)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0x3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- case 4:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 1);
- dp = row + (png_size_t)((final_width - 1) >> 1);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
- dshift = (png_size_t)(((final_width + 1) & 1) << 2);
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- else
-#endif
- {
- sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
- dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
-
- for (i = row_info->width; i; i--)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0xf);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- /*====================================================================*/
-
- default: /* 8-bit or larger (this is where the routine is modified) */
- {
- png_bytep sptr, dp;
- png_uint_32 i;
- png_size_t pixel_bytes;
- int width = (int)row_info->width;
-
- pixel_bytes = (row_info->pixel_depth >> 3);
-
- /* point sptr at the last pixel in the pre-expanded row: */
- sptr = row + (width - 1) * pixel_bytes;
-
- /* point dp at the last pixel position in the expanded row: */
- dp = row + (final_width - 1) * pixel_bytes;
-
- /* New code by Nirav Chhatrapati - Intel Corporation */
-
-#if !defined(PNG_1_0_X)
- if (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)
-#else
- if (_mmx_supported)
-#endif
- {
- int dummy_value_c; // fix 'forbidden register spilled'
- png_bytep dummy_value_S;
- png_bytep dummy_value_D;
- png_bytep dummy_value_a;
- png_bytep dummy_value_d;
-
- //--------------------------------------------------------------
- if (pixel_bytes == BPP3)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 1) << 1) - 8; // GRR: huh?
- if (width_mmx < 0)
- width_mmx = 0;
- width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes
- if (width_mmx)
- {
- // png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
- // sptr points at last pixel in pre-expanded row
- // dp points at last pixel position in expanded row
- __asm__ __volatile__ (
- "sub $3, %1 \n\t"
- "sub $9, %2 \n\t"
- // (png_pass_inc[pass] + 1)*pixel_bytes
-
- ".loop3_pass4: \n\t"
- "movq (%1), %%mm0 \n\t" // x x 5 4 3 2 1 0
- "movq %%mm0, %%mm1 \n\t" // x x 5 4 3 2 1 0
- "movq %%mm0, %%mm2 \n\t" // x x 5 4 3 2 1 0
- "psllq $24, %%mm0 \n\t" // 4 3 2 1 0 z z z
- "pand (%3), %%mm1 \n\t" // z z z z z 2 1 0
- "psrlq $24, %%mm2 \n\t" // z z z x x 5 4 3
- "por %%mm1, %%mm0 \n\t" // 4 3 2 1 0 2 1 0
- "movq %%mm2, %%mm3 \n\t" // z z z x x 5 4 3
- "psllq $8, %%mm2 \n\t" // z z x x 5 4 3 z
- "movq %%mm0, (%2) \n\t"
- "psrlq $16, %%mm3 \n\t" // z z z z z x x 5
- "pand (%4), %%mm3 \n\t" // z z z z z z z 5
- "por %%mm3, %%mm2 \n\t" // z z x x 5 4 3 5
- "sub $6, %1 \n\t"
- "movd %%mm2, 8(%2) \n\t"
- "sub $12, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop3_pass4 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (dummy_value_a),
- "=d" (dummy_value_d)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp), // edi/rdi
-#if defined(PNG_x86_64_USE_GOTPCREL) // formerly _const4 and _const6:
- "3" (&_c64._amask5_3_0), // (0x0000000000FFFFFFLL)
- "4" (&_c64._amask7_1_0) // (0x00000000000000FFLL)
-#else
- "3" (&_amask5_3_0), // eax (0x0000000000FFFFFFLL)
- "4" (&_amask7_1_0) // edx (0x00000000000000FFLL)
-#endif
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
- , "%mm2", "%mm3"
-#endif
- );
- }
-
- sptr -= width_mmx*BPP3;
- dp -= width_mmx*2*BPP3;
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
-
- png_memcpy(v, sptr, BPP3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, BPP3);
- dp -= BPP3;
- }
- sptr -= BPP3;
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- __asm__ __volatile__ (
- "sub $9, %2 \n\t"
- // (png_pass_inc[pass] - 1)*pixel_bytes
-
- ".loop3_pass2: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x x 2 1 0
- "pand (%3), %%mm0 \n\t" // z z z z z 2 1 0
- "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0
- "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z
- "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z
- "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z
- "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1
- "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z
- "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1
- "movq %%mm0, 4(%2) \n\t"
- "psrlq $16, %%mm0 \n\t" // z z 2 1 0 2 1 0
- "sub $3, %1 \n\t"
- "movd %%mm0, (%2) \n\t"
- "sub $12, %2 \n\t"
- "decl %%ecx \n\t"
- "jnz .loop3_pass2 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (dummy_value_a)
-
- : "0" (width), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp), // edi/rdi
-#if defined(PNG_x86_64_USE_GOTPCREL) // formerly _const4:
- "3" (&_c64._amask5_3_0) // (0x0000000000FFFFFFLL)
-#else
- "3" (&_amask5_3_0) // eax (0x0000000000FFFFFFLL)
-#endif
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2" // clobber list
-#endif
- );
- }
- else if (width) // && ((pass == 0) || (pass == 1))
- {
- __asm__ __volatile__ (
- "sub $21, %2 \n\t"
- // (png_pass_inc[pass] - 1)*pixel_bytes
-
- ".loop3_pass0: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x x 2 1 0
- "pand (%3), %%mm0 \n\t" // z z z z z 2 1 0
- "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0
- "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z
- "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z
- "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z
- "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1
- "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z
- "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1
- "movq %%mm0, %%mm3 \n\t" // 2 1 0 2 1 0 2 1
- "psllq $16, %%mm0 \n\t" // 0 2 1 0 2 1 z z
- "movq %%mm3, %%mm4 \n\t" // 2 1 0 2 1 0 2 1
- "punpckhdq %%mm0, %%mm3 \n\t" // 0 2 1 0 2 1 0 2
- "movq %%mm4, 16(%2) \n\t"
- "psrlq $32, %%mm0 \n\t" // z z z z 0 2 1 0
- "movq %%mm3, 8(%2) \n\t"
- "punpckldq %%mm4, %%mm0 \n\t" // 1 0 2 1 0 2 1 0
- "sub $3, %1 \n\t"
- "movq %%mm0, (%2) \n\t"
- "sub $24, %2 \n\t"
- "decl %%ecx \n\t"
- "jnz .loop3_pass0 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (dummy_value_a)
-
- : "0" (width), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp), // edi/rdi
-#if defined(PNG_x86_64_USE_GOTPCREL) // formerly _const4:
- "3" (&_c64._amask5_3_0) // (0x0000000000FFFFFFLL)
-#else
- "3" (&_amask5_3_0) // eax (0x0000000000FFFFFFLL)
-#endif
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2" // clobber list
- , "%mm3", "%mm4"
-#endif
- );
- }
- } /* end of pixel_bytes == 3 */
-
- //--------------------------------------------------------------
- else if (pixel_bytes == BPP4)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx; // 0,1 pixels => 0,4 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $4, %1 \n\t"
- "sub $12, %2 \n\t"
-
- ".loop4_pass4: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
- "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0
- "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4
- "movq %%mm0, (%2) \n\t"
- "sub $8, %1 \n\t"
- "movq %%mm1, 8(%2) \n\t"
- "sub $16, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop4_pass4 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= (width_mmx*BPP4 - BPP4); // sign fixed
- dp -= (width_mmx*2*BPP4 - BPP4); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= BPP4;
- png_memcpy(v, sptr, BPP4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= BPP4;
- png_memcpy(dp, v, BPP4);
- }
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- int width_mmx = ((width >> 1) << 1);
- width -= width_mmx; // 0,1 pixels => 0,4 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $4, %1 \n\t"
- "sub $28, %2 \n\t"
-
- ".loop4_pass2: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
- "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0
- "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4
- "movq %%mm0, (%2) \n\t"
- "movq %%mm0, 8(%2) \n\t"
- "movq %%mm1, 16(%2) \n\t"
- "movq %%mm1, 24(%2) \n\t"
- "sub $8, %1 \n\t"
- "sub $32, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop4_pass2 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= (width_mmx*4 - 4); // sign fixed
- dp -= (width_mmx*16 - 4); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 4;
- png_memcpy(v, sptr, 4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 4;
- png_memcpy(dp, v, 4);
- }
- }
- }
- else if (width) // && ((pass == 0) || (pass == 1))
- {
- int width_mmx = ((width >> 1) << 1);
- width -= width_mmx; // 0,1 pixels => 0,4 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $4, %1 \n\t"
- "sub $60, %2 \n\t"
-
- ".loop4_pass0: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
- "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0
- "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4
- "movq %%mm0, (%2) \n\t"
- "movq %%mm0, 8(%2) \n\t"
- "movq %%mm0, 16(%2) \n\t"
- "movq %%mm0, 24(%2) \n\t"
- "movq %%mm1, 32(%2) \n\t"
- "movq %%mm1, 40(%2) \n\t"
- "movq %%mm1, 48(%2) \n\t"
- "sub $8, %1 \n\t"
- "movq %%mm1, 56(%2) \n\t"
- "sub $64, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop4_pass0 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= (width_mmx*4 - 4); // sign fixed
- dp -= (width_mmx*32 - 4); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 4;
- png_memcpy(v, sptr, 4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 4;
- png_memcpy(dp, v, 4);
- }
- }
- }
- } /* end of pixel_bytes == 4 */
-
- //--------------------------------------------------------------
- else if (pixel_bytes == 1)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 3) << 3);
- width -= width_mmx; // 0-3 pixels => 0-3 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $7, %1 \n\t"
- "sub $15, %2 \n\t"
-
- ".loop1_pass4: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
- "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0
- "punpckhbw %%mm1, %%mm1 \n\t" // 7 7 6 6 5 5 4 4
- "movq %%mm1, 8(%2) \n\t"
- "sub $8, %1 \n\t"
- "movq %%mm0, (%2) \n\t"
- "sub $16, %2 \n\t"
- "subl $8, %%ecx \n\t"
- "jnz .loop1_pass4 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= width_mmx;
- dp -= width_mmx*2;
- for (i = width; i; i--)
- {
- int j;
-
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- --sptr;
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- int width_mmx = ((width >> 2) << 2);
- width -= width_mmx; // 0-3 pixels => 0-3 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $3, %1 \n\t"
- "sub $15, %2 \n\t"
-
- ".loop1_pass2: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x 3 2 1 0
- "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0
- "movq %%mm0, %%mm1 \n\t" // 3 3 2 2 1 1 0 0
- "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0
- "punpckhwd %%mm1, %%mm1 \n\t" // 3 3 3 3 2 2 2 2
- "movq %%mm0, (%2) \n\t"
- "sub $4, %1 \n\t"
- "movq %%mm1, 8(%2) \n\t"
- "sub $16, %2 \n\t"
- "subl $4, %%ecx \n\t"
- "jnz .loop1_pass2 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= width_mmx;
- dp -= width_mmx*4;
- for (i = width; i; i--)
- {
- int j;
-
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- --sptr;
- }
- }
- else if (width) // && ((pass == 0) || (pass == 1))
- {
- int width_mmx = ((width >> 2) << 2);
- width -= width_mmx; // 0-3 pixels => 0-3 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $3, %1 \n\t"
- "sub $31, %2 \n\t"
-
- ".loop1_pass0: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x 3 2 1 0
- "movq %%mm0, %%mm1 \n\t" // x x x x 3 2 1 0
- "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0
- "movq %%mm0, %%mm2 \n\t" // 3 3 2 2 1 1 0 0
- "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0
- "movq %%mm0, %%mm3 \n\t" // 1 1 1 1 0 0 0 0
- "punpckldq %%mm0, %%mm0 \n\t" // 0 0 0 0 0 0 0 0
- "punpckhdq %%mm3, %%mm3 \n\t" // 1 1 1 1 1 1 1 1
- "movq %%mm0, (%2) \n\t"
- "punpckhwd %%mm2, %%mm2 \n\t" // 3 3 3 3 2 2 2 2
- "movq %%mm3, 8(%2) \n\t"
- "movq %%mm2, %%mm4 \n\t" // 3 3 3 3 2 2 2 2
- "punpckldq %%mm2, %%mm2 \n\t" // 2 2 2 2 2 2 2 2
- "punpckhdq %%mm4, %%mm4 \n\t" // 3 3 3 3 3 3 3 3
- "movq %%mm2, 16(%2) \n\t"
- "sub $4, %1 \n\t"
- "movq %%mm4, 24(%2) \n\t"
- "sub $32, %2 \n\t"
- "subl $4, %%ecx \n\t"
- "jnz .loop1_pass0 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2" // clobber list
- , "%mm3", "%mm4"
-#endif
- );
- }
-
- sptr -= width_mmx;
- dp -= width_mmx*8;
- for (i = width; i; i--)
- {
- int j;
-
- /* I simplified this part in version 1.0.4e
- * here and in several other instances where
- * pixel_bytes == 1 -- GR-P
- *
- * Original code:
- *
- * png_byte v[8];
- * png_memcpy(v, sptr, pixel_bytes);
- * for (j = 0; j < png_pass_inc[pass]; j++)
- * {
- * png_memcpy(dp, v, pixel_bytes);
- * dp -= pixel_bytes;
- * }
- * sptr -= pixel_bytes;
- *
- * Replacement code is in the next three lines:
- */
-
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- --sptr;
- }
- }
- } /* end of pixel_bytes == 1 */
-
- //--------------------------------------------------------------
- else if (pixel_bytes == BPP2)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx; // 0,1 pixels => 0,2 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $2, %1 \n\t"
- "sub $6, %2 \n\t"
-
- ".loop2_pass4: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x 3 2 1 0
- "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0
- "sub $4, %1 \n\t"
- "movq %%mm0, (%2) \n\t"
- "sub $8, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop2_pass4 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0" // clobber list
-#endif
- );
- }
-
- sptr -= (width_mmx*BPP2 - BPP2); // sign fixed
- dp -= (width_mmx*2*BPP2 - BPP2); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= BPP2;
- png_memcpy(v, sptr, BPP2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= BPP2;
- png_memcpy(dp, v, BPP2);
- }
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx; // 0,1 pixels => 0,2 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $2, %1 \n\t"
- "sub $14, %2 \n\t"
-
- ".loop2_pass2: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x 3 2 1 0
- "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0
- "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0
- "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0
- "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2
- "movq %%mm0, (%2) \n\t"
- "sub $4, %1 \n\t"
- "movq %%mm1, 8(%2) \n\t"
- "sub $16, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop2_pass2 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= (width_mmx*2 - 2); // sign fixed
- dp -= (width_mmx*8 - 2); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 2;
- png_memcpy(v, sptr, 2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 2;
- png_memcpy(dp, v, 2);
- }
- }
- }
- else if (width) // && ((pass == 0) || (pass == 1))
- {
- int width_mmx = ((width >> 1) << 1);
- width -= width_mmx; // 0,1 pixels => 0,2 bytes
- if (width_mmx)
- {
- __asm__ __volatile__ (
- "sub $2, %1 \n\t"
- "sub $30, %2 \n\t"
-
- ".loop2_pass0: \n\t"
- "movd (%1), %%mm0 \n\t" // x x x x 3 2 1 0
- "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0
- "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0
- "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0
- "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2
- "movq %%mm0, (%2) \n\t"
- "movq %%mm0, 8(%2) \n\t"
- "movq %%mm1, 16(%2) \n\t"
- "sub $4, %1 \n\t"
- "movq %%mm1, 24(%2) \n\t"
- "sub $32, %2 \n\t"
- "subl $2, %%ecx \n\t"
- "jnz .loop2_pass0 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width_mmx), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
-
- sptr -= (width_mmx*2 - 2); // sign fixed
- dp -= (width_mmx*16 - 2); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 2;
- png_memcpy(v, sptr, 2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 2;
- png_memcpy(dp, v, 2);
- }
- }
- }
- } /* end of pixel_bytes == 2 */
-
- //--------------------------------------------------------------
- else if (pixel_bytes == BPP8)
- {
-// GRR TEST: should work, but needs testing (special 64-bit version of rpng2?)
- // GRR NOTE: no need to combine passes here!
- if (((pass == 4) || (pass == 5)) && width)
- {
- // source is 8-byte RRGGBBAA
- // dest is 16-byte RRGGBBAA RRGGBBAA
- __asm__ __volatile__ (
- "sub $8, %2 \n\t" // start of last block
-
- ".loop8_pass4: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, (%2) \n\t"
- "sub $8, %1 \n\t"
- "movq %%mm0, 8(%2) \n\t"
- "sub $16, %2 \n\t"
- "decl %%ecx \n\t"
- "jnz .loop8_pass4 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0" // clobber list
-#endif
- );
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- // source is 8-byte RRGGBBAA
- // dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA
- // (recall that expansion is _in place_: sptr and dp
- // both point at locations within same row buffer)
- __asm__ __volatile__ (
- "sub $24, %2 \n\t" // start of last block
-
- ".loop8_pass2: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, (%2) \n\t"
- "movq %%mm0, 8(%2) \n\t"
- "movq %%mm0, 16(%2) \n\t"
- "sub $8, %1 \n\t"
- "movq %%mm0, 24(%2) \n\t"
- "sub $32, %2 \n\t"
- "decl %%ecx \n\t"
- "jnz .loop8_pass2 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0" // clobber list
-#endif
- );
- }
- else if (width) // && ((pass == 0) || (pass == 1))
- {
- // source is 8-byte RRGGBBAA
- // dest is 64-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA ...
- __asm__ __volatile__ (
- "sub $56, %2 \n\t" // start of last block
-
- ".loop8_pass0: \n\t"
- "movq (%1), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
- "movq %%mm0, (%2) \n\t"
- "movq %%mm0, 8(%2) \n\t"
- "movq %%mm0, 16(%2) \n\t"
- "movq %%mm0, 24(%2) \n\t"
- "movq %%mm0, 32(%2) \n\t"
- "movq %%mm0, 40(%2) \n\t"
- "movq %%mm0, 48(%2) \n\t"
- "sub $8, %1 \n\t"
- "movq %%mm0, 56(%2) \n\t"
- "sub $64, %2 \n\t"
- "decl %%ecx \n\t"
- "jnz .loop8_pass0 \n\t"
- "EMMS \n\t" // DONE
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D)
-
- : "0" (width), // ecx // input regs
- "1" (sptr), // esi/rsi
- "2" (dp) // edi/rdi
-
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0" // clobber list
-#endif
- );
- }
- } /* end of pixel_bytes == 8 */
-
- //--------------------------------------------------------------
- else if (pixel_bytes == BPP6) // why no MMX for this case?
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, BPP6);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, BPP6);
- dp -= BPP6;
- }
- sptr -= BPP6;
- }
- } /* end of pixel_bytes == 6 */
-
- //--------------------------------------------------------------
- else
- {
- // ERROR: SHOULD NEVER BE REACHED
-#if defined(PNG_DEBUG)
- png_debug(1, "Internal libpng logic error (GCC "
- "png_do_read_interlace() _mmx_supported)\n");
-#endif
- }
-
- } // end of _mmx_supported ========================================
-
- else /* MMX not supported: use modified C code - takes advantage
- * of inlining of png_memcpy for a constant */
- {
- if (pixel_bytes == BPP3)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, BPP3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, BPP3);
- dp -= BPP3;
- }
- sptr -= BPP3;
- }
- }
- else if (pixel_bytes == BPP4)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, BPP4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
-#if defined(PNG_DEBUG) && defined(PNG_1_0_X) // row_buf_size gone in 1.2.x
- if (dp < row || dp+3 > row+png_ptr->row_buf_size)
- {
- printf("dp out of bounds: row=%10p, dp=%10p, "
- "rp=%10p\n", row, dp, row+png_ptr->row_buf_size);
- printf("row_buf_size=%lu\n", png_ptr->row_buf_size);
- }
-#endif
- png_memcpy(dp, v, BPP4);
- dp -= BPP4;
- }
- sptr -= BPP4;
- }
- }
- else if (pixel_bytes == 1)
- {
- for (i = width; i; i--)
- {
- int j;
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- --sptr;
- }
- }
- else if (pixel_bytes == BPP2)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, BPP2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, BPP2);
- dp -= BPP2;
- }
- sptr -= BPP2;
- }
- }
- else if (pixel_bytes == BPP6)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, BPP6);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, BPP6);
- dp -= BPP6;
- }
- sptr -= BPP6;
- }
- }
- else if (pixel_bytes == BPP8)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, BPP8);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, BPP8);
- dp -= BPP8;
- }
- sptr -= BPP8;
- }
- }
- else
- {
- // ERROR: SHOULD NEVER BE REACHED
-#if defined(PNG_DEBUG)
- png_debug(1, "Internal libpng logic error (GCC "
- "png_do_read_interlace() !_mmx_supported)\n");
-#endif
- }
-
- } /* end if (MMX not supported) */
- break;
- } /* end default (8-bit or larger) */
- } /* end switch (row_info->pixel_depth) */
-
- row_info->width = final_width;
-
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
- }
-
-} /* end png_do_read_interlace() */
-
-#endif /* PNG_HAVE_MMX_READ_INTERLACE */
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-
-
-#if defined(PNG_HAVE_MMX_READ_FILTER_ROW)
-#if defined(PNG_MMX_READ_FILTER_AVG_SUPPORTED)
-
-//===========================================================================//
-// //
-// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ A V G //
-// //
-//===========================================================================//
-
-// Optimized code for PNG Average filter decoder
-
-static void /* PRIVATE */
-png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row,
- png_bytep prev_row)
-{
- unsigned FullLength, MMXLength; // png_uint_32 is actually 64-bit on x86-64
- int bpp;
- int dummy_value_a;
- int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error
- int dummy_value_d;
- png_bytep dummy_value_S;
- png_bytep dummy_value_D;
- int diff; // __attribute__((used));
-
- bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel
- FullLength = row_info->rowbytes; // number of bytes to filter
-
- __asm__ __volatile__ (
- "avg_top: \n\t"
- SAVE_GOT_ebx
- SAVE_r15
- SAVE_ebp
- // initialize address pointers and offset
-//pre "movl row, %5 \n\t" // edi/rdi: ptr to Avg(x)
- "xorl %%ebx, %%ebx \n\t" // ebx: x
-//pre "movl prev_row, %4 \n\t" // esi/rsi: ptr to Prior(x)
- "mov %5, " PDX " \n\t" // copy of row ptr...
-//pre "subl bpp, " PDX " \n\t" // (bpp is preloaded into ecx)
- "sub " PCX "," PDX " \n\t" // edx/rdx: ptr to Raw(x-bpp)
-//pre "movl FullLength, %%eax \n\t" // bring in via eax...
- SAVE_FullLength // ...but store for later use
- "xorl %%eax, %%eax \n\t"
-
- // Compute the Raw value for the first bpp bytes
- // Raw(x) = Avg(x) + (Prior(x)/2)
- "avg_rlp: \n\t"
- "movb (%4," PBX ",), %%al \n\t" // load al with Prior(x)
- "incl %%ebx \n\t"
- "shrb %%al \n\t" // divide by 2
- "addb -1(%5," PBX ",), %%al \n\t" // add Avg(x); -1 to offset inc ebx
-//pre "cmpl bpp, %%ebx \n\t" // (bpp is preloaded into ecx)
- "cmpl %%ecx, %%ebx \n\t"
- "movb %%al, -1(%5," PBX ",) \n\t" // write Raw(x); -1 to offset inc ebx
- "jb avg_rlp \n\t" // mov does not affect flags
-
- // get # of bytes to alignment (32-bit mask _would_ be good enough
- // [computing delta], but 32-bit ops are zero-extended on 64-bit, argh)
- // (if swapped edx and ebp, could do 8-bit or 16-bit mask...FIXME?)
- "mov %5, " PBP " \n\t" // take start of row
- "add " PBX "," PBP " \n\t" // add bpp
- "add $0xf, " PBP " \n\t" // add 7+8 to incr past alignment bdry
-// "andl $0xfffffff8, %%ebp \n\t" // mask to alignment boundary (32-bit!)
- CLEAR_BOTTOM_3_BITS PBP "\n\t" // mask to alignment boundary
- "sub %5, " PBP " \n\t" // subtract row ptr again => ebp =
- "jz avg_go \n\t" // target value of ebx at alignment
-
- "xorl %%ecx, %%ecx \n\t"
-
- // fix alignment
- // Compute the Raw value for the bytes up to the alignment boundary
- // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
- "avg_lp1: \n\t"
- "xorl %%eax, %%eax \n\t"
- "movb (%4," PBX ",), %%cl \n\t" // load cl with Prior(x)
- "movb (" PDX "," PBX ",), %%al \n\t" // load al with Raw(x-bpp)
- "addw %%cx, %%ax \n\t"
- "incl %%ebx \n\t"
- "shrw %%ax \n\t" // divide by 2
- "addb -1(%5," PBX ",), %%al \n\t" // add Avg(x); -1 to offset inc ebx
- "cmpl %%ebp, %%ebx \n\t" // check if at alignment boundary
- "movb %%al, -1(%5," PBX ",) \n\t" // write Raw(x); -1 to offset inc ebx
- "jb avg_lp1 \n\t" // repeat until at alignment boundary
-
- "avg_go: \n\t"
- RESTORE_FullLength "%%eax \n\t" // FullLength -> eax
- "movl %%eax, %%ecx \n\t" // copy -> ecx
- "subl %%ebx, %%eax \n\t" // subtract alignment fix
- "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8
- "subl %%eax, %%ecx \n\t" // sub over-bytes from original length
-//out "movl %%ecx, MMXLength \n\t"
- "movl %%ebp, %%eax \n\t" // ebp = diff, but no reg constraint(?)
- RESTORE_ebp // (could swap ebp and edx functions)
- RESTORE_r15
- RESTORE_GOT_ebx
-
-// "There is no way for you to specify that an input operand is modified
-// without also specifying it as an output operand." [makes sense]
-
-// "Unless an output operand has the `&' constraint modifier, GCC may
-// allocate it in the same register as an unrelated input operand, on the
-// assumption the inputs are consumed before the outputs are produced."
-// [trying to _force_ this]
-
-// "`=' Means that this operand is write-only for this instruction:
-// the previous value is discarded and replaced by output data."
-// [operand == variable name, presumably]
-
- // output regs
- // these are operands 0-1 (originally 0-3):
- : "=c" (MMXLength), // %0 -> %0
- "=a" (diff) // %3 -> %1
-// "=S" (dummy_value_S), // %1 -> GONE
-// "=D" (dummy_value_D), // %2 -> GONE
-
- // input regs
- // these are operands 2-5 (originally 4-7); two of their constraints say
- // they must go in same places as operands 0-1 (originally 0-3) above:
- : "0" (bpp), // %4 -> %2 ecx
- "1" (FullLength), // %7 -> %3 eax
- "S" (prev_row), // %5 -> %4 esi/rsi
- "D" (row) // %6 -> %5 edi/rdi
-
- : "%edx" // clobber list
- _CLOBBER_r15
- _CLOBBER_ebp
- _CLOBBER_GOT_ebx
- );
-
- // now do the math for the rest of the row
- switch (bpp)
- {
- case 3:
- {
-// _ShiftBpp = 24; // == 3 * 8
-// _ShiftRem = 40; // == 64 - 24
-
- __asm__ __volatile__ (
- // re-init address pointers and offset
- LOAD_GOT_rbp
- "movq " AMASK5_3_0 ", %%mm7 \n\t" // _amask5_3_0 -> mm7
-// preload "movl diff, %%ecx \n\t" // ecx: x = offset to
- // alignment boundary
- "movq " LB_CARRY_MASK ", %%mm5 \n\t" // [interleave for parallel.?]
-// preload "movl row, %1 \n\t" // edi: Avg(x)
- "movq " HB_CLEAR_MASK ", %%mm4 \n\t" // _HBClearMask -> mm4
-// preload "movl prev_row, %0 \n\t" // esi: Prior(x)
- RESTORE_rbp
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm2 \n\t"// load previous aligned 8 bytes
- // (correct pos. in loop below)
- "avg_3lp: \n\t"
- "movq (%1," PCX ",), %%mm0 \n\t" // load mm0 with Avg(x)
- "movq %%mm5, %%mm3 \n\t"
- "psrlq $40, %%mm2 \n\t" // correct position Raw(x-bpp)
- // data
- "movq (%0," PCX ",), %%mm1 \n\t" // load mm1 with Prior(x)
- "movq %%mm7, %%mm6 \n\t"
- "pand %%mm1, %%mm3 \n\t" // get lsb for each prevrow byte
- "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
- "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
- // each byte
- // add 1st active group (Raw(x-bpp)/2) to average with LBCarry
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both lsb's were == 1
- // (valid only for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to Raw(x-bpp)/2
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
- // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
- "psllq $24, %%mm6 \n\t" // shift the mm6 mask to cover
- // bytes 3-5
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $24, %%mm2 \n\t" // shift data to pos. correctly
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both lsb's were == 1
- // (valid only for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to Raw(x-bpp)/2
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
-
- // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry
- "psllq $24, %%mm6 \n\t" // shift mm6 mask to cover last
- // two bytes
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $24, %%mm2 \n\t" // shift data to pos. correctly
- // Data need be shifted only once here to
- // get the correct x-bpp offset.
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to Raw(x-bpp)/2
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "addl $8, %%ecx \n\t"
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
- // now ready to write back to memory
- "movq %%mm0, -8(%1," PCX ",) \n\t"
- // move updated Raw(x) to use as Raw(x-bpp) for next loop
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- "movq %%mm0, %%mm2 \n\t" // mov updated Raw(x) to mm2
- "jb avg_3lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 3 bpp
-
- case 4: // formerly shared with 6 bpp case via _ShiftBpp and _ShiftRem,
- { // but loop uses all 8 MMX regs, and psrlq/psllq require 64-bit
- // mem (PIC/.so problems), MMX reg (none left), or immediate
-// _ShiftBpp = bpp << 3; // 32 (psllq)
-// _ShiftRem = 64 - _ShiftBpp; // 32 (psrlq)
-
- __asm__ __volatile__ (
- LOAD_GOT_rbp
- "movq " HB_CLEAR_MASK ", %%mm4 \n\t" // _HBClearMask -> mm4
- "movq " LB_CARRY_MASK ", %%mm5 \n\t" // _LBCarryMask -> mm5
- // re-init address pointers and offset
-// preload "movl diff, %%ecx \n\t" // ecx: x = offset to
- // alignment boundary
- "movq " AMASK0_8_0 ", %%mm7 \n\t" // _amask0_8_0 -> mm7
- RESTORE_rbp
-
- // ... and clear all bytes except for 1st active group
-// preload "movl row, %1 \n\t" // edi: Avg(x)
- "psrlq $32, %%mm7 \n\t" // was _ShiftRem
-// preload "movl prev_row, %0 \n\t" // esi: Prior(x)
- "movq %%mm7, %%mm6 \n\t"
- "psllq $32, %%mm6 \n\t" // mask for 2nd active group
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm2 \n\t" // load previous aligned 8 bytes
- // (we correct pos. in loop below)
- "avg_4lp: \n\t"
- "movq (%1," PCX ",), %%mm0 \n\t"
- "psrlq $32, %%mm2 \n\t" // shift data to pos. correctly
- "movq (%0," PCX ",), %%mm1 \n\t"
- // add (Prev_row/2) to average
- "movq %%mm5, %%mm3 \n\t"
- "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
- "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
- "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
- // each byte
- // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm7, %%mm2 \n\t" // leave only Active Group 1
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg
- // for each Active
- // byte
- // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $32, %%mm2 \n\t" // shift data to pos. correctly
- "addl $8, %%ecx \n\t"
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- // now ready to write back to memory
- "movq %%mm0, -8(%1," PCX ",) \n\t"
- // prep Raw(x-bpp) for next loop
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "jb avg_4lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 4 bpp
-
- case 1:
- {
- __asm__ __volatile__ (
- // re-init address pointers and offset
-// preload "movl diff, %%ecx \n\t" // ecx: x = offset to align. bdry
-// preload "movl row, %1 \n\t" // edi/rdi: Avg(x)
-// preload "movl FullLength, %%eax \n\t"
- "cmpl %%eax, %%ecx \n\t" // test if offset at end of array
- "jnb avg_1end \n\t"
-
- SAVE_ebp
-
- // do Avg decode for remaining bytes
-// preload "movl prev_row, %0 \n\t" // esi/rsi: Prior(x)
- "mov %1, " PBP " \n\t" // copy of row pointer...
- "dec " PBP " \n\t" // ebp/rbp: Raw(x-bpp)
- "xorl %%edx, %%edx \n\t" // zero edx before using dl & dx
- // in loop below
- SAVE_GOT_ebx
-
- "avg_1lp: \n\t"
- // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
- "xorl %%ebx, %%ebx \n\t"
- "movb (%0," PCX ",), %%dl \n\t" // load dl with Prior(x)
- "movb (" PBP "," PCX ",), %%bl \n\t" // load bl with Raw(x-bpp)
- "addw %%dx, %%bx \n\t"
- "incl %%ecx \n\t"
- "shrw %%bx \n\t" // divide by 2
- "addb -1(%1," PCX ",), %%bl \n\t" // add Avg(x); -1 to offset
- // inc ecx
- "cmpl %%eax, %%ecx \n\t" // check if at end of array
- "movb %%bl, -1(%1," PCX ",) \n\t" // write back Raw(x);
- // mov does not affect flags; -1 to offset inc ecx
- "jb avg_1lp \n\t"
-
- RESTORE_GOT_ebx
- RESTORE_ebp
-
- "avg_1end: \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (FullLength) // eax
-
- : "%edx" // clobber list
- _CLOBBER_GOT_ebx
- _CLOBBER_ebp
- );
- }
- return; // end 1 bpp
-
- case 2:
- {
-// _ShiftBpp = 16; // == 2 * 8
-// _ShiftRem = 48; // == 64 - _ShiftBpp
-
- __asm__ __volatile__ (
- LOAD_GOT_rbp
- // load (former) _ActiveMask
- "movq " AMASK6_2_0 ", %%mm7 \n\t" // _amask6_2_0 -> mm7
- // re-init address pointers and offset
-// preload "movl diff, %%ecx \n\t" // ecx: x = offset to
- // alignment boundary
- "movq " LB_CARRY_MASK ", %%mm5 \n\t" // _LBCarryMask -> mm5
-// preload "movl row, %1 \n\t" // edi: Avg(x)
- "movq " HB_CLEAR_MASK ", %%mm4 \n\t" // _HBClearMask -> mm4
-// preload "movl prev_row, %0 \n\t" // esi: Prior(x)
- RESTORE_rbp
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm2 \n\t" // load previous aligned 8 bytes
- // (we correct pos. in loop below)
- "avg_2lp: \n\t"
- "movq (%1," PCX ",), %%mm0 \n\t"
- "psrlq $48, %%mm2 \n\t" // shift data to pos. correctly
- "movq (%0," PCX ",), %%mm1 \n\t" // (GRR BUGFIX: was psllq)
- // add (Prev_row/2) to average
- "movq %%mm5, %%mm3 \n\t"
- "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
- "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
- "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
- // byte
- "movq %%mm7, %%mm6 \n\t"
- "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
- // each byte
-
- // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid
- // for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg
- // for each Active byte
-
- // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
- "psllq $16, %%mm6 \n\t" // shift the mm6 mask to cover
- // bytes 2 & 3
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $16, %%mm2 \n\t" // shift data to pos. correctly
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid
- // for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
-
- // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry
- "psllq $16, %%mm6 \n\t" // shift the mm6 mask to cover
- // bytes 4 & 5
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $16, %%mm2 \n\t" // shift data to pos. correctly
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both lsb's were == 1
- // (only valid for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
-
- // add 4th active group (Raw(x-bpp)/2) to average with _LBCarry
- "psllq $16, %%mm6 \n\t" // shift the mm6 mask to cover
- // bytes 6 & 7
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $16, %%mm2 \n\t" // shift data to pos. correctly
- "addl $8, %%ecx \n\t"
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid
- // for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- // now ready to write back to memory
- "movq %%mm0, -8(%1," PCX ",) \n\t"
- // prep Raw(x-bpp) for next loop
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "jb avg_2lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 2 bpp
-
- case 6: // formerly shared with 4 bpp case (see comments there)
- {
-// _ShiftBpp = bpp << 3; // 48 (psllq)
-// _ShiftRem = 64 - _ShiftBpp; // 16 (psrlq)
-
- __asm__ __volatile__ (
- LOAD_GOT_rbp
- "movq " HB_CLEAR_MASK ", %%mm4 \n\t" // _HBClearMask -> mm4
- "movq " LB_CARRY_MASK ", %%mm5 \n\t" // _LBCarryMask -> mm5
- // re-init address pointers and offset
-// preload "movl diff, %%ecx \n\t" // ecx: x = offset to
- // alignment boundary
- "movq " AMASK0_8_0 ", %%mm7 \n\t" // _amask0_8_0 -> mm7
- RESTORE_rbp
-
- // ... and clear all bytes except for 1st active group
-// preload "movl row, %1 \n\t" // edi: Avg(x)
- "psrlq $16, %%mm7 \n\t"
-// preload "movl prev_row, %0 \n\t" // esi: Prior(x)
- "movq %%mm7, %%mm6 \n\t"
- "psllq $48, %%mm6 \n\t" // mask for 2nd active group
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm2 \n\t" // load previous aligned 8 bytes
- // (we correct pos. in loop below)
- "avg_6lp: \n\t"
- "movq (%1," PCX ",), %%mm0 \n\t"
- "psrlq $16, %%mm2 \n\t" // shift data to pos. correctly
- "movq (%0," PCX ",), %%mm1 \n\t"
- // add (Prev_row/2) to average
- "movq %%mm5, %%mm3 \n\t"
- "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
- "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
- "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
- // each byte
- // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm7, %%mm2 \n\t" // leave only Active Group 1
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg
- // for each Active
- // byte
- // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "psllq $48, %%mm2 \n\t" // shift data to pos. correctly
- "addl $8, %%ecx \n\t"
- "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
- // LBCarrys
- "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
- // where both
- // lsb's were == 1 (only valid for active group)
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
- // byte
- "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
- // for each byte
- "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
- // bytes to add to Avg
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
- // Avg for each Active byte
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- // now ready to write back to memory
- "movq %%mm0, -8(%1," PCX ",) \n\t"
- // prep Raw(x-bpp) for next loop
- "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
- "jb avg_6lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 6 bpp
-
- case 8:
- {
- __asm__ __volatile__ (
- // re-init address pointers and offset
-// preload "movl diff, %%ecx \n\t" // ecx: x = offset to
- // alignment boundary
- LOAD_GOT_rbp
- "movq " LB_CARRY_MASK ", %%mm5 \n\t" // [interleave for parallel.?]
-// preload "movl row, %1 \n\t" // edi: Avg(x)
- "movq " HB_CLEAR_MASK ", %%mm4 \n\t" // _HBClearMask -> mm4
-// preload "movl prev_row, %0 \n\t" // esi: Prior(x)
- RESTORE_rbp
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm2 \n\t" // load previous aligned 8 bytes
- // (NO NEED to correct pos. in loop below)
-
- "avg_8lp: \n\t"
- "movq (%1," PCX ",), %%mm0 \n\t"
- "movq %%mm5, %%mm3 \n\t"
- "movq (%0," PCX ",), %%mm1 \n\t"
- "addl $8, %%ecx \n\t"
- "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
- "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
- "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte
- // where both lsb's were == 1
- "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
- "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7, each byte
- "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg, each byte
- "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7, each byte
- "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg, each
- "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- "movq %%mm0, -8(%1," PCX ",) \n\t"
- "movq %%mm0, %%mm2 \n\t" // reuse as Raw(x-bpp)
- "jb avg_8lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2" // clobber list
- , "%mm3", "%mm4", "%mm5"
-#endif
- );
- }
- break; // end 8 bpp
-
- default: // bpp != 1,2,3,4,6,8: doesn't exist
- {
- // ERROR: SHOULD NEVER BE REACHED
-#if defined(PNG_DEBUG)
- png_debug(1, "Internal libpng logic error (GCC "
- "png_read_filter_row_mmx_avg())\n");
-#endif
- }
- break;
-
- } // end switch (bpp)
-
- __asm__ __volatile__ (
- // MMX acceleration complete; now do clean-up
- // check if any remaining bytes left to decode
-//pre "movl FullLength, %%edx \n\t"
-//pre "movl MMXLength, %%eax \n\t" // eax: x == offset bytes after MMX
-//pre "movl row, %2 \n\t" // edi: Avg(x)
- "cmpl %%edx, %%eax \n\t" // test if offset at end of array
- "jnb avg_end \n\t"
-
- SAVE_ebp
-
- // do Avg decode for remaining bytes
-//pre "movl prev_row, %1 \n\t" // esi: Prior(x)
- "mov %2, " PBP " \n\t" // copy of row pointer...
-//pre "subl bpp, " PBP " \n\t" // (bpp is preloaded into ecx)
- "sub " PCX "," PBP " \n\t" // ebp: Raw(x-bpp)
- "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below
-
- SAVE_GOT_ebx
-
- "avg_lp2: \n\t"
- // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
- "xorl %%ebx, %%ebx \n\t"
- "movb (%1," PAX ",), %%cl \n\t" // load cl with Prior(x)
- "movb (" PBP "," PAX ",), %%bl \n\t" // load bl with Raw(x-bpp)
- "addw %%cx, %%bx \n\t"
- "incl %%eax \n\t"
- "shrw %%bx \n\t" // divide by 2
- "addb -1(%2," PAX ",), %%bl \n\t" // add Avg(x); -1 to offset inc eax
- "cmpl %%edx, %%eax \n\t" // check if at end of array
- "movb %%bl, -1(%2," PAX ",) \n\t" // write back Raw(x) [mov does not
- "jb avg_lp2 \n\t" // affect flags; -1 to offset inc eax]
-
- RESTORE_GOT_ebx
- RESTORE_ebp
-
- "avg_end: \n\t"
- "EMMS \n\t" // end MMX; prep for poss. FP instrs.
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (dummy_value_a),
- "=d" (dummy_value_d)
-
- : "0" (bpp), // ecx // input regs
- "1" (prev_row), // esi/rsi
- "2" (row), // edi/rdi
- "3" (MMXLength), // eax
- "4" (FullLength) // edx
-
- CLOB_COLON_ebx_ebp // clobber list
- CLOBBER_GOT_ebx
- CLOB_COMMA_ebx_ebp
- CLOBBER_ebp
- );
-
-} /* end png_read_filter_row_mmx_avg() */
-
-#endif /* PNG_MMX_READ_FILTER_AVG_SUPPORTED */
-
-
-
-#if defined(PNG_MMX_READ_FILTER_PAETH_SUPPORTED)
-#if defined(PNG_x86_64_USE_GOTPCREL) || defined(PNG_THREAD_UNSAFE_OK)
-
-//===========================================================================//
-// //
-// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ P A E T H //
-// //
-//===========================================================================//
-
-// Optimized code for PNG Paeth filter decoder
-
-static void /* PRIVATE */
-png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row,
- png_bytep prev_row)
-{
- unsigned FullLength, MMXLength; // png_uint_32 is actually 64-bit on x86-64
- int bpp;
- int dummy_value_a;
- int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error
- int dummy_value_d;
- png_charp dummy_value_S;
- png_charp dummy_value_D;
- int diff; // __attribute__((used));
-
- bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel
- FullLength = row_info->rowbytes; // number of bytes to filter
-
- __asm__ __volatile__ (
- SAVE_GOT_ebx
- SAVE_r15
- SAVE_ebp
-//pre "movl row, %2 \n\t" // edi/rdi
- "xorl %%ebx, %%ebx \n\t" // ebx: x offset
-//pre "movl prev_row, %1 \n\t" // esi/rsi
- "xorl %%edx, %%edx \n\t" // edx: x-bpp offset
-//pre "movl FullLength, %%eax \n\t" // bring in via eax...
- SAVE_FullLength // ...but store for later use
- "xorl %%eax, %%eax \n\t"
-
- // Compute the Raw value for the first bpp bytes
- // Note: the formula works out to be always
- // Paeth(x) = Raw(x) + Prior(x) where x < bpp
- "paeth_rlp: \n\t"
- "movb (%2," PBX ",), %%al \n\t"
- "addb (%1," PBX ",), %%al \n\t"
- "incl %%ebx \n\t"
-//pre "cmpl bpp, %%ebx \n\t" (bpp is preloaded into ecx)
- "cmpl %%ecx, %%ebx \n\t"
- "movb %%al, -1(%2," PBX ",) \n\t"
- "jb paeth_rlp \n\t"
-
- // get # of bytes to alignment (note: computing _delta_ of two pointers,
- // so hereafter %%ebp is sufficient even on 64-bit)
- "mov %2, " PBP " \n\t" // take start of row
- "add " PBX "," PBP " \n\t" // add bpp
- "add $0xf, " PBP " \n\t" // add 7+8 to incr past alignment bdry
-// "andl $0xfffffff8, %%ebp \n\t" // mask to alignment boundary (32-bit!)
- CLEAR_BOTTOM_3_BITS PBP "\n\t" // mask to alignment boundary
- "sub %2, " PBP " \n\t" // subtract row ptr again => ebp =
- "jz paeth_go \n\t" // target value of ebx at alignment
-
- "xorl %%ecx, %%ecx \n\t"
-
- SAVE_r11_r12_r13
-
- // fix alignment
- "paeth_lp1: \n\t"
- "xorl %%eax, %%eax \n\t"
- // pav = p - a = (a + b - c) - a = b - c
- "movb (%1," PBX ",), %%al \n\t" // load Prior(x) into al
- "movb (%1," PDX ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
- "movl %%eax, " pa_TEMP " \n\t" // Save pav for later use
- "xorl %%eax, %%eax \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movb (%2," PDX ",), %%al \n\t" // load Raw(x-bpp) into al
- "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
- "movl %%eax, %%ecx \n\t"
- // pcv = p - c = (a + b - c) - c = (a - c) + (b - c) = pav + pbv
- "addl " pa_TEMP ", %%eax \n\t" // pcv = pav + pbv
- // pc = abs(pcv)
- "testl $0x80000000, %%eax \n\t"
- "jz paeth_pca \n\t"
- "negl %%eax \n\t" // reverse sign of neg values
-
- "paeth_pca: \n\t"
- "movl %%eax, " pc_TEMP " \n\t" // save pc for later use
- // pb = abs(pbv)
- "testl $0x80000000, %%ecx \n\t"
- "jz paeth_pba \n\t"
- "negl %%ecx \n\t" // reverse sign of neg values
-
- "paeth_pba: \n\t"
- "movl %%ecx, " pb_TEMP " \n\t" // save pb for later use
- // pa = abs(pav)
- "movl " pa_TEMP ", %%eax \n\t"
- "testl $0x80000000, %%eax \n\t"
- "jz paeth_paa \n\t"
- "negl %%eax \n\t" // reverse sign of neg values
-
- "paeth_paa: \n\t"
- "movl %%eax, " pa_TEMP " \n\t" // save pa for later use
- // test if pa <= pb
- "cmpl %%ecx, %%eax \n\t"
- "jna paeth_abb \n\t"
- // pa > pb; now test if pb <= pc
- "cmpl " pc_TEMP ", %%ecx \n\t"
- "jna paeth_bbc \n\t"
- // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- "movb (%1," PDX ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "jmp paeth_paeth \n\t"
-
- "paeth_bbc: \n\t"
- // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
- "movb (%1," PBX ",), %%cl \n\t" // load Prior(x) into cl
- "jmp paeth_paeth \n\t"
-
- "paeth_abb: \n\t"
- // pa <= pb; now test if pa <= pc
- "cmpl " pc_TEMP ", %%eax \n\t"
- "jna paeth_abc \n\t"
- // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- "movb (%1," PDX ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "jmp paeth_paeth \n\t"
-
- "paeth_abc: \n\t"
- // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
- "movb (%2," PDX ",), %%cl \n\t" // load Raw(x-bpp) into cl
-
- "paeth_paeth: \n\t"
- "incl %%ebx \n\t"
- "incl %%edx \n\t"
- // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
- "addb %%cl, -1(%2," PBX ",) \n\t"
- "cmpl %%ebp, %%ebx \n\t"
- "jb paeth_lp1 \n\t"
-
- RESTORE_r11_r12_r13
-
- "paeth_go: \n\t"
- RESTORE_FullLength "%%ecx \n\t" // FullLength -> ecx
- "movl %%ecx, %%eax \n\t"
- "subl %%ebx, %%eax \n\t" // subtract alignment fix
- "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8
- "subl %%eax, %%ecx \n\t" // drop over bytes from original length
-//out "movl %%ecx, MMXLength \n\t"
- "movl %%ebp, %%eax \n\t" // ebp = diff, but no reg constraint(?)
- RESTORE_ebp // (could swap ebp and edx functions)
- RESTORE_r15
- RESTORE_GOT_ebx
-
- : "=c" (MMXLength), // output regs
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (diff)
-
- : "0" (bpp), // ecx // input regs
- "1" (prev_row), // esi/rsi
- "2" (row), // edi/rdi
- "3" (FullLength) // eax
-
- : "%edx" // clobber list
- _CLOBBER_r11_r12_r13
- _CLOBBER_r15
- _CLOBBER_ebp
- _CLOBBER_GOT_ebx
- );
-
- // now do the math for the rest of the row
- switch (bpp)
- {
- case 3:
- {
-// _ShiftBpp = 24; // == bpp * 8
-// _ShiftRem = 40; // == 64 - _ShiftBpp
-
- __asm__ __volatile__ (
- LOAD_GOT_rbp
-// preload "movl diff, %%ecx \n\t"
-// preload "movl row, %1 \n\t" // edi/rdi
-// preload "movl prev_row, %0 \n\t" // esi/rsi
- "pxor %%mm0, %%mm0 \n\t"
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm1 \n\t"
- "paeth_3lp: \n\t"
- "psrlq $40, %%mm1 \n\t" // shift last 3 bytes to 1st
- // 3 bytes
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x)
- "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
- "movq -8(%0," PCX ",), %%mm3 \n\t" // prep c=Prior(x-bpp) bytes
- "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
- "psrlq $40, %%mm3 \n\t" // shift last 3 bytes to 1st
- // 3 bytes
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
-
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "packuswb %%mm1, %%mm7 \n\t"
- "movq (%0," PCX ",), %%mm3 \n\t" // load c=Prior(x-bpp)
- "pand " AMASK5_3_0 ", %%mm7 \n\t" // _amask5_3_0 (was _ActiveMask)
- "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1
- "paddb (%1," PCX ",), %%mm7 \n\t" // add Paeth predictor + Raw(x)
- "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- "movq %%mm7, (%1," PCX ",) \n\t" // write back updated value
- "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as
- // Raw(x-bpp)
- // now do Paeth for 2nd set of bytes (3-5)
- "psrlq $24, %%mm2 \n\t" // load b=Prior(x) step 2
- "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
- "pxor %%mm7, %%mm7 \n\t"
- "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) =
- // pav + pbv = pbv + pav
- "movq %%mm5, %%mm6 \n\t"
- "paddw %%mm4, %%mm6 \n\t"
-
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm5, %%mm0 \n\t" // create mask pbv bytes < 0
- "pcmpgtw %%mm4, %%mm7 \n\t" // create mask pav bytes < 0
- "pand %%mm5, %%mm0 \n\t" // only pbv bytes < 0 in mm0
- "pand %%mm4, %%mm7 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm0, %%mm5 \n\t"
- "psubw %%mm7, %%mm4 \n\t"
- "psubw %%mm0, %%mm5 \n\t"
- "psubw %%mm7, %%mm4 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x)
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "pxor %%mm1, %%mm1 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "packuswb %%mm1, %%mm7 \n\t"
- "movq %%mm2, %%mm3 \n\t" // load c=Prior(x-bpp) step 1
- "pand " AMASK5_3_0 ", %%mm7 \n\t" // _amask5_3_0 (was _ActiveMask)
- "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
- "psllq $24, %%mm7 \n\t" // shift bytes to 2nd group of
- // 3 bytes
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- "paddb (%1," PCX ",), %%mm7 \n\t" // add Paeth predictor + Raw(x)
- "psllq $24, %%mm3 \n\t" // load c=Prior(x-bpp) step 2
- "movq %%mm7, (%1," PCX ",) \n\t" // write back updated value
- "movq %%mm7, %%mm1 \n\t"
- "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- "psllq $24, %%mm1 \n\t" // shift bytes (was _ShiftBpp)
- // now mm1 will be used as Raw(x-bpp)
- // now do Paeth for 3rd, and final, set of bytes (6-7)
- "pxor %%mm7, %%mm7 \n\t"
- "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
- "psubw %%mm3, %%mm4 \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "paddw %%mm5, %%mm6 \n\t"
-
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm1, %%mm1 \n\t"
- "packuswb %%mm7, %%mm1 \n\t"
- // step ecx to next set of 8 bytes and repeat loop til done
- "addl $8, %%ecx \n\t"
- "pand " AMASK0_2_6 ", %%mm1 \n\t" // _amask0_2_6 (_ActiveMaskEnd)
- "paddb -8(%1," PCX ",), %%mm1 \n\t" // add Paeth predictor + Raw(x)
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- "pxor %%mm0, %%mm0 \n\t" // pxor does not affect flags
- "movq %%mm1, -8(%1," PCX ",) \n\t" // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- // mm3 ready to be used as Prior(x-bpp) next loop
- "jb paeth_3lp \n\t"
- RESTORE_rbp
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 3 bpp
-
- case 4:
- {
- __asm__ __volatile__ (
-// preload "movl diff, %%ecx \n\t"
-// preload "movl row, %1 \n\t" // edi/rdi
-// preload "movl prev_row, %0 \n\t" // esi/rsi
- "pxor %%mm0, %%mm0 \n\t"
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm1 \n\t" // only time should need to read
- // a=Raw(x-bpp) bytes
- "paeth_4lp: \n\t"
- // do first set of 4 bytes
- "movq -8(%0," PCX ",), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
- "punpckhbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x)
- "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "packuswb %%mm1, %%mm7 \n\t"
- "movq (%0," PCX ",), %%mm3 \n\t" // load c=Prior(x-bpp)
- LOAD_GOT_rbp
- "pand " AMASK4_4_0 ", %%mm7 \n\t" // _amask4_4_0 (was _ActiveMask)
- RESTORE_rbp
- "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1
- "paddb (%1," PCX ",), %%mm7 \n\t" // add Paeth predictor + Raw(x)
- "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- "movq %%mm7, (%1," PCX ",) \n\t" // write back updated value
- "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as
- // Raw(x-bpp)
- // do second set of 4 bytes
- "punpckhbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b
- "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "pxor %%mm1, %%mm1 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- // step ecx to next set of 8 bytes and repeat loop til done
- "addl $8, %%ecx \n\t"
- "packuswb %%mm7, %%mm1 \n\t"
- "paddb -8(%1," PCX ",), %%mm1 \n\t" // add predictor with Raw(x)
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- "movq %%mm1, -8(%1," PCX ",) \n\t" // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- "jb paeth_4lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 4 bpp
-
- case 1:
- case 2:
- {
- __asm__ __volatile__ (
-// preload "movl diff, %%eax \n\t" // eax: x = offset to align. bdry
-// preload "movl FullLength, %%edx \n\t"
- "cmpl %%edx, %%eax \n\t"
- "jnb paeth_dend \n\t"
-
- SAVE_ebp
-
-// preload "movl row, %2 \n\t" // edi/rdi
- // do Paeth decode for remaining bytes
-// preload "movl prev_row, %1 \n\t" // esi/rsi
- "movl %%eax, %%ebp \n\t"
-// preload "subl bpp, %%ebp \n\t" // (bpp is preloaded into ecx)
- "subl %%ecx, %%ebp \n\t" // ebp = eax - bpp
- "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx
-
- SAVE_GOT_ebx
- SAVE_r11_r12_r13
-
- "paeth_dlp: \n\t"
- "xorl %%ebx, %%ebx \n\t"
- // pav = p - a = (a + b - c) - a = b - c
- "movb (%1," PAX ",), %%bl \n\t" // load Prior(x) into bl
- "movb (%1," PBP ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "subl %%ecx, %%ebx \n\t" // subtract Prior(x-bpp)
- "movl %%ebx, " pa_TEMP " \n\t" // Save pav for later use
- "xorl %%ebx, %%ebx \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movb (%2," PBP ",), %%bl \n\t" // load Raw(x-bpp) into bl
- "subl %%ecx, %%ebx \n\t" // subtract Prior(x-bpp)
- "movl %%ebx, %%ecx \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "addl " pa_TEMP ", %%ebx \n\t" // pcv = pav + pbv
- // pc = abs(pcv)
- "testl $0x80000000, %%ebx \n\t"
- "jz paeth_dpca \n\t"
- "negl %%ebx \n\t" // reverse sign of neg values
-
- "paeth_dpca: \n\t"
- "movl %%ebx, " pc_TEMP " \n\t" // save pc for later use
- // pb = abs(pbv)
- "testl $0x80000000, %%ecx \n\t"
- "jz paeth_dpba \n\t"
- "negl %%ecx \n\t" // reverse sign of neg values
-
- "paeth_dpba: \n\t"
- "movl %%ecx, " pb_TEMP " \n\t" // save pb for later use
- // pa = abs(pav)
- "movl " pa_TEMP ", %%ebx \n\t"
- "testl $0x80000000, %%ebx \n\t"
- "jz paeth_dpaa \n\t"
- "negl %%ebx \n\t" // reverse sign of neg values
-
- "paeth_dpaa: \n\t"
- "movl %%ebx, " pa_TEMP " \n\t" // save pa for later use
- // test if pa <= pb
- "cmpl %%ecx, %%ebx \n\t"
- "jna paeth_dabb \n\t"
- // pa > pb; now test if pb <= pc
- "cmpl " pc_TEMP ", %%ecx \n\t"
- "jna paeth_dbbc \n\t"
- // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- "movb (%1," PBP ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "jmp paeth_dpaeth \n\t"
-
- "paeth_dbbc: \n\t"
- // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
- "movb (%1," PAX ",), %%cl \n\t" // load Prior(x) into cl
- "jmp paeth_dpaeth \n\t"
-
- "paeth_dabb: \n\t"
- // pa <= pb; now test if pa <= pc
- "cmpl " pc_TEMP ", %%ebx \n\t"
- "jna paeth_dabc \n\t"
- // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- "movb (%1," PBP ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "jmp paeth_dpaeth \n\t"
-
- "paeth_dabc: \n\t"
- // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
- "movb (%2," PBP ",), %%cl \n\t" // load Raw(x-bpp) into cl
-
- "paeth_dpaeth: \n\t"
- "incl %%eax \n\t"
- "incl %%ebp \n\t"
- // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
- "addb %%cl, -1(%2," PAX ",) \n\t"
- "cmpl %%edx, %%eax \n\t" // check against FullLength
- "jb paeth_dlp \n\t"
-
- RESTORE_r11_r12_r13
- RESTORE_GOT_ebx
- RESTORE_ebp
-
- "paeth_dend: \n\t"
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (dummy_value_a),
- "=d" (dummy_value_d)
-
- : "0" (bpp), // ecx // input regs
- "1" (prev_row), // esi/rsi
- "2" (row), // edi/rdi
- "3" (diff), // eax
- "4" (FullLength) // edx
-
- CLOB_COLON_ebx_ebp_r1X // clobber list
- CLOBBER_GOT_ebx
- CLOB_COMMA_ebx_ebp
- CLOBBER_ebp
- CLOB_COMMA_ebX_r1X
- CLOBBER_r11_r12_r13
- );
- }
- return; // end 1 or 2 bpp (no need to go further with this one)
-
- case 6:
- {
-// _ActiveMask2 = 0xffffffff00000000LL; // NOT USED ("_amask_0_4_4")
-// _ShiftBpp = 48; // bpp << 3 == bpp * 8
-// _ShiftRem = 16; // 64 - _ShiftBpp
-
- __asm__ __volatile__ (
-// preload "movl diff, %%ecx \n\t"
-// preload "movl row, %1 \n\t" // edi/rdi
-// preload "movl prev_row, %0 \n\t" // esi/rsi
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm1 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
-
- "paeth_6lp: \n\t"
- // must shift to position Raw(x-bpp) data
- "psrlq $16, %%mm1 \n\t" // was _ShiftRem
- // do first set of 4 bytes
- "movq -8(%0," PCX ",), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
- "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x)
- "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b
- // must shift to position Prior(x-bpp) data
- "psrlq $16, %%mm3 \n\t" // was _ShiftRem
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "packuswb %%mm1, %%mm7 \n\t"
- "movq -8(%0," PCX ",), %%mm3 \n\t" // load c=Prior(x-bpp)
- LOAD_GOT_rbp
- "pand " AMASK4_4_0 ", %%mm7 \n\t" // _amask4_4_0 (was _ActiveMask)
- RESTORE_rbp
- "psrlq $16, %%mm3 \n\t"
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x) step 1
- "paddb (%1," PCX ",), %%mm7 \n\t" // add Paeth predictor + Raw(x)
- "movq %%mm2, %%mm6 \n\t"
- "movq %%mm7, (%1," PCX ",) \n\t" // write back updated value
- "movq -8(%1," PCX ",), %%mm1 \n\t"
- "psllq $48, %%mm6 \n\t" // bpp * 8 = bits per pixel
- "movq %%mm7, %%mm5 \n\t"
- "psrlq $16, %%mm1 \n\t" // 64 - (bpp * 8) = remainder
- "por %%mm6, %%mm3 \n\t"
- "psllq $48, %%mm5 \n\t" // was _ShiftBpp
- "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- "por %%mm5, %%mm1 \n\t"
- // do second set of 4 bytes
- "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
- "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "pxor %%mm1, %%mm1 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- // step ecx to next set of 8 bytes and repeat loop til done
- "addl $8, %%ecx \n\t"
- "packuswb %%mm7, %%mm1 \n\t"
- "paddb -8(%1," PCX ",), %%mm1 \n\t" // add Paeth predictor + Raw(x)
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- "movq %%mm1, -8(%1," PCX ",) \n\t" // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- "jb paeth_6lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 6 bpp
-
- case 8: // bpp == 8
- {
- __asm__ __volatile__ (
-// preload "movl diff, %%ecx \n\t"
-// preload "movl row, %1 \n\t" // edi/rdi
-// preload "movl prev_row, %0 \n\t" // esi/rsi
- "pxor %%mm0, %%mm0 \n\t"
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PCX ",), %%mm1 \n\t" // only time should need to read
- // a=Raw(x-bpp) bytes
- "paeth_8lp: \n\t"
- // do first set of 4 bytes
- "movq -8(%0," PCX ",), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
- "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x)
- "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "packuswb %%mm1, %%mm7 \n\t"
- "movq -8(%0," PCX ",), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
- LOAD_GOT_rbp
- "pand " AMASK4_4_0 ", %%mm7 \n\t" // _amask4_4_0 (was _ActiveMask)
- RESTORE_rbp
- "movq (%0," PCX ",), %%mm2 \n\t" // load b=Prior(x)
- "paddb (%1," PCX ",), %%mm7 \n\t" // add Paeth predictor + Raw(x)
- "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
- "movq %%mm7, (%1," PCX ",) \n\t" // write back updated value
- "movq -8(%1," PCX ",), %%mm1 \n\t" // read a=Raw(x-bpp) bytes
-
- // do second set of 4 bytes
- "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
- "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
- // pav = p - a = (a + b - c) - a = b - c
- "movq %%mm2, %%mm4 \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movq %%mm1, %%mm5 \n\t"
- "psubw %%mm3, %%mm4 \n\t"
- "pxor %%mm7, %%mm7 \n\t"
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- "movq %%mm4, %%mm6 \n\t"
- "psubw %%mm3, %%mm5 \n\t"
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- "pcmpgtw %%mm4, %%mm0 \n\t" // create mask pav bytes < 0
- "paddw %%mm5, %%mm6 \n\t"
- "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "pcmpgtw %%mm5, %%mm7 \n\t" // create mask pbv bytes < 0
- "psubw %%mm0, %%mm4 \n\t"
- "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
- "psubw %%mm0, %%mm4 \n\t"
- "psubw %%mm7, %%mm5 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- "pcmpgtw %%mm6, %%mm0 \n\t" // create mask pcv bytes < 0
- "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
- "psubw %%mm7, %%mm5 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- // test pa <= pb
- "movq %%mm4, %%mm7 \n\t"
- "psubw %%mm0, %%mm6 \n\t"
- "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
- "movq %%mm7, %%mm0 \n\t"
- // use mm7 mask to merge pa & pb
- "pand %%mm7, %%mm5 \n\t"
- // use mm0 mask copy to merge a & b
- "pand %%mm0, %%mm2 \n\t"
- "pandn %%mm4, %%mm7 \n\t"
- "pandn %%mm1, %%mm0 \n\t"
- "paddw %%mm5, %%mm7 \n\t"
- "paddw %%mm2, %%mm0 \n\t"
- // test ((pa <= pb)? pa:pb) <= pc
- "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
- "pxor %%mm1, %%mm1 \n\t"
- "pand %%mm7, %%mm3 \n\t"
- "pandn %%mm0, %%mm7 \n\t"
- "pxor %%mm1, %%mm1 \n\t"
- "paddw %%mm3, %%mm7 \n\t"
- "pxor %%mm0, %%mm0 \n\t"
- // step ecx to next set of 8 bytes and repeat loop til done
- "addl $8, %%ecx \n\t"
- "packuswb %%mm7, %%mm1 \n\t"
- "paddb -8(%1," PCX ",), %%mm1 \n\t" // add Paeth predictor + Raw(x)
- "cmpl %%eax, %%ecx \n\t" // MMXLength
- "movq %%mm1, -8(%1," PCX ",) \n\t" // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- "jb paeth_8lp \n\t"
-
- : "=S" (dummy_value_S), // output regs (dummy)
- "=D" (dummy_value_D),
- "=c" (dummy_value_c),
- "=a" (dummy_value_a)
-
- : "0" (prev_row), // esi/rsi // input regs
- "1" (row), // edi/rdi
- "2" (diff), // ecx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 8 bpp
-
- default: // bpp != 1,2,3,4,6,8: doesn't exist
- {
- // ERROR: SHOULD NEVER BE REACHED
-#if defined(PNG_DEBUG)
- png_debug(1, "Internal libpng logic error (GCC "
- "png_read_filter_row_mmx_paeth())\n");
-#endif
- }
- break;
-
- } // end switch (bpp)
-
- __asm__ __volatile__ (
- // MMX acceleration complete; now do clean-up
- // check if any remaining bytes left to decode
-//pre "movl FullLength, %%edx \n\t"
-//pre "movl MMXLength, %%eax \n\t"
- "cmpl %%edx, %%eax \n\t"
- "jnb paeth_end \n\t"
-
- SAVE_ebp
-
-//pre "movl row, %2 \n\t" // edi/rdi
-//pre "movl prev_row, %1 \n\t" // esi/rsi
- // do Paeth decode for remaining bytes
- "movl %%eax, %%ebp \n\t"
-//pre "subl bpp, %%ebp \n\t" // (bpp is preloaded into ecx)
- "subl %%ecx, %%ebp \n\t" // ebp = eax - bpp
- "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below
-
- SAVE_GOT_ebx
- SAVE_r11_r12_r13
-
- "paeth_lp2: \n\t"
- "xorl %%ebx, %%ebx \n\t"
- // pav = p - a = (a + b - c) - a = b - c
- "movb (%1," PAX ",), %%bl \n\t" // load Prior(x) into bl
- "movb (%1," PBP ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "subl %%ecx, %%ebx \n\t" // subtract Prior(x-bpp)
- "movl %%ebx, " pa_TEMP " \n\t" // Save pav for later use
- "xorl %%ebx, %%ebx \n\t"
- // pbv = p - b = (a + b - c) - b = a - c
- "movb (%2," PBP ",), %%bl \n\t" // load Raw(x-bpp) into bl
- "subl %%ecx, %%ebx \n\t" // subtract Prior(x-bpp)
- "movl %%ebx, %%ecx \n\t"
- // pcv = p - c = (a + b - c) - c = (a - c) + (b - c) = pav + pbv
- "addl " pa_TEMP ", %%ebx \n\t" // pcv = pav + pbv
- // pc = abs(pcv)
- "testl $0x80000000, %%ebx \n\t"
- "jz paeth_pca2 \n\t"
- "negl %%ebx \n\t" // reverse sign of neg values
-
- "paeth_pca2: \n\t"
- "movl %%ebx, " pc_TEMP " \n\t" // save pc for later use
- // pb = abs(pbv)
- "testl $0x80000000, %%ecx \n\t"
- "jz paeth_pba2 \n\t"
- "negl %%ecx \n\t" // reverse sign of neg values
-
- "paeth_pba2: \n\t"
- "movl %%ecx, " pb_TEMP " \n\t" // save pb for later use
- // pa = abs(pav)
- "movl " pa_TEMP ", %%ebx \n\t"
- "testl $0x80000000, %%ebx \n\t"
- "jz paeth_paa2 \n\t"
- "negl %%ebx \n\t" // reverse sign of neg values
-
- "paeth_paa2: \n\t"
- "movl %%ebx, " pa_TEMP " \n\t" // save pa for later use
- // test if pa <= pb
- "cmpl %%ecx, %%ebx \n\t"
- "jna paeth_abb2 \n\t"
- // pa > pb; now test if pb <= pc
- "cmpl " pc_TEMP ", %%ecx \n\t"
- "jna paeth_bbc2 \n\t"
- // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- "movb (%1," PBP ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "jmp paeth_paeth2 \n\t"
-
- "paeth_bbc2: \n\t"
- // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
- "movb (%1," PAX ",), %%cl \n\t" // load Prior(x) into cl
- "jmp paeth_paeth2 \n\t"
-
- "paeth_abb2: \n\t"
- // pa <= pb; now test if pa <= pc
- "cmpl " pc_TEMP ", %%ebx \n\t"
- "jna paeth_abc2 \n\t"
- // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- "movb (%1," PBP ",), %%cl \n\t" // load Prior(x-bpp) into cl
- "jmp paeth_paeth2 \n\t"
-
- "paeth_abc2: \n\t"
- // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
- "movb (%2," PBP ",), %%cl \n\t" // load Raw(x-bpp) into cl
-
- "paeth_paeth2: \n\t"
- "incl %%eax \n\t"
- "incl %%ebp \n\t"
- // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
- "addb %%cl, -1(%2," PAX ",) \n\t"
- "cmpl %%edx, %%eax \n\t" // check against FullLength
- "jb paeth_lp2 \n\t"
-
- RESTORE_r11_r12_r13
- RESTORE_GOT_ebx
- RESTORE_ebp
-
- "paeth_end: \n\t"
- "EMMS \n\t" // end MMX; prep for poss. FP instrs.
-
- : "=c" (dummy_value_c), // output regs (dummy)
- "=S" (dummy_value_S),
- "=D" (dummy_value_D),
- "=a" (dummy_value_a),
- "=d" (dummy_value_d)
-
- : "0" (bpp), // ecx // input regs
- "1" (prev_row), // esi/rsi
- "2" (row), // edi/rdi
- "3" (MMXLength), // eax
- "4" (FullLength) // edx
-
- CLOB_COLON_ebx_ebp_r1X // clobber list
- CLOBBER_GOT_ebx
- CLOB_COMMA_ebx_ebp
- CLOBBER_ebp
- CLOB_COMMA_ebX_r1X
- CLOBBER_r11_r12_r13
- );
-
-} /* end png_read_filter_row_mmx_paeth() */
-
-#endif // PNG_x86_64_USE_GOTPCREL || PNG_THREAD_UNSAFE_OK
-#endif /* PNG_MMX_READ_FILTER_PAETH_SUPPORTED */
-
-
-
-
-#if defined(PNG_MMX_READ_FILTER_SUB_SUPPORTED)
-
-//===========================================================================//
-// //
-// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ S U B //
-// //
-//===========================================================================//
-
-// Optimized code for PNG Sub filter decoder
-
-static void /* PRIVATE */
-png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row)
-{
- unsigned FullLength, MMXLength; // png_uint_32 is actually 64-bit on x86-64
- int bpp;
- int dummy_value_a;
- int dummy_value_c;
- int dummy_value_d;
- png_bytep dummy_value_D;
- int diff; // __attribute__((used));
-
- bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel
- FullLength = row_info->rowbytes - bpp; // number of bytes to filter
- // (why do we subtract off bpp? not so in avg or paeth...)
-
- __asm__ __volatile__ (
- SAVE_r15
- SAVE_ebp
-//pre "movl row, %1 \n\t" // edi/rdi
- "mov %1, " PSI " \n\t" // lp = row
-//pre "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
-//pre "movl FullLength, %%eax \n\t" // bring in via eax...
- SAVE_FullLength // ...but store for later use
-
- "xorl %%eax, %%eax \n\t"
-
- // get # of bytes to alignment (note: computing _delta_ of two pointers,
- // so hereafter %%ebp is sufficient even on 64-bit)
- "mov %1, " PBP " \n\t" // take start of row
- "add $0xf, " PBP " \n\t" // add 7+8 to incr past alignment bdry
-// "andl $0xfffffff8, %%ebp \n\t" // mask to alignment boundary (32-bit!)
- CLEAR_BOTTOM_3_BITS PBP "\n\t" // mask to alignment boundary
- "sub %1, " PBP " \n\t" // subtract row ptr again => ebp =
- "jz sub_go \n\t" // target value of eax at alignment
-
- "sub_lp1: \n\t" // fix alignment
- "movb (" PSI "," PAX ",), %%cl \n\t"
- "addb %%cl, (%1," PAX ",) \n\t"
- "incl %%eax \n\t"
- "cmpl %%ebp, %%eax \n\t"
- "jb sub_lp1 \n\t"
-
- "sub_go: \n\t"
- RESTORE_FullLength "%%ecx \n\t" // FullLength -> ecx
- "movl %%ecx, %%edx \n\t"
- "subl %%eax, %%edx \n\t" // subtract alignment fix
- "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8
- "subl %%edx, %%ecx \n\t" // drop over bytes from length
-//out "movl %%ecx, MMXLength \n\t"
- "movl %%ebp, %%eax \n\t" // ebp = diff, but no reg constraint(?)
- RESTORE_ebp // (could swap ebp and ecx functions,
- RESTORE_r15 // but %%cl issues...)
-
- : "=c" (MMXLength), // 0 // output regs
- "=D" (dummy_value_D), // 1
- "=a" (diff) // 2
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (FullLength) // eax
-
- : "%esi", "%edx" // clobber list
- _CLOBBER_r15
- _CLOBBER_ebp
- );
-
- // now do the math for the rest of the row
- switch (bpp)
- {
- case 3:
- {
-// _ShiftBpp = 24; // == 3 * 8
-// _ShiftRem = 40; // == 64 - 24
-
- __asm__ __volatile__ (
-// preload "mov row, %1 \n\t" // edi/rdi
- LOAD_GOT_rbp
- // load (former) _ActiveMask for 2nd active byte group
- "movq " AMASK2_3_3 ", %%mm7 \n\t" // _amask2_3_3
- RESTORE_rbp
-
-// notused "mov %1, " PSI " \n\t" // lp = row
-// preload "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
- "movq %%mm7, %%mm6 \n\t"
-// preload "movl diff, %%edx \n\t"
- "psllq $24, %%mm6 \n\t" // move mask in mm6 to cover
- // 3rd active byte group
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PDX ",), %%mm1 \n\t"
-
- "sub_3lp: \n\t" // shift data for adding first
- "psrlq $40, %%mm1 \n\t" // bpp bytes (no need for mask;
- // shift clears inactive bytes)
- // add 1st active group
- "movq (%1," PDX ",), %%mm0 \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 2nd active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $24, %%mm1 \n\t" // shift data to pos. correctly
- "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 3rd active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $24, %%mm1 \n\t" // shift data to pos. correctly
- "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group
- "addl $8, %%edx \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- "cmpl %%eax, %%edx \n\t" // MMXLength
- "movq %%mm0, -8(%1," PDX ",) \n\t" // write updated Raws to array
- "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
- "jb sub_3lp \n\t"
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=d" (dummy_value_d), // 2
- "=a" (dummy_value_a) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (diff), // edx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm6", "%mm7" // clobber list
-#endif
- );
- }
- break; // end 3 bpp
-
- case 4: // formerly shared with 6 bpp case via _ShiftBpp and _ShiftRem,
- { // but 64-bit PIC/.so problems (could still share, moving vars
- // into unused MMX regs via ecx/edx, but kludgy)
-// _ShiftBpp = bpp << 3; // 32 (psllq)
-// _ShiftRem = 64 - _ShiftBpp; // 32 (psrlq)
-
- __asm__ __volatile__ (
-// preload "mov row, %1 \n\t" // edi/rdi
-// preload "movl diff, %%edx \n\t"
-// notused "mov %1, " PSI " \n\t" // lp = row
-// preload "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PDX ",), %%mm1 \n\t"
-
- "sub_4lp: \n\t" // shift data for adding first
- "psrlq $32, %%mm1 \n\t" // bpp bytes (no need for mask;
- // shift clears inactive bytes)
- "movq (%1," PDX ",), %%mm0 \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 2nd active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $32, %%mm1 \n\t" // shift data to pos. correctly
- "addl $8, %%edx \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- "cmpl %%eax, %%edx \n\t" // MMXLength
- "movq %%mm0, -8(%1," PDX ",) \n\t" // write updated Raws to array
- "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
- "jb sub_4lp \n\t"
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=d" (dummy_value_d), // 2
- "=a" (dummy_value_a) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (diff), // edx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
- break; // end 4 bpp
-
- case 1:
- {
- __asm__ __volatile__ (
-// preload "movl diff, %%edx \n\t"
-// preload "mov row, %1 \n\t" // edi/rdi
-// preload "cmpl FullLength, %%edx \n\t"
- "cmpl %%eax, %%edx \n\t"
- "jnb sub_1end \n\t"
- "mov %1, " PSI " \n\t" // lp = row
-// irrel. "xorl %%ecx, %%ecx \n\t" // (actually bug with preload)
-// preload "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
-
- "sub_1lp: \n\t"
- "movb (" PSI "," PDX ",), %%cl \n\t"
- "addb %%cl, (%1," PDX ",) \n\t"
- "incl %%edx \n\t"
- "cmpl %%eax, %%edx \n\t" // compare with FullLength
- "jb sub_1lp \n\t"
-
- "sub_1end: \n\t"
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=d" (dummy_value_d), // 2
- "=a" (dummy_value_a) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (diff), // edx
- "3" (FullLength) // eax
-
- : "%esi" // clobber list
- );
- }
- return; // end 1 bpp (bypassing cleanup block!)
-
- case 2:
- {
-// _ShiftBpp = 16; // == 2 * 8
-// _ShiftRem = 48; // == 64 - 16
-
- __asm__ __volatile__ (
- LOAD_GOT_rbp
- // load (former) _ActiveMask for 2nd active byte group
- "movq " AMASK4_2_2 ", %%mm7 \n\t" // _amask4_2_2
- RESTORE_rbp
-// preload "movl diff, %%edx \n\t"
- "movq %%mm7, %%mm6 \n\t"
-// preload "mov row, %1 \n\t" // edi/rdi
- "psllq $16, %%mm6 \n\t" // move mask in mm6 to cover
- // 3rd active byte group
-// notused "mov %1, " PSI " \n\t" // lp = row
- "movq %%mm6, %%mm5 \n\t"
-// preload "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
- "psllq $16, %%mm5 \n\t" // move mask in mm5 to cover
- // 4th active byte group
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PDX ",), %%mm1 \n\t"
-
- "sub_2lp: \n\t" // shift data for adding first
- "psrlq $48, %%mm1 \n\t" // bpp bytes (no need for mask;
- // shift clears inactive bytes)
- // add 1st active group
- "movq (%1," PDX ",), %%mm0 \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 2nd active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $16, %%mm1 \n\t" // shift data to pos. correctly
- "pand %%mm7, %%mm1 \n\t" // mask to use 2nd active group
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 3rd active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $16, %%mm1 \n\t" // shift data to pos. correctly
- "pand %%mm6, %%mm1 \n\t" // mask to use 3rd active group
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 4th active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $16, %%mm1 \n\t" // shift data to pos. correctly
- "pand %%mm5, %%mm1 \n\t" // mask to use 4th active group
- "addl $8, %%edx \n\t"
- "paddb %%mm1, %%mm0 \n\t"
- "cmpl %%eax, %%edx \n\t" // MMXLength
- "movq %%mm0, -8(%1," PDX ",) \n\t" // write updated Raws to array
- "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
- "jb sub_2lp \n\t"
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=d" (dummy_value_d), // 2
- "=a" (dummy_value_a) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (diff), // edx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1", "%mm5", "%mm6" // clobber list
- , "%mm7"
-#endif
- );
- }
- break; // end 2 bpp
-
- case 6: // formerly shared with 4 bpp case (see comments there)
- {
-// _ShiftBpp = bpp << 3; // 48 (psllq)
-// _ShiftRem = 64 - _ShiftBpp; // 16 (psrlq)
-
- __asm__ __volatile__ (
-// preload "mov row, %1 \n\t" // edi/rdi
-// preload "movl diff, %%edx \n\t"
-// notused "mov %1, " PSI " \n\t" // lp = row
-// preload "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PDX ",), %%mm1 \n\t"
-
- "sub_6lp: \n\t" // shift data for adding first
- "psrlq $16, %%mm1 \n\t" // bpp bytes (no need for mask;
- // shift clears inactive bytes)
- "movq (%1," PDX ",), %%mm0 \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- // add 2nd active group
- "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
- "psllq $48, %%mm1 \n\t" // shift data to pos. correctly
- "addl $8, %%edx \n\t"
- "paddb %%mm1, %%mm0 \n\t"
-
- "cmpl %%eax, %%edx \n\t" // MMXLength
- "movq %%mm0, -8(%1," PDX ",) \n\t" // write updated Raws to array
- "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
- "jb sub_6lp \n\t"
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=d" (dummy_value_d), // 2
- "=a" (dummy_value_a) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (diff), // edx
- "3" (MMXLength) // eax
-
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- : "%mm0", "%mm1" // clobber list
-#endif
- );
- }
- break; // end 6 bpp
-
- case 8:
- {
- __asm__ __volatile__ (
-// preload "mov row, %1 \n\t" // edi/rdi
-// preload "movl diff, %%edx \n\t"
-// notused "mov %1, " PSI " \n\t" // lp = row
-// preload "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
-// preload "movl MMXLength, %%eax \n\t"
-
- // prime the pump: load the first Raw(x-bpp) data set
- "movq -8(%1," PDX ",), %%mm7 \n\t"
- "movl %%eax, %%esi \n\t" // copy of MMXLength -> esi
- "andl $0x0000003f, %%esi \n\t" // calc bytes over mult of 64
-
- "sub_8lp: \n\t"
- "movq (%1," PDX ",), %%mm0 \n\t" // load Sub(x) for 1st 8 bytes
- "paddb %%mm7, %%mm0 \n\t"
- "movq 8(%1," PDX ",), %%mm1 \n\t" // load Sub(x) for 2nd 8 bytes
- "movq %%mm0, (%1," PDX ",) \n\t" // write Raw(x) for 1st 8 bytes
-
- // Now mm0 will be used as Raw(x-bpp) for the 2nd group of 8 bytes.
- // This will be repeated for each group of 8 bytes with the 8th
- // group being used as the Raw(x-bpp) for the 1st group of the
- // next loop.
-
- "paddb %%mm0, %%mm1 \n\t"
- "movq 16(%1," PDX ",), %%mm2 \n\t" // load Sub(x) for 3rd 8 bytes
- "movq %%mm1, 8(%1," PDX ",) \n\t" // write Raw(x) for 2nd 8 bytes
- "paddb %%mm1, %%mm2 \n\t"
- "movq 24(%1," PDX ",), %%mm3 \n\t" // load Sub(x) for 4th 8 bytes
- "movq %%mm2, 16(%1," PDX ",) \n\t" // write Raw(x) for 3rd 8 bytes
- "paddb %%mm2, %%mm3 \n\t"
- "movq 32(%1," PDX ",), %%mm4 \n\t" // load Sub(x) for 5th 8 bytes
- "movq %%mm3, 24(%1," PDX ",) \n\t" // write Raw(x) for 4th 8 bytes
- "paddb %%mm3, %%mm4 \n\t"
- "movq 40(%1," PDX ",), %%mm5 \n\t" // load Sub(x) for 6th 8 bytes
- "movq %%mm4, 32(%1," PDX ",) \n\t" // write Raw(x) for 5th 8 bytes
- "paddb %%mm4, %%mm5 \n\t"
- "movq 48(%1," PDX ",), %%mm6 \n\t" // load Sub(x) for 7th 8 bytes
- "movq %%mm5, 40(%1," PDX ",) \n\t" // write Raw(x) for 6th 8 bytes
- "paddb %%mm5, %%mm6 \n\t"
- "movq 56(%1," PDX ",), %%mm7 \n\t" // load Sub(x) for 8th 8 bytes
- "movq %%mm6, 48(%1," PDX ",) \n\t" // write Raw(x) for 7th 8 bytes
- "addl $64, %%edx \n\t"
- "paddb %%mm6, %%mm7 \n\t"
- "cmpl %%esi, %%edx \n\t" // cmp to bytes over mult of 64
- "movq %%mm7, -8(%1," PDX ",) \n\t" // write Raw(x) for 8th 8 bytes
- "jb sub_8lp \n\t"
-
- "cmpl %%eax, %%edx \n\t" // compare to MMXLength
- "jnb sub_8lt8 \n\t"
-
- "sub_8lpA: \n\t"
- "movq (%1," PDX ",), %%mm0 \n\t"
- "addl $8, %%edx \n\t"
- "paddb %%mm7, %%mm0 \n\t"
- "cmpl %%eax, %%edx \n\t" // compare to MMXLength
- "movq %%mm0, -8(%1," PDX ",) \n\t" // -8 to offset early addl edx
- "movq %%mm0, %%mm7 \n\t" // move calculated Raw(x) data
- "jb sub_8lpA \n\t" // to mm7 to be new Raw(x-bpp)
- // for next loop
- "sub_8lt8: \n\t"
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=d" (dummy_value_d), // 2
- "=a" (dummy_value_a) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (diff), // edx
- "3" (MMXLength) // eax
-
- : "%esi" // clobber list
-#if defined(CLOBBER_MMX_REGS_SUPPORTED)
- , "%mm0", "%mm1", "%mm2", "%mm3"
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
- }
- break; // end 8 bpp
-
- default: // bpp != 1,2,3,4,6,8: doesn't exist
- {
- // ERROR: SHOULD NEVER BE REACHED
-#if defined(PNG_DEBUG)
- png_debug(1, "Internal libpng logic error (GCC "
- "png_read_filter_row_mmx_sub())\n");
-#endif
- }
- break;
-
- } // end switch (bpp)
-
- __asm__ __volatile__ (
-//pre "movl MMXLength, %%eax \n\t"
-//pre "mov row, %1 \n\t" // edi/rdi
-//pre "cmpl FullLength, %%eax \n\t"
- "cmpl %%edx, %%eax \n\t"
- "jnb sub_end \n\t"
-
- "mov %1, " PSI " \n\t" // lp = row
-//pre "movl bpp, %%ecx \n\t"
- "add " PCX ", %1 \n\t" // rp = row + bpp
- "xorl %%ecx, %%ecx \n\t"
-
- "sub_lp2: \n\t"
- "movb (" PSI "," PAX ",), %%cl \n\t"
- "addb %%cl, (%1," PAX ",) \n\t"
- "incl %%eax \n\t"
- "cmpl %%edx, %%eax \n\t" // FullLength
- "jb sub_lp2 \n\t"
-
- "sub_end: \n\t"
- "EMMS \n\t" // end MMX instructions
-
- : "=c" (dummy_value_c), // 0 // output regs (dummy)
- "=D" (dummy_value_D), // 1
- "=a" (dummy_value_a), // 2
- "=d" (dummy_value_d) // 3
-
- : "0" (bpp), // ecx // input regs
- "1" (row), // edi
- "2" (MMXLength), // eax
- "3" (FullLength) // edx
-
- : "%esi" // clobber list
- );
-
-} // end of png_read_filter_row_mmx_sub()
-
-#endif /* PNG_MMX_READ_FILTER_SUB_SUPPORTED */
-
-
-
-
-#if defined(PNG_MMX_READ_FILTER_UP_SUPPORTED)
-
-//===========================================================================//
-// //
-// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ U P //
-// //
-//===========================================================================//
-
-// Optimized code for PNG Up filter decoder
-
-static void /* PRIVATE */
-png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
- png_bytep prev_row)
-{
- unsigned len; // png_uint_32 is actually 64-bit on x86-64
- int dummy_value_d; // fix 'forbidden register 3 (dx) was spilled' error
- png_bytep dummy_value_S;
- png_bytep dummy_value_D;
-
- len = row_info->rowbytes; // number of bytes to filter
-
- __asm__ __volatile__ (
- SAVE_GOT_ebx
-//pre "mov prev_row, %1 \n\t" // esi/rsi
-//pre "movl row, %2 \n\t" // edi/rdi
-
- "xorl %%ebx, %%ebx \n\t"
- "xorl %%eax, %%eax \n\t"
-
- // get # of bytes to alignment (note: computing _delta_ of two pointers,
- // so hereafter %%ecx is sufficient even on 64-bit)
- "mov %2, " PCX " \n\t" // take start of row
- "add $0x7, " PCX " \n\t" // add 7 to incr past alignment bdry
-// "andl $0xfffffff8, %%ecx \n\t" // mask to alignment boundary (32-bit!)
- CLEAR_BOTTOM_3_BITS PCX "\n\t" // mask to alignment boundary
- "sub %2, " PCX " \n\t" // subtract row ptr again => ebp =
- "jz up_go \n\t" // target value of ecx at alignment
-
- "up_lp1: \n\t" // fix alignment
- "movb (%2," PBX ",), %%al \n\t"
- "addb (%1," PBX ",), %%al \n\t"
- "incl %%ebx \n\t"
- "cmpl %%ecx, %%ebx \n\t"
- "movb %%al, -1(%2," PBX ",) \n\t" // mov does not affect flags; -1 to
- "jb up_lp1 \n\t" // offset incl ebx
-
- "up_go: \n\t"
-//pre "movl len, %%edx \n\t"
- "movl %%edx, %%ecx \n\t"
- "subl %%ebx, %%edx \n\t" // subtract alignment fix
- "andl $0x0000003f, %%edx \n\t" // calc bytes over mult of 64
- "subl %%edx, %%ecx \n\t" // sub over-bytes from original length
-
- // unrolled loop - use all MMX registers and interleave to reduce
- // number of branch instructions (loops) and reduce partial stalls
- "up_loop: \n\t"
- "movq (%1," PBX ",), %%mm1 \n\t"
- "movq (%2," PBX ",), %%mm0 \n\t"
- "movq 8(%1," PBX ",), %%mm3 \n\t"
- "paddb %%mm1, %%mm0 \n\t"
- "movq 8(%2," PBX ",), %%mm2 \n\t"
- "movq %%mm0, (%2," PBX ",) \n\t"
- "paddb %%mm3, %%mm2 \n\t"
- "movq 16(%1," PBX ",), %%mm5 \n\t"
- "movq %%mm2, 8(%2," PBX ",) \n\t"
- "movq 16(%2," PBX ",), %%mm4 \n\t"
- "movq 24(%1," PBX ",), %%mm7 \n\t"
- "paddb %%mm5, %%mm4 \n\t"
- "movq 24(%2," PBX ",), %%mm6 \n\t"
- "movq %%mm4, 16(%2," PBX ",) \n\t"
- "paddb %%mm7, %%mm6 \n\t"
- "movq 32(%1," PBX ",), %%mm1 \n\t"
- "movq %%mm6, 24(%2," PBX ",) \n\t"
- "movq 32(%2," PBX ",), %%mm0 \n\t"
- "movq 40(%1," PBX ",), %%mm3 \n\t"
- "paddb %%mm1, %%mm0 \n\t"
- "movq 40(%2," PBX ",), %%mm2 \n\t"
- "movq %%mm0, 32(%2," PBX ",) \n\t"
- "paddb %%mm3, %%mm2 \n\t"
- "movq 48(%1," PBX ",), %%mm5 \n\t"
- "movq %%mm2, 40(%2," PBX ",) \n\t"
- "movq 48(%2," PBX ",), %%mm4 \n\t"
- "movq 56(%1," PBX ",), %%mm7 \n\t"
- "paddb %%mm5, %%mm4 \n\t"
- "movq 56(%2," PBX ",), %%mm6 \n\t"
- "movq %%mm4, 48(%2," PBX ",) \n\t"
- "addl $64, %%ebx \n\t"
- "paddb %%mm7, %%mm6 \n\t"
- "cmpl %%ecx, %%ebx \n\t"
- "movq %%mm6, -8(%2," PBX ",) \n\t" // (+56)movq does not affect flags;
- "jb up_loop \n\t" // -8 to offset addl ebx
-
- "cmpl $0, %%edx \n\t" // test for bytes over mult of 64
- "jz up_end \n\t"
-
- "cmpl $8, %%edx \n\t" // test for less than 8 bytes
- "jb up_lt8 \n\t" // [added by lcreeve at netins.net]
-
- "addl %%edx, %%ecx \n\t"
- "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8
- "subl %%edx, %%ecx \n\t" // drop over-bytes from length
- "jz up_lt8 \n\t"
-
- "up_lpA: \n\t" // use MMX regs to update 8 bytes sim.
- "movq (%1," PBX ",), %%mm1 \n\t"
- "movq (%2," PBX ",), %%mm0 \n\t"
- "addl $8, %%ebx \n\t"
- "paddb %%mm1, %%mm0 \n\t"
- "cmpl %%ecx, %%ebx \n\t"
- "movq %%mm0, -8(%2," PBX ",) \n\t" // movq does not affect flags; -8 to
- "jb up_lpA \n\t" // offset add ebx
- "cmpl $0, %%edx \n\t" // test for bytes over mult of 8
- "jz up_end \n\t"
-
- "up_lt8: \n\t"
- "xorl %%eax, %%eax \n\t"
- "addl %%edx, %%ecx \n\t" // move over byte count into counter
-
- "up_lp2: \n\t" // use x86 regs for remaining bytes
- "movb (%2," PBX ",), %%al \n\t"
- "addb (%1," PBX ",), %%al \n\t"
- "incl %%ebx \n\t"
- "cmpl %%ecx, %%ebx \n\t"
- "movb %%al, -1(%2," PBX ",) \n\t" // mov does not affect flags; -1 to
- "jb up_lp2 \n\t" // offset inc ebx
-
- "up_end: \n\t"
- "EMMS \n\t" // conversion of filtered row complete
- RESTORE_GOT_ebx
-
- : "=d" (dummy_value_d), // 0 // output regs (dummy)
- "=S" (dummy_value_S), // 1
- "=D" (dummy_value_D) // 2
-
- : "0" (len), // edx // input regs
- "1" (prev_row), // esi
- "2" (row) // edi
-
- : "%eax", "%ecx" // clobber list (no input regs!)
- _CLOBBER_GOT_ebx
-#if defined(PNG_CLOBBER_MMX_REGS_SUPPORTED)
- , "%mm0", "%mm1", "%mm2", "%mm3"
- , "%mm4", "%mm5", "%mm6", "%mm7"
-#endif
- );
-
-} // end of png_read_filter_row_mmx_up()
-
-#endif /* PNG_MMX_READ_FILTER_UP_SUPPORTED */
-
-
-
-
-/*===========================================================================*/
-/* */
-/* P N G _ R E A D _ F I L T E R _ R O W */
-/* */
-/*===========================================================================*/
-
-/* Optimized png_read_filter_row routines */
-
-void /* PRIVATE */
-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
- row, png_bytep prev_row, int filter)
-{
-#if defined(PNG_DEBUG)
- char filtname[10];
-#endif
-
- if (_mmx_supported == 2) {
-#if !defined(PNG_1_0_X)
- /* this should have happened in png_init_mmx_flags() already */
- png_warning(png_ptr, "asm_flags may not have been initialized");
-#endif
- png_mmx_support();
- }
-
-#if defined(PNG_DEBUG)
- png_debug(1, "in png_read_filter_row (pnggccrd.c)\n");
- switch (filter)
- {
- case 0:
- png_snprintf(filtname, 10, "none");
- break;
-
- case 1:
- png_snprintf(filtname, 10, "sub-%s",
-#ifdef PNG_MMX_READ_FILTER_SUB_SUPPORTED
-#if !defined(PNG_1_0_X)
- ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- _mmx_supported
-#endif
- ? "MMX" :
-#endif
- "C");
- break;
-
- case 2:
- png_snprintf(filtname, 10, "up-%s",
-#ifdef PNG_MMX_READ_FILTER_UP_SUPPORTED
-#if !defined(PNG_1_0_X)
- ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- _mmx_supported
-#endif
- ? "MMX" :
-#endif
- "C");
- break;
-
- case 3:
- png_snprintf(filtname, 10, "avg-%s",
-#ifdef PNG_MMX_READ_FILTER_AVG_SUPPORTED
-#if !defined(PNG_1_0_X)
- ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- _mmx_supported
-#endif
- ? "MMX" :
-#endif
- "C");
- break;
-
- case 4:
- png_snprintf(filtname, 10, "paeth-%s",
-#ifdef PNG_MMX_READ_FILTER_PAETH_SUPPORTED
-#if defined(PNG_x86_64_USE_GOTPCREL) || defined(PNG_THREAD_UNSAFE_OK)
-#if !defined(PNG_1_0_X)
- ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- _mmx_supported
-#endif
- ? "MMX" :
-#endif /* PNG_x86_64_USE_GOTPCREL || PNG_THREAD_UNSAFE_OK */
-#endif
- "C");
- break;
-
- default:
- png_snprintf(filtname, 10, "unknown");
- break;
- }
- png_debug2(2, "row_number=%ld, %s, ", png_ptr->row_number, filtname);
- //png_debug1(0, "png_ptr=%10p, ", png_ptr);
- //png_debug1(0, "asm_flags=0x%08lx, ", png_ptr->asm_flags);
- png_debug1(0, "row=%10p, ", row);
- png_debug2(0, "pixdepth=%d, bytes=%d, ", (int)row_info->pixel_depth,
- (int)((row_info->pixel_depth + 7) >> 3));
- png_debug1(0, "rowbytes=%ld\n", row_info->rowbytes);
-#endif /* PNG_DEBUG */
-
- switch (filter)
- {
- case PNG_FILTER_VALUE_NONE:
- break;
-
- case PNG_FILTER_VALUE_SUB:
-#ifdef PNG_MMX_READ_FILTER_SUB_SUPPORTED
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (_mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_sub(row_info, row);
- }
- else
-#endif
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_bytep rp = row + bpp;
- png_bytep lp = row;
-
- for (i = bpp; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
- rp++;
- }
- } /* end !UseMMX_sub */
- break;
-
- case PNG_FILTER_VALUE_UP:
-#ifdef PNG_MMX_READ_FILTER_UP_SUPPORTED
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (_mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_up(row_info, row, prev_row);
- }
- else
-#endif
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_bytep rp = row;
- png_bytep pp = prev_row;
-
- for (i = 0; i < istop; ++i)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
- } /* end !UseMMX_up */
- break;
-
- case PNG_FILTER_VALUE_AVG:
-#ifdef PNG_MMX_READ_FILTER_AVG_SUPPORTED
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (_mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_avg(row_info, row, prev_row);
- }
- else
-#endif
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++) >> 1)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++ + *lp++) >> 1)) & 0xff);
- rp++;
- }
- } /* end !UseMMX_avg */
- break;
-
- case PNG_FILTER_VALUE_PAETH:
-#ifdef PNG_MMX_READ_FILTER_PAETH_SUPPORTED
-#if defined(PNG_x86_64_USE_GOTPCREL) || defined(PNG_THREAD_UNSAFE_OK)
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (_mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_paeth(row_info, row, prev_row);
- }
- else
-#endif /* PNG_x86_64_USE_GOTPCREL || PNG_THREAD_UNSAFE_OK */
-#endif
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_bytep cp = prev_row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++) /* use leftover rp,pp */
- {
- int a, b, c, pa, pb, pc, p;
-
- a = *lp++;
- b = *pp++;
- c = *cp++;
-
- p = b - c;
- pc = a - c;
-
-#if defined(PNG_USE_ABS)
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- /*
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- */
-
- p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
-
- *rp = (png_byte)(((int)(*rp) + p) & 0xff);
- rp++;
- }
- } /* end !UseMMX_paeth */
- break;
-
- default:
- png_warning(png_ptr, "Ignoring bad row-filter type");
- *row=0;
- break;
- }
-}
-
-#endif /* PNG_HAVE_MMX_READ_FILTER_ROW */
-
-
-#endif /* PNG_ASSEMBLER_CODE_SUPPORTED && PNG_USE_PNGGCCRD */
-#endif /* __GNUC__ */
diff --git a/distrib/libpng-1.2.19/pngget.c b/distrib/libpng-1.2.19/pngget.c
deleted file mode 100644
index 75d2ca0..0000000
--- a/distrib/libpng-1.2.19/pngget.c
+++ /dev/null
@@ -1,962 +0,0 @@
-
-/* pngget.c - retrieval of values from info struct
- *
- * Last changed in libpng 1.2.15 January 5, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-png_uint_32 PNGAPI
-png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->valid & flag);
- else
- return(0);
-}
-
-png_uint_32 PNGAPI
-png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->rowbytes);
- else
- return(0);
-}
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-png_bytepp PNGAPI
-png_get_rows(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->row_pointers);
- else
- return(0);
-}
-#endif
-
-#ifdef PNG_EASY_ACCESS_SUPPORTED
-/* easy access to info, added in libpng-0.99 */
-png_uint_32 PNGAPI
-png_get_image_width(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->width;
- }
- return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_image_height(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->height;
- }
- return (0);
-}
-
-png_byte PNGAPI
-png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->bit_depth;
- }
- return (0);
-}
-
-png_byte PNGAPI
-png_get_color_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->color_type;
- }
- return (0);
-}
-
-png_byte PNGAPI
-png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->filter_type;
- }
- return (0);
-}
-
-png_byte PNGAPI
-png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->interlace_type;
- }
- return (0);
-}
-
-png_byte PNGAPI
-png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- {
- return info_ptr->compression_type;
- }
- return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
- return (0);
- else return (info_ptr->x_pixels_per_unit);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
- return (0);
- else return (info_ptr->y_pixels_per_unit);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-png_uint_32 PNGAPI
-png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
- if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
- info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
- return (0);
- else return (info_ptr->x_pixels_per_unit);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-float PNGAPI
-png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
- {
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
- if (info_ptr->x_pixels_per_unit == 0)
- return ((float)0.0);
- else
- return ((float)((float)info_ptr->y_pixels_per_unit
- /(float)info_ptr->x_pixels_per_unit));
- }
-#else
- return (0.0);
-#endif
- return ((float)0.0);
-}
-#endif
-
-png_int_32 PNGAPI
-png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
- return (0);
- else return (info_ptr->x_offset);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-png_int_32 PNGAPI
-png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
- return (0);
- else return (info_ptr->y_offset);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-png_int_32 PNGAPI
-png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
- return (0);
- else return (info_ptr->x_offset);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-png_int_32 PNGAPI
-png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
-#if defined(PNG_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- {
- png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
- if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
- return (0);
- else return (info_ptr->y_offset);
- }
-#else
- return (0);
-#endif
- return (0);
-}
-
-#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
-{
- return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
- *.0254 +.5));
-}
-
-png_uint_32 PNGAPI
-png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
-{
- return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
- *.0254 +.5));
-}
-
-png_uint_32 PNGAPI
-png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
-{
- return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
- *.0254 +.5));
-}
-
-float PNGAPI
-png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
-{
- return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
- *.00003937);
-}
-
-float PNGAPI
-png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
-{
- return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
- *.00003937);
-}
-
-#if defined(PNG_pHYs_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
-{
- png_uint_32 retval = 0;
-
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "pHYs");
- if (res_x != NULL)
- {
- *res_x = info_ptr->x_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (res_y != NULL)
- {
- *res_y = info_ptr->y_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (unit_type != NULL)
- {
- *unit_type = (int)info_ptr->phys_unit_type;
- retval |= PNG_INFO_pHYs;
- if(*unit_type == 1)
- {
- if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
- if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
- }
- }
- }
- return (retval);
-}
-#endif /* PNG_pHYs_SUPPORTED */
-#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
-
-/* png_get_channels really belongs in here, too, but it's been around longer */
-
-#endif /* PNG_EASY_ACCESS_SUPPORTED */
-
-png_byte PNGAPI
-png_get_channels(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->channels);
- else
- return (0);
-}
-
-png_bytep PNGAPI
-png_get_signature(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr != NULL && info_ptr != NULL)
- return(info_ptr->signature);
- else
- return (NULL);
-}
-
-#if defined(PNG_bKGD_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
- png_color_16p *background)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
- && background != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "bKGD");
- *background = &(info_ptr->background);
- return (PNG_INFO_bKGD);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
- double *white_x, double *white_y, double *red_x, double *red_y,
- double *green_x, double *green_y, double *blue_x, double *blue_y)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- {
- png_debug1(1, "in %s retrieval function\n", "cHRM");
- if (white_x != NULL)
- *white_x = (double)info_ptr->x_white;
- if (white_y != NULL)
- *white_y = (double)info_ptr->y_white;
- if (red_x != NULL)
- *red_x = (double)info_ptr->x_red;
- if (red_y != NULL)
- *red_y = (double)info_ptr->y_red;
- if (green_x != NULL)
- *green_x = (double)info_ptr->x_green;
- if (green_y != NULL)
- *green_y = (double)info_ptr->y_green;
- if (blue_x != NULL)
- *blue_x = (double)info_ptr->x_blue;
- if (blue_y != NULL)
- *blue_y = (double)info_ptr->y_blue;
- return (PNG_INFO_cHRM);
- }
- return (0);
-}
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
- png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
- png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
- png_fixed_point *blue_x, png_fixed_point *blue_y)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- {
- png_debug1(1, "in %s retrieval function\n", "cHRM");
- if (white_x != NULL)
- *white_x = info_ptr->int_x_white;
- if (white_y != NULL)
- *white_y = info_ptr->int_y_white;
- if (red_x != NULL)
- *red_x = info_ptr->int_x_red;
- if (red_y != NULL)
- *red_y = info_ptr->int_y_red;
- if (green_x != NULL)
- *green_x = info_ptr->int_x_green;
- if (green_y != NULL)
- *green_y = info_ptr->int_y_green;
- if (blue_x != NULL)
- *blue_x = info_ptr->int_x_blue;
- if (blue_y != NULL)
- *blue_y = info_ptr->int_y_blue;
- return (PNG_INFO_cHRM);
- }
- return (0);
-}
-#endif
-#endif
-
-#if defined(PNG_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
- && file_gamma != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "gAMA");
- *file_gamma = (double)info_ptr->gamma;
- return (PNG_INFO_gAMA);
- }
- return (0);
-}
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
- png_fixed_point *int_file_gamma)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
- && int_file_gamma != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "gAMA");
- *int_file_gamma = info_ptr->int_gamma;
- return (PNG_INFO_gAMA);
- }
- return (0);
-}
-#endif
-#endif
-
-#if defined(PNG_sRGB_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
- && file_srgb_intent != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "sRGB");
- *file_srgb_intent = (int)info_ptr->srgb_intent;
- return (PNG_INFO_sRGB);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_iCCP_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
- png_charpp name, int *compression_type,
- png_charpp profile, png_uint_32 *proflen)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
- && name != NULL && profile != NULL && proflen != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "iCCP");
- *name = info_ptr->iccp_name;
- *profile = info_ptr->iccp_profile;
- /* compression_type is a dummy so the API won't have to change
- if we introduce multiple compression types later. */
- *proflen = (int)info_ptr->iccp_proflen;
- *compression_type = (int)info_ptr->iccp_compression;
- return (PNG_INFO_iCCP);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_sPLT_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
- png_sPLT_tpp spalettes)
-{
- if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
- {
- *spalettes = info_ptr->splt_palettes;
- return ((png_uint_32)info_ptr->splt_palettes_num);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_hIST_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
- && hist != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "hIST");
- *hist = info_ptr->hist;
- return (PNG_INFO_hIST);
- }
- return (0);
-}
-#endif
-
-png_uint_32 PNGAPI
-png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *width, png_uint_32 *height, int *bit_depth,
- int *color_type, int *interlace_type, int *compression_type,
- int *filter_type)
-
-{
- if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
- bit_depth != NULL && color_type != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "IHDR");
- *width = info_ptr->width;
- *height = info_ptr->height;
- *bit_depth = info_ptr->bit_depth;
- if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
- png_error(png_ptr, "Invalid bit depth");
- *color_type = info_ptr->color_type;
- if (info_ptr->color_type > 6)
- png_error(png_ptr, "Invalid color type");
- if (compression_type != NULL)
- *compression_type = info_ptr->compression_type;
- if (filter_type != NULL)
- *filter_type = info_ptr->filter_type;
- if (interlace_type != NULL)
- *interlace_type = info_ptr->interlace_type;
-
- /* check for potential overflow of rowbytes */
- if (*width == 0 || *width > PNG_UINT_31_MAX)
- png_error(png_ptr, "Invalid image width");
- if (*height == 0 || *height > PNG_UINT_31_MAX)
- png_error(png_ptr, "Invalid image height");
- if (info_ptr->width > (PNG_UINT_32_MAX
- >> 3) /* 8-byte RGBA pixels */
- - 64 /* bigrowbuf hack */
- - 1 /* filter byte */
- - 7*8 /* rounding of width to multiple of 8 pixels */
- - 8) /* extra max_pixel_depth pad */
- {
- png_warning(png_ptr,
- "Width too large for libpng to process image data.");
- }
- return (1);
- }
- return (0);
-}
-
-#if defined(PNG_oFFs_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
- png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
- && offset_x != NULL && offset_y != NULL && unit_type != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "oFFs");
- *offset_x = info_ptr->x_offset;
- *offset_y = info_ptr->y_offset;
- *unit_type = (int)info_ptr->offset_unit_type;
- return (PNG_INFO_oFFs);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_pCAL_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
- png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
- png_charp *units, png_charpp *params)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
- && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
- nparams != NULL && units != NULL && params != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "pCAL");
- *purpose = info_ptr->pcal_purpose;
- *X0 = info_ptr->pcal_X0;
- *X1 = info_ptr->pcal_X1;
- *type = (int)info_ptr->pcal_type;
- *nparams = (int)info_ptr->pcal_nparams;
- *units = info_ptr->pcal_units;
- *params = info_ptr->pcal_params;
- return (PNG_INFO_pCAL);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_sCAL_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
- int *unit, double *width, double *height)
-{
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL))
- {
- *unit = info_ptr->scal_unit;
- *width = info_ptr->scal_pixel_width;
- *height = info_ptr->scal_pixel_height;
- return (PNG_INFO_sCAL);
- }
- return(0);
-}
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
- int *unit, png_charpp width, png_charpp height)
-{
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL))
- {
- *unit = info_ptr->scal_unit;
- *width = info_ptr->scal_s_width;
- *height = info_ptr->scal_s_height;
- return (PNG_INFO_sCAL);
- }
- return(0);
-}
-#endif
-#endif
-#endif
-
-#if defined(PNG_pHYs_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
-{
- png_uint_32 retval = 0;
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_debug1(1, "in %s retrieval function\n", "pHYs");
- if (res_x != NULL)
- {
- *res_x = info_ptr->x_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (res_y != NULL)
- {
- *res_y = info_ptr->y_pixels_per_unit;
- retval |= PNG_INFO_pHYs;
- }
- if (unit_type != NULL)
- {
- *unit_type = (int)info_ptr->phys_unit_type;
- retval |= PNG_INFO_pHYs;
- }
- }
- return (retval);
-}
-#endif
-
-png_uint_32 PNGAPI
-png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
- int *num_palette)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
- && palette != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "PLTE");
- *palette = info_ptr->palette;
- *num_palette = info_ptr->num_palette;
- png_debug1(3, "num_palette = %d\n", *num_palette);
- return (PNG_INFO_PLTE);
- }
- return (0);
-}
-
-#if defined(PNG_sBIT_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
- && sig_bit != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "sBIT");
- *sig_bit = &(info_ptr->sig_bit);
- return (PNG_INFO_sBIT);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_TEXT_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
- int *num_text)
-{
- if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
- {
- png_debug1(1, "in %s retrieval function\n",
- (png_ptr->chunk_name[0] == '\0' ? "text"
- : (png_const_charp)png_ptr->chunk_name));
- if (text_ptr != NULL)
- *text_ptr = info_ptr->text;
- if (num_text != NULL)
- *num_text = info_ptr->num_text;
- return ((png_uint_32)info_ptr->num_text);
- }
- if (num_text != NULL)
- *num_text = 0;
- return(0);
-}
-#endif
-
-#if defined(PNG_tIME_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
-{
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
- && mod_time != NULL)
- {
- png_debug1(1, "in %s retrieval function\n", "tIME");
- *mod_time = &(info_ptr->mod_time);
- return (PNG_INFO_tIME);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
- png_bytep *trans, int *num_trans, png_color_16p *trans_values)
-{
- png_uint_32 retval = 0;
- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
- {
- png_debug1(1, "in %s retrieval function\n", "tRNS");
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (trans != NULL)
- {
- *trans = info_ptr->trans;
- retval |= PNG_INFO_tRNS;
- }
- if (trans_values != NULL)
- *trans_values = &(info_ptr->trans_values);
- }
- else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
- {
- if (trans_values != NULL)
- {
- *trans_values = &(info_ptr->trans_values);
- retval |= PNG_INFO_tRNS;
- }
- if(trans != NULL)
- *trans = NULL;
- }
- if(num_trans != NULL)
- {
- *num_trans = info_ptr->num_trans;
- retval |= PNG_INFO_tRNS;
- }
- }
- return (retval);
-}
-#endif
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-png_uint_32 PNGAPI
-png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
- png_unknown_chunkpp unknowns)
-{
- if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
- {
- *unknowns = info_ptr->unknown_chunks;
- return ((png_uint_32)info_ptr->unknown_chunks_num);
- }
- return (0);
-}
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-png_byte PNGAPI
-png_get_rgb_to_gray_status (png_structp png_ptr)
-{
- return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
-}
-#endif
-
-#if defined(PNG_USER_CHUNKS_SUPPORTED)
-png_voidp PNGAPI
-png_get_user_chunk_ptr(png_structp png_ptr)
-{
- return (png_ptr? png_ptr->user_chunk_ptr : NULL);
-}
-#endif
-
-#ifdef PNG_WRITE_SUPPORTED
-png_uint_32 PNGAPI
-png_get_compression_buffer_size(png_structp png_ptr)
-{
- return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
-}
-#endif
-
-#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
-#ifndef PNG_1_0_X
-/* this function was added to libpng 1.2.0 and should exist by default */
-png_uint_32 PNGAPI
-png_get_asm_flags (png_structp png_ptr)
-{
-#ifdef PNG_MMX_CODE_SUPPORTED
- return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L);
-#else
- return (png_ptr? 0L: 0L);
-#endif
-}
-
-/* this function was added to libpng 1.2.0 and should exist by default */
-png_uint_32 PNGAPI
-png_get_asm_flagmask (int flag_select)
-{
-#ifdef PNG_MMX_CODE_SUPPORTED
- png_uint_32 settable_asm_flags = 0;
-
- if (flag_select & PNG_SELECT_READ)
- settable_asm_flags |=
- PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
- PNG_ASM_FLAG_MMX_READ_INTERLACE |
- PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
- PNG_ASM_FLAG_MMX_READ_FILTER_UP |
- PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
- PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
- /* no non-MMX flags yet */
-
-#if 0
- /* GRR: no write-flags yet, either, but someday... */
- if (flag_select & PNG_SELECT_WRITE)
- settable_asm_flags |=
- PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
-#endif /* 0 */
-
- return settable_asm_flags; /* _theoretically_ settable capabilities only */
-#else
- return (0L);
-#endif /* PNG_MMX_CODE_SUPPORTED */
-}
-
-
- /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
-/* this function was added to libpng 1.2.0 */
-png_uint_32 PNGAPI
-png_get_mmx_flagmask (int flag_select, int *compilerID)
-{
-#if defined(PNG_MMX_CODE_SUPPORTED)
- png_uint_32 settable_mmx_flags = 0;
-
- if (flag_select & PNG_SELECT_READ)
- settable_mmx_flags |=
- PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
- PNG_ASM_FLAG_MMX_READ_INTERLACE |
- PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
- PNG_ASM_FLAG_MMX_READ_FILTER_UP |
- PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
- PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
-#if 0
- /* GRR: no MMX write support yet, but someday... */
- if (flag_select & PNG_SELECT_WRITE)
- settable_mmx_flags |=
- PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
-#endif /* 0 */
-
- if (compilerID != NULL) {
-#ifdef PNG_USE_PNGVCRD
- *compilerID = 1; /* MSVC */
-#else
-#ifdef PNG_USE_PNGGCCRD
- *compilerID = 2; /* gcc/gas */
-#else
- *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
-#endif
-#endif
- }
-
- return settable_mmx_flags; /* _theoretically_ settable capabilities only */
-#else
- return (0L);
-#endif /* ?PNG_MMX_CODE_SUPPORTED */
-}
-
-/* this function was added to libpng 1.2.0 */
-png_byte PNGAPI
-png_get_mmx_bitdepth_threshold (png_structp png_ptr)
-{
-#if defined(PNG_MMX_CODE_SUPPORTED)
- return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0);
-#else
- return (png_ptr? 0: 0);
-#endif /* ?PNG_MMX_CODE_SUPPORTED */
-}
-
-/* this function was added to libpng 1.2.0 */
-png_uint_32 PNGAPI
-png_get_mmx_rowbytes_threshold (png_structp png_ptr)
-{
-#if defined(PNG_MMX_CODE_SUPPORTED)
- return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L);
-#else
- return (png_ptr? 0L: 0L);
-#endif /* ?PNG_MMX_CODE_SUPPORTED */
-}
-#endif /* ?PNG_1_0_X */
-#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-/* these functions were added to libpng 1.2.6 */
-png_uint_32 PNGAPI
-png_get_user_width_max (png_structp png_ptr)
-{
- return (png_ptr? png_ptr->user_width_max : 0);
-}
-png_uint_32 PNGAPI
-png_get_user_height_max (png_structp png_ptr)
-{
- return (png_ptr? png_ptr->user_height_max : 0);
-}
-#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
-
-
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngmem.c b/distrib/libpng-1.2.19/pngmem.c
deleted file mode 100644
index 248060f..0000000
--- a/distrib/libpng-1.2.19/pngmem.c
+++ /dev/null
@@ -1,608 +0,0 @@
-
-/* pngmem.c - stub functions for memory allocation
- *
- * Last changed in libpng 1.2.13 November 13, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all memory allocation. Users who
- * need special memory handling are expected to supply replacement
- * functions for png_malloc() and png_free(), and to use
- * png_create_read_struct_2() and png_create_write_struct_2() to
- * identify the replacement functions.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-/* Borland DOS special memory handler */
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* if you change this, be sure to change the one in png.h also */
-
-/* Allocate memory for a png_struct. The malloc and memset can be replaced
- by a single call to calloc() if this is thought to improve performance. */
-png_voidp /* PRIVATE */
-png_create_struct(int type)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
-}
-
-/* Alternate version of png_create_struct, for use with user-defined malloc. */
-png_voidp /* PRIVATE */
-png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_size_t size;
- png_voidp struct_ptr;
-
- if (type == PNG_STRUCT_INFO)
- size = png_sizeof(png_info);
- else if (type == PNG_STRUCT_PNG)
- size = png_sizeof(png_struct);
- else
- return (png_get_copyright(NULL));
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(malloc_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
- }
- else
-#endif /* PNG_USER_MEM_SUPPORTED */
- struct_ptr = (png_voidp)farmalloc(size);
- if (struct_ptr != NULL)
- png_memset(struct_ptr, 0, size);
- return (struct_ptr);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct(png_voidp struct_ptr)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
- png_voidp mem_ptr)
-{
-#endif
- if (struct_ptr != NULL)
- {
-#ifdef PNG_USER_MEM_SUPPORTED
- if(free_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- (*(free_fn))(png_ptr, struct_ptr);
- return;
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
- farfree (struct_ptr);
- }
-}
-
-/* Allocate memory. For reasonable files, size should never exceed
- * 64K. However, zlib may allocate more then 64K if you don't tell
- * it not to. See zconf.h and png.h for more information. zlib does
- * need to allocate exactly 64K, so whatever you call here must
- * have the ability to do that.
- *
- * Borland seems to have a problem in DOS mode for exactly 64K.
- * It gives you a segment with an offset of 8 (perhaps to store its
- * memory stuff). zlib doesn't like this at all, so we have to
- * detect and deal with it. This code should not be needed in
- * Windows or OS/2 modes, and only in 16 bit mode. This code has
- * been updated by Alexander Lehmann for version 0.89 to waste less
- * memory.
- *
- * Note that we can't use png_size_t for the "size" declaration,
- * since on some systems a png_size_t is a 16-bit quantity, and as a
- * result, we would be truncating potentially larger memory requests
- * (which should cause a fatal error) and introducing major problems.
- */
-
-png_voidp PNGAPI
-png_malloc(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ret;
-
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(png_ptr->malloc_fn != NULL)
- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
- else
- ret = (png_malloc_default(png_ptr, size));
- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of memory!");
- return (ret);
-}
-
-png_voidp PNGAPI
-png_malloc_default(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ret;
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
-#ifdef PNG_MAX_MALLOC_64K
- if (size > (png_uint_32)65536L)
- {
- png_warning(png_ptr, "Cannot Allocate > 64K");
- ret = NULL;
- }
- else
-#endif
-
- if (size != (size_t)size)
- ret = NULL;
- else if (size == (png_uint_32)65536L)
- {
- if (png_ptr->offset_table == NULL)
- {
- /* try to see if we need to do any of this fancy stuff */
- ret = farmalloc(size);
- if (ret == NULL || ((png_size_t)ret & 0xffff))
- {
- int num_blocks;
- png_uint_32 total_size;
- png_bytep table;
- int i;
- png_byte huge * hptr;
-
- if (ret != NULL)
- {
- farfree(ret);
- ret = NULL;
- }
-
- if(png_ptr->zlib_window_bits > 14)
- num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
- else
- num_blocks = 1;
- if (png_ptr->zlib_mem_level >= 7)
- num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
- else
- num_blocks++;
-
- total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
-
- table = farmalloc(total_size);
-
- if (table == NULL)
- {
-#ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
- else
- png_warning(png_ptr, "Out Of Memory.");
-#endif
- return (NULL);
- }
-
- if ((png_size_t)table & 0xfff0)
- {
-#ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr,
- "Farmalloc didn't return normalized pointer");
- else
- png_warning(png_ptr,
- "Farmalloc didn't return normalized pointer");
-#endif
- return (NULL);
- }
-
- png_ptr->offset_table = table;
- png_ptr->offset_table_ptr = farmalloc(num_blocks *
- png_sizeof (png_bytep));
-
- if (png_ptr->offset_table_ptr == NULL)
- {
-#ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
- else
- png_warning(png_ptr, "Out Of memory.");
-#endif
- return (NULL);
- }
-
- hptr = (png_byte huge *)table;
- if ((png_size_t)hptr & 0xf)
- {
- hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
- hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
- }
- for (i = 0; i < num_blocks; i++)
- {
- png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
- hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
- }
-
- png_ptr->offset_table_number = num_blocks;
- png_ptr->offset_table_count = 0;
- png_ptr->offset_table_count_free = 0;
- }
- }
-
- if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
- {
-#ifndef PNG_USER_MEM_SUPPORTED
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
- else
- png_warning(png_ptr, "Out of Memory.");
-#endif
- return (NULL);
- }
-
- ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
- }
- else
- ret = farmalloc(size);
-
-#ifndef PNG_USER_MEM_SUPPORTED
- if (ret == NULL)
- {
- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
- else
- png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
- }
-#endif
-
- return (ret);
-}
-
-/* free a pointer allocated by png_malloc(). In the default
- configuration, png_ptr is not used, but is passed in case it
- is needed. If ptr is NULL, return without taking any action. */
-void PNGAPI
-png_free(png_structp png_ptr, png_voidp ptr)
-{
- if (png_ptr == NULL || ptr == NULL)
- return;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr->free_fn != NULL)
- {
- (*(png_ptr->free_fn))(png_ptr, ptr);
- return;
- }
- else png_free_default(png_ptr, ptr);
-}
-
-void PNGAPI
-png_free_default(png_structp png_ptr, png_voidp ptr)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- if(png_ptr == NULL) return;
-
- if (png_ptr->offset_table != NULL)
- {
- int i;
-
- for (i = 0; i < png_ptr->offset_table_count; i++)
- {
- if (ptr == png_ptr->offset_table_ptr[i])
- {
- ptr = NULL;
- png_ptr->offset_table_count_free++;
- break;
- }
- }
- if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
- {
- farfree(png_ptr->offset_table);
- farfree(png_ptr->offset_table_ptr);
- png_ptr->offset_table = NULL;
- png_ptr->offset_table_ptr = NULL;
- }
- }
-
- if (ptr != NULL)
- {
- farfree(ptr);
- }
-}
-
-#else /* Not the Borland DOS special memory handler */
-
-/* Allocate memory for a png_struct or a png_info. The malloc and
- memset can be replaced by a single call to calloc() if this is thought
- to improve performance noticably. */
-png_voidp /* PRIVATE */
-png_create_struct(int type)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
-}
-
-/* Allocate memory for a png_struct or a png_info. The malloc and
- memset can be replaced by a single call to calloc() if this is thought
- to improve performance noticably. */
-png_voidp /* PRIVATE */
-png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_size_t size;
- png_voidp struct_ptr;
-
- if (type == PNG_STRUCT_INFO)
- size = png_sizeof(png_info);
- else if (type == PNG_STRUCT_PNG)
- size = png_sizeof(png_struct);
- else
- return (NULL);
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if(malloc_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- struct_ptr = (*(malloc_fn))(png_ptr, size);
- if (struct_ptr != NULL)
- png_memset(struct_ptr, 0, size);
- return (struct_ptr);
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#if defined(__TURBOC__) && !defined(__FLAT__)
- struct_ptr = (png_voidp)farmalloc(size);
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- struct_ptr = (png_voidp)halloc(size,1);
-# else
- struct_ptr = (png_voidp)malloc(size);
-# endif
-#endif
- if (struct_ptr != NULL)
- png_memset(struct_ptr, 0, size);
-
- return (struct_ptr);
-}
-
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct(png_voidp struct_ptr)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
- png_voidp mem_ptr)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- if (struct_ptr != NULL)
- {
-#ifdef PNG_USER_MEM_SUPPORTED
- if(free_fn != NULL)
- {
- png_struct dummy_struct;
- png_structp png_ptr = &dummy_struct;
- png_ptr->mem_ptr=mem_ptr;
- (*(free_fn))(png_ptr, struct_ptr);
- return;
- }
-#endif /* PNG_USER_MEM_SUPPORTED */
-#if defined(__TURBOC__) && !defined(__FLAT__)
- farfree(struct_ptr);
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- hfree(struct_ptr);
-# else
- free(struct_ptr);
-# endif
-#endif
- }
-}
-
-/* Allocate memory. For reasonable files, size should never exceed
- 64K. However, zlib may allocate more then 64K if you don't tell
- it not to. See zconf.h and png.h for more information. zlib does
- need to allocate exactly 64K, so whatever you call here must
- have the ability to do that. */
-
-png_voidp PNGAPI
-png_malloc(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ret;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
- if(png_ptr->malloc_fn != NULL)
- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
- else
- ret = (png_malloc_default(png_ptr, size));
- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of Memory!");
- return (ret);
-}
-
-png_voidp PNGAPI
-png_malloc_default(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ret;
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- if (png_ptr == NULL || size == 0)
- return (NULL);
-
-#ifdef PNG_MAX_MALLOC_64K
- if (size > (png_uint_32)65536L)
- {
-#ifndef PNG_USER_MEM_SUPPORTED
- if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Cannot Allocate > 64K");
- else
-#endif
- return NULL;
- }
-#endif
-
- /* Check for overflow */
-#if defined(__TURBOC__) && !defined(__FLAT__)
- if (size != (unsigned long)size)
- ret = NULL;
- else
- ret = farmalloc(size);
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- if (size != (unsigned long)size)
- ret = NULL;
- else
- ret = halloc(size, 1);
-# else
- if (size != (size_t)size)
- ret = NULL;
- else
- ret = malloc((size_t)size);
-# endif
-#endif
-
-#ifndef PNG_USER_MEM_SUPPORTED
- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
- png_error(png_ptr, "Out of Memory");
-#endif
-
- return (ret);
-}
-
-/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
- without taking any action. */
-void PNGAPI
-png_free(png_structp png_ptr, png_voidp ptr)
-{
- if (png_ptr == NULL || ptr == NULL)
- return;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- if (png_ptr->free_fn != NULL)
- {
- (*(png_ptr->free_fn))(png_ptr, ptr);
- return;
- }
- else png_free_default(png_ptr, ptr);
-}
-void PNGAPI
-png_free_default(png_structp png_ptr, png_voidp ptr)
-{
- if (png_ptr == NULL || ptr == NULL)
- return;
-
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-#if defined(__TURBOC__) && !defined(__FLAT__)
- farfree(ptr);
-#else
-# if defined(_MSC_VER) && defined(MAXSEG_64K)
- hfree(ptr);
-# else
- free(ptr);
-# endif
-#endif
-}
-
-#endif /* Not Borland DOS special memory handler */
-
-#if defined(PNG_1_0_X)
-# define png_malloc_warn png_malloc
-#else
-/* This function was added at libpng version 1.2.3. The png_malloc_warn()
- * function will set up png_malloc() to issue a png_warning and return NULL
- * instead of issuing a png_error, if it fails to allocate the requested
- * memory.
- */
-png_voidp PNGAPI
-png_malloc_warn(png_structp png_ptr, png_uint_32 size)
-{
- png_voidp ptr;
- png_uint_32 save_flags;
- if(png_ptr == NULL) return (NULL);
-
- save_flags=png_ptr->flags;
- png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
- ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
- png_ptr->flags=save_flags;
- return(ptr);
-}
-#endif
-
-png_voidp PNGAPI
-png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
- png_uint_32 length)
-{
- png_size_t size;
-
- size = (png_size_t)length;
- if ((png_uint_32)size != length)
- png_error(png_ptr,"Overflow in png_memcpy_check.");
-
- return(png_memcpy (s1, s2, size));
-}
-
-png_voidp PNGAPI
-png_memset_check (png_structp png_ptr, png_voidp s1, int value,
- png_uint_32 length)
-{
- png_size_t size;
-
- size = (png_size_t)length;
- if ((png_uint_32)size != length)
- png_error(png_ptr,"Overflow in png_memset_check.");
-
- return (png_memset (s1, value, size));
-
-}
-
-#ifdef PNG_USER_MEM_SUPPORTED
-/* This function is called when the application wants to use another method
- * of allocating and freeing memory.
- */
-void PNGAPI
-png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
- malloc_fn, png_free_ptr free_fn)
-{
- if(png_ptr != NULL) {
- png_ptr->mem_ptr = mem_ptr;
- png_ptr->malloc_fn = malloc_fn;
- png_ptr->free_fn = free_fn;
- }
-}
-
-/* This function returns a pointer to the mem_ptr associated with the user
- * functions. The application should free any memory associated with this
- * pointer before png_write_destroy and png_read_destroy are called.
- */
-png_voidp PNGAPI
-png_get_mem_ptr(png_structp png_ptr)
-{
- if(png_ptr == NULL) return (NULL);
- return ((png_voidp)png_ptr->mem_ptr);
-}
-#endif /* PNG_USER_MEM_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngpread.c b/distrib/libpng-1.2.19/pngpread.c
deleted file mode 100644
index 7d29e98..0000000
--- a/distrib/libpng-1.2.19/pngpread.c
+++ /dev/null
@@ -1,1585 +0,0 @@
-
-/* pngpread.c - read a png file in push mode
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-
-/* push model modes */
-#define PNG_READ_SIG_MODE 0
-#define PNG_READ_CHUNK_MODE 1
-#define PNG_READ_IDAT_MODE 2
-#define PNG_SKIP_MODE 3
-#define PNG_READ_tEXt_MODE 4
-#define PNG_READ_zTXt_MODE 5
-#define PNG_READ_DONE_MODE 6
-#define PNG_READ_iTXt_MODE 7
-#define PNG_ERROR_MODE 8
-
-void PNGAPI
-png_process_data(png_structp png_ptr, png_infop info_ptr,
- png_bytep buffer, png_size_t buffer_size)
-{
- if(png_ptr == NULL) return;
- png_push_restore_buffer(png_ptr, buffer, buffer_size);
-
- while (png_ptr->buffer_size)
- {
- png_process_some_data(png_ptr, info_ptr);
- }
-}
-
-/* What we do with the incoming data depends on what we were previously
- * doing before we ran out of data...
- */
-void /* PRIVATE */
-png_process_some_data(png_structp png_ptr, png_infop info_ptr)
-{
- if(png_ptr == NULL) return;
- switch (png_ptr->process_mode)
- {
- case PNG_READ_SIG_MODE:
- {
- png_push_read_sig(png_ptr, info_ptr);
- break;
- }
- case PNG_READ_CHUNK_MODE:
- {
- png_push_read_chunk(png_ptr, info_ptr);
- break;
- }
- case PNG_READ_IDAT_MODE:
- {
- png_push_read_IDAT(png_ptr);
- break;
- }
-#if defined(PNG_READ_tEXt_SUPPORTED)
- case PNG_READ_tEXt_MODE:
- {
- png_push_read_tEXt(png_ptr, info_ptr);
- break;
- }
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- case PNG_READ_zTXt_MODE:
- {
- png_push_read_zTXt(png_ptr, info_ptr);
- break;
- }
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- case PNG_READ_iTXt_MODE:
- {
- png_push_read_iTXt(png_ptr, info_ptr);
- break;
- }
-#endif
- case PNG_SKIP_MODE:
- {
- png_push_crc_finish(png_ptr);
- break;
- }
- default:
- {
- png_ptr->buffer_size = 0;
- break;
- }
- }
-}
-
-/* Read any remaining signature bytes from the stream and compare them with
- * the correct PNG signature. It is possible that this routine is called
- * with bytes already read from the signature, either because they have been
- * checked by the calling application, or because of multiple calls to this
- * routine.
- */
-void /* PRIVATE */
-png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
-{
- png_size_t num_checked = png_ptr->sig_bytes,
- num_to_check = 8 - num_checked;
-
- if (png_ptr->buffer_size < num_to_check)
- {
- num_to_check = png_ptr->buffer_size;
- }
-
- png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
- num_to_check);
- png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
-
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
- {
- if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
- png_error(png_ptr, "Not a PNG file");
- else
- png_error(png_ptr, "PNG file corrupted by ASCII conversion");
- }
- else
- {
- if (png_ptr->sig_bytes >= 8)
- {
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- }
- }
-}
-
-void /* PRIVATE */
-png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IHDR;
- PNG_CONST PNG_IDAT;
- PNG_CONST PNG_IEND;
- PNG_CONST PNG_PLTE;
-#if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_CONST PNG_bKGD;
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_CONST PNG_cHRM;
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_CONST PNG_gAMA;
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- PNG_CONST PNG_hIST;
-#endif
-#if defined(PNG_READ_iCCP_SUPPORTED)
- PNG_CONST PNG_iCCP;
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_CONST PNG_iTXt;
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_CONST PNG_oFFs;
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_CONST PNG_pCAL;
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_CONST PNG_pHYs;
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_CONST PNG_sBIT;
-#endif
-#if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_CONST PNG_sCAL;
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_CONST PNG_sRGB;
-#endif
-#if defined(PNG_READ_sPLT_SUPPORTED)
- PNG_CONST PNG_sPLT;
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_CONST PNG_tEXt;
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- PNG_CONST PNG_tIME;
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_CONST PNG_tRNS;
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_CONST PNG_zTXt;
-#endif
-#endif /* PNG_USE_LOCAL_ARRAYS */
- /* First we make sure we have enough data for the 4 byte chunk name
- * and the 4 byte chunk length before proceeding with decoding the
- * chunk data. To fully decode each of these chunks, we also make
- * sure we have enough data in the buffer for the 4 byte CRC at the
- * end of every chunk (except IDAT, which is handled separately).
- */
- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
- {
- png_byte chunk_length[4];
-
- if (png_ptr->buffer_size < 8)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
- }
-
- if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
- if(png_ptr->mode & PNG_AFTER_IDAT)
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
-
- png_ptr->process_mode = PNG_READ_DONE_MODE;
- png_push_have_end(png_ptr, info_ptr);
- }
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_ptr->mode |= PNG_HAVE_PLTE;
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
- }
- }
-#endif
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
- {
- /* If we reach an IDAT chunk, this means we have read all of the
- * header chunks, and we can start reading the image (or if this
- * is called after the image has been read - we have an error).
- */
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
- if (png_ptr->push_length == 0)
- return;
-
- if (png_ptr->mode & PNG_AFTER_IDAT)
- png_error(png_ptr, "Too many IDAT's found");
- }
-
- png_ptr->idat_size = png_ptr->push_length;
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_ptr->process_mode = PNG_READ_IDAT_MODE;
- png_push_have_info(png_ptr, info_ptr);
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- png_ptr->zstream.next_out = png_ptr->row_buf;
- return;
- }
-#if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_iCCP_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_sPLT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_sCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
- else
- {
- if (png_ptr->push_length + 4 > png_ptr->buffer_size)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
- png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
- }
-
- png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-}
-
-void /* PRIVATE */
-png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
-{
- png_ptr->process_mode = PNG_SKIP_MODE;
- png_ptr->skip_length = skip;
-}
-
-void /* PRIVATE */
-png_push_crc_finish(png_structp png_ptr)
-{
- if (png_ptr->skip_length && png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
- save_size = (png_size_t)png_ptr->skip_length;
- else
- save_size = png_ptr->save_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
-
- png_ptr->skip_length -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (png_ptr->skip_length && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
- save_size = (png_size_t)png_ptr->skip_length;
- else
- save_size = png_ptr->current_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
- png_ptr->skip_length -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- if (!png_ptr->skip_length)
- {
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_crc_finish(png_ptr, 0);
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- }
-}
-
-void PNGAPI
-png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
-{
- png_bytep ptr;
-
- if(png_ptr == NULL) return;
- ptr = buffer;
- if (png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (length < png_ptr->save_buffer_size)
- save_size = length;
- else
- save_size = png_ptr->save_buffer_size;
-
- png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
- length -= save_size;
- ptr += save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (length && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (length < png_ptr->current_buffer_size)
- save_size = length;
- else
- save_size = png_ptr->current_buffer_size;
-
- png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
-}
-
-void /* PRIVATE */
-png_push_save_buffer(png_structp png_ptr)
-{
- if (png_ptr->save_buffer_size)
- {
- if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
- {
- png_size_t i,istop;
- png_bytep sp;
- png_bytep dp;
-
- istop = png_ptr->save_buffer_size;
- for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
- i < istop; i++, sp++, dp++)
- {
- *dp = *sp;
- }
- }
- }
- if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
- png_ptr->save_buffer_max)
- {
- png_size_t new_max;
- png_bytep old_buffer;
-
- if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
- (png_ptr->current_buffer_size + 256))
- {
- png_error(png_ptr, "Potential overflow of save_buffer");
- }
- new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
- old_buffer = png_ptr->save_buffer;
- png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)new_max);
- png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
- png_free(png_ptr, old_buffer);
- png_ptr->save_buffer_max = new_max;
- }
- if (png_ptr->current_buffer_size)
- {
- png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
- png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
- png_ptr->save_buffer_size += png_ptr->current_buffer_size;
- png_ptr->current_buffer_size = 0;
- }
- png_ptr->save_buffer_ptr = png_ptr->save_buffer;
- png_ptr->buffer_size = 0;
-}
-
-void /* PRIVATE */
-png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
-{
- png_ptr->current_buffer = buffer;
- png_ptr->current_buffer_size = buffer_length;
- png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
- png_ptr->current_buffer_ptr = png_ptr->current_buffer;
-}
-
-void /* PRIVATE */
-png_push_read_IDAT(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
-#endif
- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
- {
- png_byte chunk_length[4];
-
- if (png_ptr->buffer_size < 8)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
-
- if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
- {
- png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_error(png_ptr, "Not enough compressed data");
- return;
- }
-
- png_ptr->idat_size = png_ptr->push_length;
- }
- if (png_ptr->idat_size && png_ptr->save_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
- {
- save_size = (png_size_t)png_ptr->idat_size;
- /* check for overflow */
- if((png_uint_32)save_size != png_ptr->idat_size)
- png_error(png_ptr, "save_size overflowed in pngpread");
- }
- else
- save_size = png_ptr->save_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
- png_ptr->idat_size -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->save_buffer_size -= save_size;
- png_ptr->save_buffer_ptr += save_size;
- }
- if (png_ptr->idat_size && png_ptr->current_buffer_size)
- {
- png_size_t save_size;
-
- if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
- {
- save_size = (png_size_t)png_ptr->idat_size;
- /* check for overflow */
- if((png_uint_32)save_size != png_ptr->idat_size)
- png_error(png_ptr, "save_size overflowed in pngpread");
- }
- else
- save_size = png_ptr->current_buffer_size;
-
- png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
-
- png_ptr->idat_size -= save_size;
- png_ptr->buffer_size -= save_size;
- png_ptr->current_buffer_size -= save_size;
- png_ptr->current_buffer_ptr += save_size;
- }
- if (!png_ptr->idat_size)
- {
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_crc_finish(png_ptr, 0);
- png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
- png_ptr->mode |= PNG_AFTER_IDAT;
- }
-}
-
-void /* PRIVATE */
-png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
-{
- int ret;
-
- if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
- png_error(png_ptr, "Extra compression data");
-
- png_ptr->zstream.next_in = buffer;
- png_ptr->zstream.avail_in = (uInt)buffer_length;
- for(;;)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK)
- {
- if (ret == Z_STREAM_END)
- {
- if (png_ptr->zstream.avail_in)
- png_error(png_ptr, "Extra compressed data");
- if (!(png_ptr->zstream.avail_out))
- {
- png_push_process_row(png_ptr);
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- else if (ret == Z_BUF_ERROR)
- break;
- else
- png_error(png_ptr, "Decompression Error");
- }
- if (!(png_ptr->zstream.avail_out))
- {
- if ((
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
- png_ptr->interlaced && png_ptr->pass > 6) ||
- (!png_ptr->interlaced &&
-#endif
- png_ptr->row_number == png_ptr->num_rows))
- {
- if (png_ptr->zstream.avail_in)
- png_warning(png_ptr, "Too much data in IDAT chunks");
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- png_push_process_row(png_ptr);
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- png_ptr->zstream.next_out = png_ptr->row_buf;
- }
- else
- break;
- }
-}
-
-void /* PRIVATE */
-png_push_process_row(png_structp png_ptr)
-{
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->iwidth;
- png_ptr->row_info.channels = png_ptr->channels;
- png_ptr->row_info.bit_depth = png_ptr->bit_depth;
- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
-
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
-
- png_read_filter_row(png_ptr, &(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->prev_row + 1,
- (int)(png_ptr->row_buf[0]));
-
- png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
- png_ptr->rowbytes + 1);
-
- if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
- png_do_read_transformations(png_ptr);
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* blow up interlaced rows to full size */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- if (png_ptr->pass < 6)
-/* old interface (pre-1.0.9):
- png_do_read_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
- */
- png_do_read_interlace(png_ptr);
-
- switch (png_ptr->pass)
- {
- case 0:
- {
- int i;
- for (i = 0; i < 8 && png_ptr->pass == 0; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
- }
- if (png_ptr->pass == 2) /* pass 1 might be empty */
- {
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- if (png_ptr->pass == 4 && png_ptr->height <= 4)
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- if (png_ptr->pass == 6 && png_ptr->height <= 4)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 1:
- {
- int i;
- for (i = 0; i < 8 && png_ptr->pass == 1; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 2) /* skip top 4 generated rows */
- {
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 2:
- {
- int i;
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- for (i = 0; i < 4 && png_ptr->pass == 2; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 4) /* pass 3 might be empty */
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 3:
- {
- int i;
- for (i = 0; i < 4 && png_ptr->pass == 3; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 4) /* skip top two generated rows */
- {
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- break;
- }
- case 4:
- {
- int i;
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- for (i = 0; i < 2 && png_ptr->pass == 4; i++)
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 6) /* pass 5 might be empty */
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 5:
- {
- int i;
- for (i = 0; i < 2 && png_ptr->pass == 5; i++)
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
- if (png_ptr->pass == 6) /* skip top generated row */
- {
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- break;
- }
- case 6:
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- if (png_ptr->pass != 6)
- break;
- png_push_have_row(png_ptr, png_bytep_NULL);
- png_read_push_finish_row(png_ptr);
- }
- }
- }
- else
-#endif
- {
- png_push_have_row(png_ptr, png_ptr->row_buf + 1);
- png_read_push_finish_row(png_ptr);
- }
-}
-
-void /* PRIVATE */
-png_read_push_finish_row(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
- /* Width of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
- PNG_CONST int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
- */
-
- /* Height of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
- PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
- */
-#endif
-
- png_ptr->row_number++;
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0,
- png_ptr->rowbytes + 1);
- do
- {
- png_ptr->pass++;
- if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
- (png_ptr->pass == 3 && png_ptr->width < 3) ||
- (png_ptr->pass == 5 && png_ptr->width < 2))
- png_ptr->pass++;
-
- if (png_ptr->pass > 7)
- png_ptr->pass--;
- if (png_ptr->pass >= 7)
- break;
-
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
- png_ptr->iwidth) + 1;
-
- if (png_ptr->transformations & PNG_INTERLACE)
- break;
-
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
-
- } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
- }
-}
-
-#if defined(PNG_READ_tEXt_SUPPORTED)
-void /* PRIVATE */
-png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
-{
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
- {
- png_error(png_ptr, "Out of place tEXt");
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- png_ptr->skip_length = 0; /* This may not be necessary */
-
- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
- {
- png_warning(png_ptr, "tEXt chunk too large to fit in memory");
- png_ptr->skip_length = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_tEXt_MODE;
-}
-
-void /* PRIVATE */
-png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp text;
- png_charp key;
- int ret;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
-#if defined(PNG_MAX_MALLOC_64K)
- if (png_ptr->skip_length)
- return;
-#endif
-
- key = png_ptr->current_text;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- if (text != key + png_ptr->current_text_size)
- text++;
-
- text_ptr = (png_textp)png_malloc(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr->key = key;
-#ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
-#endif
- text_ptr->text = text;
-
- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, key);
- png_free(png_ptr, text_ptr);
- png_ptr->current_text = NULL;
-
- if (ret)
- png_warning(png_ptr, "Insufficient memory to store text chunk.");
- }
-}
-#endif
-
-#if defined(PNG_READ_zTXt_SUPPORTED)
-void /* PRIVATE */
-png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
-{
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
- {
- png_error(png_ptr, "Out of place zTXt");
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- /* We can't handle zTXt chunks > 64K, since we don't have enough space
- * to be able to store the uncompressed data. Actually, the threshold
- * is probably around 32K, but it isn't as definite as 64K is.
- */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "zTXt chunk too large to fit in memory");
- png_push_crc_skip(png_ptr, length);
- return;
- }
-#endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_zTXt_MODE;
-}
-
-void /* PRIVATE */
-png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp text;
- png_charp key;
- int ret;
- png_size_t text_size, key_size;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
- key = png_ptr->current_text;
-
- for (text = key; *text; text++)
- /* empty loop */ ;
-
- /* zTXt can't have zero text */
- if (text == key + png_ptr->current_text_size)
- {
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- return;
- }
-
- text++;
-
- if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
- {
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- return;
- }
-
- text++;
-
- png_ptr->zstream.next_in = (png_bytep )text;
- png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
- (text - key));
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- key_size = text - key;
- text_size = 0;
- text = NULL;
- ret = Z_STREAM_END;
-
- while (png_ptr->zstream.avail_in)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- png_free(png_ptr, text);
- return;
- }
- if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
- {
- if (text == NULL)
- {
- text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
- + key_size + 1));
- png_memcpy(text + key_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_memcpy(text, key, key_size);
- text_size = key_size + png_ptr->zbuf_size -
- png_ptr->zstream.avail_out;
- *(text + text_size) = '\0';
- }
- else
- {
- png_charp tmp;
-
- tmp = text;
- text = (png_charp)png_malloc(png_ptr, text_size +
- (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
- + 1));
- png_memcpy(text, tmp, text_size);
- png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = '\0';
- }
- if (ret != Z_STREAM_END)
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- else
- {
- break;
- }
-
- if (ret == Z_STREAM_END)
- break;
- }
-
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- if (ret != Z_STREAM_END)
- {
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- png_free(png_ptr, text);
- return;
- }
-
- png_ptr->current_text = NULL;
- png_free(png_ptr, key);
- key = text;
- text += key_size;
-
- text_ptr = (png_textp)png_malloc(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
- text_ptr->key = key;
-#ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
-#endif
- text_ptr->text = text;
-
- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, key);
- png_free(png_ptr, text_ptr);
-
- if (ret)
- png_warning(png_ptr, "Insufficient memory to store text chunk.");
- }
-}
-#endif
-
-#if defined(PNG_READ_iTXt_SUPPORTED)
-void /* PRIVATE */
-png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
-{
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
- {
- png_error(png_ptr, "Out of place iTXt");
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- png_ptr->skip_length = 0; /* This may not be necessary */
-
- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
- {
- png_warning(png_ptr, "iTXt chunk too large to fit in memory");
- png_ptr->skip_length = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- png_ptr->current_text = (png_charp)png_malloc(png_ptr,
- (png_uint_32)(length+1));
- png_ptr->current_text[length] = '\0';
- png_ptr->current_text_ptr = png_ptr->current_text;
- png_ptr->current_text_size = (png_size_t)length;
- png_ptr->current_text_left = (png_size_t)length;
- png_ptr->process_mode = PNG_READ_iTXt_MODE;
-}
-
-void /* PRIVATE */
-png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
-{
-
- if (png_ptr->buffer_size && png_ptr->current_text_left)
- {
- png_size_t text_size;
-
- if (png_ptr->buffer_size < png_ptr->current_text_left)
- text_size = png_ptr->buffer_size;
- else
- text_size = png_ptr->current_text_left;
- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
- png_ptr->current_text_left -= text_size;
- png_ptr->current_text_ptr += text_size;
- }
- if (!(png_ptr->current_text_left))
- {
- png_textp text_ptr;
- png_charp key;
- int comp_flag;
- png_charp lang;
- png_charp lang_key;
- png_charp text;
- int ret;
-
- if (png_ptr->buffer_size < 4)
- {
- png_push_save_buffer(png_ptr);
- return;
- }
-
- png_push_crc_finish(png_ptr);
-
-#if defined(PNG_MAX_MALLOC_64K)
- if (png_ptr->skip_length)
- return;
-#endif
-
- key = png_ptr->current_text;
-
- for (lang = key; *lang; lang++)
- /* empty loop */ ;
-
- if (lang != key + png_ptr->current_text_size)
- lang++;
-
- comp_flag = *lang++;
- lang++; /* skip comp_type, always zero */
-
- for (lang_key = lang; *lang_key; lang_key++)
- /* empty loop */ ;
- lang_key++; /* skip NUL separator */
-
- for (text = lang_key; *text; text++)
- /* empty loop */ ;
-
- if (text != key + png_ptr->current_text_size)
- text++;
-
- text_ptr = (png_textp)png_malloc(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- text_ptr->compression = comp_flag + 2;
- text_ptr->key = key;
- text_ptr->lang = lang;
- text_ptr->lang_key = lang_key;
- text_ptr->text = text;
- text_ptr->text_length = 0;
- text_ptr->itxt_length = png_strlen(text);
-
- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_ptr->current_text = NULL;
-
- png_free(png_ptr, text_ptr);
- if (ret)
- png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
- }
-}
-#endif
-
-/* This function is called when we haven't found a handler for this
- * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
- * name or a critical chunk), the chunk is (currently) silently ignored.
- */
-void /* PRIVATE */
-png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
- length)
-{
- png_uint_32 skip=0;
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
- if (!(png_ptr->chunk_name[0] & 0x20))
- {
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- && png_ptr->read_user_chunk_fn == NULL
-#endif
- )
-#endif
- png_chunk_error(png_ptr, "unknown critical chunk");
-
- info_ptr = info_ptr; /* to quiet some compiler warnings */
- }
-
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
- {
-#ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "unknown chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
- png_strncpy((png_charp)png_ptr->unknown_chunk.name,
- (png_charp)png_ptr->chunk_name,
- png_sizeof((png_charp)png_ptr->chunk_name));
- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
- png_ptr->unknown_chunk.size = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- if(png_ptr->read_user_chunk_fn != NULL)
- {
- /* callback to user unknown chunk handler */
- int ret;
- ret = (*(png_ptr->read_user_chunk_fn))
- (png_ptr, &png_ptr->unknown_chunk);
- if (ret < 0)
- png_chunk_error(png_ptr, "error in user chunk");
- if (ret == 0)
- {
- if (!(png_ptr->chunk_name[0] & 0x20))
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS)
- png_chunk_error(png_ptr, "unknown critical chunk");
- png_set_unknown_chunks(png_ptr, info_ptr,
- &png_ptr->unknown_chunk, 1);
- }
- }
-#else
- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
-#endif
- png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
- }
- else
-#endif
- skip=length;
- png_push_crc_skip(png_ptr, skip);
-}
-
-void /* PRIVATE */
-png_push_have_info(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->info_fn != NULL)
- (*(png_ptr->info_fn))(png_ptr, info_ptr);
-}
-
-void /* PRIVATE */
-png_push_have_end(png_structp png_ptr, png_infop info_ptr)
-{
- if (png_ptr->end_fn != NULL)
- (*(png_ptr->end_fn))(png_ptr, info_ptr);
-}
-
-void /* PRIVATE */
-png_push_have_row(png_structp png_ptr, png_bytep row)
-{
- if (png_ptr->row_fn != NULL)
- (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
- (int)png_ptr->pass);
-}
-
-void PNGAPI
-png_progressive_combine_row (png_structp png_ptr,
- png_bytep old_row, png_bytep new_row)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST int FARDATA png_pass_dsp_mask[7] =
- {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
-#endif
- if(png_ptr == NULL) return;
- if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
- png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
-}
-
-void PNGAPI
-png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
- png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
- png_progressive_end_ptr end_fn)
-{
- if(png_ptr == NULL) return;
- png_ptr->info_fn = info_fn;
- png_ptr->row_fn = row_fn;
- png_ptr->end_fn = end_fn;
-
- png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
-}
-
-png_voidp PNGAPI
-png_get_progressive_ptr(png_structp png_ptr)
-{
- if(png_ptr == NULL) return (NULL);
- return png_ptr->io_ptr;
-}
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngread.c b/distrib/libpng-1.2.19/pngread.c
deleted file mode 100644
index 2e561e8..0000000
--- a/distrib/libpng-1.2.19/pngread.c
+++ /dev/null
@@ -1,1478 +0,0 @@
-
-/* pngread.c - read a PNG file
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file contains routines that an application calls directly to
- * read a PNG file or stream.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED)
-
-/* Create a PNG structure for reading, and allocate any memory needed. */
-png_structp PNGAPI
-png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn)
-{
-
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
-}
-
-/* Alternate create PNG structure for reading, and allocate any memory needed. */
-png_structp PNGAPI
-png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
-
- png_structp png_ptr;
-
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
-#endif
-#endif
-
- int i;
-
- png_debug(1, "in png_create_read_struct\n");
-#ifdef PNG_USER_MEM_SUPPORTED
- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
- (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
-#else
- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
-#endif
- if (png_ptr == NULL)
- return (NULL);
-
-#if !defined(PNG_1_0_X)
-#ifdef PNG_MMX_CODE_SUPPORTED
- png_init_mmx_flags(png_ptr); /* 1.2.0 addition */
-#endif
-#endif /* PNG_1_0_X */
-
- /* added at libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
-#else
- if (setjmp(png_ptr->jmpbuf))
-#endif
- {
- png_free(png_ptr, png_ptr->zbuf);
- png_ptr->zbuf=NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr,
- (png_free_ptr)free_fn, (png_voidp)mem_ptr);
-#else
- png_destroy_struct((png_voidp)png_ptr);
-#endif
- return (NULL);
- }
-#ifdef USE_FAR_KEYWORD
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
-#endif
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif
-
- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
- i=0;
- do
- {
- if(user_png_ver[i] != png_libpng_ver[i])
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- } while (png_libpng_ver[i++]);
-
- if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
- {
- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
- * we must recompile any applications that use any older library version.
- * For versions after libpng 1.0, we will be compatible, so we need
- * only check the first digit.
- */
- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
- (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
- (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[80];
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
-#endif
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
-#endif
- png_error(png_ptr,
- "Incompatible libpng version in application and library");
- }
- }
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
-
- switch (inflateInit(&png_ptr->zstream))
- {
- case Z_OK: /* Do nothing */ break;
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
- case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
- default: png_error(png_ptr, "Unknown zlib error");
- }
-
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* Applications that neglect to set up their own setjmp() and then encounter
- a png_error() will longjmp here. Since the jmpbuf is then meaningless we
- abort instead of returning. */
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
- PNG_ABORT();
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
-#else
- if (setjmp(png_ptr->jmpbuf))
- PNG_ABORT();
-#endif
-#endif
- return (png_ptr);
-}
-
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-/* Initialize PNG structure for reading, and allocate any memory needed.
- This interface is deprecated in favour of the png_create_read_struct(),
- and it will disappear as of libpng-1.3.0. */
-#undef png_read_init
-void PNGAPI
-png_read_init(png_structp png_ptr)
-{
- /* We only come here via pre-1.0.7-compiled applications */
- png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
-}
-
-void PNGAPI
-png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size, png_size_t png_info_size)
-{
- /* We only come here via pre-1.0.12-compiled applications */
- if(png_ptr == NULL) return;
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- if(png_sizeof(png_struct) > png_struct_size ||
- png_sizeof(png_info) > png_info_size)
- {
- char msg[80];
- png_ptr->warning_fn=NULL;
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
- }
-#endif
- if(png_sizeof(png_struct) > png_struct_size)
- {
- png_ptr->error_fn=NULL;
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
-#endif
- png_error(png_ptr,
- "The png struct allocated by the application for reading is too small.");
- }
- if(png_sizeof(png_info) > png_info_size)
- {
- png_ptr->error_fn=NULL;
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
-#endif
- png_error(png_ptr,
- "The info struct allocated by application for reading is too small.");
- }
- png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
-}
-#endif /* PNG_1_0_X || PNG_1_2_X */
-
-void PNGAPI
-png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size)
-{
-#ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp; /* to save current jump buffer */
-#endif
-
- int i=0;
-
- png_structp png_ptr=*ptr_ptr;
-
- if(png_ptr == NULL) return;
-
- do
- {
- if(user_png_ver[i] != png_libpng_ver[i])
- {
-#ifdef PNG_LEGACY_SUPPORTED
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
-#else
- png_ptr->warning_fn=NULL;
- png_warning(png_ptr,
- "Application uses deprecated png_read_init() and should be recompiled.");
- break;
-#endif
- }
- } while (png_libpng_ver[i++]);
-
- png_debug(1, "in png_read_init_3\n");
-
-#ifdef PNG_SETJMP_SUPPORTED
- /* save jump buffer and error functions */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
-#endif
-
- if(png_sizeof(png_struct) > png_struct_size)
- {
- png_destroy_struct(png_ptr);
- *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
- png_ptr = *ptr_ptr;
- }
-
- /* reset all variables to 0 */
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
-#ifdef PNG_SETJMP_SUPPORTED
- /* restore jump buffer */
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
-#endif
-
- /* added at libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
-#endif
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
-
- switch (inflateInit(&png_ptr->zstream))
- {
- case Z_OK: /* Do nothing */ break;
- case Z_MEM_ERROR:
- case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
- case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
- default: png_error(png_ptr, "Unknown zlib error");
- }
-
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
-}
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* Read the information before the actual image data. This has been
- * changed in v0.90 to allow reading a file that already has the magic
- * bytes read from the stream. You can tell libpng how many bytes have
- * been read from the beginning of the stream (up to the maximum of 8)
- * via png_set_sig_bytes(), and we will only check the remaining bytes
- * here. The application can then have access to the signature bytes we
- * read if it is determined that this isn't a valid PNG file.
- */
-void PNGAPI
-png_read_info(png_structp png_ptr, png_infop info_ptr)
-{
- if(png_ptr == NULL) return;
- png_debug(1, "in png_read_info\n");
- /* If we haven't checked all of the PNG signature bytes, do so now. */
- if (png_ptr->sig_bytes < 8)
- {
- png_size_t num_checked = png_ptr->sig_bytes,
- num_to_check = 8 - num_checked;
-
- png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
- png_ptr->sig_bytes = 8;
-
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
- {
- if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
- png_error(png_ptr, "Not a PNG file");
- else
- png_error(png_ptr, "PNG file corrupted by ASCII conversion");
- }
- if (num_checked < 3)
- png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
- }
-
- for(;;)
- {
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IHDR;
- PNG_CONST PNG_IDAT;
- PNG_CONST PNG_IEND;
- PNG_CONST PNG_PLTE;
-#if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_CONST PNG_bKGD;
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_CONST PNG_cHRM;
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_CONST PNG_gAMA;
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- PNG_CONST PNG_hIST;
-#endif
-#if defined(PNG_READ_iCCP_SUPPORTED)
- PNG_CONST PNG_iCCP;
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_CONST PNG_iTXt;
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_CONST PNG_oFFs;
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_CONST PNG_pCAL;
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_CONST PNG_pHYs;
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_CONST PNG_sBIT;
-#endif
-#if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_CONST PNG_sCAL;
-#endif
-#if defined(PNG_READ_sPLT_SUPPORTED)
- PNG_CONST PNG_sPLT;
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_CONST PNG_sRGB;
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_CONST PNG_tEXt;
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- PNG_CONST PNG_tIME;
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_CONST PNG_tRNS;
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_CONST PNG_zTXt;
-#endif
-#endif /* PNG_USE_LOCAL_ARRAYS */
- png_byte chunk_length[4];
- png_uint_32 length;
-
- png_read_data(png_ptr, chunk_length, 4);
- length = png_get_uint_31(png_ptr,chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-
- png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
- length);
-
- /* This should be a binary subdivision search or a hash for
- * matching the chunk name rather than a linear search.
- */
- if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
- if(png_ptr->mode & PNG_AFTER_IDAT)
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- png_handle_IHDR(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- png_handle_IEND(png_ptr, info_ptr, length);
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
- {
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_ptr->mode |= PNG_HAVE_IDAT;
- png_handle_unknown(png_ptr, info_ptr, length);
- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_ptr->mode |= PNG_HAVE_PLTE;
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
- break;
- }
- }
-#endif
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_handle_PLTE(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before IDAT");
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- png_error(png_ptr, "Missing PLTE before IDAT");
-
- png_ptr->idat_size = length;
- png_ptr->mode |= PNG_HAVE_IDAT;
- break;
- }
-#if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
- png_handle_sCAL(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_iCCP_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
- png_handle_iCCP(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sPLT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
- png_handle_sPLT(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
- png_handle_iTXt(png_ptr, info_ptr, length);
-#endif
- else
- png_handle_unknown(png_ptr, info_ptr, length);
- }
-}
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
-/* optional call to update the users info_ptr structure */
-void PNGAPI
-png_read_update_info(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_read_update_info\n");
- if(png_ptr == NULL) return;
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
- else
- png_warning(png_ptr,
- "Ignoring extra png_read_update_info() call; row buffer not reallocated");
- png_read_transform_info(png_ptr, info_ptr);
-}
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* Initialize palette, background, etc, after transformations
- * are set, but before any reading takes place. This allows
- * the user to obtain a gamma-corrected palette, for example.
- * If the user doesn't call this, we will do it ourselves.
- */
-void PNGAPI
-png_start_read_image(png_structp png_ptr)
-{
- png_debug(1, "in png_start_read_image\n");
- if(png_ptr == NULL) return;
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
-}
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-void PNGAPI
-png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
- PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
- 0xff};
- PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
-#endif
- int ret;
- if(png_ptr == NULL) return;
- png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
- png_ptr->row_number, png_ptr->pass);
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- png_read_start_row(png_ptr);
- if (png_ptr->row_number == 0 && png_ptr->pass == 0)
- {
- /* check for transforms that have been set but were defined out */
-#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
-#endif
-#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
-#endif
- }
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* if interlaced and we do not need a new row, combine row and return */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- switch (png_ptr->pass)
- {
- case 0:
- if (png_ptr->row_number & 0x07)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 1:
- if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 2:
- if ((png_ptr->row_number & 0x07) != 4)
- {
- if (dsp_row != NULL && (png_ptr->row_number & 4))
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 3:
- if ((png_ptr->row_number & 3) || png_ptr->width < 3)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 4:
- if ((png_ptr->row_number & 3) != 2)
- {
- if (dsp_row != NULL && (png_ptr->row_number & 2))
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 5:
- if ((png_ptr->row_number & 1) || png_ptr->width < 2)
- {
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- case 6:
- if (!(png_ptr->row_number & 1))
- {
- png_read_finish_row(png_ptr);
- return;
- }
- break;
- }
- }
-#endif
-
- if (!(png_ptr->mode & PNG_HAVE_IDAT))
- png_error(png_ptr, "Invalid attempt to read row data");
-
- png_ptr->zstream.next_out = png_ptr->row_buf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
- do
- {
- if (!(png_ptr->zstream.avail_in))
- {
- while (!png_ptr->idat_size)
- {
- png_byte chunk_length[4];
-
- png_crc_finish(png_ptr, 0);
-
- png_read_data(png_ptr, chunk_length, 4);
- png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- png_error(png_ptr, "Not enough image data");
- }
- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_in = png_ptr->zbuf;
- if (png_ptr->zbuf_size > png_ptr->idat_size)
- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
- png_crc_read(png_ptr, png_ptr->zbuf,
- (png_size_t)png_ptr->zstream.avail_in);
- png_ptr->idat_size -= png_ptr->zstream.avail_in;
- }
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
- png_ptr->idat_size)
- png_error(png_ptr, "Extra compressed data");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- if (ret != Z_OK)
- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
- "Decompression error");
-
- } while (png_ptr->zstream.avail_out);
-
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->iwidth;
- png_ptr->row_info.channels = png_ptr->channels;
- png_ptr->row_info.bit_depth = png_ptr->bit_depth;
- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
-
- if(png_ptr->row_buf[0])
- png_read_filter_row(png_ptr, &(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->prev_row + 1,
- (int)(png_ptr->row_buf[0]));
-
- png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
- png_ptr->rowbytes + 1);
-
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
- {
- /* Intrapixel differencing */
- png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
- }
-#endif
-
-
- if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
- png_do_read_transformations(png_ptr);
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
- /* blow up interlaced rows to full size */
- if (png_ptr->interlaced &&
- (png_ptr->transformations & PNG_INTERLACE))
- {
- if (png_ptr->pass < 6)
-/* old interface (pre-1.0.9):
- png_do_read_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
- */
- png_do_read_interlace(png_ptr);
-
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row,
- png_pass_dsp_mask[png_ptr->pass]);
- if (row != NULL)
- png_combine_row(png_ptr, row,
- png_pass_mask[png_ptr->pass]);
- }
- else
-#endif
- {
- if (row != NULL)
- png_combine_row(png_ptr, row, 0xff);
- if (dsp_row != NULL)
- png_combine_row(png_ptr, dsp_row, 0xff);
- }
- png_read_finish_row(png_ptr);
-
- if (png_ptr->read_row_fn != NULL)
- (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
-}
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* Read one or more rows of image data. If the image is interlaced,
- * and png_set_interlace_handling() has been called, the rows need to
- * contain the contents of the rows from the previous pass. If the
- * image has alpha or transparency, and png_handle_alpha()[*] has been
- * called, the rows contents must be initialized to the contents of the
- * screen.
- *
- * "row" holds the actual image, and pixels are placed in it
- * as they arrive. If the image is displayed after each pass, it will
- * appear to "sparkle" in. "display_row" can be used to display a
- * "chunky" progressive image, with finer detail added as it becomes
- * available. If you do not want this "chunky" display, you may pass
- * NULL for display_row. If you do not want the sparkle display, and
- * you have not called png_handle_alpha(), you may pass NULL for rows.
- * If you have called png_handle_alpha(), and the image has either an
- * alpha channel or a transparency chunk, you must provide a buffer for
- * rows. In this case, you do not have to provide a display_row buffer
- * also, but you may. If the image is not interlaced, or if you have
- * not called png_set_interlace_handling(), the display_row buffer will
- * be ignored, so pass NULL to it.
- *
- * [*] png_handle_alpha() does not exist yet, as of this version of libpng
- */
-
-void PNGAPI
-png_read_rows(png_structp png_ptr, png_bytepp row,
- png_bytepp display_row, png_uint_32 num_rows)
-{
- png_uint_32 i;
- png_bytepp rp;
- png_bytepp dp;
-
- png_debug(1, "in png_read_rows\n");
- if(png_ptr == NULL) return;
- rp = row;
- dp = display_row;
- if (rp != NULL && dp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep rptr = *rp++;
- png_bytep dptr = *dp++;
-
- png_read_row(png_ptr, rptr, dptr);
- }
- else if(rp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep rptr = *rp;
- png_read_row(png_ptr, rptr, png_bytep_NULL);
- rp++;
- }
- else if(dp != NULL)
- for (i = 0; i < num_rows; i++)
- {
- png_bytep dptr = *dp;
- png_read_row(png_ptr, png_bytep_NULL, dptr);
- dp++;
- }
-}
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* Read the entire image. If the image has an alpha channel or a tRNS
- * chunk, and you have called png_handle_alpha()[*], you will need to
- * initialize the image to the current image that PNG will be overlaying.
- * We set the num_rows again here, in case it was incorrectly set in
- * png_read_start_row() by a call to png_read_update_info() or
- * png_start_read_image() if png_set_interlace_handling() wasn't called
- * prior to either of these functions like it should have been. You can
- * only call this function once. If you desire to have an image for
- * each pass of a interlaced image, use png_read_rows() instead.
- *
- * [*] png_handle_alpha() does not exist yet, as of this version of libpng
- */
-void PNGAPI
-png_read_image(png_structp png_ptr, png_bytepp image)
-{
- png_uint_32 i,image_height;
- int pass, j;
- png_bytepp rp;
-
- png_debug(1, "in png_read_image\n");
- if(png_ptr == NULL) return;
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
- pass = png_set_interlace_handling(png_ptr);
-#else
- if (png_ptr->interlaced)
- png_error(png_ptr,
- "Cannot read interlaced image -- interlace handler disabled.");
- pass = 1;
-#endif
-
-
- image_height=png_ptr->height;
- png_ptr->num_rows = image_height; /* Make sure this is set correctly */
-
- for (j = 0; j < pass; j++)
- {
- rp = image;
- for (i = 0; i < image_height; i++)
- {
- png_read_row(png_ptr, *rp, png_bytep_NULL);
- rp++;
- }
- }
-}
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-/* Read the end of the PNG file. Will not read past the end of the
- * file, will verify the end is accurate, and will read any comments
- * or time information at the end of the file, if info is not NULL.
- */
-void PNGAPI
-png_read_end(png_structp png_ptr, png_infop info_ptr)
-{
- png_byte chunk_length[4];
- png_uint_32 length;
-
- png_debug(1, "in png_read_end\n");
- if(png_ptr == NULL) return;
- png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
-
- do
- {
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IHDR;
- PNG_CONST PNG_IDAT;
- PNG_CONST PNG_IEND;
- PNG_CONST PNG_PLTE;
-#if defined(PNG_READ_bKGD_SUPPORTED)
- PNG_CONST PNG_bKGD;
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- PNG_CONST PNG_cHRM;
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- PNG_CONST PNG_gAMA;
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- PNG_CONST PNG_hIST;
-#endif
-#if defined(PNG_READ_iCCP_SUPPORTED)
- PNG_CONST PNG_iCCP;
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- PNG_CONST PNG_iTXt;
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- PNG_CONST PNG_oFFs;
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- PNG_CONST PNG_pCAL;
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- PNG_CONST PNG_pHYs;
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- PNG_CONST PNG_sBIT;
-#endif
-#if defined(PNG_READ_sCAL_SUPPORTED)
- PNG_CONST PNG_sCAL;
-#endif
-#if defined(PNG_READ_sPLT_SUPPORTED)
- PNG_CONST PNG_sPLT;
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- PNG_CONST PNG_sRGB;
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- PNG_CONST PNG_tEXt;
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- PNG_CONST PNG_tIME;
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- PNG_CONST PNG_tRNS;
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- PNG_CONST PNG_zTXt;
-#endif
-#endif /* PNG_USE_LOCAL_ARRAYS */
-
- png_read_data(png_ptr, chunk_length, 4);
- length = png_get_uint_31(png_ptr,chunk_length);
-
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-
- png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
-
- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
- png_handle_IHDR(png_ptr, info_ptr, length);
- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
- png_handle_IEND(png_ptr, info_ptr, length);
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
- {
- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
- png_error(png_ptr, "Too many IDAT's found");
- }
- png_handle_unknown(png_ptr, info_ptr, length);
- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_ptr->mode |= PNG_HAVE_PLTE;
- }
-#endif
- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
- {
- /* Zero length IDATs are legal after the last IDAT has been
- * read, but not after other chunks have been read.
- */
- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
- png_error(png_ptr, "Too many IDAT's found");
- png_crc_finish(png_ptr, length);
- }
- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
- png_handle_PLTE(png_ptr, info_ptr, length);
-#if defined(PNG_READ_bKGD_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
- png_handle_bKGD(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_cHRM_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
- png_handle_cHRM(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_gAMA_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
- png_handle_gAMA(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
- png_handle_hIST(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_oFFs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
- png_handle_oFFs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
- png_handle_pCAL(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sCAL_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
- png_handle_sCAL(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_pHYs_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
- png_handle_pHYs(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sBIT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
- png_handle_sBIT(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sRGB_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
- png_handle_sRGB(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_iCCP_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
- png_handle_iCCP(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_sPLT_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
- png_handle_sPLT(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tEXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
- png_handle_tEXt(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tIME_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
- png_handle_tIME(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_tRNS_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
- png_handle_tRNS(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_zTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
- png_handle_zTXt(png_ptr, info_ptr, length);
-#endif
-#if defined(PNG_READ_iTXt_SUPPORTED)
- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
- png_handle_iTXt(png_ptr, info_ptr, length);
-#endif
- else
- png_handle_unknown(png_ptr, info_ptr, length);
- } while (!(png_ptr->mode & PNG_HAVE_IEND));
-}
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-
-/* free all memory used by the read */
-void PNGAPI
-png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
- png_infopp end_info_ptr_ptr)
-{
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL, end_info_ptr = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
- png_voidp mem_ptr;
-#endif
-
- png_debug(1, "in png_destroy_read_struct\n");
- if (png_ptr_ptr != NULL)
- png_ptr = *png_ptr_ptr;
-
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (end_info_ptr_ptr != NULL)
- end_info_ptr = *end_info_ptr_ptr;
-
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
- mem_ptr = png_ptr->mem_ptr;
-#endif
-
- png_read_destroy(png_ptr, info_ptr, end_info_ptr);
-
- if (info_ptr != NULL)
- {
-#if defined(PNG_TEXT_SUPPORTED)
- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
-#else
- png_destroy_struct((png_voidp)info_ptr);
-#endif
- *info_ptr_ptr = NULL;
- }
-
- if (end_info_ptr != NULL)
- {
-#if defined(PNG_READ_TEXT_SUPPORTED)
- png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
-#endif
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
-#else
- png_destroy_struct((png_voidp)end_info_ptr);
-#endif
- *end_info_ptr_ptr = NULL;
- }
-
- if (png_ptr != NULL)
- {
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
-#else
- png_destroy_struct((png_voidp)png_ptr);
-#endif
- *png_ptr_ptr = NULL;
- }
-}
-
-/* free all memory used by the read (old method) */
-void /* PRIVATE */
-png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
-{
-#ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp;
-#endif
- png_error_ptr error_fn;
- png_error_ptr warning_fn;
- png_voidp error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
-#endif
-
- png_debug(1, "in png_read_destroy\n");
- if (info_ptr != NULL)
- png_info_destroy(png_ptr, info_ptr);
-
- if (end_info_ptr != NULL)
- png_info_destroy(png_ptr, end_info_ptr);
-
- png_free(png_ptr, png_ptr->zbuf);
- png_free(png_ptr, png_ptr->big_row_buf);
- png_free(png_ptr, png_ptr->prev_row);
-#if defined(PNG_READ_DITHER_SUPPORTED)
- png_free(png_ptr, png_ptr->palette_lookup);
- png_free(png_ptr, png_ptr->dither_index);
-#endif
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- png_free(png_ptr, png_ptr->gamma_table);
-#endif
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- png_free(png_ptr, png_ptr->gamma_from_1);
- png_free(png_ptr, png_ptr->gamma_to_1);
-#endif
-#ifdef PNG_FREE_ME_SUPPORTED
- if (png_ptr->free_me & PNG_FREE_PLTE)
- png_zfree(png_ptr, png_ptr->palette);
- png_ptr->free_me &= ~PNG_FREE_PLTE;
-#else
- if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
- png_zfree(png_ptr, png_ptr->palette);
- png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
-#endif
-#if defined(PNG_tRNS_SUPPORTED) || \
- defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-#ifdef PNG_FREE_ME_SUPPORTED
- if (png_ptr->free_me & PNG_FREE_TRNS)
- png_free(png_ptr, png_ptr->trans);
- png_ptr->free_me &= ~PNG_FREE_TRNS;
-#else
- if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
- png_free(png_ptr, png_ptr->trans);
- png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
-#endif
-#endif
-#if defined(PNG_READ_hIST_SUPPORTED)
-#ifdef PNG_FREE_ME_SUPPORTED
- if (png_ptr->free_me & PNG_FREE_HIST)
- png_free(png_ptr, png_ptr->hist);
- png_ptr->free_me &= ~PNG_FREE_HIST;
-#else
- if (png_ptr->flags & PNG_FLAG_FREE_HIST)
- png_free(png_ptr, png_ptr->hist);
- png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
-#endif
-#endif
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->gamma_16_table != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_table[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_table);
- }
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_from_1 != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_from_1);
- }
- if (png_ptr->gamma_16_to_1 != NULL)
- {
- int i;
- int istop = (1 << (8 - png_ptr->gamma_shift));
- for (i = 0; i < istop; i++)
- {
- png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
- }
- png_free(png_ptr, png_ptr->gamma_16_to_1);
- }
-#endif
-#endif
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_free(png_ptr, png_ptr->time_buffer);
-#endif
-
- inflateEnd(&png_ptr->zstream);
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
- png_free(png_ptr, png_ptr->save_buffer);
-#endif
-
-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-#ifdef PNG_TEXT_SUPPORTED
- png_free(png_ptr, png_ptr->current_text);
-#endif /* PNG_TEXT_SUPPORTED */
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-
- /* Save the important info out of the png_struct, in case it is
- * being used again.
- */
-#ifdef PNG_SETJMP_SUPPORTED
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
-#endif
-
- error_fn = png_ptr->error_fn;
- warning_fn = png_ptr->warning_fn;
- error_ptr = png_ptr->error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
-#endif
-
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- png_ptr->error_ptr = error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_ptr->free_fn = free_fn;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
-#endif
-
-}
-
-void PNGAPI
-png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
-{
- if(png_ptr == NULL) return;
- png_ptr->read_row_fn = read_row_fn;
-}
-
-
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-void PNGAPI
-png_read_png(png_structp png_ptr, png_infop info_ptr,
- int transforms,
- voidp params)
-{
- int row;
-
- if(png_ptr == NULL) return;
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel from opacity to transparency
- */
- if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
- png_set_invert_alpha(png_ptr);
-#endif
-
- /* png_read_info() gives us all of the information from the
- * PNG file before the first IDAT (image data chunk).
- */
- png_read_info(png_ptr, info_ptr);
- if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
- png_error(png_ptr,"Image is too high to process with png_read_png()");
-
- /* -------------- image transformations start here ------------------- */
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
- /* tell libpng to strip 16 bit/color files down to 8 bits per color
- */
- if (transforms & PNG_TRANSFORM_STRIP_16)
- png_set_strip_16(png_ptr);
-#endif
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- /* Strip alpha bytes from the input data without combining with
- * the background (not recommended).
- */
- if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
- png_set_strip_alpha(png_ptr);
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
- /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
- * byte into separate bytes (useful for paletted and grayscale images).
- */
- if (transforms & PNG_TRANSFORM_PACKING)
- png_set_packing(png_ptr);
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- /* Change the order of packed pixels to least significant bit first
- * (not useful if you are using png_set_packing).
- */
- if (transforms & PNG_TRANSFORM_PACKSWAP)
- png_set_packswap(png_ptr);
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- /* Expand paletted colors into true RGB triplets
- * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
- * Expand paletted or RGB images with transparency to full alpha
- * channels so the data will be available as RGBA quartets.
- */
- if (transforms & PNG_TRANSFORM_EXPAND)
- if ((png_ptr->bit_depth < 8) ||
- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
- (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
- png_set_expand(png_ptr);
-#endif
-
- /* We don't handle background color or gamma transformation or dithering.
- */
-
-#if defined(PNG_READ_INVERT_SUPPORTED)
- /* invert monochrome files to have 0 as white and 1 as black
- */
- if (transforms & PNG_TRANSFORM_INVERT_MONO)
- png_set_invert_mono(png_ptr);
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
- /* If you want to shift the pixel values from the range [0,255] or
- * [0,65535] to the original [0,7] or [0,31], or whatever range the
- * colors were originally in:
- */
- if ((transforms & PNG_TRANSFORM_SHIFT)
- && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
- {
- png_color_8p sig_bit;
-
- png_get_sBIT(png_ptr, info_ptr, &sig_bit);
- png_set_shift(png_ptr, sig_bit);
- }
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED)
- /* flip the RGB pixels to BGR (or RGBA to BGRA)
- */
- if (transforms & PNG_TRANSFORM_BGR)
- png_set_bgr(png_ptr);
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
- */
- if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
- png_set_swap_alpha(png_ptr);
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED)
- /* swap bytes of 16 bit files to least significant byte first
- */
- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
- png_set_swap(png_ptr);
-#endif
-
- /* We don't handle adding filler bytes */
-
- /* Optional call to gamma correct and add the background to the palette
- * and update info structure. REQUIRED if you are expecting libpng to
- * update the palette for you (i.e., you selected such a transform above).
- */
- png_read_update_info(png_ptr, info_ptr);
-
- /* -------------- image transformations end here ------------------- */
-
-#ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
-#endif
- if(info_ptr->row_pointers == NULL)
- {
- info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
- info_ptr->height * png_sizeof(png_bytep));
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_ROWS;
-#endif
- for (row = 0; row < (int)info_ptr->height; row++)
- {
- info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
- png_get_rowbytes(png_ptr, info_ptr));
- }
- }
-
- png_read_image(png_ptr, info_ptr->row_pointers);
- info_ptr->valid |= PNG_INFO_IDAT;
-
- /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
- png_read_end(png_ptr, info_ptr);
-
- transforms = transforms; /* quiet compiler warnings */
- params = params;
-
-}
-#endif /* PNG_INFO_IMAGE_SUPPORTED */
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngrio.c b/distrib/libpng-1.2.19/pngrio.c
deleted file mode 100644
index 7d2522f..0000000
--- a/distrib/libpng-1.2.19/pngrio.c
+++ /dev/null
@@ -1,167 +0,0 @@
-
-/* pngrio.c - functions for data input
- *
- * Last changed in libpng 1.2.13 November 13, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all input. Users who need
- * special handling are expected to write a function that has the same
- * arguments as this and performs a similar function, but that possibly
- * has a different input method. Note that you shouldn't change this
- * function, but rather write a replacement function and then make
- * libpng use it at run time with png_set_read_fn(...).
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED)
-
-/* Read the data from whatever input you are using. The default routine
- reads from a file pointer. Note that this routine sometimes gets called
- with very small lengths, so you should implement some kind of simple
- buffering if you are using unbuffered reads. This should never be asked
- to read more then 64K on a 16 bit machine. */
-void /* PRIVATE */
-png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_debug1(4,"reading %d bytes\n", (int)length);
- if (png_ptr->read_data_fn != NULL)
- (*(png_ptr->read_data_fn))(png_ptr, data, length);
- else
- png_error(png_ptr, "Call to NULL read function");
-}
-
-#if !defined(PNG_NO_STDIO)
-/* This is the function that does the actual reading of data. If you are
- not reading from a standard C stream, you should create a replacement
- read_data function and use it at run time with png_set_read_fn(), rather
- than changing the library. */
-#ifndef USE_FAR_KEYWORD
-void PNGAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_size_t check;
-
- if(png_ptr == NULL) return;
- /* fread() returns 0 on error, so it is OK to store this in a png_size_t
- * instead of an int, which is what fread() actually returns.
- */
-#if defined(_WIN32_WCE)
- if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
- check = 0;
-#else
- check = (png_size_t)fread(data, (png_size_t)1, length,
- (png_FILE_p)png_ptr->io_ptr);
-#endif
-
- if (check != length)
- png_error(png_ptr, "Read Error");
-}
-#else
-/* this is the model-independent version. Since the standard I/O library
- can't handle far buffers in the medium and small models, we have to copy
- the data.
-*/
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-static void PNGAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- int check;
- png_byte *n_data;
- png_FILE_p io_ptr;
-
- if(png_ptr == NULL) return;
- /* Check if data really is near. If so, use usual code. */
- n_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)n_data == data)
- {
-#if defined(_WIN32_WCE)
- if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
- check = 0;
-#else
- check = fread(n_data, 1, length, io_ptr);
-#endif
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t read, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- read = MIN(NEAR_BUF_SIZE, remaining);
-#if defined(_WIN32_WCE)
- if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
- err = 0;
-#else
- err = fread(buf, (png_size_t)1, read, io_ptr);
-#endif
- png_memcpy(data, buf, read); /* copy far buffer to near buffer */
- if(err != read)
- break;
- else
- check += err;
- data += read;
- remaining -= read;
- }
- while (remaining != 0);
- }
- if ((png_uint_32)check != (png_uint_32)length)
- png_error(png_ptr, "read Error");
-}
-#endif
-#endif
-
-/* This function allows the application to supply a new input function
- for libpng if standard C streams aren't being used.
-
- This function takes as its arguments:
- png_ptr - pointer to a png input data structure
- io_ptr - pointer to user supplied structure containing info about
- the input functions. May be NULL.
- read_data_fn - pointer to a new input function that takes as its
- arguments a pointer to a png_struct, a pointer to
- a location where input data can be stored, and a 32-bit
- unsigned int that is the number of bytes to be read.
- To exit and output any fatal error messages the new write
- function should call png_error(png_ptr, "Error msg"). */
-void PNGAPI
-png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
- png_rw_ptr read_data_fn)
-{
- if(png_ptr == NULL) return;
- png_ptr->io_ptr = io_ptr;
-
-#if !defined(PNG_NO_STDIO)
- if (read_data_fn != NULL)
- png_ptr->read_data_fn = read_data_fn;
- else
- png_ptr->read_data_fn = png_default_read_data;
-#else
- png_ptr->read_data_fn = read_data_fn;
-#endif
-
- /* It is an error to write to a read device */
- if (png_ptr->write_data_fn != NULL)
- {
- png_ptr->write_data_fn = NULL;
- png_warning(png_ptr,
- "It's an error to set both read_data_fn and write_data_fn in the ");
- png_warning(png_ptr,
- "same structure. Resetting write_data_fn to NULL.");
- }
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_ptr->output_flush_fn = NULL;
-#endif
-}
-#endif /* PNG_READ_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngrtran.c b/distrib/libpng-1.2.19/pngrtran.c
deleted file mode 100644
index 3f04051..0000000
--- a/distrib/libpng-1.2.19/pngrtran.c
+++ /dev/null
@@ -1,4284 +0,0 @@
-
-/* pngrtran.c - transforms the data in a row for PNG readers
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file contains functions optionally called by an application
- * in order to tell libpng how to handle data when reading a PNG.
- * Transformations that are used in both reading and writing are
- * in pngtrans.c.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED)
-
-/* Set the action on getting a CRC error for an ancillary or critical chunk. */
-void PNGAPI
-png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
-{
- png_debug(1, "in png_set_crc_action\n");
- /* Tell libpng how we react to CRC errors in critical chunks */
- if(png_ptr == NULL) return;
- switch (crit_action)
- {
- case PNG_CRC_NO_CHANGE: /* leave setting as is */
- break;
- case PNG_CRC_WARN_USE: /* warn/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
- break;
- case PNG_CRC_QUIET_USE: /* quiet/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
- PNG_FLAG_CRC_CRITICAL_IGNORE;
- break;
- case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
- png_warning(png_ptr, "Can't discard critical data on CRC error.");
- case PNG_CRC_ERROR_QUIT: /* error/quit */
- case PNG_CRC_DEFAULT:
- default:
- png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
- break;
- }
-
- switch (ancil_action)
- {
- case PNG_CRC_NO_CHANGE: /* leave setting as is */
- break;
- case PNG_CRC_WARN_USE: /* warn/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
- break;
- case PNG_CRC_QUIET_USE: /* quiet/use data */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
- PNG_FLAG_CRC_ANCILLARY_NOWARN;
- break;
- case PNG_CRC_ERROR_QUIT: /* error/quit */
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
- break;
- case PNG_CRC_WARN_DISCARD: /* warn/discard data */
- case PNG_CRC_DEFAULT:
- default:
- png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
- break;
- }
-}
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
- defined(PNG_FLOATING_POINT_SUPPORTED)
-/* handle alpha and tRNS via a background color */
-void PNGAPI
-png_set_background(png_structp png_ptr,
- png_color_16p background_color, int background_gamma_code,
- int need_expand, double background_gamma)
-{
- png_debug(1, "in png_set_background\n");
- if(png_ptr == NULL) return;
- if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
- {
- png_warning(png_ptr, "Application must supply a known background gamma");
- return;
- }
-
- png_ptr->transformations |= PNG_BACKGROUND;
- png_memcpy(&(png_ptr->background), background_color,
- png_sizeof(png_color_16));
- png_ptr->background_gamma = (float)background_gamma;
- png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
- png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
-}
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* strip 16 bit depth files to 8 bit depth */
-void PNGAPI
-png_set_strip_16(png_structp png_ptr)
-{
- png_debug(1, "in png_set_strip_16\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_16_TO_8;
-}
-#endif
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-void PNGAPI
-png_set_strip_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_strip_alpha\n");
- if(png_ptr == NULL) return;
- png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-/* Dither file to 8 bit. Supply a palette, the current number
- * of elements in the palette, the maximum number of elements
- * allowed, and a histogram if possible. If the current number
- * of colors is greater then the maximum number, the palette will be
- * modified to fit in the maximum number. "full_dither" indicates
- * whether we need a dithering cube set up for RGB images, or if we
- * simply are reducing the number of colors in a paletted image.
- */
-
-typedef struct png_dsort_struct
-{
- struct png_dsort_struct FAR * next;
- png_byte left;
- png_byte right;
-} png_dsort;
-typedef png_dsort FAR * png_dsortp;
-typedef png_dsort FAR * FAR * png_dsortpp;
-
-void PNGAPI
-png_set_dither(png_structp png_ptr, png_colorp palette,
- int num_palette, int maximum_colors, png_uint_16p histogram,
- int full_dither)
-{
- png_debug(1, "in png_set_dither\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_DITHER;
-
- if (!full_dither)
- {
- int i;
-
- png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
- for (i = 0; i < num_palette; i++)
- png_ptr->dither_index[i] = (png_byte)i;
- }
-
- if (num_palette > maximum_colors)
- {
- if (histogram != NULL)
- {
- /* This is easy enough, just throw out the least used colors.
- Perhaps not the best solution, but good enough. */
-
- int i;
-
- /* initialize an array to sort colors */
- png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
-
- /* initialize the dither_sort array */
- for (i = 0; i < num_palette; i++)
- png_ptr->dither_sort[i] = (png_byte)i;
-
- /* Find the least used palette entries by starting a
- bubble sort, and running it until we have sorted
- out enough colors. Note that we don't care about
- sorting all the colors, just finding which are
- least used. */
-
- for (i = num_palette - 1; i >= maximum_colors; i--)
- {
- int done; /* to stop early if the list is pre-sorted */
- int j;
-
- done = 1;
- for (j = 0; j < i; j++)
- {
- if (histogram[png_ptr->dither_sort[j]]
- < histogram[png_ptr->dither_sort[j + 1]])
- {
- png_byte t;
-
- t = png_ptr->dither_sort[j];
- png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
- png_ptr->dither_sort[j + 1] = t;
- done = 0;
- }
- }
- if (done)
- break;
- }
-
- /* swap the palette around, and set up a table, if necessary */
- if (full_dither)
- {
- int j = num_palette;
-
- /* put all the useful colors within the max, but don't
- move the others */
- for (i = 0; i < maximum_colors; i++)
- {
- if ((int)png_ptr->dither_sort[i] >= maximum_colors)
- {
- do
- j--;
- while ((int)png_ptr->dither_sort[j] >= maximum_colors);
- palette[i] = palette[j];
- }
- }
- }
- else
- {
- int j = num_palette;
-
- /* move all the used colors inside the max limit, and
- develop a translation table */
- for (i = 0; i < maximum_colors; i++)
- {
- /* only move the colors we need to */
- if ((int)png_ptr->dither_sort[i] >= maximum_colors)
- {
- png_color tmp_color;
-
- do
- j--;
- while ((int)png_ptr->dither_sort[j] >= maximum_colors);
-
- tmp_color = palette[j];
- palette[j] = palette[i];
- palette[i] = tmp_color;
- /* indicate where the color went */
- png_ptr->dither_index[j] = (png_byte)i;
- png_ptr->dither_index[i] = (png_byte)j;
- }
- }
-
- /* find closest color for those colors we are not using */
- for (i = 0; i < num_palette; i++)
- {
- if ((int)png_ptr->dither_index[i] >= maximum_colors)
- {
- int min_d, k, min_k, d_index;
-
- /* find the closest color to one we threw out */
- d_index = png_ptr->dither_index[i];
- min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
- for (k = 1, min_k = 0; k < maximum_colors; k++)
- {
- int d;
-
- d = PNG_COLOR_DIST(palette[d_index], palette[k]);
-
- if (d < min_d)
- {
- min_d = d;
- min_k = k;
- }
- }
- /* point to closest color */
- png_ptr->dither_index[i] = (png_byte)min_k;
- }
- }
- }
- png_free(png_ptr, png_ptr->dither_sort);
- png_ptr->dither_sort=NULL;
- }
- else
- {
- /* This is much harder to do simply (and quickly). Perhaps
- we need to go through a median cut routine, but those
- don't always behave themselves with only a few colors
- as input. So we will just find the closest two colors,
- and throw out one of them (chosen somewhat randomly).
- [We don't understand this at all, so if someone wants to
- work on improving it, be our guest - AED, GRP]
- */
- int i;
- int max_d;
- int num_new_palette;
- png_dsortp t;
- png_dsortpp hash;
-
- t=NULL;
-
- /* initialize palette index arrays */
- png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
- png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(num_palette * png_sizeof (png_byte)));
-
- /* initialize the sort array */
- for (i = 0; i < num_palette; i++)
- {
- png_ptr->index_to_palette[i] = (png_byte)i;
- png_ptr->palette_to_index[i] = (png_byte)i;
- }
-
- hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
- png_sizeof (png_dsortp)));
- for (i = 0; i < 769; i++)
- hash[i] = NULL;
-/* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
-
- num_new_palette = num_palette;
-
- /* initial wild guess at how far apart the farthest pixel
- pair we will be eliminating will be. Larger
- numbers mean more areas will be allocated, Smaller
- numbers run the risk of not saving enough data, and
- having to do this all over again.
-
- I have not done extensive checking on this number.
- */
- max_d = 96;
-
- while (num_new_palette > maximum_colors)
- {
- for (i = 0; i < num_new_palette - 1; i++)
- {
- int j;
-
- for (j = i + 1; j < num_new_palette; j++)
- {
- int d;
-
- d = PNG_COLOR_DIST(palette[i], palette[j]);
-
- if (d <= max_d)
- {
-
- t = (png_dsortp)png_malloc_warn(png_ptr,
- (png_uint_32)(png_sizeof(png_dsort)));
- if (t == NULL)
- break;
- t->next = hash[d];
- t->left = (png_byte)i;
- t->right = (png_byte)j;
- hash[d] = t;
- }
- }
- if (t == NULL)
- break;
- }
-
- if (t != NULL)
- for (i = 0; i <= max_d; i++)
- {
- if (hash[i] != NULL)
- {
- png_dsortp p;
-
- for (p = hash[i]; p; p = p->next)
- {
- if ((int)png_ptr->index_to_palette[p->left]
- < num_new_palette &&
- (int)png_ptr->index_to_palette[p->right]
- < num_new_palette)
- {
- int j, next_j;
-
- if (num_new_palette & 0x01)
- {
- j = p->left;
- next_j = p->right;
- }
- else
- {
- j = p->right;
- next_j = p->left;
- }
-
- num_new_palette--;
- palette[png_ptr->index_to_palette[j]]
- = palette[num_new_palette];
- if (!full_dither)
- {
- int k;
-
- for (k = 0; k < num_palette; k++)
- {
- if (png_ptr->dither_index[k] ==
- png_ptr->index_to_palette[j])
- png_ptr->dither_index[k] =
- png_ptr->index_to_palette[next_j];
- if ((int)png_ptr->dither_index[k] ==
- num_new_palette)
- png_ptr->dither_index[k] =
- png_ptr->index_to_palette[j];
- }
- }
-
- png_ptr->index_to_palette[png_ptr->palette_to_index
- [num_new_palette]] = png_ptr->index_to_palette[j];
- png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
- = png_ptr->palette_to_index[num_new_palette];
-
- png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
- png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
- }
- if (num_new_palette <= maximum_colors)
- break;
- }
- if (num_new_palette <= maximum_colors)
- break;
- }
- }
-
- for (i = 0; i < 769; i++)
- {
- if (hash[i] != NULL)
- {
- png_dsortp p = hash[i];
- while (p)
- {
- t = p->next;
- png_free(png_ptr, p);
- p = t;
- }
- }
- hash[i] = 0;
- }
- max_d += 96;
- }
- png_free(png_ptr, hash);
- png_free(png_ptr, png_ptr->palette_to_index);
- png_free(png_ptr, png_ptr->index_to_palette);
- png_ptr->palette_to_index=NULL;
- png_ptr->index_to_palette=NULL;
- }
- num_palette = maximum_colors;
- }
- if (png_ptr->palette == NULL)
- {
- png_ptr->palette = palette;
- }
- png_ptr->num_palette = (png_uint_16)num_palette;
-
- if (full_dither)
- {
- int i;
- png_bytep distance;
- int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
- PNG_DITHER_BLUE_BITS;
- int num_red = (1 << PNG_DITHER_RED_BITS);
- int num_green = (1 << PNG_DITHER_GREEN_BITS);
- int num_blue = (1 << PNG_DITHER_BLUE_BITS);
- png_size_t num_entries = ((png_size_t)1 << total_bits);
-
- png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
- (png_uint_32)(num_entries * png_sizeof (png_byte)));
-
- png_memset(png_ptr->palette_lookup, 0, num_entries *
- png_sizeof (png_byte));
-
- distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
- png_sizeof(png_byte)));
-
- png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
-
- for (i = 0; i < num_palette; i++)
- {
- int ir, ig, ib;
- int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
- int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
- int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
-
- for (ir = 0; ir < num_red; ir++)
- {
- /* int dr = abs(ir - r); */
- int dr = ((ir > r) ? ir - r : r - ir);
- int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
-
- for (ig = 0; ig < num_green; ig++)
- {
- /* int dg = abs(ig - g); */
- int dg = ((ig > g) ? ig - g : g - ig);
- int dt = dr + dg;
- int dm = ((dr > dg) ? dr : dg);
- int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
-
- for (ib = 0; ib < num_blue; ib++)
- {
- int d_index = index_g | ib;
- /* int db = abs(ib - b); */
- int db = ((ib > b) ? ib - b : b - ib);
- int dmax = ((dm > db) ? dm : db);
- int d = dmax + dt + db;
-
- if (d < (int)distance[d_index])
- {
- distance[d_index] = (png_byte)d;
- png_ptr->palette_lookup[d_index] = (png_byte)i;
- }
- }
- }
- }
- }
-
- png_free(png_ptr, distance);
- }
-}
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
-/* Transform the image from the file_gamma to the screen_gamma. We
- * only do transformations on images where the file_gamma and screen_gamma
- * are not close reciprocals, otherwise it slows things down slightly, and
- * also needlessly introduces small errors.
- *
- * We will turn off gamma transformation later if no semitransparent entries
- * are present in the tRNS array for palette images. We can't do it here
- * because we don't necessarily have the tRNS chunk yet.
- */
-void PNGAPI
-png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
-{
- png_debug(1, "in png_set_gamma\n");
- if(png_ptr == NULL) return;
- if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
- png_ptr->transformations |= PNG_GAMMA;
- png_ptr->gamma = (float)file_gamma;
- png_ptr->screen_gamma = (float)scrn_gamma;
-}
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand paletted images to RGB, expand grayscale images of
- * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
- * to alpha channels.
- */
-void PNGAPI
-png_set_expand(png_structp png_ptr)
-{
- png_debug(1, "in png_set_expand\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-#ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
-#endif
-}
-
-/* GRR 19990627: the following three functions currently are identical
- * to png_set_expand(). However, it is entirely reasonable that someone
- * might wish to expand an indexed image to RGB but *not* expand a single,
- * fully transparent palette entry to a full alpha channel--perhaps instead
- * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
- * the transparent color with a particular RGB value, or drop tRNS entirely.
- * IOW, a future version of the library may make the transformations flag
- * a bit more fine-grained, with separate bits for each of these three
- * functions.
- *
- * More to the point, these functions make it obvious what libpng will be
- * doing, whereas "expand" can (and does) mean any number of things.
- *
- * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
- * to expand only the sample depth but not to expand the tRNS to alpha.
- */
-
-/* Expand paletted images to RGB. */
-void PNGAPI
-png_set_palette_to_rgb(png_structp png_ptr)
-{
- png_debug(1, "in png_set_palette_to_rgb\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-#ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
-#endif
-}
-
-#if !defined(PNG_1_0_X)
-/* Expand grayscale images of less than 8-bit depth to 8 bits. */
-void PNGAPI
-png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
-{
- png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_EXPAND;
-#ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
-#endif
-}
-#endif
-
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-/* Expand grayscale images of less than 8-bit depth to 8 bits. */
-/* Deprecated as of libpng-1.2.9 */
-void PNGAPI
-png_set_gray_1_2_4_to_8(png_structp png_ptr)
-{
- png_debug(1, "in png_set_gray_1_2_4_to_8\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-}
-#endif
-
-
-/* Expand tRNS chunks to alpha channels. */
-void PNGAPI
-png_set_tRNS_to_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_tRNS_to_alpha\n");
- png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
-#ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
-#endif
-}
-#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-void PNGAPI
-png_set_gray_to_rgb(png_structp png_ptr)
-{
- png_debug(1, "in png_set_gray_to_rgb\n");
- png_ptr->transformations |= PNG_GRAY_TO_RGB;
-#ifdef PNG_WARN_UNINITIALIZED_ROW
- png_ptr->flags &= !(PNG_FLAG_ROW_INIT);
-#endif
-}
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-#if defined(PNG_FLOATING_POINT_SUPPORTED)
-/* Convert a RGB image to a grayscale of the same width. This allows us,
- * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
- */
-
-void PNGAPI
-png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
- double green)
-{
- int red_fixed = (int)((float)red*100000.0 + 0.5);
- int green_fixed = (int)((float)green*100000.0 + 0.5);
- if(png_ptr == NULL) return;
- png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
-}
-#endif
-
-void PNGAPI
-png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
- png_fixed_point red, png_fixed_point green)
-{
- png_debug(1, "in png_set_rgb_to_gray\n");
- if(png_ptr == NULL) return;
- switch(error_action)
- {
- case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
- break;
- case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
- break;
- case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
- }
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- png_ptr->transformations |= PNG_EXPAND;
-#else
- {
- png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
- png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
- }
-#endif
- {
- png_uint_16 red_int, green_int;
- if(red < 0 || green < 0)
- {
- red_int = 6968; /* .212671 * 32768 + .5 */
- green_int = 23434; /* .715160 * 32768 + .5 */
- }
- else if(red + green < 100000L)
- {
- red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
- green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
- }
- else
- {
- png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
- red_int = 6968;
- green_int = 23434;
- }
- png_ptr->rgb_to_gray_red_coeff = red_int;
- png_ptr->rgb_to_gray_green_coeff = green_int;
- png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
- }
-}
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
-void PNGAPI
-png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
- read_user_transform_fn)
-{
- png_debug(1, "in png_set_read_user_transform_fn\n");
- if(png_ptr == NULL) return;
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- png_ptr->transformations |= PNG_USER_TRANSFORM;
- png_ptr->read_user_transform_fn = read_user_transform_fn;
-#endif
-#ifdef PNG_LEGACY_SUPPORTED
- if(read_user_transform_fn)
- png_warning(png_ptr,
- "This version of libpng does not support user transforms");
-#endif
-}
-#endif
-
-/* Initialize everything needed for the read. This includes modifying
- * the palette.
- */
-void /* PRIVATE */
-png_init_read_transformations(png_structp png_ptr)
-{
- png_debug(1, "in png_init_read_transformations\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if(png_ptr != NULL)
-#endif
- {
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
- || defined(PNG_READ_GAMMA_SUPPORTED)
- int color_type = png_ptr->color_type;
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* Detect gray background and attempt to enable optimization
- * for gray --> RGB case */
- /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
- * RGB_ALPHA (in which case need_expand is superfluous anyway), the
- * background color might actually be gray yet not be flagged as such.
- * This is not a problem for the current code, which uses
- * PNG_BACKGROUND_IS_GRAY only to decide when to do the
- * png_do_gray_to_rgb() transformation.
- */
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
- !(color_type & PNG_COLOR_MASK_COLOR))
- {
- png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
- } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
- !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
- (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
- png_ptr->background.red == png_ptr->background.green &&
- png_ptr->background.red == png_ptr->background.blue)
- {
- png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
- png_ptr->background.gray = png_ptr->background.red;
- }
-#endif
-
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
- (png_ptr->transformations & PNG_EXPAND))
- {
- if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
- {
- /* expand background and tRNS chunks */
- switch (png_ptr->bit_depth)
- {
- case 1:
- png_ptr->background.gray *= (png_uint_16)0xff;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- {
- png_ptr->trans_values.gray *= (png_uint_16)0xff;
- png_ptr->trans_values.red = png_ptr->trans_values.green
- = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- }
- break;
- case 2:
- png_ptr->background.gray *= (png_uint_16)0x55;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- {
- png_ptr->trans_values.gray *= (png_uint_16)0x55;
- png_ptr->trans_values.red = png_ptr->trans_values.green
- = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- }
- break;
- case 4:
- png_ptr->background.gray *= (png_uint_16)0x11;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
- {
- png_ptr->trans_values.gray *= (png_uint_16)0x11;
- png_ptr->trans_values.red = png_ptr->trans_values.green
- = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- }
- break;
- case 8:
- case 16:
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- break;
- }
- }
- else if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_ptr->background.red =
- png_ptr->palette[png_ptr->background.index].red;
- png_ptr->background.green =
- png_ptr->palette[png_ptr->background.index].green;
- png_ptr->background.blue =
- png_ptr->palette[png_ptr->background.index].blue;
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- {
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
-#endif
- {
- /* invert the alpha channel (in tRNS) unless the pixels are
- going to be expanded, in which case leave it for later */
- int i,istop;
- istop=(int)png_ptr->num_trans;
- for (i=0; i<istop; i++)
- png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
- }
- }
-#endif
-
- }
- }
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- png_ptr->background_1 = png_ptr->background;
-#endif
-#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
-
- if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
- && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
- < PNG_GAMMA_THRESHOLD))
- {
- int i,k;
- k=0;
- for (i=0; i<png_ptr->num_trans; i++)
- {
- if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
- k=1; /* partial transparency is present */
- }
- if (k == 0)
- png_ptr->transformations &= (~PNG_GAMMA);
- }
-
- if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
- png_ptr->gamma != 0.0)
- {
- png_build_gamma_table(png_ptr);
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- /* could skip if no transparency and
- */
- png_color back, back_1;
- png_colorp palette = png_ptr->palette;
- int num_palette = png_ptr->num_palette;
- int i;
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
- {
- back.red = png_ptr->gamma_table[png_ptr->background.red];
- back.green = png_ptr->gamma_table[png_ptr->background.green];
- back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
- back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
- back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
- back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
- }
- else
- {
- double g, gs;
-
- switch (png_ptr->background_gamma_type)
- {
- case PNG_BACKGROUND_GAMMA_SCREEN:
- g = (png_ptr->screen_gamma);
- gs = 1.0;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- g = 1.0 / (png_ptr->gamma);
- gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- g = 1.0 / (png_ptr->background_gamma);
- gs = 1.0 / (png_ptr->background_gamma *
- png_ptr->screen_gamma);
- break;
- default:
- g = 1.0; /* back_1 */
- gs = 1.0; /* back */
- }
-
- if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
- {
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
- }
- else
- {
- back.red = (png_byte)(pow(
- (double)png_ptr->background.red/255, gs) * 255.0 + .5);
- back.green = (png_byte)(pow(
- (double)png_ptr->background.green/255, gs) * 255.0 + .5);
- back.blue = (png_byte)(pow(
- (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
- }
-
- back_1.red = (png_byte)(pow(
- (double)png_ptr->background.red/255, g) * 255.0 + .5);
- back_1.green = (png_byte)(pow(
- (double)png_ptr->background.green/255, g) * 255.0 + .5);
- back_1.blue = (png_byte)(pow(
- (double)png_ptr->background.blue/255, g) * 255.0 + .5);
- }
- for (i = 0; i < num_palette; i++)
- {
- if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else /* if (png_ptr->trans[i] != 0xff) */
- {
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[palette[i].red];
- png_composite(w, v, png_ptr->trans[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].green];
- png_composite(w, v, png_ptr->trans[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].blue];
- png_composite(w, v, png_ptr->trans[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
- else
- /* color_type != PNG_COLOR_TYPE_PALETTE */
- {
- double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
- double g = 1.0;
- double gs = 1.0;
-
- switch (png_ptr->background_gamma_type)
- {
- case PNG_BACKGROUND_GAMMA_SCREEN:
- g = (png_ptr->screen_gamma);
- gs = 1.0;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- g = 1.0 / (png_ptr->gamma);
- gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- g = 1.0 / (png_ptr->background_gamma);
- gs = 1.0 / (png_ptr->background_gamma *
- png_ptr->screen_gamma);
- break;
- }
-
- png_ptr->background_1.gray = (png_uint_16)(pow(
- (double)png_ptr->background.gray / m, g) * m + .5);
- png_ptr->background.gray = (png_uint_16)(pow(
- (double)png_ptr->background.gray / m, gs) * m + .5);
-
- if ((png_ptr->background.red != png_ptr->background.green) ||
- (png_ptr->background.red != png_ptr->background.blue) ||
- (png_ptr->background.red != png_ptr->background.gray))
- {
- /* RGB or RGBA with color background */
- png_ptr->background_1.red = (png_uint_16)(pow(
- (double)png_ptr->background.red / m, g) * m + .5);
- png_ptr->background_1.green = (png_uint_16)(pow(
- (double)png_ptr->background.green / m, g) * m + .5);
- png_ptr->background_1.blue = (png_uint_16)(pow(
- (double)png_ptr->background.blue / m, g) * m + .5);
- png_ptr->background.red = (png_uint_16)(pow(
- (double)png_ptr->background.red / m, gs) * m + .5);
- png_ptr->background.green = (png_uint_16)(pow(
- (double)png_ptr->background.green / m, gs) * m + .5);
- png_ptr->background.blue = (png_uint_16)(pow(
- (double)png_ptr->background.blue / m, gs) * m + .5);
- }
- else
- {
- /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
- png_ptr->background_1.red = png_ptr->background_1.green
- = png_ptr->background_1.blue = png_ptr->background_1.gray;
- png_ptr->background.red = png_ptr->background.green
- = png_ptr->background.blue = png_ptr->background.gray;
- }
- }
- }
- else
- /* transformation does not include PNG_BACKGROUND */
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_colorp palette = png_ptr->palette;
- int num_palette = png_ptr->num_palette;
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- else
-#endif
-#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- /* No GAMMA transformation */
- if ((png_ptr->transformations & PNG_BACKGROUND) &&
- (color_type == PNG_COLOR_TYPE_PALETTE))
- {
- int i;
- int istop = (int)png_ptr->num_trans;
- png_color back;
- png_colorp palette = png_ptr->palette;
-
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
-
- for (i = 0; i < istop; i++)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else if (png_ptr->trans[i] != 0xff)
- {
- /* The png_composite() macro is defined in png.h */
- png_composite(palette[i].red, palette[i].red,
- png_ptr->trans[i], back.red);
- png_composite(palette[i].green, palette[i].green,
- png_ptr->trans[i], back.green);
- png_composite(palette[i].blue, palette[i].blue,
- png_ptr->trans[i], back.blue);
- }
- }
- }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
- if ((png_ptr->transformations & PNG_SHIFT) &&
- (color_type == PNG_COLOR_TYPE_PALETTE))
- {
- png_uint_16 i;
- png_uint_16 istop = png_ptr->num_palette;
- int sr = 8 - png_ptr->sig_bit.red;
- int sg = 8 - png_ptr->sig_bit.green;
- int sb = 8 - png_ptr->sig_bit.blue;
-
- if (sr < 0 || sr > 8)
- sr = 0;
- if (sg < 0 || sg > 8)
- sg = 0;
- if (sb < 0 || sb > 8)
- sb = 0;
- for (i = 0; i < istop; i++)
- {
- png_ptr->palette[i].red >>= sr;
- png_ptr->palette[i].green >>= sg;
- png_ptr->palette[i].blue >>= sb;
- }
- }
-#endif /* PNG_READ_SHIFT_SUPPORTED */
- }
-#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
- && !defined(PNG_READ_BACKGROUND_SUPPORTED)
- if(png_ptr)
- return;
-#endif
-}
-
-/* Modify the info structure to reflect the transformations. The
- * info should be updated so a PNG file could be written with it,
- * assuming the transformations result in valid PNG data.
- */
-void /* PRIVATE */
-png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_read_transform_info\n");
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS))
- info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- else
- info_ptr->color_type = PNG_COLOR_TYPE_RGB;
- info_ptr->bit_depth = 8;
- info_ptr->num_trans = 0;
- }
- else
- {
- if (png_ptr->num_trans)
- {
- if (png_ptr->transformations & PNG_EXPAND_tRNS)
- info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
- else
- info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
- }
- if (info_ptr->bit_depth < 8)
- info_ptr->bit_depth = 8;
- info_ptr->num_trans = 0;
- }
- }
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
- info_ptr->num_trans = 0;
- info_ptr->background = png_ptr->background;
- }
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->transformations & PNG_GAMMA)
- {
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- info_ptr->gamma = png_ptr->gamma;
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_gamma = png_ptr->int_gamma;
-#endif
- }
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
- if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
- info_ptr->bit_depth = 8;
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- if (png_ptr->transformations & PNG_GRAY_TO_RGB)
- info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & PNG_RGB_TO_GRAY)
- info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
- if (png_ptr->transformations & PNG_DITHER)
- {
- if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
- (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
- png_ptr->palette_lookup && info_ptr->bit_depth == 8)
- {
- info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
- }
- }
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
- info_ptr->bit_depth = 8;
-#endif
-
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- info_ptr->channels = 1;
- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
- info_ptr->channels = 3;
- else
- info_ptr->channels = 1;
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
-#endif
-
- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
- info_ptr->channels++;
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
- /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
- if ((png_ptr->transformations & PNG_FILLER) &&
- ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
- (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
- {
- info_ptr->channels++;
- /* if adding a true alpha channel not just filler */
-#if !defined(PNG_1_0_X)
- if (png_ptr->transformations & PNG_ADD_ALPHA)
- info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
-#endif
- }
-#endif
-
-#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
-defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- if(png_ptr->transformations & PNG_USER_TRANSFORM)
- {
- if(info_ptr->bit_depth < png_ptr->user_transform_depth)
- info_ptr->bit_depth = png_ptr->user_transform_depth;
- if(info_ptr->channels < png_ptr->user_transform_channels)
- info_ptr->channels = png_ptr->user_transform_channels;
- }
-#endif
-
- info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
- info_ptr->bit_depth);
-
- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
-
-#if !defined(PNG_READ_EXPAND_SUPPORTED)
- if(png_ptr)
- return;
-#endif
-}
-
-/* Transform the row. The order of transformations is significant,
- * and is very touchy. If you add a transformation, take care to
- * decide how it fits in with the other transformations here.
- */
-void /* PRIVATE */
-png_do_read_transformations(png_structp png_ptr)
-{
- png_debug(1, "in png_do_read_transformations\n");
- if (png_ptr->row_buf == NULL)
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[50];
-
- png_snprintf2(msg, 50,
- "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
- png_ptr->pass);
- png_error(png_ptr, msg);
-#else
- png_error(png_ptr, "NULL row buffer");
-#endif
- }
-#ifdef PNG_WARN_UNINITIALIZED_ROW
- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
- /* Application has failed to call either png_read_start_image()
- * or png_read_update_info() after setting transforms that expand
- * pixels. This check added to libpng-1.2.19 */
-#if (PNG_WARN_UNINITIALIZED_ROW==1)
- png_error(png_ptr, "Uninitialized row");
-#else
- png_warning(png_ptr, "Uninitialized row");
-#endif
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
- }
- else
- {
- if (png_ptr->num_trans &&
- (png_ptr->transformations & PNG_EXPAND_tRNS))
- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->trans_values));
- else
- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
- NULL);
- }
- }
-#endif
-
-#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
- png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & PNG_RGB_TO_GRAY)
- {
- int rgb_error =
- png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
- if(rgb_error)
- {
- png_ptr->rgb_to_gray_status=1;
- if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
- PNG_RGB_TO_GRAY_WARN)
- png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
- if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
- PNG_RGB_TO_GRAY_ERR)
- png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
- }
- }
-#endif
-
-/*
-From Andreas Dilger e-mail to png-implement, 26 March 1998:
-
- In most cases, the "simple transparency" should be done prior to doing
- gray-to-RGB, or you will have to test 3x as many bytes to check if a
- pixel is transparent. You would also need to make sure that the
- transparency information is upgraded to RGB.
-
- To summarize, the current flow is:
- - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
- with background "in place" if transparent,
- convert to RGB if necessary
- - Gray + alpha -> composite with gray background and remove alpha bytes,
- convert to RGB if necessary
-
- To support RGB backgrounds for gray images we need:
- - Gray + simple transparency -> convert to RGB + simple transparency, compare
- 3 or 6 bytes and composite with background
- "in place" if transparent (3x compare/pixel
- compared to doing composite with gray bkgrnd)
- - Gray + alpha -> convert to RGB + alpha, composite with background and
- remove alpha bytes (3x float operations/pixel
- compared with composite on gray background)
-
- Greg's change will do this. The reason it wasn't done before is for
- performance, as this increases the per-pixel operations. If we would check
- in advance if the background was gray or RGB, and position the gray-to-RGB
- transform appropriately, then it would save a lot of work/time.
- */
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* if gray -> RGB, do so now only if background is non-gray; else do later
- * for performance reasons */
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
- !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if ((png_ptr->transformations & PNG_BACKGROUND) &&
- ((png_ptr->num_trans != 0 ) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
- png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->trans_values), &(png_ptr->background)
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- , &(png_ptr->background_1),
- png_ptr->gamma_table, png_ptr->gamma_from_1,
- png_ptr->gamma_to_1, png_ptr->gamma_16_table,
- png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
- png_ptr->gamma_shift
-#endif
-);
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if ((png_ptr->transformations & PNG_GAMMA) &&
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- !((png_ptr->transformations & PNG_BACKGROUND) &&
- ((png_ptr->num_trans != 0) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
-#endif
- (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
- png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->gamma_table, png_ptr->gamma_16_table,
- png_ptr->gamma_shift);
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
- if (png_ptr->transformations & PNG_16_TO_8)
- png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
- if (png_ptr->transformations & PNG_DITHER)
- {
- png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->palette_lookup, png_ptr->dither_index);
- if(png_ptr->row_info.rowbytes == (png_uint_32)0)
- png_error(png_ptr, "png_do_dither returned rowbytes=0");
- }
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->shift));
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- /* if gray -> RGB, do so now only if we did not do so above */
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
- (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- (png_uint_32)png_ptr->filler, png_ptr->flags);
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_ALPHA)
- png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- if (png_ptr->transformations & PNG_USER_TRANSFORM)
- {
- if(png_ptr->read_user_transform_fn != NULL)
- (*(png_ptr->read_user_transform_fn)) /* user read transform function */
- (png_ptr, /* png_ptr */
- &(png_ptr->row_info), /* row_info: */
- /* png_uint_32 width; width of row */
- /* png_uint_32 rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
-#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if(png_ptr->user_transform_depth)
- png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
- if(png_ptr->user_transform_channels)
- png_ptr->row_info.channels = png_ptr->user_transform_channels;
-#endif
- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
- png_ptr->row_info.channels);
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
- }
-#endif
-
-}
-
-#if defined(PNG_READ_PACK_SUPPORTED)
-/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
- * without changing the actual values. Thus, if you had a row with
- * a bit depth of 1, you would end up with bytes that only contained
- * the numbers 0 or 1. If you would rather they contain 0 and 255, use
- * png_do_shift() after this.
- */
-void /* PRIVATE */
-png_do_unpack(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_unpack\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
-#else
- if (row_info->bit_depth < 8)
-#endif
- {
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- switch (row_info->bit_depth)
- {
- case 1:
- {
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x01);
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
-
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x03);
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
- png_bytep dp = row + (png_size_t)row_width - 1;
- png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
- for (i = 0; i < row_width; i++)
- {
- *dp = (png_byte)((*sp >> shift) & 0x0f);
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = (png_byte)(8 * row_info->channels);
- row_info->rowbytes = row_width * row_info->channels;
- }
-}
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED)
-/* Reverse the effects of png_do_shift. This routine merely shifts the
- * pixels back to their significant bits values. Thus, if you have
- * a row of bit depth 8, but only 5 are significant, this will shift
- * the values back to 0 through 31.
- */
-void /* PRIVATE */
-png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
-{
- png_debug(1, "in png_do_unshift\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL && sig_bits != NULL &&
-#endif
- row_info->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- int shift[4];
- int channels = 0;
- int c;
- png_uint_16 value = 0;
- png_uint_32 row_width = row_info->width;
-
- if (row_info->color_type & PNG_COLOR_MASK_COLOR)
- {
- shift[channels++] = row_info->bit_depth - sig_bits->red;
- shift[channels++] = row_info->bit_depth - sig_bits->green;
- shift[channels++] = row_info->bit_depth - sig_bits->blue;
- }
- else
- {
- shift[channels++] = row_info->bit_depth - sig_bits->gray;
- }
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- shift[channels++] = row_info->bit_depth - sig_bits->alpha;
- }
-
- for (c = 0; c < channels; c++)
- {
- if (shift[c] <= 0)
- shift[c] = 0;
- else
- value = 1;
- }
-
- if (!value)
- return;
-
- switch (row_info->bit_depth)
- {
- case 2:
- {
- png_bytep bp;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (bp = row, i = 0; i < istop; i++)
- {
- *bp >>= 1;
- *bp++ &= 0x55;
- }
- break;
- }
- case 4:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
- (png_byte)((int)0xf >> shift[0]));
-
- for (i = 0; i < istop; i++)
- {
- *bp >>= shift[0];
- *bp++ &= mask;
- }
- break;
- }
- case 8:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = row_width * channels;
-
- for (i = 0; i < istop; i++)
- {
- *bp++ >>= shift[i%channels];
- }
- break;
- }
- case 16:
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = channels * row_width;
-
- for (i = 0; i < istop; i++)
- {
- value = (png_uint_16)((*bp << 8) + *(bp + 1));
- value >>= shift[i%channels];
- *bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)(value & 0xff);
- }
- break;
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* chop rows of bit depth 16 down to 8 */
-void /* PRIVATE */
-png_do_chop(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_chop\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
-#else
- if (row_info->bit_depth == 16)
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->width * row_info->channels;
-
- for (i = 0; i<istop; i++, sp += 2, dp++)
- {
-#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
- /* This does a more accurate scaling of the 16-bit color
- * value, rather than a simple low-byte truncation.
- *
- * What the ideal calculation should be:
- * *dp = (((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
- *
- * GRR: no, I think this is what it really should be:
- * *dp = (((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
- *
- * GRR: here's the exact calculation with shifts:
- * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
- * *dp = (temp - (temp >> 8)) >> 8;
- *
- * Approximate calculation with shift/add instead of multiply/divide:
- * *dp = ((((png_uint_32)(*sp) << 8) |
- * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
- *
- * What we actually do to avoid extra shifting and conversion:
- */
-
- *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
-#else
- /* Simply discard the low order byte */
- *dp = *sp;
-#endif
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = (png_byte)(8 * row_info->channels);
- row_info->rowbytes = row_info->width * row_info->channels;
- }
-}
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
-void /* PRIVATE */
-png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_read_swap_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This converts from RGBA to ARGB */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
- }
- /* This converts from RRGGBBAA to AARRGGBB */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from GA to AG */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
- }
- /* This converts from GGAA to AAGG */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
-void /* PRIVATE */
-png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_read_invert_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This inverts the alpha channel in RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
-
-/* This does nothing:
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- We can replace it with:
-*/
- sp-=3;
- dp=sp;
- }
- }
- /* This inverts the alpha channel in RRGGBBAA */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
- *(--dp) = (png_byte)(255 - *(--sp));
-
-/* This does nothing:
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- We can replace it with:
-*/
- sp-=6;
- dp=sp;
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This inverts the alpha channel in GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
- *(--dp) = *(--sp);
- }
- }
- /* This inverts the alpha channel in GGAA */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = (png_byte)(255 - *(--sp));
- *(--dp) = (png_byte)(255 - *(--sp));
-/*
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
-*/
- sp-=2;
- dp=sp;
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
-/* Add filler channel if we have RGB color */
-void /* PRIVATE */
-png_do_read_filler(png_row_infop row_info, png_bytep row,
- png_uint_32 filler, png_uint_32 flags)
-{
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
- png_byte lo_filler = (png_byte)(filler & 0xff);
-
- png_debug(1, "in png_do_read_filler\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if(row_info->bit_depth == 8)
- {
- /* This changes the data from G to GX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- }
- *(--dp) = lo_filler;
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- /* This changes the data from G to XG */
- else
- {
- png_bytep sp = row + (png_size_t)row_width;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = lo_filler;
- }
- row_info->channels = 2;
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- }
- else if(row_info->bit_depth == 16)
- {
- /* This changes the data from GG to GGXX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 2;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- row_info->channels = 2;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- /* This changes the data from GG to XXGG */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 2;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- }
- row_info->channels = 2;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- }
- } /* COLOR_TYPE == GRAY */
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- if(row_info->bit_depth == 8)
- {
- /* This changes the data from RGB to RGBX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = lo_filler;
- row_info->channels = 4;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- /* This changes the data from RGB to XRGB */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 3;
- png_bytep dp = sp + (png_size_t)row_width;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = lo_filler;
- }
- row_info->channels = 4;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- }
- }
- else if(row_info->bit_depth == 16)
- {
- /* This changes the data from RRGGBB to RRGGBBXX */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- png_bytep sp = row + (png_size_t)row_width * 6;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 1; i < row_width; i++)
- {
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- }
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- row_info->channels = 4;
- row_info->pixel_depth = 64;
- row_info->rowbytes = row_width * 8;
- }
- /* This changes the data from RRGGBB to XXRRGGBB */
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 6;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = hi_filler;
- *(--dp) = lo_filler;
- }
- row_info->channels = 4;
- row_info->pixel_depth = 64;
- row_info->rowbytes = row_width * 8;
- }
- }
- } /* COLOR_TYPE == RGB */
-}
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-/* expand grayscale files to RGB, with or without alpha */
-void /* PRIVATE */
-png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
-{
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- png_debug(1, "in png_do_gray_to_rgb\n");
- if (row_info->bit_depth >= 8 &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- !(row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + (png_size_t)row_width - 1;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *sp;
- *(dp--) = *sp;
- *(dp--) = *(sp--);
- }
- }
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 2 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 4;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + (png_size_t)row_width * 2 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 2;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *(sp--);
- *(dp--) = *sp;
- *(dp--) = *sp;
- *(dp--) = *(sp--);
- }
- }
- else
- {
- png_bytep sp = row + (png_size_t)row_width * 4 - 1;
- png_bytep dp = sp + (png_size_t)row_width * 4;
- for (i = 0; i < row_width; i++)
- {
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *sp;
- *(dp--) = *(sp - 1);
- *(dp--) = *(sp--);
- *(dp--) = *(sp--);
- }
- }
- }
- row_info->channels += (png_byte)2;
- row_info->color_type |= PNG_COLOR_MASK_COLOR;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
-}
-#endif
-
-#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-/* reduce RGB files to grayscale, with or without alpha
- * using the equation given in Poynton's ColorFAQ at
- * <http://www.inforamp.net/~poynton/>
- * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
- *
- * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
- *
- * We approximate this with
- *
- * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
- *
- * which can be expressed with integers as
- *
- * Y = (6969 * R + 23434 * G + 2365 * B)/32768
- *
- * The calculation is to be done in a linear colorspace.
- *
- * Other integer coefficents can be used via png_set_rgb_to_gray().
- */
-int /* PRIVATE */
-png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
-
-{
- png_uint_32 i;
-
- png_uint_32 row_width = row_info->width;
- int rgb_error = 0;
-
- png_debug(1, "in png_do_rgb_to_gray\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
- png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
- png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
-
- for (i = 0; i < row_width; i++)
- {
- png_byte red = png_ptr->gamma_to_1[*(sp++)];
- png_byte green = png_ptr->gamma_to_1[*(sp++)];
- png_byte blue = png_ptr->gamma_to_1[*(sp++)];
- if(red != green || red != blue)
- {
- rgb_error |= 1;
- *(dp++) = png_ptr->gamma_from_1[
- (rc*red+gc*green+bc*blue)>>15];
- }
- else
- *(dp++) = *(sp-1);
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = *(sp++);
- png_byte green = *(sp++);
- png_byte blue = *(sp++);
- if(red != green || red != blue)
- {
- rgb_error |= 1;
- *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
- }
- else
- *(dp++) = *(sp-1);
- }
- }
- }
-
- else /* RGB bit_depth == 16 */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_to_1 != NULL &&
- png_ptr->gamma_16_from_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, w;
-
- red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
-
- if(red == green && red == blue)
- w = red;
- else
- {
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
- png_ptr->gamma_shift][red>>8];
- png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
- png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
- png_ptr->gamma_shift][blue>>8];
- png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
- + bc*blue_1)>>15);
- w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
- png_ptr->gamma_shift][gray16 >> 8];
- rgb_error |= 1;
- }
-
- *(dp++) = (png_byte)((w>>8) & 0xff);
- *(dp++) = (png_byte)(w & 0xff);
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, gray16;
-
- red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
-
- if(red != green || red != blue)
- rgb_error |= 1;
- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
- *(dp++) = (png_byte)((gray16>>8) & 0xff);
- *(dp++) = (png_byte)(gray16 & 0xff);
- }
- }
- }
- }
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = png_ptr->gamma_to_1[*(sp++)];
- png_byte green = png_ptr->gamma_to_1[*(sp++)];
- png_byte blue = png_ptr->gamma_to_1[*(sp++)];
- if(red != green || red != blue)
- rgb_error |= 1;
- *(dp++) = png_ptr->gamma_from_1
- [(rc*red + gc*green + bc*blue)>>15];
- *(dp++) = *(sp++); /* alpha */
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_byte red = *(sp++);
- png_byte green = *(sp++);
- png_byte blue = *(sp++);
- if(red != green || red != blue)
- rgb_error |= 1;
- *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
- *(dp++) = *(sp++); /* alpha */
- }
- }
- }
- else /* RGBA bit_depth == 16 */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->gamma_16_to_1 != NULL &&
- png_ptr->gamma_16_from_1 != NULL)
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, w;
-
- red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
-
- if(red == green && red == blue)
- w = red;
- else
- {
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
- png_ptr->gamma_shift][red>>8];
- png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
- png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
- png_ptr->gamma_shift][blue>>8];
- png_uint_16 gray16 = (png_uint_16)((rc * red_1
- + gc * green_1 + bc * blue_1)>>15);
- w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
- png_ptr->gamma_shift][gray16 >> 8];
- rgb_error |= 1;
- }
-
- *(dp++) = (png_byte)((w>>8) & 0xff);
- *(dp++) = (png_byte)(w & 0xff);
- *(dp++) = *(sp++); /* alpha */
- *(dp++) = *(sp++);
- }
- }
- else
-#endif
- {
- png_bytep sp = row;
- png_bytep dp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 red, green, blue, gray16;
- red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
- green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
- blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
- if(red != green || red != blue)
- rgb_error |= 1;
- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
- *(dp++) = (png_byte)((gray16>>8) & 0xff);
- *(dp++) = (png_byte)(gray16 & 0xff);
- *(dp++) = *(sp++); /* alpha */
- *(dp++) = *(sp++);
- }
- }
- }
- }
- row_info->channels -= (png_byte)2;
- row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- return rgb_error;
-}
-#endif
-
-/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
- * large of png_color. This lets grayscale images be treated as
- * paletted. Most useful for gamma correction and simplification
- * of code.
- */
-void PNGAPI
-png_build_grayscale_palette(int bit_depth, png_colorp palette)
-{
- int num_palette;
- int color_inc;
- int i;
- int v;
-
- png_debug(1, "in png_do_build_grayscale_palette\n");
- if (palette == NULL)
- return;
-
- switch (bit_depth)
- {
- case 1:
- num_palette = 2;
- color_inc = 0xff;
- break;
- case 2:
- num_palette = 4;
- color_inc = 0x55;
- break;
- case 4:
- num_palette = 16;
- color_inc = 0x11;
- break;
- case 8:
- num_palette = 256;
- color_inc = 1;
- break;
- default:
- num_palette = 0;
- color_inc = 0;
- break;
- }
-
- for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
- {
- palette[i].red = (png_byte)v;
- palette[i].green = (png_byte)v;
- palette[i].blue = (png_byte)v;
- }
-}
-
-/* This function is currently unused. Do we really need it? */
-#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
-void /* PRIVATE */
-png_correct_palette(png_structp png_ptr, png_colorp palette,
- int num_palette)
-{
- png_debug(1, "in png_correct_palette\n");
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
- defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
- if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
- {
- png_color back, back_1;
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
- {
- back.red = png_ptr->gamma_table[png_ptr->background.red];
- back.green = png_ptr->gamma_table[png_ptr->background.green];
- back.blue = png_ptr->gamma_table[png_ptr->background.blue];
-
- back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
- back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
- back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
- }
- else
- {
- double g;
-
- g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
-
- if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
- fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
- {
- back.red = png_ptr->background.red;
- back.green = png_ptr->background.green;
- back.blue = png_ptr->background.blue;
- }
- else
- {
- back.red =
- (png_byte)(pow((double)png_ptr->background.red/255, g) *
- 255.0 + 0.5);
- back.green =
- (png_byte)(pow((double)png_ptr->background.green/255, g) *
- 255.0 + 0.5);
- back.blue =
- (png_byte)(pow((double)png_ptr->background.blue/255, g) *
- 255.0 + 0.5);
- }
-
- g = 1.0 / png_ptr->background_gamma;
-
- back_1.red =
- (png_byte)(pow((double)png_ptr->background.red/255, g) *
- 255.0 + 0.5);
- back_1.green =
- (png_byte)(pow((double)png_ptr->background.green/255, g) *
- 255.0 + 0.5);
- back_1.blue =
- (png_byte)(pow((double)png_ptr->background.blue/255, g) *
- 255.0 + 0.5);
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_uint_32 i;
-
- for (i = 0; i < (png_uint_32)num_palette; i++)
- {
- if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
- {
- palette[i] = back;
- }
- else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
- {
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
- png_composite(w, v, png_ptr->trans[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
- png_composite(w, v, png_ptr->trans[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
- png_composite(w, v, png_ptr->trans[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- else
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
- {
- palette[i] = back;
- }
- else
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
- }
- }
- else
-#endif
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (png_ptr->transformations & PNG_GAMMA)
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- palette[i].red = png_ptr->gamma_table[palette[i].red];
- palette[i].green = png_ptr->gamma_table[palette[i].green];
- palette[i].blue = png_ptr->gamma_table[palette[i].blue];
- }
- }
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- else
-#endif
-#endif
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
- if (png_ptr->transformations & PNG_BACKGROUND)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_color back;
-
- back.red = (png_byte)png_ptr->background.red;
- back.green = (png_byte)png_ptr->background.green;
- back.blue = (png_byte)png_ptr->background.blue;
-
- for (i = 0; i < (int)png_ptr->num_trans; i++)
- {
- if (png_ptr->trans[i] == 0)
- {
- palette[i].red = back.red;
- palette[i].green = back.green;
- palette[i].blue = back.blue;
- }
- else if (png_ptr->trans[i] != 0xff)
- {
- png_composite(palette[i].red, png_ptr->palette[i].red,
- png_ptr->trans[i], back.red);
- png_composite(palette[i].green, png_ptr->palette[i].green,
- png_ptr->trans[i], back.green);
- png_composite(palette[i].blue, png_ptr->palette[i].blue,
- png_ptr->trans[i], back.blue);
- }
- }
- }
- else /* assume grayscale palette (what else could it be?) */
- {
- int i;
-
- for (i = 0; i < num_palette; i++)
- {
- if (i == (png_byte)png_ptr->trans_values.gray)
- {
- palette[i].red = (png_byte)png_ptr->background.red;
- palette[i].green = (png_byte)png_ptr->background.green;
- palette[i].blue = (png_byte)png_ptr->background.blue;
- }
- }
- }
- }
-#endif
-}
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED)
-/* Replace any alpha or transparency with the supplied background color.
- * "background" is already in the screen gamma, while "background_1" is
- * at a gamma of 1.0. Paletted files have already been taken care of.
- */
-void /* PRIVATE */
-png_do_background(png_row_infop row_info, png_bytep row,
- png_color_16p trans_values, png_color_16p background
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- , png_color_16p background_1,
- png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
- png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
- png_uint_16pp gamma_16_to_1, int gamma_shift
-#endif
- )
-{
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
- int shift;
-
- png_debug(1, "in png_do_background\n");
- if (background != NULL &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
- (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
- {
- switch (row_info->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- sp = row;
- shift = 7;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x01)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 7;
- sp++;
- }
- else
- shift--;
- }
- break;
- }
- case 2:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x03)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- else
- {
- png_byte p = (png_byte)((*sp >> shift) & 0x03);
- png_byte g = (png_byte)((gamma_table [p | (p << 2) |
- (p << 4) | (p << 6)] >> 6) & 0x03);
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(g << shift);
- }
- if (!shift)
- {
- shift = 6;
- sp++;
- }
- else
- shift -= 2;
- }
- }
- else
-#endif
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x03)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 6;
- sp++;
- }
- else
- shift -= 2;
- }
- }
- break;
- }
- case 4:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x0f)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- else
- {
- png_byte p = (png_byte)((*sp >> shift) & 0x0f);
- png_byte g = (png_byte)((gamma_table[p |
- (p << 4)] >> 4) & 0x0f);
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(g << shift);
- }
- if (!shift)
- {
- shift = 4;
- sp++;
- }
- else
- shift -= 4;
- }
- }
- else
-#endif
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x0f)
- == trans_values->gray)
- {
- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *sp |= (png_byte)(background->gray << shift);
- }
- if (!shift)
- {
- shift = 4;
- sp++;
- }
- else
- shift -= 4;
- }
- }
- break;
- }
- case 8:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- if (*sp == trans_values->gray)
- {
- *sp = (png_byte)background->gray;
- }
- else
- {
- *sp = gamma_table[*sp];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- if (*sp == trans_values->gray)
- {
- *sp = (png_byte)background->gray;
- }
- }
- }
- break;
- }
- case 16:
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 v;
-
- v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- if (v == trans_values->gray)
- {
- /* background is already in screen gamma */
- *sp = (png_byte)((background->gray >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->gray & 0xff);
- }
- else
- {
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 v;
-
- v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- if (v == trans_values->gray)
- {
- *sp = (png_byte)((background->gray >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->gray & 0xff);
- }
- }
- }
- break;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == trans_values->red &&
- *(sp + 1) == trans_values->green &&
- *(sp + 2) == trans_values->blue)
- {
- *sp = (png_byte)background->red;
- *(sp + 1) = (png_byte)background->green;
- *(sp + 2) = (png_byte)background->blue;
- }
- else
- {
- *sp = gamma_table[*sp];
- *(sp + 1) = gamma_table[*(sp + 1)];
- *(sp + 2) = gamma_table[*(sp + 2)];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == trans_values->red &&
- *(sp + 1) == trans_values->green &&
- *(sp + 2) == trans_values->blue)
- {
- *sp = (png_byte)background->red;
- *(sp + 1) = (png_byte)background->green;
- *(sp + 2) = (png_byte)background->blue;
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
- png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
- if (r == trans_values->red && g == trans_values->green &&
- b == trans_values->blue)
- {
- /* background is already in screen gamma */
- *sp = (png_byte)((background->red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->red & 0xff);
- *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(sp + 3) = (png_byte)(background->green & 0xff);
- *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(sp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(sp + 2) = (png_byte)((v >> 8) & 0xff);
- *(sp + 3) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(sp + 4) = (png_byte)((v >> 8) & 0xff);
- *(sp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
- png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
- png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
-
- if (r == trans_values->red && g == trans_values->green &&
- b == trans_values->blue)
- {
- *sp = (png_byte)((background->red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(background->red & 0xff);
- *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(sp + 3) = (png_byte)(background->green & 0xff);
- *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(sp + 5) = (png_byte)(background->blue & 0xff);
- }
- }
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 2, dp++)
- {
- png_uint_16 a = *(sp + 1);
-
- if (a == 0xff)
- {
- *dp = gamma_table[*sp];
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)background->gray;
- }
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, background_1->gray);
- *dp = gamma_from_1[w];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 2, dp++)
- {
- png_byte a = *(sp + 1);
-
- if (a == 0xff)
- {
- *dp = *sp;
- }
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- else if (a == 0)
- {
- *dp = (png_byte)background->gray;
- }
- else
- {
- png_composite(*dp, *sp, a, background_1->gray);
- }
-#else
- *dp = (png_byte)background->gray;
-#endif
- }
- }
- }
- else /* if (png_ptr->bit_depth == 16) */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 2)
- {
- png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
-
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- }
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- else if (a == 0)
-#else
- else
-#endif
- {
- /* background is already in screen gamma */
- *dp = (png_byte)((background->gray >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->gray & 0xff);
- }
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- else
- {
- png_uint_16 g, v, w;
-
- g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(v, g, a, background_1->gray);
- w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
- *dp = (png_byte)((w >> 8) & 0xff);
- *(dp + 1) = (png_byte)(w & 0xff);
- }
-#endif
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 2)
- {
- png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
- if (a == (png_uint_16)0xffff)
- {
- png_memcpy(dp, sp, 2);
- }
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- else if (a == 0)
-#else
- else
-#endif
- {
- *dp = (png_byte)((background->gray >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->gray & 0xff);
- }
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- else
- {
- png_uint_16 g, v;
-
- g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_composite_16(v, g, a, background_1->gray);
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- }
-#endif
- }
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 3)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *dp = gamma_table[*sp];
- *(dp + 1) = gamma_table[*(sp + 1)];
- *(dp + 2) = gamma_table[*(sp + 2)];
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)background->red;
- *(dp + 1) = (png_byte)background->green;
- *(dp + 2) = (png_byte)background->blue;
- }
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, background_1->red);
- *dp = gamma_from_1[w];
- v = gamma_to_1[*(sp + 1)];
- png_composite(w, v, a, background_1->green);
- *(dp + 1) = gamma_from_1[w];
- v = gamma_to_1[*(sp + 2)];
- png_composite(w, v, a, background_1->blue);
- *(dp + 2) = gamma_from_1[w];
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 4, dp += 3)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *dp = *sp;
- *(dp + 1) = *(sp + 1);
- *(dp + 2) = *(sp + 2);
- }
- else if (a == 0)
- {
- *dp = (png_byte)background->red;
- *(dp + 1) = (png_byte)background->green;
- *(dp + 2) = (png_byte)background->blue;
- }
- else
- {
- png_composite(*dp, *sp, a, background->red);
- png_composite(*(dp + 1), *(sp + 1), a,
- background->green);
- png_composite(*(dp + 2), *(sp + 2), a,
- background->blue);
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
-#if defined(PNG_READ_GAMMA_SUPPORTED)
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 8, dp += 6)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(dp + 2) = (png_byte)((v >> 8) & 0xff);
- *(dp + 3) = (png_byte)(v & 0xff);
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(dp + 4) = (png_byte)((v >> 8) & 0xff);
- *(dp + 5) = (png_byte)(v & 0xff);
- }
- else if (a == 0)
- {
- /* background is already in screen gamma */
- *dp = (png_byte)((background->red >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->red & 0xff);
- *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(dp + 3) = (png_byte)(background->green & 0xff);
- *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(dp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v, w, x;
-
- v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(w, v, a, background_1->red);
- x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
- *dp = (png_byte)((x >> 8) & 0xff);
- *(dp + 1) = (png_byte)(x & 0xff);
- v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
- png_composite_16(w, v, a, background_1->green);
- x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
- *(dp + 2) = (png_byte)((x >> 8) & 0xff);
- *(dp + 3) = (png_byte)(x & 0xff);
- v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
- png_composite_16(w, v, a, background_1->blue);
- x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
- *(dp + 4) = (png_byte)((x >> 8) & 0xff);
- *(dp + 5) = (png_byte)(x & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++, sp += 8, dp += 6)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
- if (a == (png_uint_16)0xffff)
- {
- png_memcpy(dp, sp, 6);
- }
- else if (a == 0)
- {
- *dp = (png_byte)((background->red >> 8) & 0xff);
- *(dp + 1) = (png_byte)(background->red & 0xff);
- *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
- *(dp + 3) = (png_byte)(background->green & 0xff);
- *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
- *(dp + 5) = (png_byte)(background->blue & 0xff);
- }
- else
- {
- png_uint_16 v;
-
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
- + *(sp + 3));
- png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
- + *(sp + 5));
-
- png_composite_16(v, r, a, background->red);
- *dp = (png_byte)((v >> 8) & 0xff);
- *(dp + 1) = (png_byte)(v & 0xff);
- png_composite_16(v, g, a, background->green);
- *(dp + 2) = (png_byte)((v >> 8) & 0xff);
- *(dp + 3) = (png_byte)(v & 0xff);
- png_composite_16(v, b, a, background->blue);
- *(dp + 4) = (png_byte)((v >> 8) & 0xff);
- *(dp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
- }
- break;
- }
- }
-
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- row_info->channels--;
- row_info->pixel_depth = (png_byte)(row_info->channels *
- row_info->bit_depth);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-/* Gamma correct the image, avoiding the alpha channel. Make sure
- * you do this after you deal with the transparency issue on grayscale
- * or RGB images. If your bit depth is 8, use gamma_table, if it
- * is 16, use gamma_16_table and gamma_shift. Build these with
- * build_gamma_table().
- */
-void /* PRIVATE */
-png_do_gamma(png_row_infop row_info, png_bytep row,
- png_bytep gamma_table, png_uint_16pp gamma_16_table,
- int gamma_shift)
-{
- png_bytep sp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_gamma\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
- (row_info->bit_depth == 16 && gamma_16_table != NULL)))
- {
- switch (row_info->color_type)
- {
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v;
-
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- *sp = gamma_table[*sp];
- sp++;
- sp++;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 4;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp += 2;
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 4;
- }
- }
- break;
- }
- case PNG_COLOR_TYPE_GRAY:
- {
- if (row_info->bit_depth == 2)
- {
- sp = row;
- for (i = 0; i < row_width; i += 4)
- {
- int a = *sp & 0xc0;
- int b = *sp & 0x30;
- int c = *sp & 0x0c;
- int d = *sp & 0x03;
-
- *sp = (png_byte)(
- ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
- ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
- ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
- ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
- sp++;
- }
- }
- if (row_info->bit_depth == 4)
- {
- sp = row;
- for (i = 0; i < row_width; i += 2)
- {
- int msb = *sp & 0xf0;
- int lsb = *sp & 0x0f;
-
- *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
- | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
- sp++;
- }
- }
- else if (row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- *sp = gamma_table[*sp];
- sp++;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- sp = row;
- for (i = 0; i < row_width; i++)
- {
- png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- sp += 2;
- }
- }
- break;
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expands a palette row to an RGB or RGBA row depending
- * upon whether you supply trans and num_trans.
- */
-void /* PRIVATE */
-png_do_expand_palette(png_row_infop row_info, png_bytep row,
- png_colorp palette, png_bytep trans, int num_trans)
-{
- int shift, value;
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_expand_palette\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (row_info->bit_depth < 8)
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- sp = row + (png_size_t)((row_width - 1) >> 3);
- dp = row + (png_size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
- {
- if ((*sp >> shift) & 0x01)
- *dp = 1;
- else
- *dp = 0;
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
- sp = row + (png_size_t)((row_width - 1) >> 2);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x03;
- *dp = (png_byte)value;
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- sp = row + (png_size_t)((row_width - 1) >> 1);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((row_width & 0x01) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x0f;
- *dp = (png_byte)value;
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
- switch (row_info->bit_depth)
- {
- case 8:
- {
- if (trans != NULL)
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width << 2) - 1;
-
- for (i = 0; i < row_width; i++)
- {
- if ((int)(*sp) >= num_trans)
- *dp-- = 0xff;
- else
- *dp-- = trans[*sp];
- *dp-- = palette[*sp].blue;
- *dp-- = palette[*sp].green;
- *dp-- = palette[*sp].red;
- sp--;
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 32;
- row_info->rowbytes = row_width * 4;
- row_info->color_type = 6;
- row_info->channels = 4;
- }
- else
- {
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width * 3) - 1;
-
- for (i = 0; i < row_width; i++)
- {
- *dp-- = palette[*sp].blue;
- *dp-- = palette[*sp].green;
- *dp-- = palette[*sp].red;
- sp--;
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 24;
- row_info->rowbytes = row_width * 3;
- row_info->color_type = 2;
- row_info->channels = 3;
- }
- break;
- }
- }
- }
-}
-
-/* If the bit depth < 8, it is expanded to 8. Also, if the already
- * expanded transparency value is supplied, an alpha channel is built.
- */
-void /* PRIVATE */
-png_do_expand(png_row_infop row_info, png_bytep row,
- png_color_16p trans_value)
-{
- int shift, value;
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_expand\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
-
- if (row_info->bit_depth < 8)
- {
- switch (row_info->bit_depth)
- {
- case 1:
- {
- gray = (png_uint_16)((gray&0x01)*0xff);
- sp = row + (png_size_t)((row_width - 1) >> 3);
- dp = row + (png_size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
- {
- if ((*sp >> shift) & 0x01)
- *dp = 0xff;
- else
- *dp = 0;
- if (shift == 7)
- {
- shift = 0;
- sp--;
- }
- else
- shift++;
-
- dp--;
- }
- break;
- }
- case 2:
- {
- gray = (png_uint_16)((gray&0x03)*0x55);
- sp = row + (png_size_t)((row_width - 1) >> 2);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x03;
- *dp = (png_byte)(value | (value << 2) | (value << 4) |
- (value << 6));
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
- case 4:
- {
- gray = (png_uint_16)((gray&0x0f)*0x11);
- sp = row + (png_size_t)((row_width - 1) >> 1);
- dp = row + (png_size_t)row_width - 1;
- shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x0f;
- *dp = (png_byte)(value | (value << 4));
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
- }
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
-
- if (trans_value != NULL)
- {
- if (row_info->bit_depth == 8)
- {
- gray = gray & 0xff;
- sp = row + (png_size_t)row_width - 1;
- dp = row + (png_size_t)(row_width << 1) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*sp == gray)
- *dp-- = 0;
- else
- *dp-- = 0xff;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_byte gray_high = (gray >> 8) & 0xff;
- png_byte gray_low = gray & 0xff;
- sp = row + row_info->rowbytes - 1;
- dp = row + (row_info->rowbytes << 1) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp-1) == gray_high && *(sp) == gray_low)
- {
- *dp-- = 0;
- *dp-- = 0;
- }
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- row_info->channels = 2;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_width);
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
- {
- if (row_info->bit_depth == 8)
- {
- png_byte red = trans_value->red & 0xff;
- png_byte green = trans_value->green & 0xff;
- png_byte blue = trans_value->blue & 0xff;
- sp = row + (png_size_t)row_info->rowbytes - 1;
- dp = row + (png_size_t)(row_width << 2) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
- *dp-- = 0;
- else
- *dp-- = 0xff;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_byte red_high = (trans_value->red > 8) & 0xff;
- png_byte green_high = (trans_value->green > 8) & 0xff;
- png_byte blue_high = (trans_value->blue > 8) & 0xff;
- png_byte red_low = trans_value->red & 0xff;
- png_byte green_low = trans_value->green & 0xff;
- png_byte blue_low = trans_value->blue & 0xff;
- sp = row + row_info->rowbytes - 1;
- dp = row + (png_size_t)(row_width << 3) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 5) == red_high &&
- *(sp - 4) == red_low &&
- *(sp - 3) == green_high &&
- *(sp - 2) == green_low &&
- *(sp - 1) == blue_high &&
- *(sp ) == blue_low)
- {
- *dp-- = 0;
- *dp-- = 0;
- }
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- row_info->channels = 4;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_DITHER_SUPPORTED)
-void /* PRIVATE */
-png_do_dither(png_row_infop row_info, png_bytep row,
- png_bytep palette_lookup, png_bytep dither_lookup)
-{
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width=row_info->width;
-
- png_debug(1, "in png_do_dither\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
- palette_lookup && row_info->bit_depth == 8)
- {
- int r, g, b, p;
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++)
- {
- r = *sp++;
- g = *sp++;
- b = *sp++;
-
- /* this looks real messy, but the compiler will reduce
- it down to a reasonable formula. For example, with
- 5 bits per color, we get:
- p = (((r >> 3) & 0x1f) << 10) |
- (((g >> 3) & 0x1f) << 5) |
- ((b >> 3) & 0x1f);
- */
- p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
- ((1 << PNG_DITHER_RED_BITS) - 1)) <<
- (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
- (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
- ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
- (PNG_DITHER_BLUE_BITS)) |
- ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
- ((1 << PNG_DITHER_BLUE_BITS) - 1));
-
- *dp++ = palette_lookup[p];
- }
- row_info->color_type = PNG_COLOR_TYPE_PALETTE;
- row_info->channels = 1;
- row_info->pixel_depth = row_info->bit_depth;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
- palette_lookup != NULL && row_info->bit_depth == 8)
- {
- int r, g, b, p;
- sp = row;
- dp = row;
- for (i = 0; i < row_width; i++)
- {
- r = *sp++;
- g = *sp++;
- b = *sp++;
- sp++;
-
- p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
- ((1 << PNG_DITHER_RED_BITS) - 1)) <<
- (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
- (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
- ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
- (PNG_DITHER_BLUE_BITS)) |
- ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
- ((1 << PNG_DITHER_BLUE_BITS) - 1));
-
- *dp++ = palette_lookup[p];
- }
- row_info->color_type = PNG_COLOR_TYPE_PALETTE;
- row_info->channels = 1;
- row_info->pixel_depth = row_info->bit_depth;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
- dither_lookup && row_info->bit_depth == 8)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp++)
- {
- *sp = dither_lookup[*sp];
- }
- }
- }
-}
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-static PNG_CONST int png_gamma_shift[] =
- {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
-
-/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
- * tables, we don't make a full table if we are reducing to 8-bit in
- * the future. Note also how the gamma_16 tables are segmented so that
- * we don't need to allocate > 64K chunks for a full 16-bit table.
- */
-void /* PRIVATE */
-png_build_gamma_table(png_structp png_ptr)
-{
- png_debug(1, "in png_build_gamma_table\n");
-
- if (png_ptr->bit_depth <= 8)
- {
- int i;
- double g;
-
- if (png_ptr->screen_gamma > .000001)
- g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- else
- g = 1.0;
-
- png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
- }
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
- {
-
- g = 1.0 / (png_ptr->gamma);
-
- png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
- }
-
-
- png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)256);
-
- if(png_ptr->screen_gamma > 0.000001)
- g = 1.0 / png_ptr->screen_gamma;
- else
- g = png_ptr->gamma; /* probably doing rgb_to_gray */
-
- for (i = 0; i < 256; i++)
- {
- png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
- g) * 255.0 + .5);
-
- }
- }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
- }
- else
- {
- double g;
- int i, j, shift, num;
- int sig_bit;
- png_uint_32 ig;
-
- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- {
- sig_bit = (int)png_ptr->sig_bit.red;
- if ((int)png_ptr->sig_bit.green > sig_bit)
- sig_bit = png_ptr->sig_bit.green;
- if ((int)png_ptr->sig_bit.blue > sig_bit)
- sig_bit = png_ptr->sig_bit.blue;
- }
- else
- {
- sig_bit = (int)png_ptr->sig_bit.gray;
- }
-
- if (sig_bit > 0)
- shift = 16 - sig_bit;
- else
- shift = 0;
-
- if (png_ptr->transformations & PNG_16_TO_8)
- {
- if (shift < (16 - PNG_MAX_GAMMA_8))
- shift = (16 - PNG_MAX_GAMMA_8);
- }
-
- if (shift > 8)
- shift = 8;
- if (shift < 0)
- shift = 0;
-
- png_ptr->gamma_shift = (png_byte)shift;
-
- num = (1 << (8 - shift));
-
- if (png_ptr->screen_gamma > .000001)
- g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
- else
- g = 1.0;
-
- png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * png_sizeof (png_uint_16p)));
-
- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
- {
- double fin, fout;
- png_uint_32 last, max;
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
- }
-
- g = 1.0 / g;
- last = 0;
- for (i = 0; i < 256; i++)
- {
- fout = ((double)i + 0.5) / 256.0;
- fin = pow(fout, g);
- max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
- while (last <= max)
- {
- png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
- [(int)(last >> (8 - shift))] = (png_uint_16)(
- (png_uint_16)i | ((png_uint_16)i << 8));
- last++;
- }
- }
- while (last < ((png_uint_32)num << 8))
- {
- png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
- [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
- last++;
- }
- }
- else
- {
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_table[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
- }
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
- {
-
- g = 1.0 / (png_ptr->gamma);
-
- png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * png_sizeof (png_uint_16p )));
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i *
- (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_to_1[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
-
- if(png_ptr->screen_gamma > 0.000001)
- g = 1.0 / png_ptr->screen_gamma;
- else
- g = png_ptr->gamma; /* probably doing rgb_to_gray */
-
- png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
- (png_uint_32)(num * png_sizeof (png_uint_16p)));
-
- for (i = 0; i < num; i++)
- {
- png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(256 * png_sizeof (png_uint_16)));
-
- ig = (((png_uint_32)i *
- (png_uint_32)png_gamma_shift[shift]) >> 4);
- for (j = 0; j < 256; j++)
- {
- png_ptr->gamma_16_from_1[i][j] =
- (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
- 65535.0, g) * 65535.0 + .5);
- }
- }
- }
-#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
- }
-}
-#endif
-/* To do: install integer version of png_build_gamma_table here */
-#endif
-
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
-/* undoes intrapixel differencing */
-void /* PRIVATE */
-png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_read_intrapixel\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- int bytes_per_pixel;
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 3;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 4;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
- *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 6;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 8;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
- png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
- png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
- png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL);
- png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
- *(rp ) = (png_byte)((red >> 8) & 0xff);
- *(rp+1) = (png_byte)(red & 0xff);
- *(rp+4) = (png_byte)((blue >> 8) & 0xff);
- *(rp+5) = (png_byte)(blue & 0xff);
- }
- }
- }
-}
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngrutil.c b/distrib/libpng-1.2.19/pngrutil.c
deleted file mode 100644
index 86e924c..0000000
--- a/distrib/libpng-1.2.19/pngrutil.c
+++ /dev/null
@@ -1,4189 +0,0 @@
-
-/* pngrutil.c - utilities to read a PNG file
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file contains routines that are only called from within
- * libpng itself during the course of reading an image.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED)
-
-#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
-# define WIN32_WCE_OLD
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-# if defined(WIN32_WCE_OLD)
-/* strtod() function is not supported on WindowsCE */
-__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
-{
- double result = 0;
- int len;
- wchar_t *str, *end;
-
- len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
- str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
- if ( NULL != str )
- {
- MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
- result = wcstod(str, &end);
- len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
- *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
- png_free(png_ptr, str);
- }
- return result;
-}
-# else
-# define png_strtod(p,a,b) strtod(a,b)
-# endif
-#endif
-
-png_uint_32 PNGAPI
-png_get_uint_31(png_structp png_ptr, png_bytep buf)
-{
- png_uint_32 i = png_get_uint_32(buf);
- if (i > PNG_UINT_31_MAX)
- png_error(png_ptr, "PNG unsigned integer out of range.");
- return (i);
-}
-#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
-/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
-png_uint_32 PNGAPI
-png_get_uint_32(png_bytep buf)
-{
- png_uint_32 i = ((png_uint_32)(*buf) << 24) +
- ((png_uint_32)(*(buf + 1)) << 16) +
- ((png_uint_32)(*(buf + 2)) << 8) +
- (png_uint_32)(*(buf + 3));
-
- return (i);
-}
-
-/* Grab a signed 32-bit integer from a buffer in big-endian format. The
- * data is stored in the PNG file in two's complement format, and it is
- * assumed that the machine format for signed integers is the same. */
-png_int_32 PNGAPI
-png_get_int_32(png_bytep buf)
-{
- png_int_32 i = ((png_int_32)(*buf) << 24) +
- ((png_int_32)(*(buf + 1)) << 16) +
- ((png_int_32)(*(buf + 2)) << 8) +
- (png_int_32)(*(buf + 3));
-
- return (i);
-}
-
-/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
-png_uint_16 PNGAPI
-png_get_uint_16(png_bytep buf)
-{
- png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
- (png_uint_16)(*(buf + 1)));
-
- return (i);
-}
-#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
-
-/* Read data, and (optionally) run it through the CRC. */
-void /* PRIVATE */
-png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
-{
- if(png_ptr == NULL) return;
- png_read_data(png_ptr, buf, length);
- png_calculate_crc(png_ptr, buf, length);
-}
-
-/* Optionally skip data and then check the CRC. Depending on whether we
- are reading a ancillary or critical chunk, and how the program has set
- things up, we may calculate the CRC on the data and print a message.
- Returns '1' if there was a CRC error, '0' otherwise. */
-int /* PRIVATE */
-png_crc_finish(png_structp png_ptr, png_uint_32 skip)
-{
- png_size_t i;
- png_size_t istop = png_ptr->zbuf_size;
-
- for (i = (png_size_t)skip; i > istop; i -= istop)
- {
- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- }
- if (i)
- {
- png_crc_read(png_ptr, png_ptr->zbuf, i);
- }
-
- if (png_crc_error(png_ptr))
- {
- if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
- !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
- (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
- (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
- {
- png_chunk_warning(png_ptr, "CRC error");
- }
- else
- {
- png_chunk_error(png_ptr, "CRC error");
- }
- return (1);
- }
-
- return (0);
-}
-
-/* Compare the CRC stored in the PNG file with that calculated by libpng from
- the data it has read thus far. */
-int /* PRIVATE */
-png_crc_error(png_structp png_ptr)
-{
- png_byte crc_bytes[4];
- png_uint_32 crc;
- int need_crc = 1;
-
- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
- else /* critical */
- {
- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
- need_crc = 0;
- }
-
- png_read_data(png_ptr, crc_bytes, 4);
-
- if (need_crc)
- {
- crc = png_get_uint_32(crc_bytes);
- return ((int)(crc != png_ptr->crc));
- }
- else
- return (0);
-}
-
-#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
- defined(PNG_READ_iCCP_SUPPORTED)
-/*
- * Decompress trailing data in a chunk. The assumption is that chunkdata
- * points at an allocated area holding the contents of a chunk with a
- * trailing compressed part. What we get back is an allocated area
- * holding the original prefix part and an uncompressed version of the
- * trailing part (the malloc area passed in is freed).
- */
-png_charp /* PRIVATE */
-png_decompress_chunk(png_structp png_ptr, int comp_type,
- png_charp chunkdata, png_size_t chunklength,
- png_size_t prefix_size, png_size_t *newlength)
-{
- static PNG_CONST char msg[] = "Error decoding compressed text";
- png_charp text;
- png_size_t text_size;
-
- if (comp_type == PNG_COMPRESSION_TYPE_BASE)
- {
- int ret = Z_OK;
- png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
- png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
- text_size = 0;
- text = NULL;
-
- while (png_ptr->zstream.avail_in)
- {
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- {
- if (png_ptr->zstream.msg != NULL)
- png_warning(png_ptr, png_ptr->zstream.msg);
- else
- png_warning(png_ptr, msg);
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- if (text == NULL)
- {
- text_size = prefix_size + png_sizeof(msg) + 1;
- text = (png_charp)png_malloc_warn(png_ptr, text_size);
- if (text == NULL)
- {
- png_free(png_ptr,chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk");
- }
- png_memcpy(text, chunkdata, prefix_size);
- }
-
- text[text_size - 1] = 0x00;
-
- /* Copy what we can of the error message into the text chunk */
- text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
- text_size = png_sizeof(msg) > text_size ? text_size :
- png_sizeof(msg);
- png_memcpy(text + prefix_size, msg, text_size + 1);
- break;
- }
- if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
- {
- if (text == NULL)
- {
- text_size = prefix_size +
- png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
- if (text == NULL)
- {
- png_free(png_ptr,chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk.");
- }
- png_memcpy(text + prefix_size, png_ptr->zbuf,
- text_size - prefix_size);
- png_memcpy(text, chunkdata, prefix_size);
- *(text + text_size) = 0x00;
- }
- else
- {
- png_charp tmp;
-
- tmp = text;
- text = (png_charp)png_malloc_warn(png_ptr,
- (png_uint_32)(text_size +
- png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
- if (text == NULL)
- {
- png_free(png_ptr, tmp);
- png_free(png_ptr, chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk..");
- }
- png_memcpy(text, tmp, text_size);
- png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = 0x00;
- }
- if (ret == Z_STREAM_END)
- break;
- else
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- }
- if (ret != Z_STREAM_END)
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char umsg[52];
-
- if (ret == Z_BUF_ERROR)
- png_snprintf(umsg, 52,
- "Buffer error in compressed datastream in %s chunk",
- png_ptr->chunk_name);
- else if (ret == Z_DATA_ERROR)
- png_snprintf(umsg, 52,
- "Data error in compressed datastream in %s chunk",
- png_ptr->chunk_name);
- else
- png_snprintf(umsg, 52,
- "Incomplete compressed datastream in %s chunk",
- png_ptr->chunk_name);
- png_warning(png_ptr, umsg);
-#else
- png_warning(png_ptr,
- "Incomplete compressed datastream in chunk other than IDAT");
-#endif
- text_size=prefix_size;
- if (text == NULL)
- {
- text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
- if (text == NULL)
- {
- png_free(png_ptr, chunkdata);
- png_error(png_ptr,"Not enough memory for text.");
- }
- png_memcpy(text, chunkdata, prefix_size);
- }
- *(text + text_size) = 0x00;
- }
-
- inflateReset(&png_ptr->zstream);
- png_ptr->zstream.avail_in = 0;
-
- png_free(png_ptr, chunkdata);
- chunkdata = text;
- *newlength=text_size;
- }
- else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char umsg[50];
-
- png_snprintf(umsg, 50,
- "Unknown zTXt compression type %d", comp_type);
- png_warning(png_ptr, umsg);
-#else
- png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
-
- *(chunkdata + prefix_size) = 0x00;
- *newlength=prefix_size;
- }
-
- return chunkdata;
-}
-#endif
-
-/* read and check the IDHR chunk */
-void /* PRIVATE */
-png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[13];
- png_uint_32 width, height;
- int bit_depth, color_type, compression_type, filter_type;
- int interlace_type;
-
- png_debug(1, "in png_handle_IHDR\n");
-
- if (png_ptr->mode & PNG_HAVE_IHDR)
- png_error(png_ptr, "Out of place IHDR");
-
- /* check the length */
- if (length != 13)
- png_error(png_ptr, "Invalid IHDR chunk");
-
- png_ptr->mode |= PNG_HAVE_IHDR;
-
- png_crc_read(png_ptr, buf, 13);
- png_crc_finish(png_ptr, 0);
-
- width = png_get_uint_31(png_ptr, buf);
- height = png_get_uint_31(png_ptr, buf + 4);
- bit_depth = buf[8];
- color_type = buf[9];
- compression_type = buf[10];
- filter_type = buf[11];
- interlace_type = buf[12];
-
- /* set internal variables */
- png_ptr->width = width;
- png_ptr->height = height;
- png_ptr->bit_depth = (png_byte)bit_depth;
- png_ptr->interlaced = (png_byte)interlace_type;
- png_ptr->color_type = (png_byte)color_type;
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_ptr->filter_type = (png_byte)filter_type;
-#endif
- png_ptr->compression_type = (png_byte)compression_type;
-
- /* find number of channels */
- switch (png_ptr->color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_PALETTE:
- png_ptr->channels = 1;
- break;
- case PNG_COLOR_TYPE_RGB:
- png_ptr->channels = 3;
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- png_ptr->channels = 2;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- png_ptr->channels = 4;
- break;
- }
-
- /* set up other useful info */
- png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
- png_ptr->channels);
- png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
- png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
- png_debug1(3,"channels = %d\n", png_ptr->channels);
- png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
- png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
- color_type, interlace_type, compression_type, filter_type);
-}
-
-/* read and check the palette */
-void /* PRIVATE */
-png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_color palette[PNG_MAX_PALETTE_LENGTH];
- int num, i;
-#ifndef PNG_NO_POINTER_INDEXING
- png_colorp pal_ptr;
-#endif
-
- png_debug(1, "in png_handle_PLTE\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before PLTE");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid PLTE after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- png_error(png_ptr, "Duplicate PLTE chunk");
-
- png_ptr->mode |= PNG_HAVE_PLTE;
-
- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
- {
- png_warning(png_ptr,
- "Ignoring PLTE chunk in grayscale PNG");
- png_crc_finish(png_ptr, length);
- return;
- }
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- png_crc_finish(png_ptr, length);
- return;
- }
-#endif
-
- if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
- {
- if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- png_warning(png_ptr, "Invalid palette chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
- else
- {
- png_error(png_ptr, "Invalid palette chunk");
- }
- }
-
- num = (int)length / 3;
-
-#ifndef PNG_NO_POINTER_INDEXING
- for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
- {
- png_byte buf[3];
-
- png_crc_read(png_ptr, buf, 3);
- pal_ptr->red = buf[0];
- pal_ptr->green = buf[1];
- pal_ptr->blue = buf[2];
- }
-#else
- for (i = 0; i < num; i++)
- {
- png_byte buf[3];
-
- png_crc_read(png_ptr, buf, 3);
- /* don't depend upon png_color being any order */
- palette[i].red = buf[0];
- palette[i].green = buf[1];
- palette[i].blue = buf[2];
- }
-#endif
-
- /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
- whatever the normal CRC configuration tells us. However, if we
- have an RGB image, the PLTE can be considered ancillary, so
- we will act as though it is. */
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-#endif
- {
- png_crc_finish(png_ptr, 0);
- }
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
- else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
- {
- /* If we don't want to use the data from an ancillary chunk,
- we have two options: an error abort, or a warning and we
- ignore the data in this chunk (which should be OK, since
- it's considered ancillary for a RGB or RGBA image). */
- if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
- {
- if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
- {
- png_chunk_error(png_ptr, "CRC error");
- }
- else
- {
- png_chunk_warning(png_ptr, "CRC error");
- return;
- }
- }
- /* Otherwise, we (optionally) emit a warning and use the chunk. */
- else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
- {
- png_chunk_warning(png_ptr, "CRC error");
- }
- }
-#endif
-
- png_set_PLTE(png_ptr, info_ptr, palette, num);
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
- {
- if (png_ptr->num_trans > (png_uint_16)num)
- {
- png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
- png_ptr->num_trans = (png_uint_16)num;
- }
- if (info_ptr->num_trans > (png_uint_16)num)
- {
- png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
- info_ptr->num_trans = (png_uint_16)num;
- }
- }
- }
-#endif
-
-}
-
-void /* PRIVATE */
-png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_debug(1, "in png_handle_IEND\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
- {
- png_error(png_ptr, "No image in file");
- }
-
- png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
-
- if (length != 0)
- {
- png_warning(png_ptr, "Incorrect IEND chunk length");
- }
- png_crc_finish(png_ptr, length);
-
- info_ptr =info_ptr; /* quiet compiler warnings about unused info_ptr */
-}
-
-#if defined(PNG_READ_gAMA_SUPPORTED)
-void /* PRIVATE */
-png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_fixed_point igamma;
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- float file_gamma;
-#endif
- png_byte buf[4];
-
- png_debug(1, "in png_handle_gAMA\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before gAMA");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid gAMA after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place gAMA chunk");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
-#if defined(PNG_READ_sRGB_SUPPORTED)
- && !(info_ptr->valid & PNG_INFO_sRGB)
-#endif
- )
- {
- png_warning(png_ptr, "Duplicate gAMA chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 4)
- {
- png_warning(png_ptr, "Incorrect gAMA chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- igamma = (png_fixed_point)png_get_uint_32(buf);
- /* check for zero gamma */
- if (igamma == 0)
- {
- png_warning(png_ptr,
- "Ignoring gAMA chunk with gamma=0");
- return;
- }
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
- if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
- {
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
-#endif
- return;
- }
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- file_gamma = (float)igamma / (float)100000.0;
-# ifdef PNG_READ_GAMMA_SUPPORTED
- png_ptr->gamma = file_gamma;
-# endif
- png_set_gAMA(png_ptr, info_ptr, file_gamma);
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
-#endif
-}
-#endif
-
-#if defined(PNG_READ_sBIT_SUPPORTED)
-void /* PRIVATE */
-png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_size_t truelen;
- png_byte buf[4];
-
- png_debug(1, "in png_handle_sBIT\n");
-
- buf[0] = buf[1] = buf[2] = buf[3] = 0;
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sBIT");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sBIT after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- {
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place sBIT chunk");
- }
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
- {
- png_warning(png_ptr, "Duplicate sBIT chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- truelen = 3;
- else
- truelen = (png_size_t)png_ptr->channels;
-
- if (length != truelen || length > 4)
- {
- png_warning(png_ptr, "Incorrect sBIT chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- {
- png_ptr->sig_bit.red = buf[0];
- png_ptr->sig_bit.green = buf[1];
- png_ptr->sig_bit.blue = buf[2];
- png_ptr->sig_bit.alpha = buf[3];
- }
- else
- {
- png_ptr->sig_bit.gray = buf[0];
- png_ptr->sig_bit.red = buf[0];
- png_ptr->sig_bit.green = buf[0];
- png_ptr->sig_bit.blue = buf[0];
- png_ptr->sig_bit.alpha = buf[1];
- }
- png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
-}
-#endif
-
-#if defined(PNG_READ_cHRM_SUPPORTED)
-void /* PRIVATE */
-png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[4];
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
-#endif
- png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
- int_y_green, int_x_blue, int_y_blue;
-
- png_uint_32 uint_x, uint_y;
-
- png_debug(1, "in png_handle_cHRM\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before cHRM");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid cHRM after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Missing PLTE before cHRM");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
-#if defined(PNG_READ_sRGB_SUPPORTED)
- && !(info_ptr->valid & PNG_INFO_sRGB)
-#endif
- )
- {
- png_warning(png_ptr, "Duplicate cHRM chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 32)
- {
- png_warning(png_ptr, "Incorrect cHRM chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x > 80000L || uint_y > 80000L ||
- uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM white point");
- png_crc_finish(png_ptr, 24);
- return;
- }
- int_x_white = (png_fixed_point)uint_x;
- int_y_white = (png_fixed_point)uint_y;
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM red point");
- png_crc_finish(png_ptr, 16);
- return;
- }
- int_x_red = (png_fixed_point)uint_x;
- int_y_red = (png_fixed_point)uint_y;
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM green point");
- png_crc_finish(png_ptr, 8);
- return;
- }
- int_x_green = (png_fixed_point)uint_x;
- int_y_green = (png_fixed_point)uint_y;
-
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM blue point");
- png_crc_finish(png_ptr, 0);
- return;
- }
- int_x_blue = (png_fixed_point)uint_x;
- int_y_blue = (png_fixed_point)uint_y;
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- white_x = (float)int_x_white / (float)100000.0;
- white_y = (float)int_y_white / (float)100000.0;
- red_x = (float)int_x_red / (float)100000.0;
- red_y = (float)int_y_red / (float)100000.0;
- green_x = (float)int_x_green / (float)100000.0;
- green_y = (float)int_y_green / (float)100000.0;
- blue_x = (float)int_x_blue / (float)100000.0;
- blue_y = (float)int_y_blue / (float)100000.0;
-#endif
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
- if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
- {
- if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
- PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
- PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
- PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
- PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
- PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
- PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
- PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
- {
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
- white_x, white_y, red_x, red_y);
- fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
- green_x, green_y, blue_x, blue_y);
-#else
- fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
- int_x_white, int_y_white, int_x_red, int_y_red);
- fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
- int_x_green, int_y_green, int_x_blue, int_y_blue);
-#endif
-#endif /* PNG_NO_CONSOLE_IO */
- }
- png_crc_finish(png_ptr, 0);
- return;
- }
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_cHRM(png_ptr, info_ptr,
- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_cHRM_fixed(png_ptr, info_ptr,
- int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
- int_y_green, int_x_blue, int_y_blue);
-#endif
- if (png_crc_finish(png_ptr, 0))
- return;
-}
-#endif
-
-#if defined(PNG_READ_sRGB_SUPPORTED)
-void /* PRIVATE */
-png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- int intent;
- png_byte buf[1];
-
- png_debug(1, "in png_handle_sRGB\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sRGB");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sRGB after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place sRGB chunk");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
- {
- png_warning(png_ptr, "Duplicate sRGB chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 1)
- {
- png_warning(png_ptr, "Incorrect sRGB chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 1);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- intent = buf[0];
- /* check for bad intent */
- if (intent >= PNG_sRGB_INTENT_LAST)
- {
- png_warning(png_ptr, "Unknown sRGB intent");
- return;
- }
-
-#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
- {
- png_fixed_point igamma;
-#ifdef PNG_FIXED_POINT_SUPPORTED
- igamma=info_ptr->int_gamma;
-#else
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
-# endif
-#endif
- if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
- {
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
-# ifdef PNG_FIXED_POINT_SUPPORTED
- fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
-# else
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
-# endif
-# endif
-#endif
- }
- }
-#endif /* PNG_READ_gAMA_SUPPORTED */
-
-#ifdef PNG_READ_cHRM_SUPPORTED
-#ifdef PNG_FIXED_POINT_SUPPORTED
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
- if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
- PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
- {
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
- }
-#endif /* PNG_FIXED_POINT_SUPPORTED */
-#endif /* PNG_READ_cHRM_SUPPORTED */
-
- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
-}
-#endif /* PNG_READ_sRGB_SUPPORTED */
-
-#if defined(PNG_READ_iCCP_SUPPORTED)
-void /* PRIVATE */
-png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-{
- png_charp chunkdata;
- png_byte compression_type;
- png_bytep pC;
- png_charp profile;
- png_uint_32 skip = 0;
- png_uint_32 profile_size, profile_length;
- png_size_t slength, prefix_length, data_length;
-
- png_debug(1, "in png_handle_iCCP\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before iCCP");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid iCCP after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->mode & PNG_HAVE_PLTE)
- /* Should be an error, but we can cope with it */
- png_warning(png_ptr, "Out of place iCCP chunk");
-
- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
- {
- png_warning(png_ptr, "Duplicate iCCP chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "iCCP chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (profile = chunkdata; *profile; profile++)
- /* empty loop to find end of name */ ;
-
- ++profile;
-
- /* there should be at least one zero (the compression type byte)
- following the separator, and we should be on it */
- if ( profile >= chunkdata + slength - 1)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Malformed iCCP chunk");
- return;
- }
-
- /* compression_type should always be zero */
- compression_type = *profile++;
- if (compression_type)
- {
- png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
- compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
- wrote nonzero) */
- }
-
- prefix_length = profile - chunkdata;
- chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
- slength, prefix_length, &data_length);
-
- profile_length = data_length - prefix_length;
-
- if ( prefix_length > data_length || profile_length < 4)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Profile size field missing from iCCP chunk");
- return;
- }
-
- /* Check the profile_size recorded in the first 32 bits of the ICC profile */
- pC = (png_bytep)(chunkdata+prefix_length);
- profile_size = ((*(pC ))<<24) |
- ((*(pC+1))<<16) |
- ((*(pC+2))<< 8) |
- ((*(pC+3)) );
-
- if(profile_size < profile_length)
- profile_length = profile_size;
-
- if(profile_size > profile_length)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Ignoring truncated iCCP profile.");
- return;
- }
-
- png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
- chunkdata + prefix_length, profile_length);
- png_free(png_ptr, chunkdata);
-}
-#endif /* PNG_READ_iCCP_SUPPORTED */
-
-#if defined(PNG_READ_sPLT_SUPPORTED)
-void /* PRIVATE */
-png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-{
- png_bytep chunkdata;
- png_bytep entry_start;
- png_sPLT_t new_palette;
-#ifdef PNG_NO_POINTER_INDEXING
- png_sPLT_entryp pp;
-#endif
- int data_length, entry_size, i;
- png_uint_32 skip = 0;
- png_size_t slength;
-
- png_debug(1, "in png_handle_sPLT\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sPLT");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sPLT after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
-
-#ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "sPLT chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (entry_start = chunkdata; *entry_start; entry_start++)
- /* empty loop to find end of name */ ;
- ++entry_start;
-
- /* a sample depth should follow the separator, and we should be on it */
- if (entry_start > chunkdata + slength - 2)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "malformed sPLT chunk");
- return;
- }
-
- new_palette.depth = *entry_start++;
- entry_size = (new_palette.depth == 8 ? 6 : 10);
- data_length = (slength - (entry_start - chunkdata));
-
- /* integrity-check the data length */
- if (data_length % entry_size)
- {
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "sPLT chunk has bad length");
- return;
- }
-
- new_palette.nentries = (png_int_32) ( data_length / entry_size);
- if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
- png_sizeof(png_sPLT_entry)))
- {
- png_warning(png_ptr, "sPLT chunk too long");
- return;
- }
- new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
- png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
- if (new_palette.entries == NULL)
- {
- png_warning(png_ptr, "sPLT chunk requires too much memory");
- return;
- }
-
-#ifndef PNG_NO_POINTER_INDEXING
- for (i = 0; i < new_palette.nentries; i++)
- {
- png_sPLT_entryp pp = new_palette.entries + i;
-
- if (new_palette.depth == 8)
- {
- pp->red = *entry_start++;
- pp->green = *entry_start++;
- pp->blue = *entry_start++;
- pp->alpha = *entry_start++;
- }
- else
- {
- pp->red = png_get_uint_16(entry_start); entry_start += 2;
- pp->green = png_get_uint_16(entry_start); entry_start += 2;
- pp->blue = png_get_uint_16(entry_start); entry_start += 2;
- pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
- }
- pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
- }
-#else
- pp = new_palette.entries;
- for (i = 0; i < new_palette.nentries; i++)
- {
-
- if (new_palette.depth == 8)
- {
- pp[i].red = *entry_start++;
- pp[i].green = *entry_start++;
- pp[i].blue = *entry_start++;
- pp[i].alpha = *entry_start++;
- }
- else
- {
- pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
- pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
- pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
- pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
- }
- pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
- }
-#endif
-
- /* discard all chunk data except the name and stash that */
- new_palette.name = (png_charp)chunkdata;
-
- png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
-
- png_free(png_ptr, chunkdata);
- png_free(png_ptr, new_palette.entries);
-}
-#endif /* PNG_READ_sPLT_SUPPORTED */
-
-#if defined(PNG_READ_tRNS_SUPPORTED)
-void /* PRIVATE */
-png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
- int bit_mask;
-
- png_debug(1, "in png_handle_tRNS\n");
-
- /* For non-indexed color, mask off any bits in the tRNS value that
- * exceed the bit depth. Some creators were writing extra bits there.
- * This is not needed for indexed color. */
- bit_mask = (1 << png_ptr->bit_depth) - 1;
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before tRNS");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid tRNS after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
- {
- png_warning(png_ptr, "Duplicate tRNS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_byte buf[2];
-
- if (length != 2)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 2);
- png_ptr->num_trans = 1;
- png_ptr->trans_values.gray = png_get_uint_16(buf) & bit_mask;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_byte buf[6];
-
- if (length != 6)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
- png_crc_read(png_ptr, buf, (png_size_t)length);
- png_ptr->num_trans = 1;
- png_ptr->trans_values.red = png_get_uint_16(buf) & bit_mask;
- png_ptr->trans_values.green = png_get_uint_16(buf + 2) & bit_mask;
- png_ptr->trans_values.blue = png_get_uint_16(buf + 4) & bit_mask;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (!(png_ptr->mode & PNG_HAVE_PLTE))
- {
- /* Should be an error, but we can cope with it. */
- png_warning(png_ptr, "Missing PLTE before tRNS");
- }
- if (length > (png_uint_32)png_ptr->num_palette ||
- length > PNG_MAX_PALETTE_LENGTH)
- {
- png_warning(png_ptr, "Incorrect tRNS chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
- if (length == 0)
- {
- png_warning(png_ptr, "Zero length tRNS chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
- png_crc_read(png_ptr, readbuf, (png_size_t)length);
- png_ptr->num_trans = (png_uint_16)length;
- }
- else
- {
- png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_ptr->num_trans = 0;
- return;
- }
-
- png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
- &(png_ptr->trans_values));
-}
-#endif
-
-#if defined(PNG_READ_bKGD_SUPPORTED)
-void /* PRIVATE */
-png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_size_t truelen;
- png_byte buf[6];
-
- png_debug(1, "in png_handle_bKGD\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before bKGD");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid bKGD after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- !(png_ptr->mode & PNG_HAVE_PLTE))
- {
- png_warning(png_ptr, "Missing PLTE before bKGD");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
- {
- png_warning(png_ptr, "Duplicate bKGD chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- truelen = 1;
- else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
- truelen = 6;
- else
- truelen = 2;
-
- if (length != truelen)
- {
- png_warning(png_ptr, "Incorrect bKGD chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- /* We convert the index value into RGB components so that we can allow
- * arbitrary RGB values for background when we have transparency, and
- * so it is easy to determine the RGB values of the background color
- * from the info_ptr struct. */
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_ptr->background.index = buf[0];
- if(info_ptr->num_palette)
- {
- if(buf[0] > info_ptr->num_palette)
- {
- png_warning(png_ptr, "Incorrect bKGD chunk index value");
- return;
- }
- png_ptr->background.red =
- (png_uint_16)png_ptr->palette[buf[0]].red;
- png_ptr->background.green =
- (png_uint_16)png_ptr->palette[buf[0]].green;
- png_ptr->background.blue =
- (png_uint_16)png_ptr->palette[buf[0]].blue;
- }
- }
- else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
- {
- png_ptr->background.red =
- png_ptr->background.green =
- png_ptr->background.blue =
- png_ptr->background.gray = png_get_uint_16(buf);
- }
- else
- {
- png_ptr->background.red = png_get_uint_16(buf);
- png_ptr->background.green = png_get_uint_16(buf + 2);
- png_ptr->background.blue = png_get_uint_16(buf + 4);
- }
-
- png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
-}
-#endif
-
-#if defined(PNG_READ_hIST_SUPPORTED)
-void /* PRIVATE */
-png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- unsigned int num, i;
- png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
-
- png_debug(1, "in png_handle_hIST\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before hIST");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid hIST after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (!(png_ptr->mode & PNG_HAVE_PLTE))
- {
- png_warning(png_ptr, "Missing PLTE before hIST");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
- {
- png_warning(png_ptr, "Duplicate hIST chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- num = length / 2 ;
- if (num != (unsigned int) png_ptr->num_palette || num >
- (unsigned int) PNG_MAX_PALETTE_LENGTH)
- {
- png_warning(png_ptr, "Incorrect hIST chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- for (i = 0; i < num; i++)
- {
- png_byte buf[2];
-
- png_crc_read(png_ptr, buf, 2);
- readbuf[i] = png_get_uint_16(buf);
- }
-
- if (png_crc_finish(png_ptr, 0))
- return;
-
- png_set_hIST(png_ptr, info_ptr, readbuf);
-}
-#endif
-
-#if defined(PNG_READ_pHYs_SUPPORTED)
-void /* PRIVATE */
-png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[9];
- png_uint_32 res_x, res_y;
- int unit_type;
-
- png_debug(1, "in png_handle_pHYs\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before pHYs");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid pHYs after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
- {
- png_warning(png_ptr, "Duplicate pHYs chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 9)
- {
- png_warning(png_ptr, "Incorrect pHYs chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- res_x = png_get_uint_32(buf);
- res_y = png_get_uint_32(buf + 4);
- unit_type = buf[8];
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
-}
-#endif
-
-#if defined(PNG_READ_oFFs_SUPPORTED)
-void /* PRIVATE */
-png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[9];
- png_int_32 offset_x, offset_y;
- int unit_type;
-
- png_debug(1, "in png_handle_oFFs\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before oFFs");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid oFFs after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
- {
- png_warning(png_ptr, "Duplicate oFFs chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (length != 9)
- {
- png_warning(png_ptr, "Incorrect oFFs chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- offset_x = png_get_int_32(buf);
- offset_y = png_get_int_32(buf + 4);
- unit_type = buf[8];
- png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
-}
-#endif
-
-#if defined(PNG_READ_pCAL_SUPPORTED)
-/* read the pCAL chunk (described in the PNG Extensions document) */
-void /* PRIVATE */
-png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_charp purpose;
- png_int_32 X0, X1;
- png_byte type, nparams;
- png_charp buf, units, endptr;
- png_charpp params;
- png_size_t slength;
- int i;
-
- png_debug(1, "in png_handle_pCAL\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before pCAL");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid pCAL after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
- {
- png_warning(png_ptr, "Duplicate pCAL chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
- length + 1);
- purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (purpose == NULL)
- {
- png_warning(png_ptr, "No memory for pCAL purpose.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)purpose, slength);
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, purpose);
- return;
- }
-
- purpose[slength] = 0x00; /* null terminate the last string */
-
- png_debug(3, "Finding end of pCAL purpose string\n");
- for (buf = purpose; *buf; buf++)
- /* empty loop */ ;
-
- endptr = purpose + slength;
-
- /* We need to have at least 12 bytes after the purpose string
- in order to get the parameter information. */
- if (endptr <= buf + 12)
- {
- png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
- return;
- }
-
- png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
- X0 = png_get_int_32((png_bytep)buf+1);
- X1 = png_get_int_32((png_bytep)buf+5);
- type = buf[9];
- nparams = buf[10];
- units = buf + 11;
-
- png_debug(3, "Checking pCAL equation type and number of parameters\n");
- /* Check that we have the right number of parameters for known
- equation types. */
- if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
- (type == PNG_EQUATION_BASE_E && nparams != 3) ||
- (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
- (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
- {
- png_warning(png_ptr, "Invalid pCAL parameters for equation type");
- png_free(png_ptr, purpose);
- return;
- }
- else if (type >= PNG_EQUATION_LAST)
- {
- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
- }
-
- for (buf = units; *buf; buf++)
- /* Empty loop to move past the units string. */ ;
-
- png_debug(3, "Allocating pCAL parameters array\n");
- params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
- *png_sizeof(png_charp))) ;
- if (params == NULL)
- {
- png_free(png_ptr, purpose);
- png_warning(png_ptr, "No memory for pCAL params.");
- return;
- }
-
- /* Get pointers to the start of each parameter string. */
- for (i = 0; i < (int)nparams; i++)
- {
- buf++; /* Skip the null string terminator from previous parameter. */
-
- png_debug1(3, "Reading pCAL parameter %d\n", i);
- for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
- /* Empty loop to move past each parameter string */ ;
-
- /* Make sure we haven't run out of data yet */
- if (buf > endptr)
- {
- png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
- png_free(png_ptr, params);
- return;
- }
- }
-
- png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
- units, params);
-
- png_free(png_ptr, purpose);
- png_free(png_ptr, params);
-}
-#endif
-
-#if defined(PNG_READ_sCAL_SUPPORTED)
-/* read the sCAL chunk */
-void /* PRIVATE */
-png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_charp buffer, ep;
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- double width, height;
- png_charp vp;
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_charp swidth, sheight;
-#endif
-#endif
- png_size_t slength;
-
- png_debug(1, "in png_handle_sCAL\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before sCAL");
- else if (png_ptr->mode & PNG_HAVE_IDAT)
- {
- png_warning(png_ptr, "Invalid sCAL after IDAT");
- png_crc_finish(png_ptr, length);
- return;
- }
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
- {
- png_warning(png_ptr, "Duplicate sCAL chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
- length + 1);
- buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (buffer == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)buffer, slength);
-
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, buffer);
- return;
- }
-
- buffer[slength] = 0x00; /* null terminate the last string */
-
- ep = buffer + 1; /* skip unit byte */
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- width = png_strtod(png_ptr, ep, &vp);
- if (*vp)
- {
- png_warning(png_ptr, "malformed width string in sCAL chunk");
- return;
- }
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
- swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
- if (swidth == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
- return;
- }
- png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
-#endif
-#endif
-
- for (ep = buffer; *ep; ep++)
- /* empty loop */ ;
- ep++;
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- height = png_strtod(png_ptr, ep, &vp);
- if (*vp)
- {
- png_warning(png_ptr, "malformed height string in sCAL chunk");
- return;
- }
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
- sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
- if (swidth == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
- return;
- }
- png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
-#endif
-#endif
-
- if (buffer + slength < ep
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- || width <= 0. || height <= 0.
-#endif
- )
- {
- png_warning(png_ptr, "Invalid sCAL data");
- png_free(png_ptr, buffer);
-#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, swidth);
- png_free(png_ptr, sheight);
-#endif
- return;
- }
-
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
-#endif
-#endif
-
- png_free(png_ptr, buffer);
-#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
- png_free(png_ptr, swidth);
- png_free(png_ptr, sheight);
-#endif
-}
-#endif
-
-#if defined(PNG_READ_tIME_SUPPORTED)
-void /* PRIVATE */
-png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_byte buf[7];
- png_time mod_time;
-
- png_debug(1, "in png_handle_tIME\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Out of place tIME chunk");
- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
- {
- png_warning(png_ptr, "Duplicate tIME chunk");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- if (length != 7)
- {
- png_warning(png_ptr, "Incorrect tIME chunk length");
- png_crc_finish(png_ptr, length);
- return;
- }
-
- png_crc_read(png_ptr, buf, 7);
- if (png_crc_finish(png_ptr, 0))
- return;
-
- mod_time.second = buf[6];
- mod_time.minute = buf[5];
- mod_time.hour = buf[4];
- mod_time.day = buf[3];
- mod_time.month = buf[2];
- mod_time.year = png_get_uint_16(buf);
-
- png_set_tIME(png_ptr, info_ptr, &mod_time);
-}
-#endif
-
-#if defined(PNG_READ_tEXt_SUPPORTED)
-/* Note: this does not properly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
-png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_textp text_ptr;
- png_charp key;
- png_charp text;
- png_uint_32 skip = 0;
- png_size_t slength;
- int ret;
-
- png_debug(1, "in png_handle_tEXt\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before tEXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "tEXt chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
-
- key = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (key == NULL)
- {
- png_warning(png_ptr, "No memory to process text chunk.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)key, slength);
-
- if (png_crc_finish(png_ptr, skip))
- {
- png_free(png_ptr, key);
- return;
- }
-
- key[slength] = 0x00;
-
- for (text = key; *text; text++)
- /* empty loop to find end of key */ ;
-
- if (text != key + slength)
- text++;
-
- text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- if (text_ptr == NULL)
- {
- png_warning(png_ptr, "Not enough memory to process text chunk.");
- png_free(png_ptr, key);
- return;
- }
- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
- text_ptr->key = key;
-#ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
- text_ptr->itxt_length = 0;
-#endif
- text_ptr->text = text;
- text_ptr->text_length = png_strlen(text);
-
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, key);
- png_free(png_ptr, text_ptr);
- if (ret)
- png_warning(png_ptr, "Insufficient memory to process text chunk.");
-}
-#endif
-
-#if defined(PNG_READ_zTXt_SUPPORTED)
-/* note: this does not correctly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
-png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_textp text_ptr;
- png_charp chunkdata;
- png_charp text;
- int comp_type;
- int ret;
- png_size_t slength, prefix_len, data_len;
-
- png_debug(1, "in png_handle_zTXt\n");
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before zTXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
- /* We will no doubt have problems with chunks even half this size, but
- there is no hard and fast rule to tell us where to stop. */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr,"zTXt chunk too large to fit in memory");
- png_crc_finish(png_ptr, length);
- return;
- }
-#endif
-
- chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (chunkdata == NULL)
- {
- png_warning(png_ptr,"Out of memory processing zTXt chunk.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (text = chunkdata; *text; text++)
- /* empty loop */ ;
-
- /* zTXt must have some text after the chunkdataword */
- if (text == chunkdata + slength - 1)
- {
- png_warning(png_ptr, "Truncated zTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
- else
- {
- comp_type = *(++text);
- if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
- {
- png_warning(png_ptr, "Unknown compression type in zTXt chunk");
- comp_type = PNG_TEXT_COMPRESSION_zTXt;
- }
- text++; /* skip the compression_method byte */
- }
- prefix_len = text - chunkdata;
-
- chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
- (png_size_t)length, prefix_len, &data_len);
-
- text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- if (text_ptr == NULL)
- {
- png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
- png_free(png_ptr, chunkdata);
- return;
- }
- text_ptr->compression = comp_type;
- text_ptr->key = chunkdata;
-#ifdef PNG_iTXt_SUPPORTED
- text_ptr->lang = NULL;
- text_ptr->lang_key = NULL;
- text_ptr->itxt_length = 0;
-#endif
- text_ptr->text = chunkdata + prefix_len;
- text_ptr->text_length = data_len;
-
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
- png_free(png_ptr, chunkdata);
- if (ret)
- png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
-}
-#endif
-
-#if defined(PNG_READ_iTXt_SUPPORTED)
-/* note: this does not correctly handle chunks that are > 64K under DOS */
-void /* PRIVATE */
-png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_textp text_ptr;
- png_charp chunkdata;
- png_charp key, lang, text, lang_key;
- int comp_flag;
- int comp_type = 0;
- int ret;
- png_size_t slength, prefix_len, data_len;
-
- png_debug(1, "in png_handle_iTXt\n");
-
- if (!(png_ptr->mode & PNG_HAVE_IHDR))
- png_error(png_ptr, "Missing IHDR before iTXt");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
-#ifdef PNG_MAX_MALLOC_64K
- /* We will no doubt have problems with chunks even half this size, but
- there is no hard and fast rule to tell us where to stop. */
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr,"iTXt chunk too large to fit in memory");
- png_crc_finish(png_ptr, length);
- return;
- }
-#endif
-
- chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (chunkdata == NULL)
- {
- png_warning(png_ptr, "No memory to process iTXt chunk.");
- return;
- }
- slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
- if (png_crc_finish(png_ptr, 0))
- {
- png_free(png_ptr, chunkdata);
- return;
- }
-
- chunkdata[slength] = 0x00;
-
- for (lang = chunkdata; *lang; lang++)
- /* empty loop */ ;
- lang++; /* skip NUL separator */
-
- /* iTXt must have a language tag (possibly empty), two compression bytes,
- translated keyword (possibly empty), and possibly some text after the
- keyword */
-
- if (lang >= chunkdata + slength - 3)
- {
- png_warning(png_ptr, "Truncated iTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
- else
- {
- comp_flag = *lang++;
- comp_type = *lang++;
- }
-
- for (lang_key = lang; *lang_key; lang_key++)
- /* empty loop */ ;
- lang_key++; /* skip NUL separator */
-
- for (text = lang_key; *text; text++)
- /* empty loop */ ;
- text++; /* skip NUL separator */
- if (text >= chunkdata + slength)
- {
- png_warning(png_ptr, "Malformed iTXt chunk");
- png_free(png_ptr, chunkdata);
- return;
- }
-
- prefix_len = text - chunkdata;
-
- key=chunkdata;
- if (comp_flag)
- chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
- (size_t)length, prefix_len, &data_len);
- else
- data_len=png_strlen(chunkdata + prefix_len);
- text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
- if (text_ptr == NULL)
- {
- png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
- png_free(png_ptr, chunkdata);
- return;
- }
- text_ptr->compression = (int)comp_flag + 1;
- text_ptr->lang_key = chunkdata+(lang_key-key);
- text_ptr->lang = chunkdata+(lang-key);
- text_ptr->itxt_length = data_len;
- text_ptr->text_length = 0;
- text_ptr->key = chunkdata;
- text_ptr->text = chunkdata + prefix_len;
-
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
-
- png_free(png_ptr, text_ptr);
- png_free(png_ptr, chunkdata);
- if (ret)
- png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
-}
-#endif
-
-/* This function is called when we haven't found a handler for a
- chunk. If there isn't a problem with the chunk itself (ie bad
- chunk name, CRC, or a critical chunk), the chunk is silently ignored
- -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
- case it will be saved away to be written out later. */
-void /* PRIVATE */
-png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-{
- png_uint_32 skip = 0;
-
- png_debug(1, "in png_handle_unknown\n");
-
- if (png_ptr->mode & PNG_HAVE_IDAT)
- {
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
-#endif
- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
- png_ptr->mode |= PNG_AFTER_IDAT;
- }
-
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
- if (!(png_ptr->chunk_name[0] & 0x20))
- {
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- && png_ptr->read_user_chunk_fn == NULL
-#endif
- )
-#endif
- png_chunk_error(png_ptr, "unknown critical chunk");
- }
-
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
- (png_ptr->read_user_chunk_fn != NULL))
- {
-#ifdef PNG_MAX_MALLOC_64K
- if (length > (png_uint_32)65535L)
- {
- png_warning(png_ptr, "unknown chunk too large to fit in memory");
- skip = length - (png_uint_32)65535L;
- length = (png_uint_32)65535L;
- }
-#endif
- png_strncpy((png_charp)png_ptr->unknown_chunk.name,
- (png_charp)png_ptr->chunk_name,
- png_sizeof((png_charp)png_ptr->chunk_name));
- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
- png_ptr->unknown_chunk.size = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- if(png_ptr->read_user_chunk_fn != NULL)
- {
- /* callback to user unknown chunk handler */
- int ret;
- ret = (*(png_ptr->read_user_chunk_fn))
- (png_ptr, &png_ptr->unknown_chunk);
- if (ret < 0)
- png_chunk_error(png_ptr, "error in user chunk");
- if (ret == 0)
- {
- if (!(png_ptr->chunk_name[0] & 0x20))
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
- PNG_HANDLE_CHUNK_ALWAYS)
- png_chunk_error(png_ptr, "unknown critical chunk");
- png_set_unknown_chunks(png_ptr, info_ptr,
- &png_ptr->unknown_chunk, 1);
- }
- }
-#else
- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
-#endif
- png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
- }
- else
-#endif
- skip = length;
-
- png_crc_finish(png_ptr, skip);
-
-#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
-#endif
-}
-
-/* This function is called to verify that a chunk name is valid.
- This function can't have the "critical chunk check" incorporated
- into it, since in the future we will need to be able to call user
- functions to handle unknown critical chunks after we check that
- the chunk name itself is valid. */
-
-#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-
-void /* PRIVATE */
-png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
-{
- png_debug(1, "in png_check_chunk_name\n");
- if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
- isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
- {
- png_chunk_error(png_ptr, "invalid chunk type");
- }
-}
-
-/* Combines the row recently read in with the existing pixels in the
- row. This routine takes care of alpha and transparency if requested.
- This routine also handles the two methods of progressive display
- of interlaced images, depending on the mask value.
- The mask value describes which pixels are to be combined with
- the row. The pattern always repeats every 8 pixels, so just 8
- bits are needed. A one indicates the pixel is to be combined,
- a zero indicates the pixel is to be skipped. This is in addition
- to any alpha or transparency value associated with the pixel. If
- you want all pixels to be combined, pass 0xff (255) in mask. */
-
-/* Optimized C version of utilities to read a PNG file
- *
- * Based on code contributed by Nirav Chhatrapati, Intel Corp., 1998.
- * Interface to libpng contributed by Gilles Vollant, 1999.
- * GNU C port by Greg Roelofs, 1999-2001.
- *
- */
-
-#if defined(PNG_OPTIMIZED_CODE_SUPPORTED)
-#if !defined(PNG_HAVE_MMX_COMBINE_ROW)
-
-/*===========================================================================*/
-/* */
-/* P N G _ C O M B I N E _ R O W */
-/* */
-/*===========================================================================*/
-
-
-#define BPP2 2
-#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */
-#define BPP4 4
-#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */
-#define BPP8 8
-
-/* Combines the row recently read in with the previous row.
- This routine takes care of alpha and transparency if requested.
- This routine also handles the two methods of progressive display
- of interlaced images, depending on the mask value.
- The mask value describes which pixels are to be combined with
- the row. The pattern always repeats every 8 pixels, so just 8
- bits are needed. A one indicates the pixel is to be combined; a
- zero indicates the pixel is to be skipped. This is in addition
- to any alpha or transparency value associated with the pixel.
- If you want all pixels to be combined, pass 0xff (255) in mask. */
-
-/* Use this routine for the x86 platform - it uses a faster MMX routine
- if the machine supports MMX. */
-
-void /* PRIVATE */
-png_combine_row(png_structp png_ptr, png_bytep row, int mask)
-{
-
-#if defined(PNG_USE_LOCAL_ARRAYS)
-static PNG_CONST int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-static PNG_CONST int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-static PNG_CONST int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1};
-#endif
-
- png_debug(1, "in png_combine_row (pngrutil.c OPTIMIZED)\n");
-
- if (mask == 0xff)
- {
- png_debug(2,"mask == 0xff: doing single png_memcpy()\n");
- png_memcpy(row, png_ptr->row_buf + 1,
- (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width));
- }
- else /* (png_combine_row() is never called with mask == 0) */
- {
- switch (png_ptr->row_info.pixel_depth)
- {
- /* most common case: combining 24-bit RGB */
- case 24: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP3 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP3;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 24 bpp */
-
- case 32: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP4 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP4;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- }
-
- break;
- } /* end 32 bpp */
-
- case 8: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
- {
- register png_uint_32 i;
- png_uint_32 initial_val = png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff /* *BPP1 */ ;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- }
-
- break;
- } /* end 8 bpp */
-
- case 1: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep sp;
- png_bytep dp;
- int s_inc, s_start, s_end;
- int m;
- int shift;
- png_uint_32 i;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
- else
-#endif
- {
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- int value;
-
- value = (*sp >> shift) & 0x1;
- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- } /* end 1 bpp */
-
- case 2: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep sp;
- png_bytep dp;
- int s_start, s_end, s_inc;
- int m;
- int shift;
- png_uint_32 i;
- int value;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
- else
-#endif
- {
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0x3;
- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- } /* end 2 bpp */
-
- case 4: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep sp;
- png_bytep dp;
- int s_start, s_end, s_inc;
- int m;
- int shift;
- png_uint_32 i;
- int value;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
- else
-#endif
- {
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0xf;
- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- } /* end 4 bpp */
-
- case 16: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
-
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP2 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP2;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- } /* end of else (_mmx_supported) */
-
- break;
- } /* end 16 bpp */
-
-
-
- case 48: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
- {
- register png_uint_32 i;
- png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP6 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP6;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
- }
- break;
- } /* end 48 bpp */
-
- case 64: /* png_ptr->row_info.pixel_depth */
- {
- png_bytep srcptr;
- png_bytep dstptr;
- register png_uint_32 i;
- png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass];
- /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
- register int stride = BPP8 * png_pass_inc[png_ptr->pass];
- /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
- register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass];
- /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
- png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
- int diff = (int) (png_ptr->width & 7); /* amount lost */
- register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */
-
- srcptr = png_ptr->row_buf + 1 + initial_val;
- dstptr = row + initial_val;
-
- for (i = initial_val; i < final_val; i += stride)
- {
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- if (diff) /* number of leftover pixels: 3 for pngtest */
- {
- final_val += diff*BPP8;
- for (; i < final_val; i += stride)
- {
- if (rep_bytes > (int)(final_val-i))
- rep_bytes = (int)(final_val-i);
- png_memcpy(dstptr, srcptr, rep_bytes);
- srcptr += stride;
- dstptr += stride;
- }
- }
-
- break;
- } /* end 64 bpp */
-
- default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */
- {
- /* this should never happen */
- png_warning(png_ptr, "Invalid row_info.pixel_depth in pngrutil");
- break;
- }
- } /* end switch (png_ptr->row_info.pixel_depth) */
-
- } /* end if (non-trivial mask) */
-
-} /* end png_combine_row() */
-#endif /* PNG_HAVE_MMX_COMBINE_ROW */
-
-
-
-/*===========================================================================*/
-/* */
-/* P N G _ D O _ R E A D _ I N T E R L A C E */
-/* */
-/*===========================================================================*/
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-#if !defined(PNG_HAVE_MMX_READ_INTERLACE)
-
-/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion
- * has taken place. [GRR: what other steps come before and/or after?]
- */
-
-void /* PRIVATE */
-png_do_read_interlace(png_structp png_ptr)
-{
-#if defined(PNG_USE_LOCAL_ARRAYS)
-static PNG_CONST int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-#endif
- png_row_infop row_info = &(png_ptr->row_info);
- png_bytep row = png_ptr->row_buf + 1;
- int pass = png_ptr->pass;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- png_uint_32 transformations = png_ptr->transformations;
-#endif
- png_debug(1,"in png_do_read_interlace (pngrutil.c OPTIMIZED)\n");
-
- if (row != NULL && row_info != NULL)
- {
- png_uint_32 final_width;
-
- final_width = row_info->width * png_pass_inc[pass];
-
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_byte v;
- png_uint_32 i;
- int j;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 3);
- dp = row + (png_size_t)((final_width - 1) >> 3);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)((row_info->width + 7) & 7);
- dshift = (int)((final_width + 7) & 7);
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
- else
-#endif
- {
- sshift = 7 - (int)((row_info->width + 7) & 7);
- dshift = 7 - (int)((final_width + 7) & 7);
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
-
- for (i = row_info->width; i; i--)
- {
- v = (png_byte)((*sp >> sshift) & 0x1);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- case 2:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 2);
- dp = row + (png_size_t)((final_width - 1) >> 2);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
- dshift = (png_size_t)(((final_width + 3) & 3) << 1);
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
- else
-#endif
- {
- sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
- dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
-
- for (i = row_info->width; i; i--)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0x3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- case 4:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 1);
- dp = row + (png_size_t)((final_width - 1) >> 1);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
- dshift = (png_size_t)(((final_width + 1) & 1) << 2);
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- else
-#endif
- {
- sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
- dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
-
- for (i = row_info->width; i; i--)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0xf);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- /*====================================================================*/
-
- default: /* 8-bit or larger (this is where the routine is modified) */
- {
- png_bytep sptr, dp;
- png_uint_32 i;
- png_size_t pixel_bytes;
- int width = (int)row_info->width;
-
- pixel_bytes = (row_info->pixel_depth >> 3);
-
- /* point sptr at the last pixel in the pre-expanded row: */
- sptr = row + (width - 1) * pixel_bytes;
-
- /* point dp at the last pixel position in the expanded row: */
- dp = row + (final_width - 1) * pixel_bytes;
-
- /* MMX not supported: use modified C code - takes advantage
- * of inlining of png_memcpy for a constant */
- /* GRR 19991007: does it? or should pixel_bytes in each
- * block be replaced with immediate value (e.g., 1)? */
- /* GRR 19991017: replaced with constants in each case */
- {
- if (pixel_bytes == 1)
- {
- for (i = width; i; i--)
- {
- int j;
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- --sptr;
- }
- }
- else if (pixel_bytes == 3)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, 3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, 3);
- dp -= 3;
- }
- sptr -= 3;
- }
- }
- else if (pixel_bytes == 2)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, 2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, 2);
- dp -= 2;
- }
- sptr -= 2;
- }
- }
- else if (pixel_bytes == 4)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, 4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
-#if defined(PNG_DEBUG) && defined(PNG_1_0_X)
- if (dp < row || dp+3 > row+png_ptr->row_buf_size)
- {
- printf("dp out of bounds: row=%d, dp=%d, rp=%d\n",
- row, dp, row+png_ptr->row_buf_size);
- printf("row_buf=%d\n",png_ptr->row_buf_size);
- }
-#endif
- png_memcpy(dp, v, 4);
- dp -= 4;
- }
- sptr -= 4;
- }
- }
- else if (pixel_bytes == 6)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, 6);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, 6);
- dp -= 6;
- }
- sptr -= 6;
- }
- }
- else if (pixel_bytes == 8)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, 8);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, 8);
- dp -= 8;
- }
- sptr -= 8;
- }
- }
- else /* GRR: should never be reached */
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr -= pixel_bytes;
- }
- }
-
- }
- break;
- }
- } /* end switch (row_info->pixel_depth) */
-
- row_info->width = final_width;
-
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
- }
-
-} /* end png_do_read_interlace() */
-
-#endif /* PNG_HAVE_MMX_READ_INTERLACE */
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-
-
-#if !defined(PNG_HAVE_MMX_READ_FILTER_ROW)
-/*===========================================================================*/
-/* */
-/* P N G _ R E A D _ F I L T E R _ R O W */
-/* */
-/*===========================================================================*/
-
-
-/* Optimized png_read_filter_row routines */
-
-void /* PRIVATE */
-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
- row, png_bytep prev_row, int filter)
-{
-#if defined(PNG_DEBUG)
- char filnm[10];
-#endif
-
-
-#if defined(PNG_DEBUG)
- png_debug(1, "in png_read_filter_row (pngrutil.c OPTIMIZED)\n");
- switch (filter)
- {
- case 0:
- png_snprintf(filnm, 10, "none");
- break;
-
- case 1:
- png_snprintf(filnm, 10, "sub-%s",
- "x86");
- break;
-
- case 2:
- png_snprintf(filnm, 10, "up-%s",
- "x86");
- break;
-
- case 3:
- png_snprintf(filnm, 10, "avg-%s",
- "x86");
- break;
-
- case 4:
- png_snprintf(filnm, 10, "Paeth-%s",
- "x86");
- break;
-
- default:
- png_snprintf(filnm, 10, "unknown");
- break;
- }
- png_debug2(0, "row_number=%5ld, %10s, ", png_ptr->row_number, filnm);
- png_debug1(0, "row=0x%08lx, ", (unsigned long)row);
- png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth,
- (int)((row_info->pixel_depth + 7) >> 3));
- png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes);
-#endif /* PNG_DEBUG */
-
- switch (filter)
- {
- case PNG_FILTER_VALUE_NONE:
- break;
-
- case PNG_FILTER_VALUE_SUB:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_bytep rp = row + bpp;
- png_bytep lp = row;
-
- for (i = bpp; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
- rp++;
- }
- }
- break;
-
- case PNG_FILTER_VALUE_UP:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_bytep rp = row;
- png_bytep pp = prev_row;
-
- for (i = 0; i < istop; ++i)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
- }
- break;
-
- case PNG_FILTER_VALUE_AVG:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++) >> 1)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++ + *lp++) >> 1)) & 0xff);
- rp++;
- }
- }
- break;
-
- case PNG_FILTER_VALUE_PAETH:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_bytep cp = prev_row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++) /* use leftover rp,pp */
- {
- int a, b, c, pa, pb, pc, p;
-
- a = *lp++;
- b = *pp++;
- c = *cp++;
-
- p = b - c;
- pc = a - c;
-
-#if defined(PNG_USE_ABS)
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- /*
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- */
-
- p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
-
- *rp = (png_byte)(((int)(*rp) + p) & 0xff);
- rp++;
- }
- }
- break;
-
- default:
- png_warning(png_ptr, "Ignoring bad row-filter type");
- *row=0;
- break;
- }
-}
-
-#endif /* PNG_HAVE_MMX_READ_FILTER_ROW */
-#endif /* PNG_OPTIMIZED_CODE_SUPPORTED */
-
-#if !defined(PNG_USE_PNGGCCRD) && !defined(PNG_USE_PNGVCRD)
-#if !defined(PNG_OPTIMIZED_CODE_SUPPORTED)
-/* Use the unoptimized original C code. This might be removed from a future
- * version of libpng if testing proves it to be worthless. */
-void /* PRIVATE */
-png_combine_row(png_structp png_ptr, png_bytep row, int mask)
-{
- png_debug(1,"in png_combine_row NOT OPTIMIZED\n");
- if (mask == 0xff)
- {
- png_memcpy(row, png_ptr->row_buf + 1,
- PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
- }
- else
- {
- switch (png_ptr->row_info.pixel_depth)
- {
- case 1:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_inc, s_start, s_end;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
- else
-#endif
- {
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
-
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- int value;
-
- value = (*sp >> shift) & 0x01;
- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- case 2:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_start, s_end, s_inc;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- int value;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
- else
-#endif
- {
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
-
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0x03;
- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- int s_start, s_end, s_inc;
- int m = 0x80;
- int shift;
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- int value;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
- else
-#endif
- {
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- shift = s_start;
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0xf;
- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- default:
- {
- png_bytep sp = png_ptr->row_buf + 1;
- png_bytep dp = row;
- png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- png_uint_32 i;
- png_uint_32 row_width = png_ptr->width;
- png_byte m = 0x80;
-
-
- for (i = 0; i < row_width; i++)
- {
- if (m & mask)
- {
- png_memcpy(dp, sp, pixel_bytes);
- }
-
- sp += pixel_bytes;
- dp += pixel_bytes;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
- }
- }
-}
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-/* OLD pre-1.0.9 interface:
-void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
- png_uint_32 transformations)
- */
-void /* PRIVATE */
-png_do_read_interlace(png_structp png_ptr)
-{
- png_row_infop row_info = &(png_ptr->row_info);
- png_bytep row = png_ptr->row_buf + 1;
- int pass = png_ptr->pass;
- png_uint_32 transformations = png_ptr->transformations;
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
- /* offset to next interlace block */
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-#endif
-
- png_debug(1,"in png_do_read_interlace (pngrutil.c NOT OPTIMIZED)\n");
- if (row != NULL && row_info != NULL)
- {
- png_uint_32 final_width;
-
- final_width = row_info->width * png_pass_inc[pass];
-
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
- png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- int jstop = png_pass_inc[pass];
- png_byte v;
- png_uint_32 i;
- int j;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)((row_info->width + 7) & 0x07);
- dshift = (int)((final_width + 7) & 0x07);
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
- else
-#endif
- {
- sshift = 7 - (int)((row_info->width + 7) & 0x07);
- dshift = 7 - (int)((final_width + 7) & 0x07);
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- v = (png_byte)((*sp >> sshift) & 0x01);
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- case 2:
- {
- png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
- png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- int jstop = png_pass_inc[pass];
- png_uint_32 i;
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)(((row_info->width + 3) & 0x03) << 1);
- dshift = (int)(((final_width + 3) & 0x03) << 1);
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
- else
-#endif
- {
- sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
- dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0x03);
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- case 4:
- {
- png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
- png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
- int jstop = png_pass_inc[pass];
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)(((row_info->width + 1) & 0x01) << 2);
- dshift = (int)(((final_width + 1) & 0x01) << 2);
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- else
-#endif
- {
- sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
- dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v = (png_byte)((*sp >> sshift) & 0xf);
- int j;
-
- for (j = 0; j < jstop; j++)
- {
- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
- default:
- {
- png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
- png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
- png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
-
- int jstop = png_pass_inc[pass];
- png_uint_32 i;
-
- for (i = 0; i < row_info->width; i++)
- {
- png_byte v[8];
- int j;
-
- png_memcpy(v, sp, pixel_bytes);
- for (j = 0; j < jstop; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sp -= pixel_bytes;
- }
- break;
- }
- }
- row_info->width = final_width;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
- }
-#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
- transformations = transformations; /* silence compiler warning */
-#endif
-}
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-void /* PRIVATE */
-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
- png_bytep prev_row, int filter)
-{
- png_debug(1, "in png_read_filter_row (NOT OPTIMIZED)\n");
- png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
- switch (filter)
- {
- case PNG_FILTER_VALUE_NONE:
- break;
- case PNG_FILTER_VALUE_SUB:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_bytep rp = row + bpp;
- png_bytep lp = row;
-
- for (i = bpp; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_UP:
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_bytep rp = row;
- png_bytep pp = prev_row;
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_AVG:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++) / 2 )) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- (int)(*pp++ + *lp++) / 2 ) & 0xff);
- rp++;
- }
- break;
- }
- case PNG_FILTER_VALUE_PAETH:
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_bytep cp = prev_row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop=row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++) /* use leftover rp,pp */
- {
- int a, b, c, pa, pb, pc, p;
-
- a = *lp++;
- b = *pp++;
- c = *cp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- /*
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- */
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *rp = (png_byte)(((int)(*rp) + p) & 0xff);
- rp++;
- }
- break;
- }
- default:
- png_warning(png_ptr, "Ignoring bad adaptive filter type");
- *row=0;
- break;
- }
-}
-#endif /* !PNG_OPTIMIZED_CODE_SUPPORTED */
-#endif /* !PNG_USE_PNGGCCRD && !PNG_USE_PNGVCRD */
-
-void /* PRIVATE */
-png_read_finish_row(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
- png_debug(1, "in png_read_finish_row\n");
- png_ptr->row_number++;
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0,
- png_ptr->rowbytes + 1);
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
- png_ptr->iwidth) + 1;
-
- if (!(png_ptr->transformations & PNG_INTERLACE))
- {
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
- if (!(png_ptr->num_rows))
- continue;
- }
- else /* if (png_ptr->transformations & PNG_INTERLACE) */
- break;
- } while (png_ptr->iwidth == 0);
-
- if (png_ptr->pass < 7)
- return;
- }
-
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
- {
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST PNG_IDAT;
-#endif
- char extra;
- int ret;
-
- png_ptr->zstream.next_out = (Byte *)&extra;
- png_ptr->zstream.avail_out = (uInt)1;
- for(;;)
- {
- if (!(png_ptr->zstream.avail_in))
- {
- while (!png_ptr->idat_size)
- {
- png_byte chunk_length[4];
-
- png_crc_finish(png_ptr, 0);
-
- png_read_data(png_ptr, chunk_length, 4);
- png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
- png_error(png_ptr, "Not enough image data");
-
- }
- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_in = png_ptr->zbuf;
- if (png_ptr->zbuf_size > png_ptr->idat_size)
- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
- png_ptr->idat_size -= png_ptr->zstream.avail_in;
- }
- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
- if (ret == Z_STREAM_END)
- {
- if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
- png_ptr->idat_size)
- png_warning(png_ptr, "Extra compressed data");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
- if (ret != Z_OK)
- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
- "Decompression Error");
-
- if (!(png_ptr->zstream.avail_out))
- {
- png_warning(png_ptr, "Extra compressed data.");
- png_ptr->mode |= PNG_AFTER_IDAT;
- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
- break;
- }
-
- }
- png_ptr->zstream.avail_out = 0;
- }
-
- if (png_ptr->idat_size || png_ptr->zstream.avail_in)
- png_warning(png_ptr, "Extra compression data");
-
- inflateReset(&png_ptr->zstream);
-
- png_ptr->mode |= PNG_AFTER_IDAT;
-}
-
-void /* PRIVATE */
-png_read_start_row(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
- int max_pixel_depth;
- png_uint_32 row_bytes;
-
- png_debug(1, "in png_read_start_row\n");
- png_ptr->zstream.avail_in = 0;
- png_init_read_transformations(png_ptr);
- if (png_ptr->interlaced)
- {
- if (!(png_ptr->transformations & PNG_INTERLACE))
- png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
- png_pass_ystart[0]) / png_pass_yinc[0];
- else
- png_ptr->num_rows = png_ptr->height;
-
- png_ptr->iwidth = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
-
- row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
-
- png_ptr->irowbytes = (png_size_t)row_bytes;
- if((png_uint_32)png_ptr->irowbytes != row_bytes)
- png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
- }
- else
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->iwidth = png_ptr->width;
- png_ptr->irowbytes = png_ptr->rowbytes + 1;
- }
- max_pixel_depth = png_ptr->pixel_depth;
-
-#if defined(PNG_READ_PACK_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
- max_pixel_depth = 8;
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- if (png_ptr->transformations & PNG_EXPAND)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (png_ptr->num_trans)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 24;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (max_pixel_depth < 8)
- max_pixel_depth = 8;
- if (png_ptr->num_trans)
- max_pixel_depth *= 2;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (png_ptr->num_trans)
- {
- max_pixel_depth *= 4;
- max_pixel_depth /= 3;
- }
- }
- }
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & (PNG_FILLER))
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- max_pixel_depth = 32;
- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
- {
- if (max_pixel_depth <= 8)
- max_pixel_depth = 16;
- else
- max_pixel_depth = 32;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- if (max_pixel_depth <= 32)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 64;
- }
- }
-#endif
-
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
- if (png_ptr->transformations & PNG_GRAY_TO_RGB)
- {
- if (
-#if defined(PNG_READ_EXPAND_SUPPORTED)
- (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
-#endif
-#if defined(PNG_READ_FILLER_SUPPORTED)
- (png_ptr->transformations & (PNG_FILLER)) ||
-#endif
- png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- if (max_pixel_depth <= 16)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 64;
- }
- else
- {
- if (max_pixel_depth <= 8)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- max_pixel_depth = 32;
- else
- max_pixel_depth = 24;
- }
- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- max_pixel_depth = 64;
- else
- max_pixel_depth = 48;
- }
- }
-#endif
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
-defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if(png_ptr->transformations & PNG_USER_TRANSFORM)
- {
- int user_pixel_depth=png_ptr->user_transform_depth*
- png_ptr->user_transform_channels;
- if(user_pixel_depth > max_pixel_depth)
- max_pixel_depth=user_pixel_depth;
- }
-#endif
-
- /* align the width on the next larger 8 pixels. Mainly used
- for interlacing */
- row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
- /* calculate the maximum bytes needed, adding a byte and a pixel
- for safety's sake */
- row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
- 1 + ((max_pixel_depth + 7) >> 3);
-#ifdef PNG_MAX_MALLOC_64K
- if (row_bytes > (png_uint_32)65536L)
- png_error(png_ptr, "This image requires a row greater than 64KB");
-#endif
- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
- png_ptr->row_buf = png_ptr->big_row_buf+32;
-#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) && defined(PNG_1_0_X)
- png_ptr->row_buf_size = row_bytes;
-#endif
-
-#ifdef PNG_MAX_MALLOC_64K
- if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
- png_error(png_ptr, "This image requires a row greater than 64KB");
-#endif
- if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
- png_error(png_ptr, "Row has too many bytes to allocate in memory.");
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
- png_ptr->rowbytes + 1));
-
- png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
-
- png_debug1(3, "width = %lu,\n", png_ptr->width);
- png_debug1(3, "height = %lu,\n", png_ptr->height);
- png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
- png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
- png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
- png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
-
- png_ptr->flags |= PNG_FLAG_ROW_INIT;
-}
-#endif /* PNG_READ_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngset.c b/distrib/libpng-1.2.19/pngset.c
deleted file mode 100644
index 8d1cbfc..0000000
--- a/distrib/libpng-1.2.19/pngset.c
+++ /dev/null
@@ -1,1284 +0,0 @@
-
-/* pngset.c - storage of image information into info struct
- *
- * Last changed in libpng 1.2.17 May 15, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * The functions here are used during reads to store data from the file
- * into the info struct, and during writes to store application data
- * into the info struct for writing into the file. This abstracts the
- * info struct and allows us to change the structure in the future.
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-#if defined(PNG_bKGD_SUPPORTED)
-void PNGAPI
-png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
-{
- png_debug1(1, "in %s storage function\n", "bKGD");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
- info_ptr->valid |= PNG_INFO_bKGD;
-}
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
- double white_x, double white_y, double red_x, double red_y,
- double green_x, double green_y, double blue_x, double blue_y)
-{
- png_debug1(1, "in %s storage function\n", "cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (white_x < 0.0 || white_y < 0.0 ||
- red_x < 0.0 || red_y < 0.0 ||
- green_x < 0.0 || green_y < 0.0 ||
- blue_x < 0.0 || blue_y < 0.0)
- {
- png_warning(png_ptr,
- "Ignoring attempt to set negative chromaticity value");
- return;
- }
- if (white_x > 21474.83 || white_y > 21474.83 ||
- red_x > 21474.83 || red_y > 21474.83 ||
- green_x > 21474.83 || green_y > 21474.83 ||
- blue_x > 21474.83 || blue_y > 21474.83)
- {
- png_warning(png_ptr,
- "Ignoring attempt to set chromaticity value exceeding 21474.83");
- return;
- }
-
- info_ptr->x_white = (float)white_x;
- info_ptr->y_white = (float)white_y;
- info_ptr->x_red = (float)red_x;
- info_ptr->y_red = (float)red_y;
- info_ptr->x_green = (float)green_x;
- info_ptr->y_green = (float)green_y;
- info_ptr->x_blue = (float)blue_x;
- info_ptr->y_blue = (float)blue_y;
-#ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
- info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
- info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5);
- info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5);
- info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
- info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
- info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5);
- info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5);
-#endif
- info_ptr->valid |= PNG_INFO_cHRM;
-}
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-void PNGAPI
-png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
- png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
- png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
- png_fixed_point blue_x, png_fixed_point blue_y)
-{
- png_debug1(1, "in %s storage function\n", "cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (white_x < 0 || white_y < 0 ||
- red_x < 0 || red_y < 0 ||
- green_x < 0 || green_y < 0 ||
- blue_x < 0 || blue_y < 0)
- {
- png_warning(png_ptr,
- "Ignoring attempt to set negative chromaticity value");
- return;
- }
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- if (white_x > (double) PNG_UINT_31_MAX ||
- white_y > (double) PNG_UINT_31_MAX ||
- red_x > (double) PNG_UINT_31_MAX ||
- red_y > (double) PNG_UINT_31_MAX ||
- green_x > (double) PNG_UINT_31_MAX ||
- green_y > (double) PNG_UINT_31_MAX ||
- blue_x > (double) PNG_UINT_31_MAX ||
- blue_y > (double) PNG_UINT_31_MAX)
-#else
- if (white_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- white_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- red_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- red_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- green_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- green_y > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- blue_x > (png_fixed_point) PNG_UINT_31_MAX/100000L ||
- blue_y > (png_fixed_point) PNG_UINT_31_MAX/100000L)
-#endif
- {
- png_warning(png_ptr,
- "Ignoring attempt to set chromaticity value exceeding 21474.83");
- return;
- }
- info_ptr->int_x_white = white_x;
- info_ptr->int_y_white = white_y;
- info_ptr->int_x_red = red_x;
- info_ptr->int_y_red = red_y;
- info_ptr->int_x_green = green_x;
- info_ptr->int_y_green = green_y;
- info_ptr->int_x_blue = blue_x;
- info_ptr->int_y_blue = blue_y;
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- info_ptr->x_white = (float)(white_x/100000.);
- info_ptr->y_white = (float)(white_y/100000.);
- info_ptr->x_red = (float)( red_x/100000.);
- info_ptr->y_red = (float)( red_y/100000.);
- info_ptr->x_green = (float)(green_x/100000.);
- info_ptr->y_green = (float)(green_y/100000.);
- info_ptr->x_blue = (float)( blue_x/100000.);
- info_ptr->y_blue = (float)( blue_y/100000.);
-#endif
- info_ptr->valid |= PNG_INFO_cHRM;
-}
-#endif
-#endif
-
-#if defined(PNG_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
-{
- double gamma;
- png_debug1(1, "in %s storage function\n", "gAMA");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- /* Check for overflow */
- if (file_gamma > 21474.83)
- {
- png_warning(png_ptr, "Limiting gamma to 21474.83");
- gamma=21474.83;
- }
- else
- gamma=file_gamma;
- info_ptr->gamma = (float)gamma;
-#ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_gamma = (int)(gamma*100000.+.5);
-#endif
- info_ptr->valid |= PNG_INFO_gAMA;
- if(gamma == 0.0)
- png_warning(png_ptr, "Setting gamma=0");
-}
-#endif
-void PNGAPI
-png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
- int_gamma)
-{
- png_fixed_point gamma;
-
- png_debug1(1, "in %s storage function\n", "gAMA");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (int_gamma > (png_fixed_point) PNG_UINT_31_MAX)
- {
- png_warning(png_ptr, "Limiting gamma to 21474.83");
- gamma=PNG_UINT_31_MAX;
- }
- else
- {
- if (int_gamma < 0)
- {
- png_warning(png_ptr, "Setting negative gamma to zero");
- gamma=0;
- }
- else
- gamma=int_gamma;
- }
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- info_ptr->gamma = (float)(gamma/100000.);
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- info_ptr->int_gamma = gamma;
-#endif
- info_ptr->valid |= PNG_INFO_gAMA;
- if(gamma == 0)
- png_warning(png_ptr, "Setting gamma=0");
-}
-#endif
-
-#if defined(PNG_hIST_SUPPORTED)
-void PNGAPI
-png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
-{
- int i;
-
- png_debug1(1, "in %s storage function\n", "hIST");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- if (info_ptr->num_palette <= 0 || info_ptr->num_palette
- > PNG_MAX_PALETTE_LENGTH)
- {
- png_warning(png_ptr,
- "Invalid palette size, hIST allocation skipped.");
- return;
- }
-
-#ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
-#endif
- /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in version
- 1.2.1 */
- png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
- (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof (png_uint_16)));
- if (png_ptr->hist == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
- return;
- }
-
- for (i = 0; i < info_ptr->num_palette; i++)
- png_ptr->hist[i] = hist[i];
- info_ptr->hist = png_ptr->hist;
- info_ptr->valid |= PNG_INFO_hIST;
-
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_HIST;
-#else
- png_ptr->flags |= PNG_FLAG_FREE_HIST;
-#endif
-}
-#endif
-
-void PNGAPI
-png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_type, int compression_type,
- int filter_type)
-{
- png_debug1(1, "in %s storage function\n", "IHDR");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- /* check for width and height valid values */
- if (width == 0 || height == 0)
- png_error(png_ptr, "Image width or height is zero in IHDR");
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- if (width > png_ptr->user_width_max || height > png_ptr->user_height_max)
- png_error(png_ptr, "image size exceeds user limits in IHDR");
-#else
- if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
- png_error(png_ptr, "image size exceeds user limits in IHDR");
-#endif
- if (width > PNG_UINT_31_MAX || height > PNG_UINT_31_MAX)
- png_error(png_ptr, "Invalid image size in IHDR");
- if ( width > (PNG_UINT_32_MAX
- >> 3) /* 8-byte RGBA pixels */
- - 64 /* bigrowbuf hack */
- - 1 /* filter byte */
- - 7*8 /* rounding of width to multiple of 8 pixels */
- - 8) /* extra max_pixel_depth pad */
- png_warning(png_ptr, "Width is too large for libpng to process pixels");
-
- /* check other values */
- if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
- bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth in IHDR");
-
- if (color_type < 0 || color_type == 1 ||
- color_type == 5 || color_type > 6)
- png_error(png_ptr, "Invalid color type in IHDR");
-
- if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
- ((color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
- png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
-
- if (interlace_type >= PNG_INTERLACE_LAST)
- png_error(png_ptr, "Unknown interlace method in IHDR");
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- png_error(png_ptr, "Unknown compression method in IHDR");
-
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- /* Accept filter_method 64 (intrapixel differencing) only if
- * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
- * 2. Libpng did not read a PNG signature (this filter_method is only
- * used in PNG datastreams that are embedded in MNG datastreams) and
- * 3. The application called png_permit_mng_features with a mask that
- * included PNG_FLAG_MNG_FILTER_64 and
- * 4. The filter_method is 64 and
- * 5. The color_type is RGB or RGBA
- */
- if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
- png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
- if(filter_type != PNG_FILTER_TYPE_BASE)
- {
- if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
- ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
- (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
- png_error(png_ptr, "Unknown filter method in IHDR");
- if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
- png_warning(png_ptr, "Invalid filter method in IHDR");
- }
-#else
- if(filter_type != PNG_FILTER_TYPE_BASE)
- png_error(png_ptr, "Unknown filter method in IHDR");
-#endif
-
- info_ptr->width = width;
- info_ptr->height = height;
- info_ptr->bit_depth = (png_byte)bit_depth;
- info_ptr->color_type =(png_byte) color_type;
- info_ptr->compression_type = (png_byte)compression_type;
- info_ptr->filter_type = (png_byte)filter_type;
- info_ptr->interlace_type = (png_byte)interlace_type;
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- info_ptr->channels = 1;
- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
- info_ptr->channels = 3;
- else
- info_ptr->channels = 1;
- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
- info_ptr->channels++;
- info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
-
- /* check for potential overflow */
- if (width > (PNG_UINT_32_MAX
- >> 3) /* 8-byte RGBA pixels */
- - 64 /* bigrowbuf hack */
- - 1 /* filter byte */
- - 7*8 /* rounding of width to multiple of 8 pixels */
- - 8) /* extra max_pixel_depth pad */
- info_ptr->rowbytes = (png_size_t)0;
- else
- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width);
-}
-
-#if defined(PNG_oFFs_SUPPORTED)
-void PNGAPI
-png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
- png_int_32 offset_x, png_int_32 offset_y, int unit_type)
-{
- png_debug1(1, "in %s storage function\n", "oFFs");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_offset = offset_x;
- info_ptr->y_offset = offset_y;
- info_ptr->offset_unit_type = (png_byte)unit_type;
- info_ptr->valid |= PNG_INFO_oFFs;
-}
-#endif
-
-#if defined(PNG_pCAL_SUPPORTED)
-void PNGAPI
-png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
- png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
- png_charp units, png_charpp params)
-{
- png_uint_32 length;
- int i;
-
- png_debug1(1, "in %s storage function\n", "pCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- length = png_strlen(purpose) + 1;
- png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
- info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->pcal_purpose == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
- return;
- }
- png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
-
- png_debug(3, "storing X0, X1, type, and nparams in info\n");
- info_ptr->pcal_X0 = X0;
- info_ptr->pcal_X1 = X1;
- info_ptr->pcal_type = (png_byte)type;
- info_ptr->pcal_nparams = (png_byte)nparams;
-
- length = png_strlen(units) + 1;
- png_debug1(3, "allocating units for info (%lu bytes)\n", length);
- info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->pcal_units == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL units.");
- return;
- }
- png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
-
- info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
- (png_uint_32)((nparams + 1) * png_sizeof(png_charp)));
- if (info_ptr->pcal_params == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL params.");
- return;
- }
-
- info_ptr->pcal_params[nparams] = NULL;
-
- for (i = 0; i < nparams; i++)
- {
- length = png_strlen(params[i]) + 1;
- png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
- info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->pcal_params[i] == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
- return;
- }
- png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
- }
-
- info_ptr->valid |= PNG_INFO_pCAL;
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_PCAL;
-#endif
-}
-#endif
-
-#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
- int unit, double width, double height)
-{
- png_debug1(1, "in %s storage function\n", "sCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->scal_unit = (png_byte)unit;
- info_ptr->scal_pixel_width = width;
- info_ptr->scal_pixel_height = height;
-
- info_ptr->valid |= PNG_INFO_sCAL;
-}
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
-void PNGAPI
-png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
- int unit, png_charp swidth, png_charp sheight)
-{
- png_uint_32 length;
-
- png_debug1(1, "in %s storage function\n", "sCAL");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->scal_unit = (png_byte)unit;
-
- length = png_strlen(swidth) + 1;
- png_debug1(3, "allocating unit for info (%d bytes)\n", length);
- info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->scal_s_width == NULL)
- {
- png_warning(png_ptr,
- "Memory allocation failed while processing sCAL.");
- }
- png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
-
- length = png_strlen(sheight) + 1;
- png_debug1(3, "allocating unit for info (%d bytes)\n", length);
- info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
- if (info_ptr->scal_s_height == NULL)
- {
- png_free (png_ptr, info_ptr->scal_s_width);
- png_warning(png_ptr,
- "Memory allocation failed while processing sCAL.");
- }
- png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
-
- info_ptr->valid |= PNG_INFO_sCAL;
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_SCAL;
-#endif
-}
-#endif
-#endif
-#endif
-
-#if defined(PNG_pHYs_SUPPORTED)
-void PNGAPI
-png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
- png_uint_32 res_x, png_uint_32 res_y, int unit_type)
-{
- png_debug1(1, "in %s storage function\n", "pHYs");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->x_pixels_per_unit = res_x;
- info_ptr->y_pixels_per_unit = res_y;
- info_ptr->phys_unit_type = (png_byte)unit_type;
- info_ptr->valid |= PNG_INFO_pHYs;
-}
-#endif
-
-void PNGAPI
-png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
- png_colorp palette, int num_palette)
-{
-
- png_debug1(1, "in %s storage function\n", "PLTE");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
- {
- if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- png_error(png_ptr, "Invalid palette length");
- else
- {
- png_warning(png_ptr, "Invalid palette length");
- return;
- }
- }
-
- /*
- * It may not actually be necessary to set png_ptr->palette here;
- * we do it for backward compatibility with the way the png_handle_tRNS
- * function used to do the allocation.
- */
-#ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
-#endif
-
- /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
- of num_palette entries,
- in case of an invalid PNG file that has too-large sample values. */
- png_ptr->palette = (png_colorp)png_malloc(png_ptr,
- PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
- png_memset(png_ptr->palette, 0, PNG_MAX_PALETTE_LENGTH *
- png_sizeof(png_color));
- png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color));
- info_ptr->palette = png_ptr->palette;
- info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
-
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_PLTE;
-#else
- png_ptr->flags |= PNG_FLAG_FREE_PLTE;
-#endif
-
- info_ptr->valid |= PNG_INFO_PLTE;
-}
-
-#if defined(PNG_sBIT_SUPPORTED)
-void PNGAPI
-png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
- png_color_8p sig_bit)
-{
- png_debug1(1, "in %s storage function\n", "sBIT");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8));
- info_ptr->valid |= PNG_INFO_sBIT;
-}
-#endif
-
-#if defined(PNG_sRGB_SUPPORTED)
-void PNGAPI
-png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
-{
- png_debug1(1, "in %s storage function\n", "sRGB");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->srgb_intent = (png_byte)intent;
- info_ptr->valid |= PNG_INFO_sRGB;
-}
-
-void PNGAPI
-png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
- int intent)
-{
-#if defined(PNG_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- float file_gamma;
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_fixed_point int_file_gamma;
-#endif
-#endif
-#if defined(PNG_cHRM_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
- int_green_y, int_blue_x, int_blue_y;
-#endif
-#endif
- png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_set_sRGB(png_ptr, info_ptr, intent);
-
-#if defined(PNG_gAMA_SUPPORTED)
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- file_gamma = (float).45455;
- png_set_gAMA(png_ptr, info_ptr, file_gamma);
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
- int_file_gamma = 45455L;
- png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
-#endif
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED)
-#ifdef PNG_FIXED_POINT_SUPPORTED
- int_white_x = 31270L;
- int_white_y = 32900L;
- int_red_x = 64000L;
- int_red_y = 33000L;
- int_green_x = 30000L;
- int_green_y = 60000L;
- int_blue_x = 15000L;
- int_blue_y = 6000L;
-
- png_set_cHRM_fixed(png_ptr, info_ptr,
- int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
- int_blue_x, int_blue_y);
-#endif
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- white_x = (float).3127;
- white_y = (float).3290;
- red_x = (float).64;
- red_y = (float).33;
- green_x = (float).30;
- green_y = (float).60;
- blue_x = (float).15;
- blue_y = (float).06;
-
- png_set_cHRM(png_ptr, info_ptr,
- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
-#endif
-#endif
-}
-#endif
-
-
-#if defined(PNG_iCCP_SUPPORTED)
-void PNGAPI
-png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
- png_charp name, int compression_type,
- png_charp profile, png_uint_32 proflen)
-{
- png_charp new_iccp_name;
- png_charp new_iccp_profile;
-
- png_debug1(1, "in %s storage function\n", "iCCP");
- if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
- return;
-
- new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1);
- if (new_iccp_name == NULL)
- {
- png_warning(png_ptr, "Insufficient memory to process iCCP chunk.");
- return;
- }
- png_strncpy(new_iccp_name, name, png_sizeof(new_iccp_name));
- new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
- if (new_iccp_profile == NULL)
- {
- png_free (png_ptr, new_iccp_name);
- png_warning(png_ptr, "Insufficient memory to process iCCP profile.");
- return;
- }
- png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
-
- png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
-
- info_ptr->iccp_proflen = proflen;
- info_ptr->iccp_name = new_iccp_name;
- info_ptr->iccp_profile = new_iccp_profile;
- /* Compression is always zero but is here so the API and info structure
- * does not have to change if we introduce multiple compression types */
- info_ptr->iccp_compression = (png_byte)compression_type;
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_ICCP;
-#endif
- info_ptr->valid |= PNG_INFO_iCCP;
-}
-#endif
-
-#if defined(PNG_TEXT_SUPPORTED)
-void PNGAPI
-png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
- int num_text)
-{
- int ret;
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
- if (ret)
- png_error(png_ptr, "Insufficient memory to store text");
-}
-
-int /* PRIVATE */
-png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
- int num_text)
-{
- int i;
-
- png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
- "text" : (png_const_charp)png_ptr->chunk_name));
-
- if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
- return(0);
-
- /* Make sure we have enough space in the "text" array in info_struct
- * to hold all of the incoming text_ptr objects.
- */
- if (info_ptr->num_text + num_text > info_ptr->max_text)
- {
- if (info_ptr->text != NULL)
- {
- png_textp old_text;
- int old_max;
-
- old_max = info_ptr->max_text;
- info_ptr->max_text = info_ptr->num_text + num_text + 8;
- old_text = info_ptr->text;
- info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
- if (info_ptr->text == NULL)
- {
- png_free(png_ptr, old_text);
- return(1);
- }
- png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
- png_sizeof(png_text)));
- png_free(png_ptr, old_text);
- }
- else
- {
- info_ptr->max_text = num_text + 8;
- info_ptr->num_text = 0;
- info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)(info_ptr->max_text * png_sizeof (png_text)));
- if (info_ptr->text == NULL)
- return(1);
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_TEXT;
-#endif
- }
- png_debug1(3, "allocated %d entries for info_ptr->text\n",
- info_ptr->max_text);
- }
- for (i = 0; i < num_text; i++)
- {
- png_size_t text_length,key_len;
- png_size_t lang_len,lang_key_len;
- png_textp textp = &(info_ptr->text[info_ptr->num_text]);
-
- if (text_ptr[i].key == NULL)
- continue;
-
- key_len = png_strlen(text_ptr[i].key);
-
- if(text_ptr[i].compression <= 0)
- {
- lang_len = 0;
- lang_key_len = 0;
- }
- else
-#ifdef PNG_iTXt_SUPPORTED
- {
- /* set iTXt data */
- if (text_ptr[i].lang != NULL)
- lang_len = png_strlen(text_ptr[i].lang);
- else
- lang_len = 0;
- if (text_ptr[i].lang_key != NULL)
- lang_key_len = png_strlen(text_ptr[i].lang_key);
- else
- lang_key_len = 0;
- }
-#else
- {
- png_warning(png_ptr, "iTXt chunk not supported.");
- continue;
- }
-#endif
-
- if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
- {
- text_length = 0;
-#ifdef PNG_iTXt_SUPPORTED
- if(text_ptr[i].compression > 0)
- textp->compression = PNG_ITXT_COMPRESSION_NONE;
- else
-#endif
- textp->compression = PNG_TEXT_COMPRESSION_NONE;
- }
- else
- {
- text_length = png_strlen(text_ptr[i].text);
- textp->compression = text_ptr[i].compression;
- }
-
- textp->key = (png_charp)png_malloc_warn(png_ptr,
- (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
- if (textp->key == NULL)
- return(1);
- png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
- (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
- (int)textp->key);
-
- png_memcpy(textp->key, text_ptr[i].key,
- (png_size_t)(key_len));
- *(textp->key+key_len) = '\0';
-#ifdef PNG_iTXt_SUPPORTED
- if (text_ptr[i].compression > 0)
- {
- textp->lang=textp->key + key_len + 1;
- png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
- *(textp->lang+lang_len) = '\0';
- textp->lang_key=textp->lang + lang_len + 1;
- png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
- *(textp->lang_key+lang_key_len) = '\0';
- textp->text=textp->lang_key + lang_key_len + 1;
- }
- else
-#endif
- {
-#ifdef PNG_iTXt_SUPPORTED
- textp->lang=NULL;
- textp->lang_key=NULL;
-#endif
- textp->text=textp->key + key_len + 1;
- }
- if(text_length)
- png_memcpy(textp->text, text_ptr[i].text,
- (png_size_t)(text_length));
- *(textp->text+text_length) = '\0';
-
-#ifdef PNG_iTXt_SUPPORTED
- if(textp->compression > 0)
- {
- textp->text_length = 0;
- textp->itxt_length = text_length;
- }
- else
-#endif
- {
- textp->text_length = text_length;
-#ifdef PNG_iTXt_SUPPORTED
- textp->itxt_length = 0;
-#endif
- }
- info_ptr->num_text++;
- png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
- }
- return(0);
-}
-#endif
-
-#if defined(PNG_tIME_SUPPORTED)
-void PNGAPI
-png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
-{
- png_debug1(1, "in %s storage function\n", "tIME");
- if (png_ptr == NULL || info_ptr == NULL ||
- (png_ptr->mode & PNG_WROTE_tIME))
- return;
-
- png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time));
- info_ptr->valid |= PNG_INFO_tIME;
-}
-#endif
-
-#if defined(PNG_tRNS_SUPPORTED)
-void PNGAPI
-png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
- png_bytep trans, int num_trans, png_color_16p trans_values)
-{
- png_debug1(1, "in %s storage function\n", "tRNS");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if (trans != NULL)
- {
- /*
- * It may not actually be necessary to set png_ptr->trans here;
- * we do it for backward compatibility with the way the png_handle_tRNS
- * function used to do the allocation.
- */
-#ifdef PNG_FREE_ME_SUPPORTED
- png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
-#endif
- /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
- png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)PNG_MAX_PALETTE_LENGTH);
- if (num_trans <= PNG_MAX_PALETTE_LENGTH)
- png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_TRNS;
-#else
- png_ptr->flags |= PNG_FLAG_FREE_TRNS;
-#endif
- }
-
- if (trans_values != NULL)
- {
- png_memcpy(&(info_ptr->trans_values), trans_values,
- png_sizeof(png_color_16));
- if (num_trans == 0)
- num_trans = 1;
- }
- info_ptr->num_trans = (png_uint_16)num_trans;
- info_ptr->valid |= PNG_INFO_tRNS;
-}
-#endif
-
-#if defined(PNG_sPLT_SUPPORTED)
-void PNGAPI
-png_set_sPLT(png_structp png_ptr,
- png_infop info_ptr, png_sPLT_tp entries, int nentries)
-{
- png_sPLT_tp np;
- int i;
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- np = (png_sPLT_tp)png_malloc_warn(png_ptr,
- (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t));
- if (np == NULL)
- {
- png_warning(png_ptr, "No memory for sPLT palettes.");
- return;
- }
-
- png_memcpy(np, info_ptr->splt_palettes,
- info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
- png_free(png_ptr, info_ptr->splt_palettes);
- info_ptr->splt_palettes=NULL;
-
- for (i = 0; i < nentries; i++)
- {
- png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
- png_sPLT_tp from = entries + i;
-
- to->name = (png_charp)png_malloc_warn(png_ptr,
- png_strlen(from->name) + 1);
- if (to->name == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing sPLT chunk");
- }
- /* TODO: use png_malloc_warn */
- png_strncpy(to->name, from->name, png_strlen(from->name));
- to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
- from->nentries * png_sizeof(png_sPLT_entry));
- /* TODO: use png_malloc_warn */
- png_memcpy(to->entries, from->entries,
- from->nentries * png_sizeof(png_sPLT_entry));
- if (to->entries == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing sPLT chunk");
- png_free(png_ptr,to->name);
- to->name = NULL;
- }
- to->nentries = from->nentries;
- to->depth = from->depth;
- }
-
- info_ptr->splt_palettes = np;
- info_ptr->splt_palettes_num += nentries;
- info_ptr->valid |= PNG_INFO_sPLT;
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_SPLT;
-#endif
-}
-#endif /* PNG_sPLT_SUPPORTED */
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-void PNGAPI
-png_set_unknown_chunks(png_structp png_ptr,
- png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
-{
- png_unknown_chunkp np;
- int i;
-
- if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
- return;
-
- np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
- (info_ptr->unknown_chunks_num + num_unknowns) *
- png_sizeof(png_unknown_chunk));
- if (np == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing unknown chunk.");
- return;
- }
-
- png_memcpy(np, info_ptr->unknown_chunks,
- info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
- png_free(png_ptr, info_ptr->unknown_chunks);
- info_ptr->unknown_chunks=NULL;
-
- for (i = 0; i < num_unknowns; i++)
- {
- png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
- png_unknown_chunkp from = unknowns + i;
-
- png_strncpy((png_charp)to->name, (png_charp)from->name, 5);
- to->data = (png_bytep)png_malloc_warn(png_ptr, from->size);
- if (to->data == NULL)
- {
- png_warning(png_ptr,
- "Out of memory while processing unknown chunk.");
- }
- else
- {
- png_memcpy(to->data, from->data, from->size);
- to->size = from->size;
-
- /* note our location in the read or write sequence */
- to->location = (png_byte)(png_ptr->mode & 0xff);
- }
- }
-
- info_ptr->unknown_chunks = np;
- info_ptr->unknown_chunks_num += num_unknowns;
-#ifdef PNG_FREE_ME_SUPPORTED
- info_ptr->free_me |= PNG_FREE_UNKN;
-#endif
-}
-void PNGAPI
-png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
- int chunk, int location)
-{
- if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
- (int)info_ptr->unknown_chunks_num)
- info_ptr->unknown_chunks[chunk].location = (png_byte)location;
-}
-#endif
-
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
-void PNGAPI
-png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
-{
- /* This function is deprecated in favor of png_permit_mng_features()
- and will be removed from libpng-1.3.0 */
- png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
- if (png_ptr == NULL)
- return;
- png_ptr->mng_features_permitted = (png_byte)
- ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
- ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
-}
-#endif
-#endif
-
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
-png_uint_32 PNGAPI
-png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
-{
- png_debug(1, "in png_permit_mng_features\n");
- if (png_ptr == NULL)
- return (png_uint_32)0;
- png_ptr->mng_features_permitted =
- (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
- return (png_uint_32)png_ptr->mng_features_permitted;
-}
-#endif
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
-void PNGAPI
-png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
- chunk_list, int num_chunks)
-{
- png_bytep new_list, p;
- int i, old_num_chunks;
- if (png_ptr == NULL)
- return;
- if (num_chunks == 0)
- {
- if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
- png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
- else
- png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
-
- if(keep == PNG_HANDLE_CHUNK_ALWAYS)
- png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
- else
- png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
- return;
- }
- if (chunk_list == NULL)
- return;
- old_num_chunks=png_ptr->num_chunk_list;
- new_list=(png_bytep)png_malloc(png_ptr,
- (png_uint_32)(5*(num_chunks+old_num_chunks)));
- if(png_ptr->chunk_list != NULL)
- {
- png_memcpy(new_list, png_ptr->chunk_list,
- (png_size_t)(5*old_num_chunks));
- png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list=NULL;
- }
- png_memcpy(new_list+5*old_num_chunks, chunk_list,
- (png_size_t)(5*num_chunks));
- for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
- *p=(png_byte)keep;
- png_ptr->num_chunk_list=old_num_chunks+num_chunks;
- png_ptr->chunk_list=new_list;
-#ifdef PNG_FREE_ME_SUPPORTED
- png_ptr->free_me |= PNG_FREE_LIST;
-#endif
-}
-#endif
-
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
-void PNGAPI
-png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
- png_user_chunk_ptr read_user_chunk_fn)
-{
- png_debug(1, "in png_set_read_user_chunk_fn\n");
- if (png_ptr == NULL)
- return;
- png_ptr->read_user_chunk_fn = read_user_chunk_fn;
- png_ptr->user_chunk_ptr = user_chunk_ptr;
-}
-#endif
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-void PNGAPI
-png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
-{
- png_debug1(1, "in %s storage function\n", "rows");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
- png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
- info_ptr->row_pointers = row_pointers;
- if(row_pointers)
- info_ptr->valid |= PNG_INFO_IDAT;
-}
-#endif
-
-#ifdef PNG_WRITE_SUPPORTED
-void PNGAPI
-png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
-{
- if (png_ptr == NULL)
- return;
- if(png_ptr->zbuf)
- png_free(png_ptr, png_ptr->zbuf);
- png_ptr->zbuf_size = (png_size_t)size;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-}
-#endif
-
-void PNGAPI
-png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
-{
- if (png_ptr && info_ptr)
- info_ptr->valid &= ~(mask);
-}
-
-
-#ifndef PNG_1_0_X
-#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
-/* this function was added to libpng 1.2.0 and should always exist by default */
-void PNGAPI
-png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
-{
-#ifdef PNG_MMX_CODE_SUPPORTED
- png_uint_32 settable_asm_flags;
- png_uint_32 settable_mmx_flags;
-#endif
- if (png_ptr == NULL)
- return;
-#ifdef PNG_MMX_CODE_SUPPORTED
-
- settable_mmx_flags =
-#ifdef PNG_HAVE_MMX_COMBINE_ROW
- PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
-#endif
-#ifdef PNG_HAVE_MMX_READ_INTERLACE
- PNG_ASM_FLAG_MMX_READ_INTERLACE |
-#endif
-#ifdef PNG_HAVE_MMX_READ_FILTER_ROW
- PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
- PNG_ASM_FLAG_MMX_READ_FILTER_UP |
- PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
- PNG_ASM_FLAG_MMX_READ_FILTER_PAETH |
-#endif
- 0;
-
- /* could be some non-MMX ones in the future, but not currently: */
- settable_asm_flags = settable_mmx_flags;
-
- if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) ||
- !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU))
- {
- /* clear all MMX flags if MMX isn't supported */
- settable_asm_flags &= ~settable_mmx_flags;
- png_ptr->asm_flags &= ~settable_mmx_flags;
- }
-
- /* we're replacing the settable bits with those passed in by the user,
- * so first zero them out of the master copy, then bitwise-OR in the
- * allowed subset that was requested */
-
- png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */
- png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */
-#endif /* ?PNG_MMX_CODE_SUPPORTED */
-}
-
-/* this function was added to libpng 1.2.0 */
-void PNGAPI
-png_set_mmx_thresholds (png_structp png_ptr,
- png_byte mmx_bitdepth_threshold,
- png_uint_32 mmx_rowbytes_threshold)
-{
- if (png_ptr == NULL)
- return;
-#ifdef PNG_MMX_CODE_SUPPORTED
- png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold;
- png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold;
-#endif /* ?PNG_MMX_CODE_SUPPORTED */
-}
-#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-/* this function was added to libpng 1.2.6 */
-void PNGAPI
-png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
- png_uint_32 user_height_max)
-{
- /* Images with dimensions larger than these limits will be
- * rejected by png_set_IHDR(). To accept any PNG datastream
- * regardless of dimensions, set both limits to 0x7ffffffL.
- */
- if(png_ptr == NULL) return;
- png_ptr->user_width_max = user_width_max;
- png_ptr->user_height_max = user_height_max;
-}
-#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
-
-#endif /* ?PNG_1_0_X */
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngtrans.c b/distrib/libpng-1.2.19/pngtrans.c
deleted file mode 100644
index 1640095..0000000
--- a/distrib/libpng-1.2.19/pngtrans.c
+++ /dev/null
@@ -1,662 +0,0 @@
-
-/* pngtrans.c - transforms the data in a row (used by both readers and writers)
- *
- * Last changed in libpng 1.2.17 May 15, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* turn on BGR-to-RGB mapping */
-void PNGAPI
-png_set_bgr(png_structp png_ptr)
-{
- png_debug(1, "in png_set_bgr\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_BGR;
-}
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* turn on 16 bit byte swapping */
-void PNGAPI
-png_set_swap(png_structp png_ptr)
-{
- png_debug(1, "in png_set_swap\n");
- if(png_ptr == NULL) return;
- if (png_ptr->bit_depth == 16)
- png_ptr->transformations |= PNG_SWAP_BYTES;
-}
-#endif
-
-#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-/* turn on pixel packing */
-void PNGAPI
-png_set_packing(png_structp png_ptr)
-{
- png_debug(1, "in png_set_packing\n");
- if(png_ptr == NULL) return;
- if (png_ptr->bit_depth < 8)
- {
- png_ptr->transformations |= PNG_PACK;
- png_ptr->usr_bit_depth = 8;
- }
-}
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-/* turn on packed pixel swapping */
-void PNGAPI
-png_set_packswap(png_structp png_ptr)
-{
- png_debug(1, "in png_set_packswap\n");
- if(png_ptr == NULL) return;
- if (png_ptr->bit_depth < 8)
- png_ptr->transformations |= PNG_PACKSWAP;
-}
-#endif
-
-#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-void PNGAPI
-png_set_shift(png_structp png_ptr, png_color_8p true_bits)
-{
- png_debug(1, "in png_set_shift\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_SHIFT;
- png_ptr->shift = *true_bits;
-}
-#endif
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
- defined(PNG_WRITE_INTERLACING_SUPPORTED)
-int PNGAPI
-png_set_interlace_handling(png_structp png_ptr)
-{
- png_debug(1, "in png_set_interlace handling\n");
- if (png_ptr && png_ptr->interlaced)
- {
- png_ptr->transformations |= PNG_INTERLACE;
- return (7);
- }
-
- return (1);
-}
-#endif
-
-#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte on read, or remove a filler or alpha byte on write.
- * The filler type has changed in v0.95 to allow future 2-byte fillers
- * for 48-bit input data, as well as to avoid problems with some compilers
- * that don't like bytes as parameters.
- */
-void PNGAPI
-png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
-{
- png_debug(1, "in png_set_filler\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_FILLER;
- png_ptr->filler = (png_byte)filler;
- if (filler_loc == PNG_FILLER_AFTER)
- png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
- else
- png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
-
- /* This should probably go in the "do_read_filler" routine.
- * I attempted to do that in libpng-1.0.1a but that caused problems
- * so I restored it in libpng-1.0.2a
- */
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_ptr->usr_channels = 4;
- }
-
- /* Also I added this in libpng-1.0.2a (what happens when we expand
- * a less-than-8-bit grayscale to GA? */
-
- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
- {
- png_ptr->usr_channels = 2;
- }
-}
-
-#if !defined(PNG_1_0_X)
-/* Added to libpng-1.2.7 */
-void PNGAPI
-png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
-{
- png_debug(1, "in png_set_add_alpha\n");
- if(png_ptr == NULL) return;
- png_set_filler(png_ptr, filler, filler_loc);
- png_ptr->transformations |= PNG_ADD_ALPHA;
-}
-#endif
-
-#endif
-
-#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void PNGAPI
-png_set_swap_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_swap_alpha\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_SWAP_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
- defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void PNGAPI
-png_set_invert_alpha(png_structp png_ptr)
-{
- png_debug(1, "in png_set_invert_alpha\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_INVERT_ALPHA;
-}
-#endif
-
-#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-void PNGAPI
-png_set_invert_mono(png_structp png_ptr)
-{
- png_debug(1, "in png_set_invert_mono\n");
- if(png_ptr == NULL) return;
- png_ptr->transformations |= PNG_INVERT_MONO;
-}
-
-/* invert monochrome grayscale data */
-void /* PRIVATE */
-png_do_invert(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_invert\n");
- /* This test removed from libpng version 1.0.13 and 1.2.0:
- * if (row_info->bit_depth == 1 &&
- */
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row == NULL || row_info == NULL)
- return;
-#endif
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(~(*rp));
- rp++;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
- row_info->bit_depth == 8)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i+=2)
- {
- *rp = (png_byte)(~(*rp));
- rp+=2;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
- row_info->bit_depth == 16)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
-
- for (i = 0; i < istop; i+=4)
- {
- *rp = (png_byte)(~(*rp));
- *(rp+1) = (png_byte)(~(*(rp+1)));
- rp+=4;
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* swaps byte order on 16 bit depth images */
-void /* PRIVATE */
-png_do_swap(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_swap\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->bit_depth == 16)
- {
- png_bytep rp = row;
- png_uint_32 i;
- png_uint_32 istop= row_info->width * row_info->channels;
-
- for (i = 0; i < istop; i++, rp += 2)
- {
- png_byte t = *rp;
- *rp = *(rp + 1);
- *(rp + 1) = t;
- }
- }
-}
-#endif
-
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-static PNG_CONST png_byte onebppswaptable[256] = {
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-};
-
-static PNG_CONST png_byte twobppswaptable[256] = {
- 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
- 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
- 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
- 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
- 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
- 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
- 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
- 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
- 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
- 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
- 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
- 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
- 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
- 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
- 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
- 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
- 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
- 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
- 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
- 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
- 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
- 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
- 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
- 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
- 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
- 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
- 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
- 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
- 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
- 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
- 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
- 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
-};
-
-static PNG_CONST png_byte fourbppswaptable[256] = {
- 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
- 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
- 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
- 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
- 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
- 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
- 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
- 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
- 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
- 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
- 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
- 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
- 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
- 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
- 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
- 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
- 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
- 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
- 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
- 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
- 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
- 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
- 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
- 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
- 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
- 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
- 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
- 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
- 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
- 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
- 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
- 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
-};
-
-/* swaps pixel packing order within bytes */
-void /* PRIVATE */
-png_do_packswap(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_packswap\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->bit_depth < 8)
- {
- png_bytep rp, end, table;
-
- end = row + row_info->rowbytes;
-
- if (row_info->bit_depth == 1)
- table = (png_bytep)onebppswaptable;
- else if (row_info->bit_depth == 2)
- table = (png_bytep)twobppswaptable;
- else if (row_info->bit_depth == 4)
- table = (png_bytep)fourbppswaptable;
- else
- return;
-
- for (rp = row; rp < end; rp++)
- *rp = table[*rp];
- }
-}
-#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
- defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-/* remove filler or alpha byte(s) */
-void /* PRIVATE */
-png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
-{
- png_debug(1, "in png_do_strip_filler\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- png_bytep sp=row;
- png_bytep dp=row;
- png_uint_32 row_width=row_info->width;
- png_uint_32 i;
-
- if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
- (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
- (flags & PNG_FLAG_STRIP_ALPHA))) &&
- row_info->channels == 4)
- {
- if (row_info->bit_depth == 8)
- {
- /* This converts from RGBX or RGBA to RGB */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- dp+=3; sp+=4;
- for (i = 1; i < row_width; i++)
- {
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp++;
- }
- }
- /* This converts from XRGB or ARGB to RGB */
- else
- {
- for (i = 0; i < row_width; i++)
- {
- sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 24;
- row_info->rowbytes = row_width * 3;
- }
- else /* if (row_info->bit_depth == 16) */
- {
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
- sp += 8; dp += 6;
- for (i = 1; i < row_width; i++)
- {
- /* This could be (although png_memcpy is probably slower):
- png_memcpy(dp, sp, 6);
- sp += 8;
- dp += 6;
- */
-
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp += 2;
- }
- }
- else
- {
- /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
- for (i = 0; i < row_width; i++)
- {
- /* This could be (although png_memcpy is probably slower):
- png_memcpy(dp, sp, 6);
- sp += 8;
- dp += 6;
- */
-
- sp+=2;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 48;
- row_info->rowbytes = row_width * 6;
- }
- row_info->channels = 3;
- }
- else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
- (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
- (flags & PNG_FLAG_STRIP_ALPHA))) &&
- row_info->channels == 2)
- {
- if (row_info->bit_depth == 8)
- {
- /* This converts from GX or GA to G */
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- for (i = 0; i < row_width; i++)
- {
- *dp++ = *sp++;
- sp++;
- }
- }
- /* This converts from XG or AG to G */
- else
- {
- for (i = 0; i < row_width; i++)
- {
- sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
- else /* if (row_info->bit_depth == 16) */
- {
- if (flags & PNG_FLAG_FILLER_AFTER)
- {
- /* This converts from GGXX or GGAA to GG */
- sp += 4; dp += 2;
- for (i = 1; i < row_width; i++)
- {
- *dp++ = *sp++;
- *dp++ = *sp++;
- sp += 2;
- }
- }
- else
- {
- /* This converts from XXGG or AAGG to GG */
- for (i = 0; i < row_width; i++)
- {
- sp += 2;
- *dp++ = *sp++;
- *dp++ = *sp++;
- }
- }
- row_info->pixel_depth = 16;
- row_info->rowbytes = row_width * 2;
- }
- row_info->channels = 1;
- }
- if (flags & PNG_FLAG_STRIP_ALPHA)
- row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
- }
-}
-#endif
-
-#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-/* swaps red and blue bytes within a pixel */
-void /* PRIVATE */
-png_do_bgr(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_bgr\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 3)
- {
- png_byte save = *rp;
- *rp = *(rp + 2);
- *(rp + 2) = save;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 4)
- {
- png_byte save = *rp;
- *rp = *(rp + 2);
- *(rp + 2) = save;
- }
- }
- }
- else if (row_info->bit_depth == 16)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 6)
- {
- png_byte save = *rp;
- *rp = *(rp + 4);
- *(rp + 4) = save;
- save = *(rp + 1);
- *(rp + 1) = *(rp + 5);
- *(rp + 5) = save;
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- png_bytep rp;
- png_uint_32 i;
-
- for (i = 0, rp = row; i < row_width; i++, rp += 8)
- {
- png_byte save = *rp;
- *rp = *(rp + 4);
- *(rp + 4) = save;
- save = *(rp + 1);
- *(rp + 1) = *(rp + 5);
- *(rp + 5) = save;
- }
- }
- }
- }
-}
-#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
-
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
- defined(PNG_LEGACY_SUPPORTED)
-void PNGAPI
-png_set_user_transform_info(png_structp png_ptr, png_voidp
- user_transform_ptr, int user_transform_depth, int user_transform_channels)
-{
- png_debug(1, "in png_set_user_transform_info\n");
- if(png_ptr == NULL) return;
-#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- png_ptr->user_transform_ptr = user_transform_ptr;
- png_ptr->user_transform_depth = (png_byte)user_transform_depth;
- png_ptr->user_transform_channels = (png_byte)user_transform_channels;
-#else
- if(user_transform_ptr || user_transform_depth || user_transform_channels)
- png_warning(png_ptr,
- "This version of libpng does not support user transform info");
-#endif
-}
-#endif
-
-/* This function returns a pointer to the user_transform_ptr associated with
- * the user transform functions. The application should free any memory
- * associated with this pointer before png_write_destroy and png_read_destroy
- * are called.
- */
-png_voidp PNGAPI
-png_get_user_transform_ptr(png_structp png_ptr)
-{
-#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if (png_ptr == NULL) return (NULL);
- return ((png_voidp)png_ptr->user_transform_ptr);
-#else
- return (NULL);
-#endif
-}
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngvcrd.c b/distrib/libpng-1.2.19/pngvcrd.c
deleted file mode 100644
index 34d42c9..0000000
--- a/distrib/libpng-1.2.19/pngvcrd.c
+++ /dev/null
@@ -1,3922 +0,0 @@
-
-/* pngvcrd.c - mixed C/assembler version of utilities to read a PNG file
- *
- * For Intel x86 CPU and Microsoft Visual C++ compiler
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * Copyright (c) 1998, Intel Corporation
- *
- * Contributed by Nirav Chhatrapati, Intel Corporation, 1998
- * Interface to libpng contributed by Gilles Vollant, 1999
- *
- *
- * In png_do_read_interlace() in libpng versions 1.0.3a through 1.0.4d,
- * a sign error in the post-MMX cleanup code for each pixel_depth resulted
- * in bad pixels at the beginning of some rows of some images, and also
- * (due to out-of-range memory reads and writes) caused heap corruption
- * when compiled with MSVC 6.0. The error was fixed in version 1.0.4e.
- *
- * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916]
- *
- * [runtime MMX configuration, GRR 20010102]
- *
- * [Copy 6 bytes per pixel, not 4, and use stride of 6, not 4, in the
- * second loop of interlace processing of 48-bit pixels, GR-P 20070717]
- *
- * [move instances of uAll union into local, except for two constant
- * instances, GR-P 20070805]
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#if defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD)
-
-
-static int mmx_supported=2;
-
-int PNGAPI
-png_mmx_support(void)
-{
- int mmx_supported_local = 0;
- _asm {
- push ebx //CPUID will trash these
- push ecx
- push edx
-
- pushfd //Save Eflag to stack
- pop eax //Get Eflag from stack into eax
- mov ecx, eax //Make another copy of Eflag in ecx
- xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)]
- push eax //Save modified Eflag back to stack
-
- popfd //Restored modified value back to Eflag reg
- pushfd //Save Eflag to stack
- pop eax //Get Eflag from stack
- push ecx // save original Eflag to stack
- popfd // restore original Eflag
- xor eax, ecx //Compare the new Eflag with the original Eflag
- jz NOT_SUPPORTED //If the same, CPUID instruction is not supported,
- //skip following instructions and jump to
- //NOT_SUPPORTED label
-
- xor eax, eax //Set eax to zero
-
- _asm _emit 0x0f //CPUID instruction (two bytes opcode)
- _asm _emit 0xa2
-
- cmp eax, 1 //make sure eax return non-zero value
- jl NOT_SUPPORTED //If eax is zero, mmx not supported
-
- xor eax, eax //set eax to zero
- inc eax //Now increment eax to 1. This instruction is
- //faster than the instruction "mov eax, 1"
-
- _asm _emit 0x0f //CPUID instruction
- _asm _emit 0xa2
-
- and edx, 0x00800000 //mask out all bits but mmx bit(24)
- cmp edx, 0 // 0 = mmx not supported
- jz NOT_SUPPORTED // non-zero = Yes, mmx IS supported
-
- mov mmx_supported_local, 1 //set return value to 1
-
-NOT_SUPPORTED:
- mov eax, mmx_supported_local //move return value to eax
- pop edx //CPUID trashed these
- pop ecx
- pop ebx
- }
-
- //mmx_supported_local=0; // test code for force don't support MMX
- //printf("MMX : %u (1=MMX supported)\n",mmx_supported_local);
-
- mmx_supported = mmx_supported_local;
- return mmx_supported_local;
-}
-
-/* Combines the row recently read in with the previous row.
- This routine takes care of alpha and transparency if requested.
- This routine also handles the two methods of progressive display
- of interlaced images, depending on the mask value.
- The mask value describes which pixels are to be combined with
- the row. The pattern always repeats every 8 pixels, so just 8
- bits are needed. A one indicates the pixel is to be combined; a
- zero indicates the pixel is to be skipped. This is in addition
- to any alpha or transparency value associated with the pixel. If
- you want all pixels to be combined, pass 0xff (255) in mask. */
-
-/* Use this routine for x86 platform - uses faster MMX routine if machine
- supports MMX */
-
-void /* PRIVATE */
-png_combine_row(png_structp png_ptr, png_bytep row, int mask)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-#endif
-
- png_debug(1,"in png_combine_row_asm\n");
-
- if (mmx_supported == 2) {
-#if !defined(PNG_1_0_X)
- /* this should have happened in png_init_mmx_flags() already */
- png_warning(png_ptr, "asm_flags may not have been initialized");
-#endif
- png_mmx_support();
- }
-
- if (mask == 0xff)
- {
- png_memcpy(row, png_ptr->row_buf + 1,
- (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->width));
- }
- /* GRR: add "else if (mask == 0)" case?
- * or does png_combine_row() not even get called in that case? */
- else
- {
- switch (png_ptr->row_info.pixel_depth)
- {
- case 24:
- {
- png_bytep srcptr;
- png_bytep dstptr;
- png_uint_32 len;
- int unmask, diff;
-
- __int64 mask2=0x0101010202020404, //24bpp
- mask1=0x0408080810101020,
- mask0=0x2020404040808080;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
-
- unmask = ~mask;
- len = (png_ptr->width)&~7;
- diff = (png_ptr->width)&7;
-
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
- /* && mmx_supported */ )
-#else
- if (mmx_supported)
-#endif
- {
- _asm
- {
- movd mm7, unmask //load bit pattern
- psubb mm6,mm6 //zero mm6
- punpcklbw mm7,mm7
- punpcklwd mm7,mm7
- punpckldq mm7,mm7 //fill register with 8 masks
-
- movq mm0,mask0
- movq mm1,mask1
- movq mm2,mask2
-
- pand mm0,mm7
- pand mm1,mm7
- pand mm2,mm7
-
- pcmpeqb mm0,mm6
- pcmpeqb mm1,mm6
- pcmpeqb mm2,mm6
-
- mov ecx,len //load length of line
- mov esi,srcptr //load source
- mov ebx,dstptr //load dest
- cmp ecx,0
- jz mainloop24end
-
-mainloop24:
- movq mm4,[esi]
- pand mm4,mm0
- movq mm6,mm0
- movq mm7,[ebx]
- pandn mm6,mm7
- por mm4,mm6
- movq [ebx],mm4
-
-
- movq mm5,[esi+8]
- pand mm5,mm1
- movq mm7,mm1
- movq mm6,[ebx+8]
- pandn mm7,mm6
- por mm5,mm7
- movq [ebx+8],mm5
-
- movq mm6,[esi+16]
- pand mm6,mm2
- movq mm4,mm2
- movq mm7,[ebx+16]
- pandn mm4,mm7
- por mm6,mm4
- movq [ebx+16],mm6
-
- add esi,24 //inc by 24 bytes processed
- add ebx,24
- sub ecx,8 //dec by 8 pixels processed
-
- ja mainloop24
-
-mainloop24end:
- mov ecx,diff
- cmp ecx,0
- jz end24
-
- mov edx,mask
- sal edx,24 //make low byte the high byte
-secondloop24:
- sal edx,1 //move high bit to CF
- jnc skip24 //if CF = 0
- mov ax,[esi]
- mov [ebx],ax
- xor eax,eax
- mov al,[esi+2]
- mov [ebx+2],al
-skip24:
- add esi,3
- add ebx,3
-
- dec ecx
- jnz secondloop24
-
-end24:
- emms
- }
- }
- else /* mmx not supported - use modified C routine */
- {
- register unsigned int incr1, initial_val, final_val;
- png_size_t pixel_bytes;
- png_uint_32 i;
- register int disp = png_pass_inc[png_ptr->pass];
- int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
-
- pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
- pixel_bytes;
- dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
- initial_val = offset_table[png_ptr->pass]*pixel_bytes;
- final_val = png_ptr->width*pixel_bytes;
- incr1 = (disp)*pixel_bytes;
- for (i = initial_val; i < final_val; i += incr1)
- {
- png_memcpy(dstptr, srcptr, pixel_bytes);
- srcptr += incr1;
- dstptr += incr1;
- }
- } /* end of else */
-
- break;
- } // end 24 bpp
-
- case 32:
- {
- png_bytep srcptr;
- png_bytep dstptr;
- png_uint_32 len;
- int unmask, diff;
-
- __int64 mask3=0x0101010102020202, //32bpp
- mask2=0x0404040408080808,
- mask1=0x1010101020202020,
- mask0=0x4040404080808080;
-
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
-
- unmask = ~mask;
- len = (png_ptr->width)&~7;
- diff = (png_ptr->width)&7;
-
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
- /* && mmx_supported */ )
-#else
- if (mmx_supported)
-#endif
- {
- _asm
- {
- movd mm7, unmask //load bit pattern
- psubb mm6,mm6 //zero mm6
- punpcklbw mm7,mm7
- punpcklwd mm7,mm7
- punpckldq mm7,mm7 //fill register with 8 masks
-
- movq mm0,mask0
- movq mm1,mask1
- movq mm2,mask2
- movq mm3,mask3
-
- pand mm0,mm7
- pand mm1,mm7
- pand mm2,mm7
- pand mm3,mm7
-
- pcmpeqb mm0,mm6
- pcmpeqb mm1,mm6
- pcmpeqb mm2,mm6
- pcmpeqb mm3,mm6
-
- mov ecx,len //load length of line
- mov esi,srcptr //load source
- mov ebx,dstptr //load dest
-
- cmp ecx,0 //lcr
- jz mainloop32end
-
-mainloop32:
- movq mm4,[esi]
- pand mm4,mm0
- movq mm6,mm0
- movq mm7,[ebx]
- pandn mm6,mm7
- por mm4,mm6
- movq [ebx],mm4
-
- movq mm5,[esi+8]
- pand mm5,mm1
- movq mm7,mm1
- movq mm6,[ebx+8]
- pandn mm7,mm6
- por mm5,mm7
- movq [ebx+8],mm5
-
- movq mm6,[esi+16]
- pand mm6,mm2
- movq mm4,mm2
- movq mm7,[ebx+16]
- pandn mm4,mm7
- por mm6,mm4
- movq [ebx+16],mm6
-
- movq mm7,[esi+24]
- pand mm7,mm3
- movq mm5,mm3
- movq mm4,[ebx+24]
- pandn mm5,mm4
- por mm7,mm5
- movq [ebx+24],mm7
-
- add esi,32 //inc by 32 bytes processed
- add ebx,32
- sub ecx,8 //dec by 8 pixels processed
-
- ja mainloop32
-
-mainloop32end:
- mov ecx,diff
- cmp ecx,0
- jz end32
-
- mov edx,mask
- sal edx,24 //make low byte the high byte
-secondloop32:
- sal edx,1 //move high bit to CF
- jnc skip32 //if CF = 0
- mov eax,[esi]
- mov [ebx],eax
-skip32:
- add esi,4
- add ebx,4
-
- dec ecx
- jnz secondloop32
-
-end32:
- emms
- }
- }
- else /* mmx _not supported - Use modified C routine */
- {
- register unsigned int incr1, initial_val, final_val;
- png_size_t pixel_bytes;
- png_uint_32 i;
- register int disp = png_pass_inc[png_ptr->pass];
- int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
-
- pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
- pixel_bytes;
- dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
- initial_val = offset_table[png_ptr->pass]*pixel_bytes;
- final_val = png_ptr->width*pixel_bytes;
- incr1 = (disp)*pixel_bytes;
- for (i = initial_val; i < final_val; i += incr1)
- {
- png_memcpy(dstptr, srcptr, pixel_bytes);
- srcptr += incr1;
- dstptr += incr1;
- }
- } /* end of else */
-
- break;
- } // end 32 bpp
-
- case 8:
- {
- png_bytep srcptr;
- png_bytep dstptr;
- png_uint_32 len;
- int m;
- int diff, unmask;
-
- __int64 mask0=0x0102040810204080;
-
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
- /* && mmx_supported */ )
-#else
- if (mmx_supported)
-#endif
- {
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
- m = 0x80;
- unmask = ~mask;
- len = png_ptr->width &~7; //reduce to multiple of 8
- diff = png_ptr->width & 7; //amount lost
-
- _asm
- {
- movd mm7, unmask //load bit pattern
- psubb mm6,mm6 //zero mm6
- punpcklbw mm7,mm7
- punpcklwd mm7,mm7
- punpckldq mm7,mm7 //fill register with 8 masks
-
- movq mm0,mask0
-
- pand mm0,mm7 //nonzero if keep byte
- pcmpeqb mm0,mm6 //zeros->1s, v versa
-
- mov ecx,len //load length of line (pixels)
- mov esi,srcptr //load source
- mov ebx,dstptr //load dest
- cmp ecx,0 //lcr
- je mainloop8end
-
-mainloop8:
- movq mm4,[esi]
- pand mm4,mm0
- movq mm6,mm0
- pandn mm6,[ebx]
- por mm4,mm6
- movq [ebx],mm4
-
- add esi,8 //inc by 8 bytes processed
- add ebx,8
- sub ecx,8 //dec by 8 pixels processed
-
- ja mainloop8
-mainloop8end:
-
- mov ecx,diff
- cmp ecx,0
- jz end8
-
- mov edx,mask
- sal edx,24 //make low byte the high byte
-
-secondloop8:
- sal edx,1 //move high bit to CF
- jnc skip8 //if CF = 0
- mov al,[esi]
- mov [ebx],al
-skip8:
- inc esi
- inc ebx
-
- dec ecx
- jnz secondloop8
-end8:
- emms
- }
- }
- else /* mmx not supported - use modified C routine */
- {
- register unsigned int incr1, initial_val, final_val;
- png_size_t pixel_bytes;
- png_uint_32 i;
- register int disp = png_pass_inc[png_ptr->pass];
- int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
-
- pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
- pixel_bytes;
- dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
- initial_val = offset_table[png_ptr->pass]*pixel_bytes;
- final_val = png_ptr->width*pixel_bytes;
- incr1 = (disp)*pixel_bytes;
- for (i = initial_val; i < final_val; i += incr1)
- {
- png_memcpy(dstptr, srcptr, pixel_bytes);
- srcptr += incr1;
- dstptr += incr1;
- }
- } /* end of else */
-
- break;
- } // end 8 bpp
-
- case 1:
- {
- png_bytep sp;
- png_bytep dp;
- int s_inc, s_start, s_end;
- int m;
- int shift;
- png_uint_32 i;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
- else
-#endif
- {
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- int value;
-
- value = (*sp >> shift) & 0x1;
- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
-
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
-
- case 2:
- {
- png_bytep sp;
- png_bytep dp;
- int s_start, s_end, s_inc;
- int m;
- int shift;
- png_uint_32 i;
- int value;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
- else
-#endif
- {
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
-
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0x3;
- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
-
- case 4:
- {
- png_bytep sp;
- png_bytep dp;
- int s_start, s_end, s_inc;
- int m;
- int shift;
- png_uint_32 i;
- int value;
-
- sp = png_ptr->row_buf + 1;
- dp = row;
- m = 0x80;
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- {
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
- else
-#endif
- {
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- shift = s_start;
-
- for (i = 0; i < png_ptr->width; i++)
- {
- if (m & mask)
- {
- value = (*sp >> shift) & 0xf;
- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
- *dp |= (png_byte)(value << shift);
- }
-
- if (shift == s_end)
- {
- shift = s_start;
- sp++;
- dp++;
- }
- else
- shift += s_inc;
- if (m == 1)
- m = 0x80;
- else
- m >>= 1;
- }
- break;
- }
-
- case 16:
- {
- png_bytep srcptr;
- png_bytep dstptr;
- png_uint_32 len;
- int unmask, diff;
- __int64 mask1=0x0101020204040808,
- mask0=0x1010202040408080;
-
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
- /* && mmx_supported */ )
-#else
- if (mmx_supported)
-#endif
- {
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
-
- unmask = ~mask;
- len = (png_ptr->width)&~7;
- diff = (png_ptr->width)&7;
- _asm
- {
- movd mm7, unmask //load bit pattern
- psubb mm6,mm6 //zero mm6
- punpcklbw mm7,mm7
- punpcklwd mm7,mm7
- punpckldq mm7,mm7 //fill register with 8 masks
-
- movq mm0,mask0
- movq mm1,mask1
-
- pand mm0,mm7
- pand mm1,mm7
-
- pcmpeqb mm0,mm6
- pcmpeqb mm1,mm6
-
- mov ecx,len //load length of line
- mov esi,srcptr //load source
- mov ebx,dstptr //load dest
- cmp ecx,0 //lcr
- jz mainloop16end
-
-mainloop16:
- movq mm4,[esi]
- pand mm4,mm0
- movq mm6,mm0
- movq mm7,[ebx]
- pandn mm6,mm7
- por mm4,mm6
- movq [ebx],mm4
-
- movq mm5,[esi+8]
- pand mm5,mm1
- movq mm7,mm1
- movq mm6,[ebx+8]
- pandn mm7,mm6
- por mm5,mm7
- movq [ebx+8],mm5
-
- add esi,16 //inc by 16 bytes processed
- add ebx,16
- sub ecx,8 //dec by 8 pixels processed
-
- ja mainloop16
-
-mainloop16end:
- mov ecx,diff
- cmp ecx,0
- jz end16
-
- mov edx,mask
- sal edx,24 //make low byte the high byte
-secondloop16:
- sal edx,1 //move high bit to CF
- jnc skip16 //if CF = 0
- mov ax,[esi]
- mov [ebx],ax
-skip16:
- add esi,2
- add ebx,2
-
- dec ecx
- jnz secondloop16
-end16:
- emms
- }
- }
- else /* mmx not supported - use modified C routine */
- {
- register unsigned int incr1, initial_val, final_val;
- png_size_t pixel_bytes;
- png_uint_32 i;
- register int disp = png_pass_inc[png_ptr->pass];
- int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
-
- pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
- pixel_bytes;
- dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
- initial_val = offset_table[png_ptr->pass]*pixel_bytes;
- final_val = png_ptr->width*pixel_bytes;
- incr1 = (disp)*pixel_bytes;
- for (i = initial_val; i < final_val; i += incr1)
- {
- png_memcpy(dstptr, srcptr, pixel_bytes);
- srcptr += incr1;
- dstptr += incr1;
- }
- } /* end of else */
-
- break;
- } // end 16 bpp
-
- case 48:
- {
- png_bytep srcptr;
- png_bytep dstptr;
- png_uint_32 len;
- int unmask, diff;
-
- __int64 mask5=0x0101010101010202,
- mask4=0x0202020204040404,
- mask3=0x0404080808080808,
- mask2=0x1010101010102020,
- mask1=0x2020202040404040,
- mask0=0x4040808080808080;
-
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
- /* && mmx_supported */ )
-#else
- if (mmx_supported)
-#endif
- {
- srcptr = png_ptr->row_buf + 1;
- dstptr = row;
-
- unmask = ~mask;
- len = (png_ptr->width)&~7;
- diff = (png_ptr->width)&7;
- _asm
- {
- movd mm7, unmask //load bit pattern
- psubb mm6,mm6 //zero mm6
- punpcklbw mm7,mm7
- punpcklwd mm7,mm7
- punpckldq mm7,mm7 //fill register with 8 masks
-
- movq mm0,mask0
- movq mm1,mask1
- movq mm2,mask2
- movq mm3,mask3
- movq mm4,mask4
- movq mm5,mask5
-
- pand mm0,mm7
- pand mm1,mm7
- pand mm2,mm7
- pand mm3,mm7
- pand mm4,mm7
- pand mm5,mm7
-
- pcmpeqb mm0,mm6
- pcmpeqb mm1,mm6
- pcmpeqb mm2,mm6
- pcmpeqb mm3,mm6
- pcmpeqb mm4,mm6
- pcmpeqb mm5,mm6
-
- mov ecx,len //load length of line
- mov esi,srcptr //load source
- mov ebx,dstptr //load dest
-
- cmp ecx,0
- jz mainloop48end
-
-mainloop48:
- movq mm7,[esi]
- pand mm7,mm0
- movq mm6,mm0
- pandn mm6,[ebx]
- por mm7,mm6
- movq [ebx],mm7
-
- movq mm6,[esi+8]
- pand mm6,mm1
- movq mm7,mm1
- pandn mm7,[ebx+8]
- por mm6,mm7
- movq [ebx+8],mm6
-
- movq mm6,[esi+16]
- pand mm6,mm2
- movq mm7,mm2
- pandn mm7,[ebx+16]
- por mm6,mm7
- movq [ebx+16],mm6
-
- movq mm7,[esi+24]
- pand mm7,mm3
- movq mm6,mm3
- pandn mm6,[ebx+24]
- por mm7,mm6
- movq [ebx+24],mm7
-
- movq mm6,[esi+32]
- pand mm6,mm4
- movq mm7,mm4
- pandn mm7,[ebx+32]
- por mm6,mm7
- movq [ebx+32],mm6
-
- movq mm7,[esi+40]
- pand mm7,mm5
- movq mm6,mm5
- pandn mm6,[ebx+40]
- por mm7,mm6
- movq [ebx+40],mm7
-
- add esi,48 //inc by 32 bytes processed
- add ebx,48
- sub ecx,8 //dec by 8 pixels processed
-
- ja mainloop48
-mainloop48end:
-
- mov ecx,diff
- cmp ecx,0
- jz end48
-
- mov edx,mask
- sal edx,24 //make low byte the high byte
-
-secondloop48:
- sal edx,1 //move high bit to CF
- jnc skip48 //if CF = 0
- mov eax,[esi]
- mov [ebx],eax
- mov ax,[esi+4] // These 2 lines added 20070717
- mov [ebx+4],ax // Glenn R-P
-skip48:
- add esi,6 // Changed 4 to 6 on these 2
- add ebx,6 // lines. Glenn R-P 20070717
-
- dec ecx
- jnz secondloop48
-
-end48:
- emms
- }
- }
- else /* mmx _not supported - Use modified C routine */
- {
- register unsigned int incr1, initial_val, final_val;
- png_size_t pixel_bytes;
- png_uint_32 i;
- register int disp = png_pass_inc[png_ptr->pass];
- int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
-
- pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
- pixel_bytes;
- dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
- initial_val = offset_table[png_ptr->pass]*pixel_bytes;
- final_val = png_ptr->width*pixel_bytes;
- incr1 = (disp)*pixel_bytes;
- for (i = initial_val; i < final_val; i += incr1)
- {
- png_memcpy(dstptr, srcptr, pixel_bytes);
- srcptr += incr1;
- dstptr += incr1;
- }
- } /* end of else */
-
- break;
- } // end 48 bpp
-
- default:
- {
- png_bytep sptr;
- png_bytep dp;
- png_size_t pixel_bytes;
- int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
- unsigned int i;
- register int disp = png_pass_inc[png_ptr->pass]; // get the offset
- register unsigned int incr1, initial_val, final_val;
-
- pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
- sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
- pixel_bytes;
- dp = row + offset_table[png_ptr->pass]*pixel_bytes;
- initial_val = offset_table[png_ptr->pass]*pixel_bytes;
- final_val = png_ptr->width*pixel_bytes;
- incr1 = (disp)*pixel_bytes;
- for (i = initial_val; i < final_val; i += incr1)
- {
- png_memcpy(dp, sptr, pixel_bytes);
- sptr += incr1;
- dp += incr1;
- }
- break;
- }
- } /* end switch (png_ptr->row_info.pixel_depth) */
- } /* end if (non-trivial mask) */
-
-} /* end png_combine_row() */
-
-
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-
-void /* PRIVATE */
-png_do_read_interlace(png_structp png_ptr)
-{
- png_row_infop row_info = &(png_ptr->row_info);
- png_bytep row = png_ptr->row_buf + 1;
- int pass = png_ptr->pass;
- png_uint_32 transformations = png_ptr->transformations;
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-#endif
-
- png_debug(1,"in png_do_read_interlace\n");
-
- if (mmx_supported == 2) {
-#if !defined(PNG_1_0_X)
- /* this should have happened in png_init_mmx_flags() already */
- png_warning(png_ptr, "asm_flags may not have been initialized");
-#endif
- png_mmx_support();
- }
-
- if (row != NULL && row_info != NULL)
- {
- png_uint_32 final_width;
-
- final_width = row_info->width * png_pass_inc[pass];
-
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_byte v;
- png_uint_32 i;
- int j;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 3);
- dp = row + (png_size_t)((final_width - 1) >> 3);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (int)((row_info->width + 7) & 7);
- dshift = (int)((final_width + 7) & 7);
- s_start = 7;
- s_end = 0;
- s_inc = -1;
- }
- else
-#endif
- {
- sshift = 7 - (int)((row_info->width + 7) & 7);
- dshift = 7 - (int)((final_width + 7) & 7);
- s_start = 0;
- s_end = 7;
- s_inc = 1;
- }
-
- for (i = row_info->width; i; i--)
- {
- v = (png_byte)((*sp >> sshift) & 0x1);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- case 2:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 2);
- dp = row + (png_size_t)((final_width - 1) >> 2);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
- dshift = (png_size_t)(((final_width + 3) & 3) << 1);
- s_start = 6;
- s_end = 0;
- s_inc = -2;
- }
- else
-#endif
- {
- sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
- dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
- s_start = 0;
- s_end = 6;
- s_inc = 2;
- }
-
- for (i = row_info->width; i; i--)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0x3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- case 4:
- {
- png_bytep sp, dp;
- int sshift, dshift;
- int s_start, s_end, s_inc;
- png_uint_32 i;
-
- sp = row + (png_size_t)((row_info->width - 1) >> 1);
- dp = row + (png_size_t)((final_width - 1) >> 1);
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (transformations & PNG_PACKSWAP)
- {
- sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
- dshift = (png_size_t)(((final_width + 1) & 1) << 2);
- s_start = 4;
- s_end = 0;
- s_inc = -4;
- }
- else
-#endif
- {
- sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
- dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
- s_start = 0;
- s_end = 4;
- s_inc = 4;
- }
-
- for (i = row_info->width; i; i--)
- {
- png_byte v;
- int j;
-
- v = (png_byte)((*sp >> sshift) & 0xf);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
- *dp |= (png_byte)(v << dshift);
- if (dshift == s_end)
- {
- dshift = s_start;
- dp--;
- }
- else
- dshift += s_inc;
- }
- if (sshift == s_end)
- {
- sshift = s_start;
- sp--;
- }
- else
- sshift += s_inc;
- }
- break;
- }
-
- default: // This is the place where the routine is modified
- {
- __int64 const4 = 0x0000000000FFFFFF;
- // __int64 const5 = 0x000000FFFFFF0000; // unused...
- __int64 const6 = 0x00000000000000FF;
- png_bytep sptr, dp;
- png_uint_32 i;
- png_size_t pixel_bytes;
- int width = row_info->width;
-
- pixel_bytes = (row_info->pixel_depth >> 3);
-
- sptr = row + (width - 1) * pixel_bytes;
- dp = row + (final_width - 1) * pixel_bytes;
- // New code by Nirav Chhatrapati - Intel Corporation
- // sign fix by GRR
- // NOTE: there is NO MMX code for 48-bit and 64-bit images
-
- // use MMX routine if machine supports it
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)
- /* && mmx_supported */ )
-#else
- if (mmx_supported)
-#endif
- {
- if (pixel_bytes == 3)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 1) << 1) - 8;
- if (width_mmx < 0)
- width_mmx = 0;
- width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 3
- sub edi, 9
-loop_pass4:
- movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3
- movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3
- movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3
- psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0
- pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3
- psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0
- por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3
- movq mm5, mm6 ; 0 0 0 X X v2 v1 v0
- psllq mm6, 8 ; 0 0 X X v2 v1 v0 0
- movq [edi], mm0 ; move quad to memory
- psrlq mm5, 16 ; 0 0 0 0 0 X X v2
- pand mm5, const6 ; 0 0 0 0 0 0 0 v2
- por mm6, mm5 ; 0 0 X X v2 v1 v0 v2
- movd [edi+8], mm6 ; move double to memory
- sub esi, 6
- sub edi, 12
- sub ecx, 2
- jnz loop_pass4
- EMMS
- }
- }
-
- sptr -= width_mmx*3;
- dp -= width_mmx*6;
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
-
- png_memcpy(v, sptr, 3);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, 3);
- dp -= 3;
- }
- sptr -= 3;
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width
- sub edi, 9 // (png_pass_inc[pass] - 1)*pixel_bytes
-loop_pass2:
- movd mm0, [esi] ; X X X X X v2 v1 v0
- pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0
- movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0
- psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0
- movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0
- psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0
- psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1
- por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0
- por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1
- movq [edi+4], mm0 ; move to memory
- psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0
- movd [edi], mm0 ; move to memory
- sub esi, 3
- sub edi, 12
- dec ecx
- jnz loop_pass2
- EMMS
- }
- }
- else if (width) /* && ((pass == 0) || (pass == 1))) */
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width
- sub edi, 21 // (png_pass_inc[pass] - 1)*pixel_bytes
-loop_pass0:
- movd mm0, [esi] ; X X X X X v2 v1 v0
- pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0
- movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0
- psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0
- movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0
- psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0
- psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1
- por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0
- por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1
- movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1
- psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0
- movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1
- punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2
- movq [edi+16] , mm4
- psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0
- movq [edi+8] , mm3
- punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0
- sub esi, 3
- movq [edi], mm0
- sub edi, 24
- //sub esi, 3
- dec ecx
- jnz loop_pass0
- EMMS
- }
- }
- } /* end of pixel_bytes == 3 */
-
- else if (pixel_bytes == 1)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 3) << 3);
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub edi, 15
- sub esi, 7
-loop1_pass4:
- movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7
- movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7
- punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7
- //movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
- punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3
- movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3
- sub esi, 8
- movq [edi], mm0 ; move to memory v4 v5 v6 and v7
- //sub esi, 4
- sub edi, 16
- sub ecx, 8
- jnz loop1_pass4
- EMMS
- }
- }
-
- sptr -= width_mmx;
- dp -= width_mmx*2;
- for (i = width; i; i--)
- {
- int j;
-
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- sptr --;
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- int width_mmx = ((width >> 2) << 2);
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub edi, 15
- sub esi, 3
-loop1_pass2:
- movd mm0, [esi] ; X X X X v0 v1 v2 v3
- punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
- movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
- punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3
- punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1
- movq [edi], mm0 ; move to memory v2 and v3
- sub esi, 4
- movq [edi+8], mm1 ; move to memory v1 and v0
- sub edi, 16
- sub ecx, 4
- jnz loop1_pass2
- EMMS
- }
- }
-
- sptr -= width_mmx;
- dp -= width_mmx*4;
- for (i = width; i; i--)
- {
- int j;
-
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- *dp-- = *sptr;
- }
- sptr --;
- }
- }
- else if (width) /* && ((pass == 0) || (pass == 1))) */
- {
- int width_mmx = ((width >> 2) << 2);
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub edi, 31
- sub esi, 3
-loop1_pass0:
- movd mm0, [esi] ; X X X X v0 v1 v2 v3
- movq mm1, mm0 ; X X X X v0 v1 v2 v3
- punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
- movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
- punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3
- movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3
- punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3
- punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2
- movq [edi], mm0 ; move to memory v3
- punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1
- movq [edi+8], mm3 ; move to memory v2
- movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1
- punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1
- punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0
- movq [edi+16], mm2 ; move to memory v1
- movq [edi+24], mm4 ; move to memory v0
- sub esi, 4
- sub edi, 32
- sub ecx, 4
- jnz loop1_pass0
- EMMS
- }
- }
-
- sptr -= width_mmx;
- dp -= width_mmx*8;
- for (i = width; i; i--)
- {
- int j;
-
- /* I simplified this part in version 1.0.4e
- * here and in several other instances where
- * pixel_bytes == 1 -- GR-P
- *
- * Original code:
- *
- * png_byte v[8];
- * png_memcpy(v, sptr, pixel_bytes);
- * for (j = 0; j < png_pass_inc[pass]; j++)
- * {
- * png_memcpy(dp, v, pixel_bytes);
- * dp -= pixel_bytes;
- * }
- * sptr -= pixel_bytes;
- *
- * Replacement code is in the next three lines:
- */
-
- for (j = 0; j < png_pass_inc[pass]; j++)
- *dp-- = *sptr;
- sptr--;
- }
- }
- } /* end of pixel_bytes == 1 */
-
- else if (pixel_bytes == 2)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 2
- sub edi, 6
-loop2_pass4:
- movd mm0, [esi] ; X X X X v1 v0 v3 v2
- punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
- sub esi, 4
- movq [edi], mm0
- sub edi, 8
- sub ecx, 2
- jnz loop2_pass4
- EMMS
- }
- }
-
- sptr -= (width_mmx*2 - 2); // sign fixed
- dp -= (width_mmx*4 - 2); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 2;
- png_memcpy(v, sptr, 2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 2;
- png_memcpy(dp, v, 2);
- }
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 2
- sub edi, 14
-loop2_pass2:
- movd mm0, [esi] ; X X X X v1 v0 v3 v2
- punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
- movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
- punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2
- punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0
- movq [edi], mm0
- sub esi, 4
- movq [edi + 8], mm1
- //sub esi, 4
- sub edi, 16
- sub ecx, 2
- jnz loop2_pass2
- EMMS
- }
- }
-
- sptr -= (width_mmx*2 - 2); // sign fixed
- dp -= (width_mmx*8 - 2); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 2;
- png_memcpy(v, sptr, 2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 2;
- png_memcpy(dp, v, 2);
- }
- }
- }
- else if (width) /* && ((pass == 0) || (pass == 1))) */
- {
- int width_mmx = ((width >> 1) << 1);
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 2
- sub edi, 30
-loop2_pass0:
- movd mm0, [esi] ; X X X X v1 v0 v3 v2
- punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
- movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
- punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2
- punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0
- movq [edi], mm0
- movq [edi + 8], mm0
- movq [edi + 16], mm1
- movq [edi + 24], mm1
- sub esi, 4
- sub edi, 32
- sub ecx, 2
- jnz loop2_pass0
- EMMS
- }
- }
-
- sptr -= (width_mmx*2 - 2); // sign fixed
- dp -= (width_mmx*16 - 2); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 2;
- png_memcpy(v, sptr, 2);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 2;
- png_memcpy(dp, v, 2);
- }
- }
- }
- } /* end of pixel_bytes == 2 */
-
- else if (pixel_bytes == 4)
- {
- if (((pass == 4) || (pass == 5)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 4
- sub edi, 12
-loop4_pass4:
- movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4
- movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4
- punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4
- punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0
- movq [edi], mm0
- sub esi, 8
- movq [edi + 8], mm1
- sub edi, 16
- sub ecx, 2
- jnz loop4_pass4
- EMMS
- }
- }
-
- sptr -= (width_mmx*4 - 4); // sign fixed
- dp -= (width_mmx*8 - 4); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 4;
- png_memcpy(v, sptr, 4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 4;
- png_memcpy(dp, v, 4);
- }
- }
- }
- else if (((pass == 2) || (pass == 3)) && width)
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 4
- sub edi, 28
-loop4_pass2:
- movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4
- movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4
- punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4
- punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0
- movq [edi], mm0
- movq [edi + 8], mm0
- movq [edi+16], mm1
- movq [edi + 24], mm1
- sub esi, 8
- sub edi, 32
- sub ecx, 2
- jnz loop4_pass2
- EMMS
- }
- }
-
- sptr -= (width_mmx*4 - 4); // sign fixed
- dp -= (width_mmx*16 - 4); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 4;
- png_memcpy(v, sptr, 4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 4;
- png_memcpy(dp, v, 4);
- }
- }
- }
- else if (width) /* && ((pass == 0) || (pass == 1))) */
- {
- int width_mmx = ((width >> 1) << 1) ;
- width -= width_mmx;
- if (width_mmx)
- {
- _asm
- {
- mov esi, sptr
- mov edi, dp
- mov ecx, width_mmx
- sub esi, 4
- sub edi, 60
-loop4_pass0:
- movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4
- movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4
- punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4
- punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0
- movq [edi], mm0
- movq [edi + 8], mm0
- movq [edi + 16], mm0
- movq [edi + 24], mm0
- movq [edi+32], mm1
- movq [edi + 40], mm1
- movq [edi+ 48], mm1
- sub esi, 8
- movq [edi + 56], mm1
- sub edi, 64
- sub ecx, 2
- jnz loop4_pass0
- EMMS
- }
- }
-
- sptr -= (width_mmx*4 - 4); // sign fixed
- dp -= (width_mmx*32 - 4); // sign fixed
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- sptr -= 4;
- png_memcpy(v, sptr, 4);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- dp -= 4;
- png_memcpy(dp, v, 4);
- }
- }
- }
-
- } /* end of pixel_bytes == 4 */
-
- else if (pixel_bytes == 6)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, 6);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, 6);
- dp -= 6;
- }
- sptr -= 6;
- }
- } /* end of pixel_bytes == 6 */
-
- else
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr-= pixel_bytes;
- }
- }
- } /* end of mmx_supported */
-
- else /* MMX not supported: use modified C code - takes advantage
- * of inlining of memcpy for a constant */
- {
- if (pixel_bytes == 1)
- {
- for (i = width; i; i--)
- {
- int j;
- for (j = 0; j < png_pass_inc[pass]; j++)
- *dp-- = *sptr;
- sptr--;
- }
- }
- else if (pixel_bytes == 3)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr -= pixel_bytes;
- }
- }
- else if (pixel_bytes == 2)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr -= pixel_bytes;
- }
- }
- else if (pixel_bytes == 4)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr -= pixel_bytes;
- }
- }
- else if (pixel_bytes == 6)
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr -= pixel_bytes;
- }
- }
- else
- {
- for (i = width; i; i--)
- {
- png_byte v[8];
- int j;
- png_memcpy(v, sptr, pixel_bytes);
- for (j = 0; j < png_pass_inc[pass]; j++)
- {
- png_memcpy(dp, v, pixel_bytes);
- dp -= pixel_bytes;
- }
- sptr -= pixel_bytes;
- }
- }
-
- } /* end of MMX not supported */
- break;
- }
- } /* end switch (row_info->pixel_depth) */
-
- row_info->width = final_width;
-
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
- }
-
-}
-
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
-
-
-// These global constants are declared
-// here to ensure alignment on 8-byte boundaries.
- union uAll {
- __int64 use;
- double double_align;
- long long long_long_align;
- } ;
- static PNG_CONST union uAll LBCarryMask = {0x0101010101010101},
- HBClearMask = {0x7f7f7f7f7f7f7f7f};
-
-// Optimized code for PNG Average filter decoder
-void /* PRIVATE */
-png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row
- , png_bytep prev_row)
-{
- // These variables are declared
- // here to ensure alignment on 8-byte boundaries.
- union uAll ActiveMask, ShiftBpp, ShiftRem;
-
- int bpp;
- png_uint_32 FullLength;
- png_uint_32 MMXLength;
- //png_uint_32 len;
- int diff;
-
- bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
- FullLength = row_info->rowbytes; // # of bytes to filter
- _asm {
- // Init address pointers and offset
- mov edi, row // edi ==> Avg(x)
- xor ebx, ebx // ebx ==> x
- mov edx, edi
- mov esi, prev_row // esi ==> Prior(x)
- sub edx, bpp // edx ==> Raw(x-bpp)
-
- xor eax, eax
- // Compute the Raw value for the first bpp bytes
- // Raw(x) = Avg(x) + (Prior(x)/2)
-davgrlp:
- mov al, [esi + ebx] // Load al with Prior(x)
- inc ebx
- shr al, 1 // divide by 2
- add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
- cmp ebx, bpp
- mov [edi+ebx-1], al // Write back Raw(x);
- // mov does not affect flags; -1 to offset inc ebx
- jb davgrlp
- // get # of bytes to alignment
- mov diff, edi // take start of row
- add diff, ebx // add bpp
- add diff, 0xf // add 7 + 8 to incr past alignment boundary
- and diff, 0xfffffff8 // mask to alignment boundary
- sub diff, edi // subtract from start ==> value ebx at alignment
- jz davggo
- // fix alignment
- // Compute the Raw value for the bytes upto the alignment boundary
- // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
- xor ecx, ecx
-davglp1:
- xor eax, eax
- mov cl, [esi + ebx] // load cl with Prior(x)
- mov al, [edx + ebx] // load al with Raw(x-bpp)
- add ax, cx
- inc ebx
- shr ax, 1 // divide by 2
- add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
- cmp ebx, diff // Check if at alignment boundary
- mov [edi+ebx-1], al // Write back Raw(x);
- // mov does not affect flags; -1 to offset inc ebx
- jb davglp1 // Repeat until at alignment boundary
-davggo:
- mov eax, FullLength
- mov ecx, eax
- sub eax, ebx // subtract alignment fix
- and eax, 0x00000007 // calc bytes over mult of 8
- sub ecx, eax // drop over bytes from original length
- mov MMXLength, ecx
- } // end _asm block
- // Now do the math for the rest of the row
- switch ( bpp )
- {
- case 3:
- {
- ActiveMask.use = 0x0000000000ffffff;
- ShiftBpp.use = 24; // == 3 * 8
- ShiftRem.use = 40; // == 64 - 24
- _asm {
- // Re-init address pointers and offset
- movq mm7, ActiveMask
- mov ebx, diff // ebx ==> x = offset to alignment boundary
- movq mm5, LBCarryMask
- mov edi, row // edi ==> Avg(x)
- movq mm4, HBClearMask
- mov esi, prev_row // esi ==> Prior(x)
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
- // (we correct position in loop below)
-davg3lp:
- movq mm0, [edi + ebx] // Load mm0 with Avg(x)
- // Add (Prev_row/2) to Average
- movq mm3, mm5
- psrlq mm2, ShiftRem // Correct position Raw(x-bpp) data
- movq mm1, [esi + ebx] // Load mm1 with Prior(x)
- movq mm6, mm7
- pand mm3, mm1 // get lsb for each prev_row byte
- psrlq mm1, 1 // divide prev_row bytes by 2
- pand mm1, mm4 // clear invalid bit 7 of each byte
- paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
- // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
- // byte
- // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
- psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 3-5
- movq mm2, mm0 // mov updated Raws to mm2
- psllq mm2, ShiftBpp // shift data to position correctly
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
- // byte
-
- // Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry
- psllq mm6, ShiftBpp // shift the mm6 mask to cover the last two
- // bytes
- movq mm2, mm0 // mov updated Raws to mm2
- psllq mm2, ShiftBpp // shift data to position correctly
- // Data only needs to be shifted once here to
- // get the correct x-bpp offset.
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
- add ebx, 8
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
- // byte
-
- // Now ready to write back to memory
- movq [edi + ebx - 8], mm0
- // Move updated Raw(x) to use as Raw(x-bpp) for next loop
- cmp ebx, MMXLength
- movq mm2, mm0 // mov updated Raw(x) to mm2
- jb davg3lp
- } // end _asm block
- }
- break;
-
- case 6:
- case 4:
- case 7:
- case 5:
- {
- ActiveMask.use = 0xffffffffffffffff; // use shift below to clear
- // appropriate inactive bytes
- ShiftBpp.use = bpp << 3;
- ShiftRem.use = 64 - ShiftBpp.use;
- _asm {
- movq mm4, HBClearMask
- // Re-init address pointers and offset
- mov ebx, diff // ebx ==> x = offset to alignment boundary
- // Load ActiveMask and clear all bytes except for 1st active group
- movq mm7, ActiveMask
- mov edi, row // edi ==> Avg(x)
- psrlq mm7, ShiftRem
- mov esi, prev_row // esi ==> Prior(x)
- movq mm6, mm7
- movq mm5, LBCarryMask
- psllq mm6, ShiftBpp // Create mask for 2nd active group
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
- // (we correct position in loop below)
-davg4lp:
- movq mm0, [edi + ebx]
- psrlq mm2, ShiftRem // shift data to position correctly
- movq mm1, [esi + ebx]
- // Add (Prev_row/2) to Average
- movq mm3, mm5
- pand mm3, mm1 // get lsb for each prev_row byte
- psrlq mm1, 1 // divide prev_row bytes by 2
- pand mm1, mm4 // clear invalid bit 7 of each byte
- paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
- // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm7 // Leave only Active Group 1 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
- // byte
- // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
- movq mm2, mm0 // mov updated Raws to mm2
- psllq mm2, ShiftBpp // shift data to position correctly
- add ebx, 8
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
- // byte
- cmp ebx, MMXLength
- // Now ready to write back to memory
- movq [edi + ebx - 8], mm0
- // Prep Raw(x-bpp) for next loop
- movq mm2, mm0 // mov updated Raws to mm2
- jb davg4lp
- } // end _asm block
- }
- break;
- case 2:
- {
- ActiveMask.use = 0x000000000000ffff;
- ShiftBpp.use = 16; // == 2 * 8 [BUGFIX]
- ShiftRem.use = 48; // == 64 - 16 [BUGFIX]
- _asm {
- // Load ActiveMask
- movq mm7, ActiveMask
- // Re-init address pointers and offset
- mov ebx, diff // ebx ==> x = offset to alignment boundary
- movq mm5, LBCarryMask
- mov edi, row // edi ==> Avg(x)
- movq mm4, HBClearMask
- mov esi, prev_row // esi ==> Prior(x)
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
- // (we correct position in loop below)
-davg2lp:
- movq mm0, [edi + ebx]
- psrlq mm2, ShiftRem // shift data to position correctly [BUGFIX]
- movq mm1, [esi + ebx]
- // Add (Prev_row/2) to Average
- movq mm3, mm5
- pand mm3, mm1 // get lsb for each prev_row byte
- psrlq mm1, 1 // divide prev_row bytes by 2
- pand mm1, mm4 // clear invalid bit 7 of each byte
- movq mm6, mm7
- paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
- // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
- // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
- psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 2 & 3
- movq mm2, mm0 // mov updated Raws to mm2
- psllq mm2, ShiftBpp // shift data to position correctly
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
-
- // Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry
- psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 4 & 5
- movq mm2, mm0 // mov updated Raws to mm2
- psllq mm2, ShiftBpp // shift data to position correctly
- // Data only needs to be shifted once here to
- // get the correct x-bpp offset.
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
-
- // Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry
- psllq mm6, ShiftBpp // shift the mm6 mask to cover bytes 6 & 7
- movq mm2, mm0 // mov updated Raws to mm2
- psllq mm2, ShiftBpp // shift data to position correctly
- // Data only needs to be shifted once here to
- // get the correct x-bpp offset.
- add ebx, 8
- movq mm1, mm3 // now use mm1 for getting LBCarrys
- pand mm1, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1 (Only valid for active group)
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
- pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
- paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
-
- cmp ebx, MMXLength
- // Now ready to write back to memory
- movq [edi + ebx - 8], mm0
- // Prep Raw(x-bpp) for next loop
- movq mm2, mm0 // mov updated Raws to mm2
- jb davg2lp
- } // end _asm block
- }
- break;
-
- case 1: // bpp == 1
- {
- _asm {
- // Re-init address pointers and offset
- mov ebx, diff // ebx ==> x = offset to alignment boundary
- mov edi, row // edi ==> Avg(x)
- cmp ebx, FullLength // Test if offset at end of array
- jnb davg1end
- // Do Paeth decode for remaining bytes
- mov esi, prev_row // esi ==> Prior(x)
- mov edx, edi
- xor ecx, ecx // zero ecx before using cl & cx in loop below
- sub edx, bpp // edx ==> Raw(x-bpp)
-davg1lp:
- // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
- xor eax, eax
- mov cl, [esi + ebx] // load cl with Prior(x)
- mov al, [edx + ebx] // load al with Raw(x-bpp)
- add ax, cx
- inc ebx
- shr ax, 1 // divide by 2
- add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
- cmp ebx, FullLength // Check if at end of array
- mov [edi+ebx-1], al // Write back Raw(x);
- // mov does not affect flags; -1 to offset inc ebx
- jb davg1lp
-davg1end:
- } // end _asm block
- }
- return;
-
- case 8: // bpp == 8
- {
- _asm {
- // Re-init address pointers and offset
- mov ebx, diff // ebx ==> x = offset to alignment boundary
- movq mm5, LBCarryMask
- mov edi, row // edi ==> Avg(x)
- movq mm4, HBClearMask
- mov esi, prev_row // esi ==> Prior(x)
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
- // (NO NEED to correct position in loop below)
-davg8lp:
- movq mm0, [edi + ebx]
- movq mm3, mm5
- movq mm1, [esi + ebx]
- add ebx, 8
- pand mm3, mm1 // get lsb for each prev_row byte
- psrlq mm1, 1 // divide prev_row bytes by 2
- pand mm3, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm1, mm4 // clear invalid bit 7 of each byte
- paddb mm0, mm3 // add LBCarrys to Avg for each byte
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
- paddb mm0, mm2 // add (Raw/2) to Avg for each byte
- cmp ebx, MMXLength
- movq [edi + ebx - 8], mm0
- movq mm2, mm0 // reuse as Raw(x-bpp)
- jb davg8lp
- } // end _asm block
- }
- break;
- default: // bpp greater than 8
- {
- _asm {
- movq mm5, LBCarryMask
- // Re-init address pointers and offset
- mov ebx, diff // ebx ==> x = offset to alignment boundary
- mov edi, row // edi ==> Avg(x)
- movq mm4, HBClearMask
- mov edx, edi
- mov esi, prev_row // esi ==> Prior(x)
- sub edx, bpp // edx ==> Raw(x-bpp)
-davgAlp:
- movq mm0, [edi + ebx]
- movq mm3, mm5
- movq mm1, [esi + ebx]
- pand mm3, mm1 // get lsb for each prev_row byte
- movq mm2, [edx + ebx]
- psrlq mm1, 1 // divide prev_row bytes by 2
- pand mm3, mm2 // get LBCarrys for each byte where both
- // lsb's were == 1
- psrlq mm2, 1 // divide raw bytes by 2
- pand mm1, mm4 // clear invalid bit 7 of each byte
- paddb mm0, mm3 // add LBCarrys to Avg for each byte
- pand mm2, mm4 // clear invalid bit 7 of each byte
- paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
- add ebx, 8
- paddb mm0, mm2 // add (Raw/2) to Avg for each byte
- cmp ebx, MMXLength
- movq [edi + ebx - 8], mm0
- jb davgAlp
- } // end _asm block
- }
- break;
- } // end switch ( bpp )
-
- _asm {
- // MMX acceleration complete now do clean-up
- // Check if any remaining bytes left to decode
- mov ebx, MMXLength // ebx ==> x = offset bytes remaining after MMX
- mov edi, row // edi ==> Avg(x)
- cmp ebx, FullLength // Test if offset at end of array
- jnb davgend
- // Do Paeth decode for remaining bytes
- mov esi, prev_row // esi ==> Prior(x)
- mov edx, edi
- xor ecx, ecx // zero ecx before using cl & cx in loop below
- sub edx, bpp // edx ==> Raw(x-bpp)
-davglp2:
- // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
- xor eax, eax
- mov cl, [esi + ebx] // load cl with Prior(x)
- mov al, [edx + ebx] // load al with Raw(x-bpp)
- add ax, cx
- inc ebx
- shr ax, 1 // divide by 2
- add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
- cmp ebx, FullLength // Check if at end of array
- mov [edi+ebx-1], al // Write back Raw(x);
- // mov does not affect flags; -1 to offset inc ebx
- jb davglp2
-davgend:
- emms // End MMX instructions; prep for possible FP instrs.
- } // end _asm block
-}
-
-// Optimized code for PNG Paeth filter decoder
-void /* PRIVATE */
-png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row,
- png_bytep prev_row)
-{
- // These variables are declared
- // here to ensure alignment on 8-byte boundaries.
- union uAll ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem;
-
- png_uint_32 FullLength;
- png_uint_32 MMXLength;
- //png_uint_32 len;
- int bpp;
- int diff;
- //int ptemp;
- int patemp, pbtemp, pctemp;
-
- bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
- FullLength = row_info->rowbytes; // # of bytes to filter
- _asm
- {
- xor ebx, ebx // ebx ==> x offset
- mov edi, row
- xor edx, edx // edx ==> x-bpp offset
- mov esi, prev_row
- xor eax, eax
-
- // Compute the Raw value for the first bpp bytes
- // Note: the formula works out to be always
- // Paeth(x) = Raw(x) + Prior(x) where x < bpp
-dpthrlp:
- mov al, [edi + ebx]
- add al, [esi + ebx]
- inc ebx
- cmp ebx, bpp
- mov [edi + ebx - 1], al
- jb dpthrlp
- // get # of bytes to alignment
- mov diff, edi // take start of row
- add diff, ebx // add bpp
- xor ecx, ecx
- add diff, 0xf // add 7 + 8 to incr past alignment boundary
- and diff, 0xfffffff8 // mask to alignment boundary
- sub diff, edi // subtract from start ==> value ebx at alignment
- jz dpthgo
- // fix alignment
-dpthlp1:
- xor eax, eax
- // pav = p - a = (a + b - c) - a = b - c
- mov al, [esi + ebx] // load Prior(x) into al
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- sub eax, ecx // subtract Prior(x-bpp)
- mov patemp, eax // Save pav for later use
- xor eax, eax
- // pbv = p - b = (a + b - c) - b = a - c
- mov al, [edi + edx] // load Raw(x-bpp) into al
- sub eax, ecx // subtract Prior(x-bpp)
- mov ecx, eax
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- add eax, patemp // pcv = pav + pbv
- // pc = abs(pcv)
- test eax, 0x80000000
- jz dpthpca
- neg eax // reverse sign of neg values
-dpthpca:
- mov pctemp, eax // save pc for later use
- // pb = abs(pbv)
- test ecx, 0x80000000
- jz dpthpba
- neg ecx // reverse sign of neg values
-dpthpba:
- mov pbtemp, ecx // save pb for later use
- // pa = abs(pav)
- mov eax, patemp
- test eax, 0x80000000
- jz dpthpaa
- neg eax // reverse sign of neg values
-dpthpaa:
- mov patemp, eax // save pa for later use
- // test if pa <= pb
- cmp eax, ecx
- jna dpthabb
- // pa > pb; now test if pb <= pc
- cmp ecx, pctemp
- jna dpthbbc
- // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- jmp dpthpaeth
-dpthbbc:
- // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
- mov cl, [esi + ebx] // load Prior(x) into cl
- jmp dpthpaeth
-dpthabb:
- // pa <= pb; now test if pa <= pc
- cmp eax, pctemp
- jna dpthabc
- // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- jmp dpthpaeth
-dpthabc:
- // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
- mov cl, [edi + edx] // load Raw(x-bpp) into cl
-dpthpaeth:
- inc ebx
- inc edx
- // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
- add [edi + ebx - 1], cl
- cmp ebx, diff
- jb dpthlp1
-dpthgo:
- mov ecx, FullLength
- mov eax, ecx
- sub eax, ebx // subtract alignment fix
- and eax, 0x00000007 // calc bytes over mult of 8
- sub ecx, eax // drop over bytes from original length
- mov MMXLength, ecx
- } // end _asm block
- // Now do the math for the rest of the row
- switch ( bpp )
- {
- case 3:
- {
- ActiveMask.use = 0x0000000000ffffff;
- ActiveMaskEnd.use = 0xffff000000000000;
- ShiftBpp.use = 24; // == bpp(3) * 8
- ShiftRem.use = 40; // == 64 - 24
- _asm
- {
- mov ebx, diff
- mov edi, row
- mov esi, prev_row
- pxor mm0, mm0
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8]
-dpth3lp:
- psrlq mm1, ShiftRem // shift last 3 bytes to 1st 3 bytes
- movq mm2, [esi + ebx] // load b=Prior(x)
- punpcklbw mm1, mm0 // Unpack High bytes of a
- movq mm3, [esi+ebx-8] // Prep c=Prior(x-bpp) bytes
- punpcklbw mm2, mm0 // Unpack High bytes of b
- psrlq mm3, ShiftRem // shift last 3 bytes to 1st 3 bytes
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- punpcklbw mm3, mm0 // Unpack High bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
-
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- paddw mm7, mm3
- pxor mm0, mm0
- packuswb mm7, mm1
- movq mm3, [esi + ebx] // load c=Prior(x-bpp)
- pand mm7, ActiveMask
- movq mm2, mm3 // load b=Prior(x) step 1
- paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
- punpcklbw mm3, mm0 // Unpack High bytes of c
- movq [edi + ebx], mm7 // write back updated value
- movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp)
- // Now do Paeth for 2nd set of bytes (3-5)
- psrlq mm2, ShiftBpp // load b=Prior(x) step 2
- punpcklbw mm1, mm0 // Unpack High bytes of a
- pxor mm7, mm7
- punpcklbw mm2, mm0 // Unpack High bytes of b
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- psubw mm5, mm3
- psubw mm4, mm3
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) =
- // pav + pbv = pbv + pav
- movq mm6, mm5
- paddw mm6, mm4
-
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm5 // Create mask pbv bytes < 0
- pcmpgtw mm7, mm4 // Create mask pav bytes < 0
- pand mm0, mm5 // Only pbv bytes < 0 in mm0
- pand mm7, mm4 // Only pav bytes < 0 in mm7
- psubw mm5, mm0
- psubw mm4, mm7
- psubw mm5, mm0
- psubw mm4, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- movq mm2, [esi + ebx] // load b=Prior(x)
- pand mm3, mm7
- pandn mm7, mm0
- pxor mm1, mm1
- paddw mm7, mm3
- pxor mm0, mm0
- packuswb mm7, mm1
- movq mm3, mm2 // load c=Prior(x-bpp) step 1
- pand mm7, ActiveMask
- punpckhbw mm2, mm0 // Unpack High bytes of b
- psllq mm7, ShiftBpp // Shift bytes to 2nd group of 3 bytes
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
- psllq mm3, ShiftBpp // load c=Prior(x-bpp) step 2
- movq [edi + ebx], mm7 // write back updated value
- movq mm1, mm7
- punpckhbw mm3, mm0 // Unpack High bytes of c
- psllq mm1, ShiftBpp // Shift bytes
- // Now mm1 will be used as Raw(x-bpp)
- // Now do Paeth for 3rd, and final, set of bytes (6-7)
- pxor mm7, mm7
- punpckhbw mm1, mm0 // Unpack High bytes of a
- psubw mm4, mm3
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- pxor mm0, mm0
- paddw mm6, mm5
-
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- pandn mm0, mm1
- pandn mm7, mm4
- paddw mm0, mm2
- paddw mm7, mm5
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pand mm3, mm7
- pandn mm7, mm0
- paddw mm7, mm3
- pxor mm1, mm1
- packuswb mm1, mm7
- // Step ebx to next set of 8 bytes and repeat loop til done
- add ebx, 8
- pand mm1, ActiveMaskEnd
- paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
-
- cmp ebx, MMXLength
- pxor mm0, mm0 // pxor does not affect flags
- movq [edi + ebx - 8], mm1 // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- // mm3 ready to be used as Prior(x-bpp) next loop
- jb dpth3lp
- } // end _asm block
- }
- break;
-
- case 6:
- case 7:
- case 5:
- {
- ActiveMask.use = 0x00000000ffffffff;
- ActiveMask2.use = 0xffffffff00000000;
- ShiftBpp.use = bpp << 3; // == bpp * 8
- ShiftRem.use = 64 - ShiftBpp.use;
- _asm
- {
- mov ebx, diff
- mov edi, row
- mov esi, prev_row
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8]
- pxor mm0, mm0
-dpth6lp:
- // Must shift to position Raw(x-bpp) data
- psrlq mm1, ShiftRem
- // Do first set of 4 bytes
- movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
- punpcklbw mm1, mm0 // Unpack Low bytes of a
- movq mm2, [esi + ebx] // load b=Prior(x)
- punpcklbw mm2, mm0 // Unpack Low bytes of b
- // Must shift to position Prior(x-bpp) data
- psrlq mm3, ShiftRem
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- punpcklbw mm3, mm0 // Unpack Low bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- paddw mm7, mm3
- pxor mm0, mm0
- packuswb mm7, mm1
- movq mm3, [esi + ebx - 8] // load c=Prior(x-bpp)
- pand mm7, ActiveMask
- psrlq mm3, ShiftRem
- movq mm2, [esi + ebx] // load b=Prior(x) step 1
- paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
- movq mm6, mm2
- movq [edi + ebx], mm7 // write back updated value
- movq mm1, [edi+ebx-8]
- psllq mm6, ShiftBpp
- movq mm5, mm7
- psrlq mm1, ShiftRem
- por mm3, mm6
- psllq mm5, ShiftBpp
- punpckhbw mm3, mm0 // Unpack High bytes of c
- por mm1, mm5
- // Do second set of 4 bytes
- punpckhbw mm2, mm0 // Unpack High bytes of b
- punpckhbw mm1, mm0 // Unpack High bytes of a
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- pxor mm1, mm1
- paddw mm7, mm3
- pxor mm0, mm0
- // Step ex to next set of 8 bytes and repeat loop til done
- add ebx, 8
- packuswb mm1, mm7
- paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
- cmp ebx, MMXLength
- movq [edi + ebx - 8], mm1 // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- jb dpth6lp
- } // end _asm block
- }
- break;
-
- case 4:
- {
- ActiveMask.use = 0x00000000ffffffff;
- _asm {
- mov ebx, diff
- mov edi, row
- mov esi, prev_row
- pxor mm0, mm0
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8] // Only time should need to read
- // a=Raw(x-bpp) bytes
-dpth4lp:
- // Do first set of 4 bytes
- movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
- punpckhbw mm1, mm0 // Unpack Low bytes of a
- movq mm2, [esi + ebx] // load b=Prior(x)
- punpcklbw mm2, mm0 // Unpack High bytes of b
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- punpckhbw mm3, mm0 // Unpack High bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- paddw mm7, mm3
- pxor mm0, mm0
- packuswb mm7, mm1
- movq mm3, [esi + ebx] // load c=Prior(x-bpp)
- pand mm7, ActiveMask
- movq mm2, mm3 // load b=Prior(x) step 1
- paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
- punpcklbw mm3, mm0 // Unpack High bytes of c
- movq [edi + ebx], mm7 // write back updated value
- movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp)
- // Do second set of 4 bytes
- punpckhbw mm2, mm0 // Unpack Low bytes of b
- punpcklbw mm1, mm0 // Unpack Low bytes of a
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- pxor mm1, mm1
- paddw mm7, mm3
- pxor mm0, mm0
- // Step ex to next set of 8 bytes and repeat loop til done
- add ebx, 8
- packuswb mm1, mm7
- paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
- cmp ebx, MMXLength
- movq [edi + ebx - 8], mm1 // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- jb dpth4lp
- } // end _asm block
- }
- break;
- case 8: // bpp == 8
- {
- ActiveMask.use = 0x00000000ffffffff;
- _asm {
- mov ebx, diff
- mov edi, row
- mov esi, prev_row
- pxor mm0, mm0
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8] // Only time should need to read
- // a=Raw(x-bpp) bytes
-dpth8lp:
- // Do first set of 4 bytes
- movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
- punpcklbw mm1, mm0 // Unpack Low bytes of a
- movq mm2, [esi + ebx] // load b=Prior(x)
- punpcklbw mm2, mm0 // Unpack Low bytes of b
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- punpcklbw mm3, mm0 // Unpack Low bytes of c
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- paddw mm7, mm3
- pxor mm0, mm0
- packuswb mm7, mm1
- movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
- pand mm7, ActiveMask
- movq mm2, [esi + ebx] // load b=Prior(x)
- paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
- punpckhbw mm3, mm0 // Unpack High bytes of c
- movq [edi + ebx], mm7 // write back updated value
- movq mm1, [edi+ebx-8] // read a=Raw(x-bpp) bytes
-
- // Do second set of 4 bytes
- punpckhbw mm2, mm0 // Unpack High bytes of b
- punpckhbw mm1, mm0 // Unpack High bytes of a
- // pav = p - a = (a + b - c) - a = b - c
- movq mm4, mm2
- // pbv = p - b = (a + b - c) - b = a - c
- movq mm5, mm1
- psubw mm4, mm3
- pxor mm7, mm7
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- movq mm6, mm4
- psubw mm5, mm3
- // pa = abs(p-a) = abs(pav)
- // pb = abs(p-b) = abs(pbv)
- // pc = abs(p-c) = abs(pcv)
- pcmpgtw mm0, mm4 // Create mask pav bytes < 0
- paddw mm6, mm5
- pand mm0, mm4 // Only pav bytes < 0 in mm7
- pcmpgtw mm7, mm5 // Create mask pbv bytes < 0
- psubw mm4, mm0
- pand mm7, mm5 // Only pbv bytes < 0 in mm0
- psubw mm4, mm0
- psubw mm5, mm7
- pxor mm0, mm0
- pcmpgtw mm0, mm6 // Create mask pcv bytes < 0
- pand mm0, mm6 // Only pav bytes < 0 in mm7
- psubw mm5, mm7
- psubw mm6, mm0
- // test pa <= pb
- movq mm7, mm4
- psubw mm6, mm0
- pcmpgtw mm7, mm5 // pa > pb?
- movq mm0, mm7
- // use mm7 mask to merge pa & pb
- pand mm5, mm7
- // use mm0 mask copy to merge a & b
- pand mm2, mm0
- pandn mm7, mm4
- pandn mm0, mm1
- paddw mm7, mm5
- paddw mm0, mm2
- // test ((pa <= pb)? pa:pb) <= pc
- pcmpgtw mm7, mm6 // pab > pc?
- pxor mm1, mm1
- pand mm3, mm7
- pandn mm7, mm0
- pxor mm1, mm1
- paddw mm7, mm3
- pxor mm0, mm0
- // Step ex to next set of 8 bytes and repeat loop til done
- add ebx, 8
- packuswb mm1, mm7
- paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
- cmp ebx, MMXLength
- movq [edi + ebx - 8], mm1 // write back updated value
- // mm1 will be used as Raw(x-bpp) next loop
- jb dpth8lp
- } // end _asm block
- }
- break;
-
- case 1: // bpp = 1
- case 2: // bpp = 2
- default: // bpp > 8
- {
- _asm {
- mov ebx, diff
- cmp ebx, FullLength
- jnb dpthdend
- mov edi, row
- mov esi, prev_row
- // Do Paeth decode for remaining bytes
- mov edx, ebx
- xor ecx, ecx // zero ecx before using cl & cx in loop below
- sub edx, bpp // Set edx = ebx - bpp
-dpthdlp:
- xor eax, eax
- // pav = p - a = (a + b - c) - a = b - c
- mov al, [esi + ebx] // load Prior(x) into al
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- sub eax, ecx // subtract Prior(x-bpp)
- mov patemp, eax // Save pav for later use
- xor eax, eax
- // pbv = p - b = (a + b - c) - b = a - c
- mov al, [edi + edx] // load Raw(x-bpp) into al
- sub eax, ecx // subtract Prior(x-bpp)
- mov ecx, eax
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- add eax, patemp // pcv = pav + pbv
- // pc = abs(pcv)
- test eax, 0x80000000
- jz dpthdpca
- neg eax // reverse sign of neg values
-dpthdpca:
- mov pctemp, eax // save pc for later use
- // pb = abs(pbv)
- test ecx, 0x80000000
- jz dpthdpba
- neg ecx // reverse sign of neg values
-dpthdpba:
- mov pbtemp, ecx // save pb for later use
- // pa = abs(pav)
- mov eax, patemp
- test eax, 0x80000000
- jz dpthdpaa
- neg eax // reverse sign of neg values
-dpthdpaa:
- mov patemp, eax // save pa for later use
- // test if pa <= pb
- cmp eax, ecx
- jna dpthdabb
- // pa > pb; now test if pb <= pc
- cmp ecx, pctemp
- jna dpthdbbc
- // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- jmp dpthdpaeth
-dpthdbbc:
- // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
- mov cl, [esi + ebx] // load Prior(x) into cl
- jmp dpthdpaeth
-dpthdabb:
- // pa <= pb; now test if pa <= pc
- cmp eax, pctemp
- jna dpthdabc
- // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- jmp dpthdpaeth
-dpthdabc:
- // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
- mov cl, [edi + edx] // load Raw(x-bpp) into cl
-dpthdpaeth:
- inc ebx
- inc edx
- // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
- add [edi + ebx - 1], cl
- cmp ebx, FullLength
- jb dpthdlp
-dpthdend:
- } // end _asm block
- }
- return; // No need to go further with this one
- } // end switch ( bpp )
- _asm
- {
- // MMX acceleration complete now do clean-up
- // Check if any remaining bytes left to decode
- mov ebx, MMXLength
- cmp ebx, FullLength
- jnb dpthend
- mov edi, row
- mov esi, prev_row
- // Do Paeth decode for remaining bytes
- mov edx, ebx
- xor ecx, ecx // zero ecx before using cl & cx in loop below
- sub edx, bpp // Set edx = ebx - bpp
-dpthlp2:
- xor eax, eax
- // pav = p - a = (a + b - c) - a = b - c
- mov al, [esi + ebx] // load Prior(x) into al
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- sub eax, ecx // subtract Prior(x-bpp)
- mov patemp, eax // Save pav for later use
- xor eax, eax
- // pbv = p - b = (a + b - c) - b = a - c
- mov al, [edi + edx] // load Raw(x-bpp) into al
- sub eax, ecx // subtract Prior(x-bpp)
- mov ecx, eax
- // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
- add eax, patemp // pcv = pav + pbv
- // pc = abs(pcv)
- test eax, 0x80000000
- jz dpthpca2
- neg eax // reverse sign of neg values
-dpthpca2:
- mov pctemp, eax // save pc for later use
- // pb = abs(pbv)
- test ecx, 0x80000000
- jz dpthpba2
- neg ecx // reverse sign of neg values
-dpthpba2:
- mov pbtemp, ecx // save pb for later use
- // pa = abs(pav)
- mov eax, patemp
- test eax, 0x80000000
- jz dpthpaa2
- neg eax // reverse sign of neg values
-dpthpaa2:
- mov patemp, eax // save pa for later use
- // test if pa <= pb
- cmp eax, ecx
- jna dpthabb2
- // pa > pb; now test if pb <= pc
- cmp ecx, pctemp
- jna dpthbbc2
- // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- jmp dpthpaeth2
-dpthbbc2:
- // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
- mov cl, [esi + ebx] // load Prior(x) into cl
- jmp dpthpaeth2
-dpthabb2:
- // pa <= pb; now test if pa <= pc
- cmp eax, pctemp
- jna dpthabc2
- // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
- mov cl, [esi + edx] // load Prior(x-bpp) into cl
- jmp dpthpaeth2
-dpthabc2:
- // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
- mov cl, [edi + edx] // load Raw(x-bpp) into cl
-dpthpaeth2:
- inc ebx
- inc edx
- // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
- add [edi + ebx - 1], cl
- cmp ebx, FullLength
- jb dpthlp2
-dpthend:
- emms // End MMX instructions; prep for possible FP instrs.
- } // end _asm block
-}
-
-// Optimized code for PNG Sub filter decoder
-void /* PRIVATE */
-png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row)
-{
- // These variables are declared
- // here to ensure alignment on 8-byte boundaries.
- union uAll ActiveMask, ShiftBpp, ShiftRem;
-
- //int test;
- int bpp;
- png_uint_32 FullLength;
- png_uint_32 MMXLength;
- int diff;
-
- bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
- FullLength = row_info->rowbytes - bpp; // # of bytes to filter
- _asm {
- mov edi, row
- mov esi, edi // lp = row
- add edi, bpp // rp = row + bpp
- xor eax, eax
- // get # of bytes to alignment
- mov diff, edi // take start of row
- add diff, 0xf // add 7 + 8 to incr past
- // alignment boundary
- xor ebx, ebx
- and diff, 0xfffffff8 // mask to alignment boundary
- sub diff, edi // subtract from start ==> value
- // ebx at alignment
- jz dsubgo
- // fix alignment
-dsublp1:
- mov al, [esi+ebx]
- add [edi+ebx], al
- inc ebx
- cmp ebx, diff
- jb dsublp1
-dsubgo:
- mov ecx, FullLength
- mov edx, ecx
- sub edx, ebx // subtract alignment fix
- and edx, 0x00000007 // calc bytes over mult of 8
- sub ecx, edx // drop over bytes from length
- mov MMXLength, ecx
- } // end _asm block
-
- // Now do the math for the rest of the row
- switch ( bpp )
- {
- case 3:
- {
- ActiveMask.use = 0x0000ffffff000000;
- ShiftBpp.use = 24; // == 3 * 8
- ShiftRem.use = 40; // == 64 - 24
- _asm {
- mov edi, row
- movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group
- mov esi, edi // lp = row
- add edi, bpp // rp = row + bpp
- movq mm6, mm7
- mov ebx, diff
- psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active
- // byte group
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8]
-dsub3lp:
- psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
- // no need for mask; shift clears inactive bytes
- // Add 1st active group
- movq mm0, [edi+ebx]
- paddb mm0, mm1
- // Add 2nd active group
- movq mm1, mm0 // mov updated Raws to mm1
- psllq mm1, ShiftBpp // shift data to position correctly
- pand mm1, mm7 // mask to use only 2nd active group
- paddb mm0, mm1
- // Add 3rd active group
- movq mm1, mm0 // mov updated Raws to mm1
- psllq mm1, ShiftBpp // shift data to position correctly
- pand mm1, mm6 // mask to use only 3rd active group
- add ebx, 8
- paddb mm0, mm1
- cmp ebx, MMXLength
- movq [edi+ebx-8], mm0 // Write updated Raws back to array
- // Prep for doing 1st add at top of loop
- movq mm1, mm0
- jb dsub3lp
- } // end _asm block
- }
- break;
-
- case 1:
- {
- // Placed here just in case this is a duplicate of the
- // non-MMX code for the SUB filter in png_read_filter_row below
- //
- // png_bytep rp;
- // png_bytep lp;
- // png_uint_32 i;
- // bpp = (row_info->pixel_depth + 7) >> 3;
- // for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
- // i < row_info->rowbytes; i++, rp++, lp++)
- // {
- // *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
- // }
- _asm {
- mov ebx, diff
- mov edi, row
- cmp ebx, FullLength
- jnb dsub1end
- mov esi, edi // lp = row
- xor eax, eax
- add edi, bpp // rp = row + bpp
-dsub1lp:
- mov al, [esi+ebx]
- add [edi+ebx], al
- inc ebx
- cmp ebx, FullLength
- jb dsub1lp
-dsub1end:
- } // end _asm block
- }
- return;
-
- case 6:
- case 7:
- case 4:
- case 5:
- {
- ShiftBpp.use = bpp << 3;
- ShiftRem.use = 64 - ShiftBpp.use;
- _asm {
- mov edi, row
- mov ebx, diff
- mov esi, edi // lp = row
- add edi, bpp // rp = row + bpp
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8]
-dsub4lp:
- psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
- // no need for mask; shift clears inactive bytes
- movq mm0, [edi+ebx]
- paddb mm0, mm1
- // Add 2nd active group
- movq mm1, mm0 // mov updated Raws to mm1
- psllq mm1, ShiftBpp // shift data to position correctly
- // there is no need for any mask
- // since shift clears inactive bits/bytes
- add ebx, 8
- paddb mm0, mm1
- cmp ebx, MMXLength
- movq [edi+ebx-8], mm0
- movq mm1, mm0 // Prep for doing 1st add at top of loop
- jb dsub4lp
- } // end _asm block
- }
- break;
-
- case 2:
- {
- ActiveMask.use = 0x00000000ffff0000;
- ShiftBpp.use = 16; // == 2 * 8
- ShiftRem.use = 48; // == 64 - 16
- _asm {
- movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group
- mov ebx, diff
- movq mm6, mm7
- mov edi, row
- psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active
- // byte group
- mov esi, edi // lp = row
- movq mm5, mm6
- add edi, bpp // rp = row + bpp
- psllq mm5, ShiftBpp // Move mask in mm5 to cover 4th active
- // byte group
- // PRIME the pump (load the first Raw(x-bpp) data set
- movq mm1, [edi+ebx-8]
-dsub2lp:
- // Add 1st active group
- psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
- // no need for mask; shift clears inactive
- // bytes
- movq mm0, [edi+ebx]
- paddb mm0, mm1
- // Add 2nd active group
- movq mm1, mm0 // mov updated Raws to mm1
- psllq mm1, ShiftBpp // shift data to position correctly
- pand mm1, mm7 // mask to use only 2nd active group
- paddb mm0, mm1
- // Add 3rd active group
- movq mm1, mm0 // mov updated Raws to mm1
- psllq mm1, ShiftBpp // shift data to position correctly
- pand mm1, mm6 // mask to use only 3rd active group
- paddb mm0, mm1
- // Add 4th active group
- movq mm1, mm0 // mov updated Raws to mm1
- psllq mm1, ShiftBpp // shift data to position correctly
- pand mm1, mm5 // mask to use only 4th active group
- add ebx, 8
- paddb mm0, mm1
- cmp ebx, MMXLength
- movq [edi+ebx-8], mm0 // Write updated Raws back to array
- movq mm1, mm0 // Prep for doing 1st add at top of loop
- jb dsub2lp
- } // end _asm block
- }
- break;
- case 8:
- {
- _asm {
- mov edi, row
- mov ebx, diff
- mov esi, edi // lp = row
- add edi, bpp // rp = row + bpp
- mov ecx, MMXLength
- movq mm7, [edi+ebx-8] // PRIME the pump (load the first
- // Raw(x-bpp) data set
- and ecx, 0x0000003f // calc bytes over mult of 64
-dsub8lp:
- movq mm0, [edi+ebx] // Load Sub(x) for 1st 8 bytes
- paddb mm0, mm7
- movq mm1, [edi+ebx+8] // Load Sub(x) for 2nd 8 bytes
- movq [edi+ebx], mm0 // Write Raw(x) for 1st 8 bytes
- // Now mm0 will be used as Raw(x-bpp) for
- // the 2nd group of 8 bytes. This will be
- // repeated for each group of 8 bytes with
- // the 8th group being used as the Raw(x-bpp)
- // for the 1st group of the next loop.
- paddb mm1, mm0
- movq mm2, [edi+ebx+16] // Load Sub(x) for 3rd 8 bytes
- movq [edi+ebx+8], mm1 // Write Raw(x) for 2nd 8 bytes
- paddb mm2, mm1
- movq mm3, [edi+ebx+24] // Load Sub(x) for 4th 8 bytes
- movq [edi+ebx+16], mm2 // Write Raw(x) for 3rd 8 bytes
- paddb mm3, mm2
- movq mm4, [edi+ebx+32] // Load Sub(x) for 5th 8 bytes
- movq [edi+ebx+24], mm3 // Write Raw(x) for 4th 8 bytes
- paddb mm4, mm3
- movq mm5, [edi+ebx+40] // Load Sub(x) for 6th 8 bytes
- movq [edi+ebx+32], mm4 // Write Raw(x) for 5th 8 bytes
- paddb mm5, mm4
- movq mm6, [edi+ebx+48] // Load Sub(x) for 7th 8 bytes
- movq [edi+ebx+40], mm5 // Write Raw(x) for 6th 8 bytes
- paddb mm6, mm5
- movq mm7, [edi+ebx+56] // Load Sub(x) for 8th 8 bytes
- movq [edi+ebx+48], mm6 // Write Raw(x) for 7th 8 bytes
- add ebx, 64
- paddb mm7, mm6
- cmp ebx, ecx
- movq [edi+ebx-8], mm7 // Write Raw(x) for 8th 8 bytes
- jb dsub8lp
- cmp ebx, MMXLength
- jnb dsub8lt8
-dsub8lpA:
- movq mm0, [edi+ebx]
- add ebx, 8
- paddb mm0, mm7
- cmp ebx, MMXLength
- movq [edi+ebx-8], mm0 // use -8 to offset early add to ebx
- movq mm7, mm0 // Move calculated Raw(x) data to mm1 to
- // be the new Raw(x-bpp) for the next loop
- jb dsub8lpA
-dsub8lt8:
- } // end _asm block
- }
- break;
-
- default: // bpp greater than 8 bytes
- {
- _asm {
- mov ebx, diff
- mov edi, row
- mov esi, edi // lp = row
- add edi, bpp // rp = row + bpp
-dsubAlp:
- movq mm0, [edi+ebx]
- movq mm1, [esi+ebx]
- add ebx, 8
- paddb mm0, mm1
- cmp ebx, MMXLength
- movq [edi+ebx-8], mm0 // mov does not affect flags; -8 to offset
- // add ebx
- jb dsubAlp
- } // end _asm block
- }
- break;
-
- } // end switch ( bpp )
-
- _asm {
- mov ebx, MMXLength
- mov edi, row
- cmp ebx, FullLength
- jnb dsubend
- mov esi, edi // lp = row
- xor eax, eax
- add edi, bpp // rp = row + bpp
-dsublp2:
- mov al, [esi+ebx]
- add [edi+ebx], al
- inc ebx
- cmp ebx, FullLength
- jb dsublp2
-dsubend:
- emms // End MMX instructions; prep for possible FP instrs.
- } // end _asm block
-}
-
-// Optimized code for PNG Up filter decoder
-void /* PRIVATE */
-png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
- png_bytep prev_row)
-{
- png_uint_32 len;
- len = row_info->rowbytes; // # of bytes to filter
- _asm {
- mov edi, row
- // get # of bytes to alignment
- mov ecx, edi
- xor ebx, ebx
- add ecx, 0x7
- xor eax, eax
- and ecx, 0xfffffff8
- mov esi, prev_row
- sub ecx, edi
- jz dupgo
- // fix alignment
-duplp1:
- mov al, [edi+ebx]
- add al, [esi+ebx]
- inc ebx
- cmp ebx, ecx
- mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx
- jb duplp1
-dupgo:
- mov ecx, len
- mov edx, ecx
- sub edx, ebx // subtract alignment fix
- and edx, 0x0000003f // calc bytes over mult of 64
- sub ecx, edx // drop over bytes from length
- // Unrolled loop - use all MMX registers and interleave to reduce
- // number of branch instructions (loops) and reduce partial stalls
-duploop:
- movq mm1, [esi+ebx]
- movq mm0, [edi+ebx]
- movq mm3, [esi+ebx+8]
- paddb mm0, mm1
- movq mm2, [edi+ebx+8]
- movq [edi+ebx], mm0
- paddb mm2, mm3
- movq mm5, [esi+ebx+16]
- movq [edi+ebx+8], mm2
- movq mm4, [edi+ebx+16]
- movq mm7, [esi+ebx+24]
- paddb mm4, mm5
- movq mm6, [edi+ebx+24]
- movq [edi+ebx+16], mm4
- paddb mm6, mm7
- movq mm1, [esi+ebx+32]
- movq [edi+ebx+24], mm6
- movq mm0, [edi+ebx+32]
- movq mm3, [esi+ebx+40]
- paddb mm0, mm1
- movq mm2, [edi+ebx+40]
- movq [edi+ebx+32], mm0
- paddb mm2, mm3
- movq mm5, [esi+ebx+48]
- movq [edi+ebx+40], mm2
- movq mm4, [edi+ebx+48]
- movq mm7, [esi+ebx+56]
- paddb mm4, mm5
- movq mm6, [edi+ebx+56]
- movq [edi+ebx+48], mm4
- add ebx, 64
- paddb mm6, mm7
- cmp ebx, ecx
- movq [edi+ebx-8], mm6 // (+56)movq does not affect flags;
- // -8 to offset add ebx
- jb duploop
-
- cmp edx, 0 // Test for bytes over mult of 64
- jz dupend
-
-
- // 2 lines added by lcreeve at netins.net
- // (mail 11 Jul 98 in png-implement list)
- cmp edx, 8 //test for less than 8 bytes
- jb duplt8
-
-
- add ecx, edx
- and edx, 0x00000007 // calc bytes over mult of 8
- sub ecx, edx // drop over bytes from length
- jz duplt8
- // Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously
-duplpA:
- movq mm1, [esi+ebx]
- movq mm0, [edi+ebx]
- add ebx, 8
- paddb mm0, mm1
- cmp ebx, ecx
- movq [edi+ebx-8], mm0 // movq does not affect flags; -8 to offset add ebx
- jb duplpA
- cmp edx, 0 // Test for bytes over mult of 8
- jz dupend
-duplt8:
- xor eax, eax
- add ecx, edx // move over byte count into counter
- // Loop using x86 registers to update remaining bytes
-duplp2:
- mov al, [edi + ebx]
- add al, [esi + ebx]
- inc ebx
- cmp ebx, ecx
- mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx
- jb duplp2
-dupend:
- // Conversion of filtered row completed
- emms // End MMX instructions; prep for possible FP instrs.
- } // end _asm block
-}
-
-
-// Optimized png_read_filter_row routines
-void /* PRIVATE */
-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
- row, png_bytep prev_row, int filter)
-{
-#ifdef PNG_DEBUG
- char filnm[10];
-#endif
-
- if (mmx_supported == 2) {
-#if !defined(PNG_1_0_X)
- /* this should have happened in png_init_mmx_flags() already */
- png_warning(png_ptr, "asm_flags may not have been initialized");
-#endif
- png_mmx_support();
- }
-
-#ifdef PNG_DEBUG
- png_debug(1, "in png_read_filter_row\n");
- switch (filter)
- {
- case 0: png_snprintf(filnm, 10, "none");
- break;
-#if !defined(PNG_1_0_X)
- case 1: png_snprintf(filnm, 10, "sub-%s",
- (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86");
- break;
- case 2: png_snprintf(filnm, 10, "up-%s",
- (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : "x86");
- break;
- case 3: png_snprintf(filnm, 10, "avg-%s",
- (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : "x86");
- break;
- case 4: png_snprintf(filnm, 10, "Paeth-%s",
- (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86");
- break;
-#else
- case 1: png_snprintf(filnm, 10, "sub");
- break;
- case 2: png_snprintf(filnm, 10, "up");
- break;
- case 3: png_snprintf(filnm, 10, "avg");
- break;
- case 4: png_snprintf(filnm, 10, "Paeth");
- break;
-#endif
- default: png_snprintf(filnm, 10, "unknw");
- break;
- }
- png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm);
- png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth,
- (int)((row_info->pixel_depth + 7) >> 3));
- png_debug1(0,"len=%8d, ", row_info->rowbytes);
-#endif /* PNG_DEBUG */
-
- switch (filter)
- {
- case PNG_FILTER_VALUE_NONE:
- break;
-
- case PNG_FILTER_VALUE_SUB:
- {
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_sub(row_info, row);
- }
- else
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_bytep rp = row + bpp;
- png_bytep lp = row;
-
- for (i = bpp; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
- rp++;
- }
- }
- break;
- }
-
- case PNG_FILTER_VALUE_UP:
- {
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_up(row_info, row, prev_row);
- }
- else
- {
- png_uint_32 i;
- png_uint_32 istop = row_info->rowbytes;
- png_bytep rp = row;
- png_bytep pp = prev_row;
-
- for (i = 0; i < istop; ++i)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
- }
- break;
- }
-
- case PNG_FILTER_VALUE_AVG:
- {
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_avg(row_info, row, prev_row);
- }
- else
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop = row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++) >> 1)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++)
- {
- *rp = (png_byte)(((int)(*rp) +
- ((int)(*pp++ + *lp++) >> 1)) & 0xff);
- rp++;
- }
- }
- break;
- }
-
- case PNG_FILTER_VALUE_PAETH:
- {
-#if !defined(PNG_1_0_X)
- if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) &&
- (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
- (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
-#else
- if (mmx_supported)
-#endif
- {
- png_read_filter_row_mmx_paeth(row_info, row, prev_row);
- }
- else
- {
- png_uint_32 i;
- png_bytep rp = row;
- png_bytep pp = prev_row;
- png_bytep lp = row;
- png_bytep cp = prev_row;
- png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
- png_uint_32 istop=row_info->rowbytes - bpp;
-
- for (i = 0; i < bpp; i++)
- {
- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
- rp++;
- }
-
- for (i = 0; i < istop; i++) // use leftover rp,pp
- {
- int a, b, c, pa, pb, pc, p;
-
- a = *lp++;
- b = *pp++;
- c = *cp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- /*
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- */
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *rp = (png_byte)(((int)(*rp) + p) & 0xff);
- rp++;
- }
- }
- break;
- }
-
- default:
- png_warning(png_ptr, "Ignoring bad row filter type");
- *row=0;
- break;
- }
-}
-
-#endif /* PNG_MMX_CODE_SUPPORTED && PNG_USE_PNGVCRD */
diff --git a/distrib/libpng-1.2.19/pngwio.c b/distrib/libpng-1.2.19/pngwio.c
deleted file mode 100644
index 371a4fa..0000000
--- a/distrib/libpng-1.2.19/pngwio.c
+++ /dev/null
@@ -1,234 +0,0 @@
-
-/* pngwio.c - functions for data output
- *
- * Last changed in libpng 1.2.13 November 13, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- *
- * This file provides a location for all output. Users who need
- * special handling are expected to write functions that have the same
- * arguments as these and perform similar functions, but that possibly
- * use different output methods. Note that you shouldn't change these
- * functions, but rather write replacement functions and then change
- * them at run time with png_set_write_fn(...).
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Write the data to whatever output you are using. The default routine
- writes to a file pointer. Note that this routine sometimes gets called
- with very small lengths, so you should implement some kind of simple
- buffering if you are using unbuffered writes. This should never be asked
- to write more than 64K on a 16 bit machine. */
-
-void /* PRIVATE */
-png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- if (png_ptr->write_data_fn != NULL )
- (*(png_ptr->write_data_fn))(png_ptr, data, length);
- else
- png_error(png_ptr, "Call to NULL write function");
-}
-
-#if !defined(PNG_NO_STDIO)
-/* This is the function that does the actual writing of data. If you are
- not writing to a standard C stream, you should create a replacement
- write_data function and use it at run time with png_set_write_fn(), rather
- than changing the library. */
-#ifndef USE_FAR_KEYWORD
-void PNGAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_uint_32 check;
-
- if(png_ptr == NULL) return;
-#if defined(_WIN32_WCE)
- if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
- check = 0;
-#else
- check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
-#endif
- if (check != length)
- png_error(png_ptr, "Write Error");
-}
-#else
-/* this is the model-independent version. Since the standard I/O library
- can't handle far buffers in the medium and small models, we have to copy
- the data.
-*/
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-void PNGAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- png_uint_32 check;
- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
- png_FILE_p io_ptr;
-
- if(png_ptr == NULL) return;
- /* Check if data really is near. If so, use usual code. */
- near_data = (png_byte *)CVT_PTR_NOCHECK(data);
- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
- if ((png_bytep)near_data == data)
- {
-#if defined(_WIN32_WCE)
- if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
- check = 0;
-#else
- check = fwrite(near_data, 1, length, io_ptr);
-#endif
- }
- else
- {
- png_byte buf[NEAR_BUF_SIZE];
- png_size_t written, remaining, err;
- check = 0;
- remaining = length;
- do
- {
- written = MIN(NEAR_BUF_SIZE, remaining);
- png_memcpy(buf, data, written); /* copy far buffer to near buffer */
-#if defined(_WIN32_WCE)
- if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
- err = 0;
-#else
- err = fwrite(buf, 1, written, io_ptr);
-#endif
- if (err != written)
- break;
- else
- check += err;
- data += written;
- remaining -= written;
- }
- while (remaining != 0);
- }
- if (check != length)
- png_error(png_ptr, "Write Error");
-}
-
-#endif
-#endif
-
-/* This function is called to output any data pending writing (normally
- to disk). After png_flush is called, there should be no data pending
- writing in any buffers. */
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-void /* PRIVATE */
-png_flush(png_structp png_ptr)
-{
- if (png_ptr->output_flush_fn != NULL)
- (*(png_ptr->output_flush_fn))(png_ptr);
-}
-
-#if !defined(PNG_NO_STDIO)
-void PNGAPI
-png_default_flush(png_structp png_ptr)
-{
-#if !defined(_WIN32_WCE)
- png_FILE_p io_ptr;
-#endif
- if(png_ptr == NULL) return;
-#if !defined(_WIN32_WCE)
- io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
- if (io_ptr != NULL)
- fflush(io_ptr);
-#endif
-}
-#endif
-#endif
-
-/* This function allows the application to supply new output functions for
- libpng if standard C streams aren't being used.
-
- This function takes as its arguments:
- png_ptr - pointer to a png output data structure
- io_ptr - pointer to user supplied structure containing info about
- the output functions. May be NULL.
- write_data_fn - pointer to a new output function that takes as its
- arguments a pointer to a png_struct, a pointer to
- data to be written, and a 32-bit unsigned int that is
- the number of bytes to be written. The new write
- function should call png_error(png_ptr, "Error msg")
- to exit and output any fatal error messages.
- flush_data_fn - pointer to a new flush function that takes as its
- arguments a pointer to a png_struct. After a call to
- the flush function, there should be no data in any buffers
- or pending transmission. If the output method doesn't do
- any buffering of ouput, a function prototype must still be
- supplied although it doesn't have to do anything. If
- PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
- time, output_flush_fn will be ignored, although it must be
- supplied for compatibility. */
-void PNGAPI
-png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
- png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
-{
- if(png_ptr == NULL) return;
- png_ptr->io_ptr = io_ptr;
-
-#if !defined(PNG_NO_STDIO)
- if (write_data_fn != NULL)
- png_ptr->write_data_fn = write_data_fn;
- else
- png_ptr->write_data_fn = png_default_write_data;
-#else
- png_ptr->write_data_fn = write_data_fn;
-#endif
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-#if !defined(PNG_NO_STDIO)
- if (output_flush_fn != NULL)
- png_ptr->output_flush_fn = output_flush_fn;
- else
- png_ptr->output_flush_fn = png_default_flush;
-#else
- png_ptr->output_flush_fn = output_flush_fn;
-#endif
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
- /* It is an error to read while writing a png file */
- if (png_ptr->read_data_fn != NULL)
- {
- png_ptr->read_data_fn = NULL;
- png_warning(png_ptr,
- "Attempted to set both read_data_fn and write_data_fn in");
- png_warning(png_ptr,
- "the same structure. Resetting read_data_fn to NULL.");
- }
-}
-
-#if defined(USE_FAR_KEYWORD)
-#if defined(_MSC_VER)
-void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
-{
- void *near_ptr;
- void FAR *far_ptr;
- FP_OFF(near_ptr) = FP_OFF(ptr);
- far_ptr = (void FAR *)near_ptr;
- if(check != 0)
- if(FP_SEG(ptr) != FP_SEG(far_ptr))
- png_error(png_ptr,"segment lost in conversion");
- return(near_ptr);
-}
-# else
-void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
-{
- void *near_ptr;
- void FAR *far_ptr;
- near_ptr = (void FAR *)ptr;
- far_ptr = (void FAR *)near_ptr;
- if(check != 0)
- if(far_ptr != ptr)
- png_error(png_ptr,"segment lost in conversion");
- return(near_ptr);
-}
-# endif
-# endif
-#endif /* PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngwrite.c b/distrib/libpng-1.2.19/pngwrite.c
deleted file mode 100644
index 8d5b98a..0000000
--- a/distrib/libpng-1.2.19/pngwrite.c
+++ /dev/null
@@ -1,1530 +0,0 @@
-
-/* pngwrite.c - general routines to write a PNG file
- *
- * Last changed in libpng 1.2.15 January 5, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-/* get internal access to png.h */
-#define PNG_INTERNAL
-#include "png.h"
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Writes all the PNG information. This is the suggested way to use the
- * library. If you have a new chunk to add, make a function to write it,
- * and put it in the correct location here. If you want the chunk written
- * after the image data, put it in png_write_end(). I strongly encourage
- * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
- * the chunk, as that will keep the code from breaking if you want to just
- * write a plain PNG file. If you have long comments, I suggest writing
- * them in png_write_end(), and compressing them.
- */
-void PNGAPI
-png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_write_info_before_PLTE\n");
- if (png_ptr == NULL || info_ptr == NULL)
- return;
- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
- {
- png_write_sig(png_ptr); /* write PNG signature */
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
- {
- png_warning(png_ptr,"MNG features are not allowed in a PNG datastream");
- png_ptr->mng_features_permitted=0;
- }
-#endif
- /* write IHDR information. */
- png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
- info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
- info_ptr->filter_type,
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- info_ptr->interlace_type);
-#else
- 0);
-#endif
- /* the rest of these check to see if the valid field has the appropriate
- flag set, and if it does, writes the chunk. */
-#if defined(PNG_WRITE_gAMA_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_gAMA)
- {
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- png_write_gAMA(png_ptr, info_ptr->gamma);
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
-# endif
-#endif
- }
-#endif
-#if defined(PNG_WRITE_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
- png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
-#endif
-#if defined(PNG_WRITE_iCCP_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_iCCP)
- png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
- info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
-#endif
-#if defined(PNG_WRITE_sBIT_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sBIT)
- png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
-#endif
-#if defined(PNG_WRITE_cHRM_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_cHRM)
- {
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- png_write_cHRM(png_ptr,
- info_ptr->x_white, info_ptr->y_white,
- info_ptr->x_red, info_ptr->y_red,
- info_ptr->x_green, info_ptr->y_green,
- info_ptr->x_blue, info_ptr->y_blue);
-#else
-# ifdef PNG_FIXED_POINT_SUPPORTED
- png_write_cHRM_fixed(png_ptr,
- info_ptr->int_x_white, info_ptr->int_y_white,
- info_ptr->int_x_red, info_ptr->int_y_red,
- info_ptr->int_x_green, info_ptr->int_y_green,
- info_ptr->int_x_blue, info_ptr->int_y_blue);
-# endif
-#endif
- }
-#endif
-#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
- if (info_ptr->unknown_chunks_num)
- {
- png_unknown_chunk *up;
-
- png_debug(5, "writing extra chunks\n");
-
- for (up = info_ptr->unknown_chunks;
- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
- up++)
- {
- int keep=png_handle_as_unknown(png_ptr, up->name);
- if (keep != PNG_HANDLE_CHUNK_NEVER &&
- up->location && !(up->location & PNG_HAVE_PLTE) &&
- !(up->location & PNG_HAVE_IDAT) &&
- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
- {
- png_write_chunk(png_ptr, up->name, up->data, up->size);
- }
- }
- }
-#endif
- png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
- }
-}
-
-void PNGAPI
-png_write_info(png_structp png_ptr, png_infop info_ptr)
-{
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
- int i;
-#endif
-
- png_debug(1, "in png_write_info\n");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- png_write_info_before_PLTE(png_ptr, info_ptr);
-
- if (info_ptr->valid & PNG_INFO_PLTE)
- png_write_PLTE(png_ptr, info_ptr->palette,
- (png_uint_32)info_ptr->num_palette);
- else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- png_error(png_ptr, "Valid palette required for paletted images");
-
-#if defined(PNG_WRITE_tRNS_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_tRNS)
- {
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel (in tRNS) */
- if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
- info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- int j;
- for (j=0; j<(int)info_ptr->num_trans; j++)
- info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
- }
-#endif
- png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
- info_ptr->num_trans, info_ptr->color_type);
- }
-#endif
-#if defined(PNG_WRITE_bKGD_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_bKGD)
- png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
-#endif
-#if defined(PNG_WRITE_hIST_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_hIST)
- png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
-#endif
-#if defined(PNG_WRITE_oFFs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_oFFs)
- png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
- info_ptr->offset_unit_type);
-#endif
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pCAL)
- png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
- info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
- info_ptr->pcal_units, info_ptr->pcal_params);
-#endif
-#if defined(PNG_WRITE_sCAL_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sCAL)
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
- png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
- info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
- png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
- info_ptr->scal_s_width, info_ptr->scal_s_height);
-#else
- png_warning(png_ptr,
- "png_write_sCAL not supported; sCAL chunk not written.");
-#endif
-#endif
-#endif
-#if defined(PNG_WRITE_pHYs_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_pHYs)
- png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
- info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
-#endif
-#if defined(PNG_WRITE_tIME_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_tIME)
- {
- png_write_tIME(png_ptr, &(info_ptr->mod_time));
- png_ptr->mode |= PNG_WROTE_tIME;
- }
-#endif
-#if defined(PNG_WRITE_sPLT_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sPLT)
- for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
- png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
-#endif
-#if defined(PNG_WRITE_TEXT_SUPPORTED)
- /* Check to see if we need to write text chunks */
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_debug2(2, "Writing header text chunk %d, type %d\n", i,
- info_ptr->text[i].compression);
- /* an internationalized chunk? */
- if (info_ptr->text[i].compression > 0)
- {
-#if defined(PNG_WRITE_iTXt_SUPPORTED)
- /* write international chunk */
- png_write_iTXt(png_ptr,
- info_ptr->text[i].compression,
- info_ptr->text[i].key,
- info_ptr->text[i].lang,
- info_ptr->text[i].lang_key,
- info_ptr->text[i].text);
-#else
- png_warning(png_ptr, "Unable to write international text");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- /* If we want a compressed text chunk */
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
- {
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write compressed chunk */
- png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, 0,
- info_ptr->text[i].compression);
-#else
- png_warning(png_ptr, "Unable to write compressed text");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
- }
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- {
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write uncompressed chunk */
- png_write_tEXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text,
- 0);
-#else
- png_warning(png_ptr, "Unable to write uncompressed text");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- }
-#endif
-#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
- if (info_ptr->unknown_chunks_num)
- {
- png_unknown_chunk *up;
-
- png_debug(5, "writing extra chunks\n");
-
- for (up = info_ptr->unknown_chunks;
- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
- up++)
- {
- int keep=png_handle_as_unknown(png_ptr, up->name);
- if (keep != PNG_HANDLE_CHUNK_NEVER &&
- up->location && (up->location & PNG_HAVE_PLTE) &&
- !(up->location & PNG_HAVE_IDAT) &&
- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
- {
- png_write_chunk(png_ptr, up->name, up->data, up->size);
- }
- }
- }
-#endif
-}
-
-/* Writes the end of the PNG file. If you don't want to write comments or
- * time information, you can pass NULL for info. If you already wrote these
- * in png_write_info(), do not write them again here. If you have long
- * comments, I suggest writing them here, and compressing them.
- */
-void PNGAPI
-png_write_end(png_structp png_ptr, png_infop info_ptr)
-{
- png_debug(1, "in png_write_end\n");
- if (png_ptr == NULL)
- return;
- if (!(png_ptr->mode & PNG_HAVE_IDAT))
- png_error(png_ptr, "No IDATs written into file");
-
- /* see if user wants us to write information chunks */
- if (info_ptr != NULL)
- {
-#if defined(PNG_WRITE_TEXT_SUPPORTED)
- int i; /* local index variable */
-#endif
-#if defined(PNG_WRITE_tIME_SUPPORTED)
- /* check to see if user has supplied a time chunk */
- if ((info_ptr->valid & PNG_INFO_tIME) &&
- !(png_ptr->mode & PNG_WROTE_tIME))
- png_write_tIME(png_ptr, &(info_ptr->mod_time));
-#endif
-#if defined(PNG_WRITE_TEXT_SUPPORTED)
- /* loop through comment chunks */
- for (i = 0; i < info_ptr->num_text; i++)
- {
- png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
- info_ptr->text[i].compression);
- /* an internationalized chunk? */
- if (info_ptr->text[i].compression > 0)
- {
-#if defined(PNG_WRITE_iTXt_SUPPORTED)
- /* write international chunk */
- png_write_iTXt(png_ptr,
- info_ptr->text[i].compression,
- info_ptr->text[i].key,
- info_ptr->text[i].lang,
- info_ptr->text[i].lang_key,
- info_ptr->text[i].text);
-#else
- png_warning(png_ptr, "Unable to write international text");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
- {
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
- /* write compressed chunk */
- png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, 0,
- info_ptr->text[i].compression);
-#else
- png_warning(png_ptr, "Unable to write compressed text");
-#endif
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
- }
- else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- {
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
- /* write uncompressed chunk */
- png_write_tEXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, 0);
-#else
- png_warning(png_ptr, "Unable to write uncompressed text");
-#endif
-
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- }
- }
-#endif
-#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
- if (info_ptr->unknown_chunks_num)
- {
- png_unknown_chunk *up;
-
- png_debug(5, "writing extra chunks\n");
-
- for (up = info_ptr->unknown_chunks;
- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
- up++)
- {
- int keep=png_handle_as_unknown(png_ptr, up->name);
- if (keep != PNG_HANDLE_CHUNK_NEVER &&
- up->location && (up->location & PNG_AFTER_IDAT) &&
- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
- {
- png_write_chunk(png_ptr, up->name, up->data, up->size);
- }
- }
- }
-#endif
- }
-
- png_ptr->mode |= PNG_AFTER_IDAT;
-
- /* write end of PNG file */
- png_write_IEND(png_ptr);
-}
-
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-#if !defined(_WIN32_WCE)
-/* "time.h" functions are not supported on WindowsCE */
-void PNGAPI
-png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
-{
- png_debug(1, "in png_convert_from_struct_tm\n");
- ptime->year = (png_uint_16)(1900 + ttime->tm_year);
- ptime->month = (png_byte)(ttime->tm_mon + 1);
- ptime->day = (png_byte)ttime->tm_mday;
- ptime->hour = (png_byte)ttime->tm_hour;
- ptime->minute = (png_byte)ttime->tm_min;
- ptime->second = (png_byte)ttime->tm_sec;
-}
-
-void PNGAPI
-png_convert_from_time_t(png_timep ptime, time_t ttime)
-{
- struct tm *tbuf;
-
- png_debug(1, "in png_convert_from_time_t\n");
- tbuf = gmtime(&ttime);
- png_convert_from_struct_tm(ptime, tbuf);
-}
-#endif
-#endif
-
-/* Initialize png_ptr structure, and allocate any memory needed */
-png_structp PNGAPI
-png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn)
-{
-#ifdef PNG_USER_MEM_SUPPORTED
- return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
-}
-
-/* Alternate initialize png_ptr structure, and allocate any memory needed */
-png_structp PNGAPI
-png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
-{
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_structp png_ptr;
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
- jmp_buf jmpbuf;
-#endif
-#endif
- int i;
- png_debug(1, "in png_create_write_struct\n");
-#ifdef PNG_USER_MEM_SUPPORTED
- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
- (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
-#else
- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
-#endif /* PNG_USER_MEM_SUPPORTED */
- if (png_ptr == NULL)
- return (NULL);
-
-#if !defined(PNG_1_0_X)
-#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
-#ifdef PNG_MMX_CODE_SUPPORTED
- png_init_mmx_flags(png_ptr); /* 1.2.0 addition */
-#endif
-#endif
-#endif /* PNG_1_0_X */
-
- /* added at libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
-#else
- if (setjmp(png_ptr->jmpbuf))
-#endif
- {
- png_free(png_ptr, png_ptr->zbuf);
- png_ptr->zbuf=NULL;
- png_destroy_struct(png_ptr);
- return (NULL);
- }
-#ifdef USE_FAR_KEYWORD
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
-#endif
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
-
- i=0;
- do
- {
- if(user_png_ver[i] != png_libpng_ver[i])
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- } while (png_libpng_ver[i++]);
-
- if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
- {
- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
- * we must recompile any applications that use any older library version.
- * For versions after libpng 1.0, we will be compatible, so we need
- * only check the first digit.
- */
- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
- (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
- (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[80];
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
-#endif
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
-#endif
- png_error(png_ptr,
- "Incompatible libpng version in application and library");
- }
- }
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
-
- png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
- png_flush_ptr_NULL);
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
- 1, png_doublep_NULL, png_doublep_NULL);
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-/* Applications that neglect to set up their own setjmp() and then encounter
- a png_error() will longjmp here. Since the jmpbuf is then meaningless we
- abort instead of returning. */
-#ifdef USE_FAR_KEYWORD
- if (setjmp(jmpbuf))
- PNG_ABORT();
- png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
-#else
- if (setjmp(png_ptr->jmpbuf))
- PNG_ABORT();
-#endif
-#endif
- return (png_ptr);
-}
-
-/* Initialize png_ptr structure, and allocate any memory needed */
-#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
-/* Deprecated. */
-#undef png_write_init
-void PNGAPI
-png_write_init(png_structp png_ptr)
-{
- /* We only come here via pre-1.0.7-compiled applications */
- png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
-}
-
-void PNGAPI
-png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size, png_size_t png_info_size)
-{
- /* We only come here via pre-1.0.12-compiled applications */
- if(png_ptr == NULL) return;
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- if(png_sizeof(png_struct) > png_struct_size ||
- png_sizeof(png_info) > png_info_size)
- {
- char msg[80];
- png_ptr->warning_fn=NULL;
- if (user_png_ver)
- {
- png_snprintf(msg, 80,
- "Application was compiled with png.h from libpng-%.20s",
- user_png_ver);
- png_warning(png_ptr, msg);
- }
- png_snprintf(msg, 80,
- "Application is running with png.c from libpng-%.20s",
- png_libpng_ver);
- png_warning(png_ptr, msg);
- }
-#endif
- if(png_sizeof(png_struct) > png_struct_size)
- {
- png_ptr->error_fn=NULL;
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
-#endif
- png_error(png_ptr,
- "The png struct allocated by the application for writing is too small.");
- }
- if(png_sizeof(png_info) > png_info_size)
- {
- png_ptr->error_fn=NULL;
-#ifdef PNG_ERROR_NUMBERS_SUPPORTED
- png_ptr->flags=0;
-#endif
- png_error(png_ptr,
- "The info struct allocated by the application for writing is too small.");
- }
- png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
-}
-#endif /* PNG_1_0_X || PNG_1_2_X */
-
-
-void PNGAPI
-png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
- png_size_t png_struct_size)
-{
- png_structp png_ptr=*ptr_ptr;
-#ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp; /* to save current jump buffer */
-#endif
-
- int i = 0;
-
- if (png_ptr == NULL)
- return;
-
- do
- {
- if (user_png_ver[i] != png_libpng_ver[i])
- {
-#ifdef PNG_LEGACY_SUPPORTED
- png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
-#else
- png_ptr->warning_fn=NULL;
- png_warning(png_ptr,
- "Application uses deprecated png_write_init() and should be recompiled.");
- break;
-#endif
- }
- } while (png_libpng_ver[i++]);
-
- png_debug(1, "in png_write_init_3\n");
-
-#ifdef PNG_SETJMP_SUPPORTED
- /* save jump buffer and error functions */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
-#endif
-
- if (png_sizeof(png_struct) > png_struct_size)
- {
- png_destroy_struct(png_ptr);
- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
- *ptr_ptr = png_ptr;
- }
-
- /* reset all variables to 0 */
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- /* added at libpng-1.2.6 */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
- png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
-#endif
-
-#if !defined(PNG_1_0_X)
-#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
-#ifdef PNG_MMX_CODE_SUPPORTED
- png_init_mmx_flags(png_ptr); /* 1.2.0 addition */
-#endif
-#endif
-#endif /* PNG_1_0_X */
-
-#ifdef PNG_SETJMP_SUPPORTED
- /* restore jump buffer */
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
-#endif
-
- png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
- png_flush_ptr_NULL);
-
- /* initialize zbuf - compression buffer */
- png_ptr->zbuf_size = PNG_ZBUF_SIZE;
- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
- 1, png_doublep_NULL, png_doublep_NULL);
-#endif
-}
-
-/* Write a few rows of image data. If the image is interlaced,
- * either you will have to write the 7 sub images, or, if you
- * have called png_set_interlace_handling(), you will have to
- * "write" the image seven times.
- */
-void PNGAPI
-png_write_rows(png_structp png_ptr, png_bytepp row,
- png_uint_32 num_rows)
-{
- png_uint_32 i; /* row counter */
- png_bytepp rp; /* row pointer */
-
- png_debug(1, "in png_write_rows\n");
-
- if (png_ptr == NULL)
- return;
-
- /* loop through the rows */
- for (i = 0, rp = row; i < num_rows; i++, rp++)
- {
- png_write_row(png_ptr, *rp);
- }
-}
-
-/* Write the image. You only need to call this function once, even
- * if you are writing an interlaced image.
- */
-void PNGAPI
-png_write_image(png_structp png_ptr, png_bytepp image)
-{
- png_uint_32 i; /* row index */
- int pass, num_pass; /* pass variables */
- png_bytepp rp; /* points to current row */
-
- if (png_ptr == NULL)
- return;
-
- png_debug(1, "in png_write_image\n");
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* intialize interlace handling. If image is not interlaced,
- this will set pass to 1 */
- num_pass = png_set_interlace_handling(png_ptr);
-#else
- num_pass = 1;
-#endif
- /* loop through passes */
- for (pass = 0; pass < num_pass; pass++)
- {
- /* loop through image */
- for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
- {
- png_write_row(png_ptr, *rp);
- }
- }
-}
-
-/* called by user to write a row of image data */
-void PNGAPI
-png_write_row(png_structp png_ptr, png_bytep row)
-{
- if (png_ptr == NULL)
- return;
- png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
- png_ptr->row_number, png_ptr->pass);
-
- /* initialize transformations and other stuff if first time */
- if (png_ptr->row_number == 0 && png_ptr->pass == 0)
- {
- /* make sure we wrote the header info */
- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
- png_error(png_ptr,
- "png_write_info was never called before png_write_row.");
-
- /* check for transforms that have been set but were defined out */
-#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
-#endif
-#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
-#endif
-
- png_write_start_row(png_ptr);
- }
-
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* if interlaced and not interested in row, return */
- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
- {
- switch (png_ptr->pass)
- {
- case 0:
- if (png_ptr->row_number & 0x07)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 1:
- if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 2:
- if ((png_ptr->row_number & 0x07) != 4)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 3:
- if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 4:
- if ((png_ptr->row_number & 0x03) != 2)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 5:
- if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- case 6:
- if (!(png_ptr->row_number & 0x01))
- {
- png_write_finish_row(png_ptr);
- return;
- }
- break;
- }
- }
-#endif
-
- /* set up row info for transformations */
- png_ptr->row_info.color_type = png_ptr->color_type;
- png_ptr->row_info.width = png_ptr->usr_width;
- png_ptr->row_info.channels = png_ptr->usr_channels;
- png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
- png_ptr->row_info.channels);
-
- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
- png_ptr->row_info.width);
-
- png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
- png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
- png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
- png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
- png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
- png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
-
- /* Copy user's row into buffer, leaving room for filter byte. */
- png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
- png_ptr->row_info.rowbytes);
-
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
- /* handle interlacing */
- if (png_ptr->interlaced && png_ptr->pass < 6 &&
- (png_ptr->transformations & PNG_INTERLACE))
- {
- png_do_write_interlace(&(png_ptr->row_info),
- png_ptr->row_buf + 1, png_ptr->pass);
- /* this should always get caught above, but still ... */
- if (!(png_ptr->row_info.width))
- {
- png_write_finish_row(png_ptr);
- return;
- }
- }
-#endif
-
- /* handle other transformations */
- if (png_ptr->transformations)
- png_do_write_transformations(png_ptr);
-
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- /* Write filter_method 64 (intrapixel differencing) only if
- * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
- * 2. Libpng did not write a PNG signature (this filter_method is only
- * used in PNG datastreams that are embedded in MNG datastreams) and
- * 3. The application called png_permit_mng_features with a mask that
- * included PNG_FLAG_MNG_FILTER_64 and
- * 4. The filter_method is 64 and
- * 5. The color_type is RGB or RGBA
- */
- if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
- {
- /* Intrapixel differencing */
- png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
- }
-#endif
-
- /* Find a filter if necessary, filter the row and write it out. */
- png_write_find_filter(png_ptr, &(png_ptr->row_info));
-
- if (png_ptr->write_row_fn != NULL)
- (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
-}
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
-/* Set the automatic flush interval or 0 to turn flushing off */
-void PNGAPI
-png_set_flush(png_structp png_ptr, int nrows)
-{
- png_debug(1, "in png_set_flush\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
-}
-
-/* flush the current output buffers now */
-void PNGAPI
-png_write_flush(png_structp png_ptr)
-{
- int wrote_IDAT;
-
- png_debug(1, "in png_write_flush\n");
- if (png_ptr == NULL)
- return;
- /* We have already written out all of the data */
- if (png_ptr->row_number >= png_ptr->num_rows)
- return;
-
- do
- {
- int ret;
-
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
- wrote_IDAT = 0;
-
- /* check for compression errors */
- if (ret != Z_OK)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- if (!(png_ptr->zstream.avail_out))
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- wrote_IDAT = 1;
- }
- } while(wrote_IDAT == 1);
-
- /* If there is any data left to be output, write it into a new IDAT */
- if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- png_ptr->flush_rows = 0;
- png_flush(png_ptr);
-}
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-
-/* free all memory used by the write */
-void PNGAPI
-png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
-{
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn = NULL;
- png_voidp mem_ptr = NULL;
-#endif
-
- png_debug(1, "in png_destroy_write_struct\n");
- if (png_ptr_ptr != NULL)
- {
- png_ptr = *png_ptr_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
- mem_ptr = png_ptr->mem_ptr;
-#endif
- }
-
- if (info_ptr_ptr != NULL)
- info_ptr = *info_ptr_ptr;
-
- if (info_ptr != NULL)
- {
- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->num_chunk_list)
- {
- png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list=NULL;
- png_ptr->num_chunk_list=0;
- }
-#endif
-
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
-#else
- png_destroy_struct((png_voidp)info_ptr);
-#endif
- *info_ptr_ptr = NULL;
- }
-
- if (png_ptr != NULL)
- {
- png_write_destroy(png_ptr);
-#ifdef PNG_USER_MEM_SUPPORTED
- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
- (png_voidp)mem_ptr);
-#else
- png_destroy_struct((png_voidp)png_ptr);
-#endif
- *png_ptr_ptr = NULL;
- }
-}
-
-
-/* Free any memory used in png_ptr struct (old method) */
-void /* PRIVATE */
-png_write_destroy(png_structp png_ptr)
-{
-#ifdef PNG_SETJMP_SUPPORTED
- jmp_buf tmp_jmp; /* save jump buffer */
-#endif
- png_error_ptr error_fn;
- png_error_ptr warning_fn;
- png_voidp error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_free_ptr free_fn;
-#endif
-
- png_debug(1, "in png_write_destroy\n");
- /* free any memory zlib uses */
- deflateEnd(&png_ptr->zstream);
-
- /* free our memory. png_free checks NULL for us. */
- png_free(png_ptr, png_ptr->zbuf);
- png_free(png_ptr, png_ptr->row_buf);
- png_free(png_ptr, png_ptr->prev_row);
- png_free(png_ptr, png_ptr->sub_row);
- png_free(png_ptr, png_ptr->up_row);
- png_free(png_ptr, png_ptr->avg_row);
- png_free(png_ptr, png_ptr->paeth_row);
-
-#if defined(PNG_TIME_RFC1123_SUPPORTED)
- png_free(png_ptr, png_ptr->time_buffer);
-#endif
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- png_free(png_ptr, png_ptr->prev_filters);
- png_free(png_ptr, png_ptr->filter_weights);
- png_free(png_ptr, png_ptr->inv_filter_weights);
- png_free(png_ptr, png_ptr->filter_costs);
- png_free(png_ptr, png_ptr->inv_filter_costs);
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
- /* reset structure */
- png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
-#endif
-
- error_fn = png_ptr->error_fn;
- warning_fn = png_ptr->warning_fn;
- error_ptr = png_ptr->error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- free_fn = png_ptr->free_fn;
-#endif
-
- png_memset(png_ptr, 0, png_sizeof (png_struct));
-
- png_ptr->error_fn = error_fn;
- png_ptr->warning_fn = warning_fn;
- png_ptr->error_ptr = error_ptr;
-#ifdef PNG_USER_MEM_SUPPORTED
- png_ptr->free_fn = free_fn;
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
- png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
-#endif
-}
-
-/* Allow the application to select one or more row filters to use. */
-void PNGAPI
-png_set_filter(png_structp png_ptr, int method, int filters)
-{
- png_debug(1, "in png_set_filter\n");
- if (png_ptr == NULL)
- return;
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- (method == PNG_INTRAPIXEL_DIFFERENCING))
- method = PNG_FILTER_TYPE_BASE;
-#endif
- if (method == PNG_FILTER_TYPE_BASE)
- {
- switch (filters & (PNG_ALL_FILTERS | 0x07))
- {
-#ifndef PNG_NO_WRITE_FILTER
- case 5:
- case 6:
- case 7: png_warning(png_ptr, "Unknown row filter for method 0");
-#endif /* PNG_NO_WRITE_FILTER */
- case PNG_FILTER_VALUE_NONE:
- png_ptr->do_filter=PNG_FILTER_NONE; break;
-#ifndef PNG_NO_WRITE_FILTER
- case PNG_FILTER_VALUE_SUB:
- png_ptr->do_filter=PNG_FILTER_SUB; break;
- case PNG_FILTER_VALUE_UP:
- png_ptr->do_filter=PNG_FILTER_UP; break;
- case PNG_FILTER_VALUE_AVG:
- png_ptr->do_filter=PNG_FILTER_AVG; break;
- case PNG_FILTER_VALUE_PAETH:
- png_ptr->do_filter=PNG_FILTER_PAETH; break;
- default: png_ptr->do_filter = (png_byte)filters; break;
-#else
- default: png_warning(png_ptr, "Unknown row filter for method 0");
-#endif /* PNG_NO_WRITE_FILTER */
- }
-
- /* If we have allocated the row_buf, this means we have already started
- * with the image and we should have allocated all of the filter buffers
- * that have been selected. If prev_row isn't already allocated, then
- * it is too late to start using the filters that need it, since we
- * will be missing the data in the previous row. If an application
- * wants to start and stop using particular filters during compression,
- * it should start out with all of the filters, and then add and
- * remove them after the start of compression.
- */
- if (png_ptr->row_buf != NULL)
- {
-#ifndef PNG_NO_WRITE_FILTER
- if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Up filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_UP;
- }
- else
- {
- png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Average filter after starting");
- png_ptr->do_filter &= ~PNG_FILTER_AVG;
- }
- else
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
- png_ptr->paeth_row == NULL)
- {
- if (png_ptr->prev_row == NULL)
- {
- png_warning(png_ptr, "Can't add Paeth filter after starting");
- png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
- }
- else
- {
- png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
- }
-
- if (png_ptr->do_filter == PNG_NO_FILTERS)
-#endif /* PNG_NO_WRITE_FILTER */
- png_ptr->do_filter = PNG_FILTER_NONE;
- }
- }
- else
- png_error(png_ptr, "Unknown custom filter method");
-}
-
-/* This allows us to influence the way in which libpng chooses the "best"
- * filter for the current scanline. While the "minimum-sum-of-absolute-
- * differences metric is relatively fast and effective, there is some
- * question as to whether it can be improved upon by trying to keep the
- * filtered data going to zlib more consistent, hopefully resulting in
- * better compression.
- */
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
-void PNGAPI
-png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
- int num_weights, png_doublep filter_weights,
- png_doublep filter_costs)
-{
- int i;
-
- png_debug(1, "in png_set_filter_heuristics\n");
- if (png_ptr == NULL)
- return;
- if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
- {
- png_warning(png_ptr, "Unknown filter heuristic method");
- return;
- }
-
- if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
- {
- heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
- }
-
- if (num_weights < 0 || filter_weights == NULL ||
- heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
- {
- num_weights = 0;
- }
-
- png_ptr->num_prev_filters = (png_byte)num_weights;
- png_ptr->heuristic_method = (png_byte)heuristic_method;
-
- if (num_weights > 0)
- {
- if (png_ptr->prev_filters == NULL)
- {
- png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_byte) * num_weights));
-
- /* To make sure that the weighting starts out fairly */
- for (i = 0; i < num_weights; i++)
- {
- png_ptr->prev_filters[i] = 255;
- }
- }
-
- if (png_ptr->filter_weights == NULL)
- {
- png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
-
- png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * num_weights));
- for (i = 0; i < num_weights; i++)
- {
- png_ptr->inv_filter_weights[i] =
- png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
- }
- }
-
- for (i = 0; i < num_weights; i++)
- {
- if (filter_weights[i] < 0.0)
- {
- png_ptr->inv_filter_weights[i] =
- png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
- }
- else
- {
- png_ptr->inv_filter_weights[i] =
- (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
- png_ptr->filter_weights[i] =
- (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
- }
- }
- }
-
- /* If, in the future, there are other filter methods, this would
- * need to be based on png_ptr->filter.
- */
- if (png_ptr->filter_costs == NULL)
- {
- png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
- png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
-
- for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
- {
- png_ptr->inv_filter_costs[i] =
- png_ptr->filter_costs[i] = PNG_COST_FACTOR;
- }
- }
-
- /* Here is where we set the relative costs of the different filters. We
- * should take the desired compression level into account when setting
- * the costs, so that Paeth, for instance, has a high relative cost at low
- * compression levels, while it has a lower relative cost at higher
- * compression settings. The filter types are in order of increasing
- * relative cost, so it would be possible to do this with an algorithm.
- */
- for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
- {
- if (filter_costs == NULL || filter_costs[i] < 0.0)
- {
- png_ptr->inv_filter_costs[i] =
- png_ptr->filter_costs[i] = PNG_COST_FACTOR;
- }
- else if (filter_costs[i] >= 1.0)
- {
- png_ptr->inv_filter_costs[i] =
- (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
- png_ptr->filter_costs[i] =
- (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
- }
- }
-}
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-
-void PNGAPI
-png_set_compression_level(png_structp png_ptr, int level)
-{
- png_debug(1, "in png_set_compression_level\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
- png_ptr->zlib_level = level;
-}
-
-void PNGAPI
-png_set_compression_mem_level(png_structp png_ptr, int mem_level)
-{
- png_debug(1, "in png_set_compression_mem_level\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
- png_ptr->zlib_mem_level = mem_level;
-}
-
-void PNGAPI
-png_set_compression_strategy(png_structp png_ptr, int strategy)
-{
- png_debug(1, "in png_set_compression_strategy\n");
- if (png_ptr == NULL)
- return;
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
- png_ptr->zlib_strategy = strategy;
-}
-
-void PNGAPI
-png_set_compression_window_bits(png_structp png_ptr, int window_bits)
-{
- if (png_ptr == NULL)
- return;
- if (window_bits > 15)
- png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
- else if (window_bits < 8)
- png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
-#ifndef WBITS_8_OK
- /* avoid libpng bug with 256-byte windows */
- if (window_bits == 8)
- {
- png_warning(png_ptr, "Compression window is being reset to 512");
- window_bits=9;
- }
-#endif
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
- png_ptr->zlib_window_bits = window_bits;
-}
-
-void PNGAPI
-png_set_compression_method(png_structp png_ptr, int method)
-{
- png_debug(1, "in png_set_compression_method\n");
- if (png_ptr == NULL)
- return;
- if (method != 8)
- png_warning(png_ptr, "Only compression method 8 is supported by PNG");
- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
- png_ptr->zlib_method = method;
-}
-
-void PNGAPI
-png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
-{
- if (png_ptr == NULL)
- return;
- png_ptr->write_row_fn = write_row_fn;
-}
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-void PNGAPI
-png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
- write_user_transform_fn)
-{
- png_debug(1, "in png_set_write_user_transform_fn\n");
- if (png_ptr == NULL)
- return;
- png_ptr->transformations |= PNG_USER_TRANSFORM;
- png_ptr->write_user_transform_fn = write_user_transform_fn;
-}
-#endif
-
-
-#if defined(PNG_INFO_IMAGE_SUPPORTED)
-void PNGAPI
-png_write_png(png_structp png_ptr, png_infop info_ptr,
- int transforms, voidp params)
-{
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- /* invert the alpha channel from opacity to transparency */
- if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
- png_set_invert_alpha(png_ptr);
-#endif
-
- /* Write the file header information. */
- png_write_info(png_ptr, info_ptr);
-
- /* ------ these transformations don't touch the info structure ------- */
-
-#if defined(PNG_WRITE_INVERT_SUPPORTED)
- /* invert monochrome pixels */
- if (transforms & PNG_TRANSFORM_INVERT_MONO)
- png_set_invert_mono(png_ptr);
-#endif
-
-#if defined(PNG_WRITE_SHIFT_SUPPORTED)
- /* Shift the pixels up to a legal bit depth and fill in
- * as appropriate to correctly scale the image.
- */
- if ((transforms & PNG_TRANSFORM_SHIFT)
- && (info_ptr->valid & PNG_INFO_sBIT))
- png_set_shift(png_ptr, &info_ptr->sig_bit);
-#endif
-
-#if defined(PNG_WRITE_PACK_SUPPORTED)
- /* pack pixels into bytes */
- if (transforms & PNG_TRANSFORM_PACKING)
- png_set_packing(png_ptr);
-#endif
-
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- /* swap location of alpha bytes from ARGB to RGBA */
- if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
- png_set_swap_alpha(png_ptr);
-#endif
-
-#if defined(PNG_WRITE_FILLER_SUPPORTED)
- /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
- * RGB (4 channels -> 3 channels). The second parameter is not used.
- */
- if (transforms & PNG_TRANSFORM_STRIP_FILLER)
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-#endif
-
-#if defined(PNG_WRITE_BGR_SUPPORTED)
- /* flip BGR pixels to RGB */
- if (transforms & PNG_TRANSFORM_BGR)
- png_set_bgr(png_ptr);
-#endif
-
-#if defined(PNG_WRITE_SWAP_SUPPORTED)
- /* swap bytes of 16-bit files to most significant byte first */
- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
- png_set_swap(png_ptr);
-#endif
-
-#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- /* swap bits of 1, 2, 4 bit packed pixel formats */
- if (transforms & PNG_TRANSFORM_PACKSWAP)
- png_set_packswap(png_ptr);
-#endif
-
- /* ----------------------- end of transformations ------------------- */
-
- /* write the bits */
- if (info_ptr->valid & PNG_INFO_IDAT)
- png_write_image(png_ptr, info_ptr->row_pointers);
-
- /* It is REQUIRED to call this to finish writing the rest of the file */
- png_write_end(png_ptr, info_ptr);
-
- transforms = transforms; /* quiet compiler warnings */
- params = params;
-}
-#endif
-#endif /* PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngwtran.c b/distrib/libpng-1.2.19/pngwtran.c
deleted file mode 100644
index 0372fe6..0000000
--- a/distrib/libpng-1.2.19/pngwtran.c
+++ /dev/null
@@ -1,572 +0,0 @@
-
-/* pngwtran.c - transforms the data in a row for PNG writers
- *
- * Last changed in libpng 1.2.9 April 14, 2006
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2006 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Transform the data according to the user's wishes. The order of
- * transformations is significant.
- */
-void /* PRIVATE */
-png_do_write_transformations(png_structp png_ptr)
-{
- png_debug(1, "in png_do_write_transformations\n");
-
- if (png_ptr == NULL)
- return;
-
-#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
- if (png_ptr->transformations & PNG_USER_TRANSFORM)
- if(png_ptr->write_user_transform_fn != NULL)
- (*(png_ptr->write_user_transform_fn)) /* user write transform function */
- (png_ptr, /* png_ptr */
- &(png_ptr->row_info), /* row_info: */
- /* png_uint_32 width; width of row */
- /* png_uint_32 rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
-#endif
-#if defined(PNG_WRITE_FILLER_SUPPORTED)
- if (png_ptr->transformations & PNG_FILLER)
- png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
- png_ptr->flags);
-#endif
-#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_PACKSWAP)
- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-#if defined(PNG_WRITE_PACK_SUPPORTED)
- if (png_ptr->transformations & PNG_PACK)
- png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
- (png_uint_32)png_ptr->bit_depth);
-#endif
-#if defined(PNG_WRITE_SWAP_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_BYTES)
- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-#if defined(PNG_WRITE_SHIFT_SUPPORTED)
- if (png_ptr->transformations & PNG_SHIFT)
- png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
- &(png_ptr->shift));
-#endif
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_SWAP_ALPHA)
- png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-#if defined(PNG_WRITE_BGR_SUPPORTED)
- if (png_ptr->transformations & PNG_BGR)
- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-#if defined(PNG_WRITE_INVERT_SUPPORTED)
- if (png_ptr->transformations & PNG_INVERT_MONO)
- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
-#endif
-}
-
-#if defined(PNG_WRITE_PACK_SUPPORTED)
-/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
- * row_info bit depth should be 8 (one pixel per byte). The channels
- * should be 1 (this only happens on grayscale and paletted images).
- */
-void /* PRIVATE */
-png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
-{
- png_debug(1, "in png_do_pack\n");
- if (row_info->bit_depth == 8 &&
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- row_info->channels == 1)
- {
- switch ((int)bit_depth)
- {
- case 1:
- {
- png_bytep sp, dp;
- int mask, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- mask = 0x80;
- v = 0;
-
- for (i = 0; i < row_width; i++)
- {
- if (*sp != 0)
- v |= mask;
- sp++;
- if (mask > 1)
- mask >>= 1;
- else
- {
- mask = 0x80;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- }
- if (mask != 0x80)
- *dp = (png_byte)v;
- break;
- }
- case 2:
- {
- png_bytep sp, dp;
- int shift, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- shift = 6;
- v = 0;
- for (i = 0; i < row_width; i++)
- {
- png_byte value;
-
- value = (png_byte)(*sp & 0x03);
- v |= (value << shift);
- if (shift == 0)
- {
- shift = 6;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- else
- shift -= 2;
- sp++;
- }
- if (shift != 6)
- *dp = (png_byte)v;
- break;
- }
- case 4:
- {
- png_bytep sp, dp;
- int shift, v;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- sp = row;
- dp = row;
- shift = 4;
- v = 0;
- for (i = 0; i < row_width; i++)
- {
- png_byte value;
-
- value = (png_byte)(*sp & 0x0f);
- v |= (value << shift);
-
- if (shift == 0)
- {
- shift = 4;
- *dp = (png_byte)v;
- dp++;
- v = 0;
- }
- else
- shift -= 4;
-
- sp++;
- }
- if (shift != 4)
- *dp = (png_byte)v;
- break;
- }
- }
- row_info->bit_depth = (png_byte)bit_depth;
- row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_info->width);
- }
-}
-#endif
-
-#if defined(PNG_WRITE_SHIFT_SUPPORTED)
-/* Shift pixel values to take advantage of whole range. Pass the
- * true number of bits in bit_depth. The row should be packed
- * according to row_info->bit_depth. Thus, if you had a row of
- * bit depth 4, but the pixels only had values from 0 to 7, you
- * would pass 3 as bit_depth, and this routine would translate the
- * data to 0 to 15.
- */
-void /* PRIVATE */
-png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
-{
- png_debug(1, "in png_do_shift\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL &&
-#else
- if (
-#endif
- row_info->color_type != PNG_COLOR_TYPE_PALETTE)
- {
- int shift_start[4], shift_dec[4];
- int channels = 0;
-
- if (row_info->color_type & PNG_COLOR_MASK_COLOR)
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->red;
- shift_dec[channels] = bit_depth->red;
- channels++;
- shift_start[channels] = row_info->bit_depth - bit_depth->green;
- shift_dec[channels] = bit_depth->green;
- channels++;
- shift_start[channels] = row_info->bit_depth - bit_depth->blue;
- shift_dec[channels] = bit_depth->blue;
- channels++;
- }
- else
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->gray;
- shift_dec[channels] = bit_depth->gray;
- channels++;
- }
- if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
- {
- shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
- shift_dec[channels] = bit_depth->alpha;
- channels++;
- }
-
- /* with low row depths, could only be grayscale, so one channel */
- if (row_info->bit_depth < 8)
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_byte mask;
- png_uint_32 row_bytes = row_info->rowbytes;
-
- if (bit_depth->gray == 1 && row_info->bit_depth == 2)
- mask = 0x55;
- else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
- mask = 0x11;
- else
- mask = 0xff;
-
- for (i = 0; i < row_bytes; i++, bp++)
- {
- png_uint_16 v;
- int j;
-
- v = *bp;
- *bp = 0;
- for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
- {
- if (j > 0)
- *bp |= (png_byte)((v << j) & 0xff);
- else
- *bp |= (png_byte)((v >> (-j)) & mask);
- }
- }
- }
- else if (row_info->bit_depth == 8)
- {
- png_bytep bp = row;
- png_uint_32 i;
- png_uint_32 istop = channels * row_info->width;
-
- for (i = 0; i < istop; i++, bp++)
- {
-
- png_uint_16 v;
- int j;
- int c = (int)(i%channels);
-
- v = *bp;
- *bp = 0;
- for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
- {
- if (j > 0)
- *bp |= (png_byte)((v << j) & 0xff);
- else
- *bp |= (png_byte)((v >> (-j)) & 0xff);
- }
- }
- }
- else
- {
- png_bytep bp;
- png_uint_32 i;
- png_uint_32 istop = channels * row_info->width;
-
- for (bp = row, i = 0; i < istop; i++)
- {
- int c = (int)(i%channels);
- png_uint_16 value, v;
- int j;
-
- v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
- value = 0;
- for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
- {
- if (j > 0)
- value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
- else
- value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
- }
- *bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)(value & 0xff);
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-void /* PRIVATE */
-png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_write_swap_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This converts from ARGB to RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save;
- }
- }
- /* This converts from AARRGGBB to RRGGBBAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save[2];
- save[0] = *(sp++);
- save[1] = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save[0];
- *(dp++) = save[1];
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from AG to GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save;
- }
- }
- /* This converts from AAGG to GGAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- png_byte save[2];
- save[0] = *(sp++);
- save[1] = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = save[0];
- *(dp++) = save[1];
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-void /* PRIVATE */
-png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_write_invert_alpha\n");
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL)
-#endif
- {
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- {
- /* This inverts the alpha channel in RGBA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- /* does nothing
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- */
- sp+=3; dp = sp;
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- /* This inverts the alpha channel in RRGGBBAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- /* does nothing
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- */
- sp+=6; dp = sp;
- *(dp++) = (png_byte)(255 - *(sp++));
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- }
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This inverts the alpha channel in GA */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- *(dp++) = *(sp++);
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- /* This inverts the alpha channel in GGAA */
- else
- {
- png_bytep sp, dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- for (i = 0, sp = dp = row; i < row_width; i++)
- {
- /* does nothing
- *(dp++) = *(sp++);
- *(dp++) = *(sp++);
- */
- sp+=2; dp = sp;
- *(dp++) = (png_byte)(255 - *(sp++));
- *(dp++) = (png_byte)(255 - *(sp++));
- }
- }
- }
- }
-}
-#endif
-
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
-/* undoes intrapixel differencing */
-void /* PRIVATE */
-png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_write_intrapixel\n");
- if (
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- row != NULL && row_info != NULL &&
-#endif
- (row_info->color_type & PNG_COLOR_MASK_COLOR))
- {
- int bytes_per_pixel;
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 3;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 4;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
- *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 6;
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 8;
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
- png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
- png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
- png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
- png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
- *(rp ) = (png_byte)((red >> 8) & 0xff);
- *(rp+1) = (png_byte)(red & 0xff);
- *(rp+4) = (png_byte)((blue >> 8) & 0xff);
- *(rp+5) = (png_byte)(blue & 0xff);
- }
- }
- }
-}
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
-#endif /* PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/pngwutil.c b/distrib/libpng-1.2.19/pngwutil.c
deleted file mode 100644
index 849ee7d..0000000
--- a/distrib/libpng-1.2.19/pngwutil.c
+++ /dev/null
@@ -1,2782 +0,0 @@
-
-/* pngwutil.c - utilities to write a PNG file
- *
- * Last changed in libpng 1.2.19 August 18, 2007
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2007 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
- */
-
-#define PNG_INTERNAL
-#include "png.h"
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Place a 32-bit number into a buffer in PNG byte order. We work
- * with unsigned numbers for convenience, although one supported
- * ancillary chunk uses signed (two's complement) numbers.
- */
-void PNGAPI
-png_save_uint_32(png_bytep buf, png_uint_32 i)
-{
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
-}
-
-/* The png_save_int_32 function assumes integers are stored in two's
- * complement format. If this isn't the case, then this routine needs to
- * be modified to write data in two's complement format.
- */
-void PNGAPI
-png_save_int_32(png_bytep buf, png_int_32 i)
-{
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
-}
-
-/* Place a 16-bit number into a buffer in PNG byte order.
- * The parameter is declared unsigned int, not png_uint_16,
- * just to avoid potential problems on pre-ANSI C compilers.
- */
-void PNGAPI
-png_save_uint_16(png_bytep buf, unsigned int i)
-{
- buf[0] = (png_byte)((i >> 8) & 0xff);
- buf[1] = (png_byte)(i & 0xff);
-}
-
-/* Write a PNG chunk all at once. The type is an array of ASCII characters
- * representing the chunk name. The array must be at least 4 bytes in
- * length, and does not need to be null terminated. To be safe, pass the
- * pre-defined chunk names here, and if you need a new one, define it
- * where the others are defined. The length is the length of the data.
- * All the data must be present. If that is not possible, use the
- * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
- * functions instead.
- */
-void PNGAPI
-png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
- png_bytep data, png_size_t length)
-{
- if(png_ptr == NULL) return;
- png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
- png_write_chunk_data(png_ptr, data, length);
- png_write_chunk_end(png_ptr);
-}
-
-/* Write the start of a PNG chunk. The type is the chunk type.
- * The total_length is the sum of the lengths of all the data you will be
- * passing in png_write_chunk_data().
- */
-void PNGAPI
-png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
- png_uint_32 length)
-{
- png_byte buf[4];
- png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
- if(png_ptr == NULL) return;
-
- /* write the length */
- png_save_uint_32(buf, length);
- png_write_data(png_ptr, buf, (png_size_t)4);
-
- /* write the chunk name */
- png_write_data(png_ptr, chunk_name, (png_size_t)4);
- /* reset the crc and run it over the chunk name */
- png_reset_crc(png_ptr);
- png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
-}
-
-/* Write the data of a PNG chunk started with png_write_chunk_start().
- * Note that multiple calls to this function are allowed, and that the
- * sum of the lengths from these calls *must* add up to the total_length
- * given to png_write_chunk_start().
- */
-void PNGAPI
-png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- /* write the data, and run the CRC over it */
- if(png_ptr == NULL) return;
- if (data != NULL && length > 0)
- {
- png_calculate_crc(png_ptr, data, length);
- png_write_data(png_ptr, data, length);
- }
-}
-
-/* Finish a chunk started with png_write_chunk_start(). */
-void PNGAPI
-png_write_chunk_end(png_structp png_ptr)
-{
- png_byte buf[4];
-
- if(png_ptr == NULL) return;
-
- /* write the crc */
- png_save_uint_32(buf, png_ptr->crc);
-
- png_write_data(png_ptr, buf, (png_size_t)4);
-}
-
-/* Simple function to write the signature. If we have already written
- * the magic bytes of the signature, or more likely, the PNG stream is
- * being embedded into another stream and doesn't need its own signature,
- * we should call png_set_sig_bytes() to tell libpng how many of the
- * bytes have already been written.
- */
-void /* PRIVATE */
-png_write_sig(png_structp png_ptr)
-{
- png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
- /* write the rest of the 8 byte signature */
- png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
- (png_size_t)8 - png_ptr->sig_bytes);
- if(png_ptr->sig_bytes < 3)
- png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
-}
-
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
-/*
- * This pair of functions encapsulates the operation of (a) compressing a
- * text string, and (b) issuing it later as a series of chunk data writes.
- * The compression_state structure is shared context for these functions
- * set up by the caller in order to make the whole mess thread-safe.
- */
-
-typedef struct
-{
- char *input; /* the uncompressed input data */
- int input_len; /* its length */
- int num_output_ptr; /* number of output pointers used */
- int max_output_ptr; /* size of output_ptr */
- png_charpp output_ptr; /* array of pointers to output */
-} compression_state;
-
-/* compress given text into storage in the png_ptr structure */
-static int /* PRIVATE */
-png_text_compress(png_structp png_ptr,
- png_charp text, png_size_t text_len, int compression,
- compression_state *comp)
-{
- int ret;
-
- comp->num_output_ptr = 0;
- comp->max_output_ptr = 0;
- comp->output_ptr = NULL;
- comp->input = NULL;
- comp->input_len = 0;
-
- /* we may just want to pass the text right through */
- if (compression == PNG_TEXT_COMPRESSION_NONE)
- {
- comp->input = text;
- comp->input_len = text_len;
- return((int)text_len);
- }
-
- if (compression >= PNG_TEXT_COMPRESSION_LAST)
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[50];
- png_snprintf(msg, 50, "Unknown compression type %d", compression);
- png_warning(png_ptr, msg);
-#else
- png_warning(png_ptr, "Unknown compression type");
-#endif
- }
-
- /* We can't write the chunk until we find out how much data we have,
- * which means we need to run the compressor first and save the
- * output. This shouldn't be a problem, as the vast majority of
- * comments should be reasonable, but we will set up an array of
- * malloc'd pointers to be sure.
- *
- * If we knew the application was well behaved, we could simplify this
- * greatly by assuming we can always malloc an output buffer large
- * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
- * and malloc this directly. The only time this would be a bad idea is
- * if we can't malloc more than 64K and we have 64K of random input
- * data, or if the input string is incredibly large (although this
- * wouldn't cause a failure, just a slowdown due to swapping).
- */
-
- /* set up the compression buffers */
- png_ptr->zstream.avail_in = (uInt)text_len;
- png_ptr->zstream.next_in = (Bytef *)text;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
-
- /* this is the same compression loop as in png_write_row() */
- do
- {
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
- if (ret != Z_OK)
- {
- /* error */
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out))
- {
- /* make sure the output array has room */
- if (comp->num_output_ptr >= comp->max_output_ptr)
- {
- int old_max;
-
- old_max = comp->max_output_ptr;
- comp->max_output_ptr = comp->num_output_ptr + 4;
- if (comp->output_ptr != NULL)
- {
- png_charpp old_ptr;
-
- old_ptr = comp->output_ptr;
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charpp)));
- png_memcpy(comp->output_ptr, old_ptr, old_max
- * png_sizeof (png_charp));
- png_free(png_ptr, old_ptr);
- }
- else
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charp)));
- }
-
- /* save the data */
- comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
- (png_uint_32)png_ptr->zbuf_size);
- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
- png_ptr->zbuf_size);
- comp->num_output_ptr++;
-
- /* and reset the buffer */
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
- /* continue until we don't have any more to compress */
- } while (png_ptr->zstream.avail_in);
-
- /* finish the compression */
- do
- {
- /* tell zlib we are finished */
- ret = deflate(&png_ptr->zstream, Z_FINISH);
-
- if (ret == Z_OK)
- {
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out))
- {
- /* check to make sure our output array has room */
- if (comp->num_output_ptr >= comp->max_output_ptr)
- {
- int old_max;
-
- old_max = comp->max_output_ptr;
- comp->max_output_ptr = comp->num_output_ptr + 4;
- if (comp->output_ptr != NULL)
- {
- png_charpp old_ptr;
-
- old_ptr = comp->output_ptr;
- /* This could be optimized to realloc() */
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charpp)));
- png_memcpy(comp->output_ptr, old_ptr,
- old_max * png_sizeof (png_charp));
- png_free(png_ptr, old_ptr);
- }
- else
- comp->output_ptr = (png_charpp)png_malloc(png_ptr,
- (png_uint_32)(comp->max_output_ptr *
- png_sizeof (png_charp)));
- }
-
- /* save off the data */
- comp->output_ptr[comp->num_output_ptr] =
- (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
- png_ptr->zbuf_size);
- comp->num_output_ptr++;
-
- /* and reset the buffer pointers */
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
- }
- }
- else if (ret != Z_STREAM_END)
- {
- /* we got an error */
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- } while (ret != Z_STREAM_END);
-
- /* text length is number of buffers plus last buffer */
- text_len = png_ptr->zbuf_size * comp->num_output_ptr;
- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
- text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
-
- return((int)text_len);
-}
-
-/* ship the compressed text out via chunk writes */
-static void /* PRIVATE */
-png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
-{
- int i;
-
- /* handle the no-compression case */
- if (comp->input)
- {
- png_write_chunk_data(png_ptr, (png_bytep)comp->input,
- (png_size_t)comp->input_len);
- return;
- }
-
- /* write saved output buffers, if any */
- for (i = 0; i < comp->num_output_ptr; i++)
- {
- png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
- png_ptr->zbuf_size);
- png_free(png_ptr, comp->output_ptr[i]);
- comp->output_ptr[i]=NULL;
- }
- if (comp->max_output_ptr != 0)
- png_free(png_ptr, comp->output_ptr);
- comp->output_ptr=NULL;
- /* write anything left in zbuf */
- if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
- png_write_chunk_data(png_ptr, png_ptr->zbuf,
- png_ptr->zbuf_size - png_ptr->zstream.avail_out);
-
- /* reset zlib for another zTXt/iTXt or image data */
- deflateReset(&png_ptr->zstream);
- png_ptr->zstream.data_type = Z_BINARY;
-}
-#endif
-
-/* Write the IHDR chunk, and update the png_struct with the necessary
- * information. Note that the rest of this code depends upon this
- * information being correct.
- */
-void /* PRIVATE */
-png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
- int bit_depth, int color_type, int compression_type, int filter_type,
- int interlace_type)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IHDR;
-#endif
- png_byte buf[13]; /* buffer to store the IHDR info */
-
- png_debug(1, "in png_write_IHDR\n");
- /* Check that we have valid input data from the application info */
- switch (color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16: png_ptr->channels = 1; break;
- default: png_error(png_ptr,"Invalid bit depth for grayscale image");
- }
- break;
- case PNG_COLOR_TYPE_RGB:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for RGB image");
- png_ptr->channels = 3;
- break;
- case PNG_COLOR_TYPE_PALETTE:
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- case 8: png_ptr->channels = 1; break;
- default: png_error(png_ptr, "Invalid bit depth for paletted image");
- }
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
- png_ptr->channels = 2;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- if (bit_depth != 8 && bit_depth != 16)
- png_error(png_ptr, "Invalid bit depth for RGBA image");
- png_ptr->channels = 4;
- break;
- default:
- png_error(png_ptr, "Invalid image color type specified");
- }
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- {
- png_warning(png_ptr, "Invalid compression type specified");
- compression_type = PNG_COMPRESSION_TYPE_BASE;
- }
-
- /* Write filter_method 64 (intrapixel differencing) only if
- * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
- * 2. Libpng did not write a PNG signature (this filter_method is only
- * used in PNG datastreams that are embedded in MNG datastreams) and
- * 3. The application called png_permit_mng_features with a mask that
- * included PNG_FLAG_MNG_FILTER_64 and
- * 4. The filter_method is 64 and
- * 5. The color_type is RGB or RGBA
- */
- if (
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
- ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
- (color_type == PNG_COLOR_TYPE_RGB ||
- color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
- (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
-#endif
- filter_type != PNG_FILTER_TYPE_BASE)
- {
- png_warning(png_ptr, "Invalid filter type specified");
- filter_type = PNG_FILTER_TYPE_BASE;
- }
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- if (interlace_type != PNG_INTERLACE_NONE &&
- interlace_type != PNG_INTERLACE_ADAM7)
- {
- png_warning(png_ptr, "Invalid interlace type specified");
- interlace_type = PNG_INTERLACE_ADAM7;
- }
-#else
- interlace_type=PNG_INTERLACE_NONE;
-#endif
-
- /* save off the relevent information */
- png_ptr->bit_depth = (png_byte)bit_depth;
- png_ptr->color_type = (png_byte)color_type;
- png_ptr->interlaced = (png_byte)interlace_type;
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- png_ptr->filter_type = (png_byte)filter_type;
-#endif
- png_ptr->compression_type = (png_byte)compression_type;
- png_ptr->width = width;
- png_ptr->height = height;
-
- png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
- png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
- /* set the usr info, so any transformations can modify it */
- png_ptr->usr_width = png_ptr->width;
- png_ptr->usr_bit_depth = png_ptr->bit_depth;
- png_ptr->usr_channels = png_ptr->channels;
-
- /* pack the header information into the buffer */
- png_save_uint_32(buf, width);
- png_save_uint_32(buf + 4, height);
- buf[8] = (png_byte)bit_depth;
- buf[9] = (png_byte)color_type;
- buf[10] = (png_byte)compression_type;
- buf[11] = (png_byte)filter_type;
- buf[12] = (png_byte)interlace_type;
-
- /* write the chunk */
- png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
-
- /* initialize zlib with PNG info */
- png_ptr->zstream.zalloc = png_zalloc;
- png_ptr->zstream.zfree = png_zfree;
- png_ptr->zstream.opaque = (voidpf)png_ptr;
- if (!(png_ptr->do_filter))
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
- png_ptr->bit_depth < 8)
- png_ptr->do_filter = PNG_FILTER_NONE;
- else
- png_ptr->do_filter = PNG_ALL_FILTERS;
- }
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
- {
- if (png_ptr->do_filter != PNG_FILTER_NONE)
- png_ptr->zlib_strategy = Z_FILTERED;
- else
- png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
- }
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
- png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
- png_ptr->zlib_mem_level = 8;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
- png_ptr->zlib_window_bits = 15;
- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
- png_ptr->zlib_method = 8;
- if (deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
- png_ptr->zlib_method, png_ptr->zlib_window_bits,
- png_ptr->zlib_mem_level, png_ptr->zlib_strategy) != Z_OK)
- png_error(png_ptr, "zlib failed to initialize compressor");
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- /* libpng is not interested in zstream.data_type */
- /* set it to a predefined value, to avoid its evaluation inside zlib */
- png_ptr->zstream.data_type = Z_BINARY;
-
- png_ptr->mode = PNG_HAVE_IHDR;
-}
-
-/* write the palette. We are careful not to trust png_color to be in the
- * correct order for PNG, so people can redefine it to any convenient
- * structure.
- */
-void /* PRIVATE */
-png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_PLTE;
-#endif
- png_uint_32 i;
- png_colorp pal_ptr;
- png_byte buf[3];
-
- png_debug(1, "in png_write_PLTE\n");
- if ((
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
-#endif
- num_pal == 0) || num_pal > 256)
- {
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- png_error(png_ptr, "Invalid number of colors in palette");
- }
- else
- {
- png_warning(png_ptr, "Invalid number of colors in palette");
- return;
- }
- }
-
- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
- {
- png_warning(png_ptr,
- "Ignoring request to write a PLTE chunk in grayscale PNG");
- return;
- }
-
- png_ptr->num_palette = (png_uint_16)num_pal;
- png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
-
- png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
-#ifndef PNG_NO_POINTER_INDEXING
- for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
- {
- buf[0] = pal_ptr->red;
- buf[1] = pal_ptr->green;
- buf[2] = pal_ptr->blue;
- png_write_chunk_data(png_ptr, buf, (png_size_t)3);
- }
-#else
- /* This is a little slower but some buggy compilers need to do this instead */
- pal_ptr=palette;
- for (i = 0; i < num_pal; i++)
- {
- buf[0] = pal_ptr[i].red;
- buf[1] = pal_ptr[i].green;
- buf[2] = pal_ptr[i].blue;
- png_write_chunk_data(png_ptr, buf, (png_size_t)3);
- }
-#endif
- png_write_chunk_end(png_ptr);
- png_ptr->mode |= PNG_HAVE_PLTE;
-}
-
-/* write an IDAT chunk */
-void /* PRIVATE */
-png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IDAT;
-#endif
- png_debug(1, "in png_write_IDAT\n");
-
- /* Optimize the CMF field in the zlib stream. */
- /* This hack of the zlib stream is compliant to the stream specification. */
- if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
- png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
- {
- unsigned int z_cmf = data[0]; /* zlib compression method and flags */
- if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
- {
- /* Avoid memory underflows and multiplication overflows. */
- /* The conditions below are practically always satisfied;
- however, they still must be checked. */
- if (length >= 2 &&
- png_ptr->height < 16384 && png_ptr->width < 16384)
- {
- png_uint_32 uncompressed_idat_size = png_ptr->height *
- ((png_ptr->width *
- png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
- unsigned int z_cinfo = z_cmf >> 4;
- unsigned int half_z_window_size = 1 << (z_cinfo + 7);
- while (uncompressed_idat_size <= half_z_window_size &&
- half_z_window_size >= 256)
- {
- z_cinfo--;
- half_z_window_size >>= 1;
- }
- z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
- if (data[0] != (png_byte)z_cmf)
- {
- data[0] = (png_byte)z_cmf;
- data[1] &= 0xe0;
- data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
- }
- }
- }
- else
- png_error(png_ptr,
- "Invalid zlib compression method or flags in IDAT");
- }
-
- png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
- png_ptr->mode |= PNG_HAVE_IDAT;
-}
-
-/* write an IEND chunk */
-void /* PRIVATE */
-png_write_IEND(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IEND;
-#endif
- png_debug(1, "in png_write_IEND\n");
- png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
- (png_size_t)0);
- png_ptr->mode |= PNG_HAVE_IEND;
-}
-
-#if defined(PNG_WRITE_gAMA_SUPPORTED)
-/* write a gAMA chunk */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-void /* PRIVATE */
-png_write_gAMA(png_structp png_ptr, double file_gamma)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_gAMA;
-#endif
- png_uint_32 igamma;
- png_byte buf[4];
-
- png_debug(1, "in png_write_gAMA\n");
- /* file_gamma is saved in 1/100,000ths */
- igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
- png_save_uint_32(buf, igamma);
- png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
-}
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-void /* PRIVATE */
-png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_gAMA;
-#endif
- png_byte buf[4];
-
- png_debug(1, "in png_write_gAMA\n");
- /* file_gamma is saved in 1/100,000ths */
- png_save_uint_32(buf, (png_uint_32)file_gamma);
- png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
-}
-#endif
-#endif
-
-#if defined(PNG_WRITE_sRGB_SUPPORTED)
-/* write a sRGB chunk */
-void /* PRIVATE */
-png_write_sRGB(png_structp png_ptr, int srgb_intent)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sRGB;
-#endif
- png_byte buf[1];
-
- png_debug(1, "in png_write_sRGB\n");
- if(srgb_intent >= PNG_sRGB_INTENT_LAST)
- png_warning(png_ptr,
- "Invalid sRGB rendering intent specified");
- buf[0]=(png_byte)srgb_intent;
- png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
-}
-#endif
-
-#if defined(PNG_WRITE_iCCP_SUPPORTED)
-/* write an iCCP chunk */
-void /* PRIVATE */
-png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
- png_charp profile, int profile_len)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_iCCP;
-#endif
- png_size_t name_len;
- png_charp new_name;
- compression_state comp;
- int embedded_profile_len = 0;
-
- png_debug(1, "in png_write_iCCP\n");
-
- comp.num_output_ptr = 0;
- comp.max_output_ptr = 0;
- comp.output_ptr = NULL;
- comp.input = NULL;
- comp.input_len = 0;
-
- if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
- &new_name)) == 0)
- {
- png_warning(png_ptr, "Empty keyword in iCCP chunk");
- return;
- }
-
- if (compression_type != PNG_COMPRESSION_TYPE_BASE)
- png_warning(png_ptr, "Unknown compression type in iCCP chunk");
-
- if (profile == NULL)
- profile_len = 0;
-
- if (profile_len > 3)
- embedded_profile_len =
- ((*( (png_bytep)profile ))<<24) |
- ((*( (png_bytep)profile+1))<<16) |
- ((*( (png_bytep)profile+2))<< 8) |
- ((*( (png_bytep)profile+3)) );
-
- if (profile_len < embedded_profile_len)
- {
- png_warning(png_ptr,
- "Embedded profile length too large in iCCP chunk");
- return;
- }
-
- if (profile_len > embedded_profile_len)
- {
- png_warning(png_ptr,
- "Truncating profile to actual length in iCCP chunk");
- profile_len = embedded_profile_len;
- }
-
- if (profile_len)
- profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
- PNG_COMPRESSION_TYPE_BASE, &comp);
-
- /* make sure we include the NULL after the name and the compression type */
- png_write_chunk_start(png_ptr, png_iCCP,
- (png_uint_32)name_len+profile_len+2);
- new_name[name_len+1]=0x00;
- png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
-
- if (profile_len)
- png_write_compressed_data_out(png_ptr, &comp);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_name);
-}
-#endif
-
-#if defined(PNG_WRITE_sPLT_SUPPORTED)
-/* write a sPLT chunk */
-void /* PRIVATE */
-png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sPLT;
-#endif
- png_size_t name_len;
- png_charp new_name;
- png_byte entrybuf[10];
- int entry_size = (spalette->depth == 8 ? 6 : 10);
- int palette_size = entry_size * spalette->nentries;
- png_sPLT_entryp ep;
-#ifdef PNG_NO_POINTER_INDEXING
- int i;
-#endif
-
- png_debug(1, "in png_write_sPLT\n");
- if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
- spalette->name, &new_name))==0)
- {
- png_warning(png_ptr, "Empty keyword in sPLT chunk");
- return;
- }
-
- /* make sure we include the NULL after the name */
- png_write_chunk_start(png_ptr, png_sPLT,
- (png_uint_32)(name_len + 2 + palette_size));
- png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
- png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
-
- /* loop through each palette entry, writing appropriately */
-#ifndef PNG_NO_POINTER_INDEXING
- for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
- {
- if (spalette->depth == 8)
- {
- entrybuf[0] = (png_byte)ep->red;
- entrybuf[1] = (png_byte)ep->green;
- entrybuf[2] = (png_byte)ep->blue;
- entrybuf[3] = (png_byte)ep->alpha;
- png_save_uint_16(entrybuf + 4, ep->frequency);
- }
- else
- {
- png_save_uint_16(entrybuf + 0, ep->red);
- png_save_uint_16(entrybuf + 2, ep->green);
- png_save_uint_16(entrybuf + 4, ep->blue);
- png_save_uint_16(entrybuf + 6, ep->alpha);
- png_save_uint_16(entrybuf + 8, ep->frequency);
- }
- png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
- }
-#else
- ep=spalette->entries;
- for (i=0; i>spalette->nentries; i++)
- {
- if (spalette->depth == 8)
- {
- entrybuf[0] = (png_byte)ep[i].red;
- entrybuf[1] = (png_byte)ep[i].green;
- entrybuf[2] = (png_byte)ep[i].blue;
- entrybuf[3] = (png_byte)ep[i].alpha;
- png_save_uint_16(entrybuf + 4, ep[i].frequency);
- }
- else
- {
- png_save_uint_16(entrybuf + 0, ep[i].red);
- png_save_uint_16(entrybuf + 2, ep[i].green);
- png_save_uint_16(entrybuf + 4, ep[i].blue);
- png_save_uint_16(entrybuf + 6, ep[i].alpha);
- png_save_uint_16(entrybuf + 8, ep[i].frequency);
- }
- png_write_chunk_data(png_ptr, entrybuf, entry_size);
- }
-#endif
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_name);
-}
-#endif
-
-#if defined(PNG_WRITE_sBIT_SUPPORTED)
-/* write the sBIT chunk */
-void /* PRIVATE */
-png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sBIT;
-#endif
- png_byte buf[4];
- png_size_t size;
-
- png_debug(1, "in png_write_sBIT\n");
- /* make sure we don't depend upon the order of PNG_COLOR_8 */
- if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_byte maxbits;
-
- maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
- png_ptr->usr_bit_depth);
- if (sbit->red == 0 || sbit->red > maxbits ||
- sbit->green == 0 || sbit->green > maxbits ||
- sbit->blue == 0 || sbit->blue > maxbits)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[0] = sbit->red;
- buf[1] = sbit->green;
- buf[2] = sbit->blue;
- size = 3;
- }
- else
- {
- if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[0] = sbit->gray;
- size = 1;
- }
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- {
- if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
- {
- png_warning(png_ptr, "Invalid sBIT depth specified");
- return;
- }
- buf[size++] = sbit->alpha;
- }
-
- png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
-}
-#endif
-
-#if defined(PNG_WRITE_cHRM_SUPPORTED)
-/* write the cHRM chunk */
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-void /* PRIVATE */
-png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
- double red_x, double red_y, double green_x, double green_y,
- double blue_x, double blue_y)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_cHRM;
-#endif
- png_byte buf[32];
- png_uint_32 itemp;
-
- png_debug(1, "in png_write_cHRM\n");
- /* each value is saved in 1/100,000ths */
- if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
- white_x + white_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM white point specified");
-#if !defined(PNG_NO_CONSOLE_IO)
- fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
-#endif
- return;
- }
- itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
- png_save_uint_32(buf, itemp);
- itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 4, itemp);
-
- if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM red point specified");
- return;
- }
- itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 8, itemp);
- itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 12, itemp);
-
- if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM green point specified");
- return;
- }
- itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 16, itemp);
- itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 20, itemp);
-
- if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0)
- {
- png_warning(png_ptr, "Invalid cHRM blue point specified");
- return;
- }
- itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
- png_save_uint_32(buf + 24, itemp);
- itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
- png_save_uint_32(buf + 28, itemp);
-
- png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
-}
-#endif
-#ifdef PNG_FIXED_POINT_SUPPORTED
-void /* PRIVATE */
-png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
- png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
- png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
- png_fixed_point blue_y)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_cHRM;
-#endif
- png_byte buf[32];
-
- png_debug(1, "in png_write_cHRM\n");
- /* each value is saved in 1/100,000ths */
- if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
- {
- png_warning(png_ptr, "Invalid fixed cHRM white point specified");
-#if !defined(PNG_NO_CONSOLE_IO)
- fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
-#endif
- return;
- }
- png_save_uint_32(buf, (png_uint_32)white_x);
- png_save_uint_32(buf + 4, (png_uint_32)white_y);
-
- if (red_x + red_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM fixed red point specified");
- return;
- }
- png_save_uint_32(buf + 8, (png_uint_32)red_x);
- png_save_uint_32(buf + 12, (png_uint_32)red_y);
-
- if (green_x + green_y > 100000L)
- {
- png_warning(png_ptr, "Invalid fixed cHRM green point specified");
- return;
- }
- png_save_uint_32(buf + 16, (png_uint_32)green_x);
- png_save_uint_32(buf + 20, (png_uint_32)green_y);
-
- if (blue_x + blue_y > 100000L)
- {
- png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
- return;
- }
- png_save_uint_32(buf + 24, (png_uint_32)blue_x);
- png_save_uint_32(buf + 28, (png_uint_32)blue_y);
-
- png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
-}
-#endif
-#endif
-
-#if defined(PNG_WRITE_tRNS_SUPPORTED)
-/* write the tRNS chunk */
-void /* PRIVATE */
-png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
- int num_trans, int color_type)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_tRNS;
-#endif
- png_byte buf[6];
-
- png_debug(1, "in png_write_tRNS\n");
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
- {
- png_warning(png_ptr,"Invalid number of transparent colors specified");
- return;
- }
- /* write the chunk out as it is */
- png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans);
- }
- else if (color_type == PNG_COLOR_TYPE_GRAY)
- {
- /* one 16 bit value */
- if(tran->gray >= (1 << png_ptr->bit_depth))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
- return;
- }
- png_save_uint_16(buf, tran->gray);
- png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
- }
- else if (color_type == PNG_COLOR_TYPE_RGB)
- {
- /* three 16 bit values */
- png_save_uint_16(buf, tran->red);
- png_save_uint_16(buf + 2, tran->green);
- png_save_uint_16(buf + 4, tran->blue);
- if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
- return;
- }
- png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
- }
- else
- {
- png_warning(png_ptr, "Can't write tRNS with an alpha channel");
- }
-}
-#endif
-
-#if defined(PNG_WRITE_bKGD_SUPPORTED)
-/* write the background chunk */
-void /* PRIVATE */
-png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_bKGD;
-#endif
- png_byte buf[6];
-
- png_debug(1, "in png_write_bKGD\n");
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
- (png_ptr->num_palette ||
- (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
-#endif
- back->index > png_ptr->num_palette)
- {
- png_warning(png_ptr, "Invalid background palette index");
- return;
- }
- buf[0] = back->index;
- png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
- }
- else if (color_type & PNG_COLOR_MASK_COLOR)
- {
- png_save_uint_16(buf, back->red);
- png_save_uint_16(buf + 2, back->green);
- png_save_uint_16(buf + 4, back->blue);
- if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
- return;
- }
- png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
- }
- else
- {
- if(back->gray >= (1 << png_ptr->bit_depth))
- {
- png_warning(png_ptr,
- "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
- return;
- }
- png_save_uint_16(buf, back->gray);
- png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
- }
-}
-#endif
-
-#if defined(PNG_WRITE_hIST_SUPPORTED)
-/* write the histogram */
-void /* PRIVATE */
-png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_hIST;
-#endif
- int i;
- png_byte buf[3];
-
- png_debug(1, "in png_write_hIST\n");
- if (num_hist > (int)png_ptr->num_palette)
- {
- png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
- png_ptr->num_palette);
- png_warning(png_ptr, "Invalid number of histogram entries specified");
- return;
- }
-
- png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
- for (i = 0; i < num_hist; i++)
- {
- png_save_uint_16(buf, hist[i]);
- png_write_chunk_data(png_ptr, buf, (png_size_t)2);
- }
- png_write_chunk_end(png_ptr);
-}
-#endif
-
-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
-/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
- * and if invalid, correct the keyword rather than discarding the entire
- * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
- * length, forbids leading or trailing whitespace, multiple internal spaces,
- * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
- *
- * The new_key is allocated to hold the corrected keyword and must be freed
- * by the calling routine. This avoids problems with trying to write to
- * static keywords without having to have duplicate copies of the strings.
- */
-png_size_t /* PRIVATE */
-png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
-{
- png_size_t key_len;
- png_charp kp, dp;
- int kflag;
- int kwarn=0;
-
- png_debug(1, "in png_check_keyword\n");
- *new_key = NULL;
-
- if (key == NULL || (key_len = png_strlen(key)) == 0)
- {
- png_warning(png_ptr, "zero length keyword");
- return ((png_size_t)0);
- }
-
- png_debug1(2, "Keyword to be checked is '%s'\n", key);
-
- *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
- if (*new_key == NULL)
- {
- png_warning(png_ptr, "Out of memory while procesing keyword");
- return ((png_size_t)0);
- }
-
- /* Replace non-printing characters with a blank and print a warning */
- for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
- {
- if ((png_byte)*kp < 0x20 ||
- ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
- {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char msg[40];
-
- png_snprintf(msg, 40,
- "invalid keyword character 0x%02X", (png_byte)*kp);
- png_warning(png_ptr, msg);
-#else
- png_warning(png_ptr, "invalid character in keyword");
-#endif
- *dp = ' ';
- }
- else
- {
- *dp = *kp;
- }
- }
- *dp = '\0';
-
- /* Remove any trailing white space. */
- kp = *new_key + key_len - 1;
- if (*kp == ' ')
- {
- png_warning(png_ptr, "trailing spaces removed from keyword");
-
- while (*kp == ' ')
- {
- *(kp--) = '\0';
- key_len--;
- }
- }
-
- /* Remove any leading white space. */
- kp = *new_key;
- if (*kp == ' ')
- {
- png_warning(png_ptr, "leading spaces removed from keyword");
-
- while (*kp == ' ')
- {
- kp++;
- key_len--;
- }
- }
-
- png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
-
- /* Remove multiple internal spaces. */
- for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
- {
- if (*kp == ' ' && kflag == 0)
- {
- *(dp++) = *kp;
- kflag = 1;
- }
- else if (*kp == ' ')
- {
- key_len--;
- kwarn=1;
- }
- else
- {
- *(dp++) = *kp;
- kflag = 0;
- }
- }
- *dp = '\0';
- if(kwarn)
- png_warning(png_ptr, "extra interior spaces removed from keyword");
-
- if (key_len == 0)
- {
- png_free(png_ptr, *new_key);
- *new_key=NULL;
- png_warning(png_ptr, "Zero length keyword");
- }
-
- if (key_len > 79)
- {
- png_warning(png_ptr, "keyword length must be 1 - 79 characters");
- new_key[79] = '\0';
- key_len = 79;
- }
-
- return (key_len);
-}
-#endif
-
-#if defined(PNG_WRITE_tEXt_SUPPORTED)
-/* write a tEXt chunk */
-void /* PRIVATE */
-png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
- png_size_t text_len)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_tEXt;
-#endif
- png_size_t key_len;
- png_charp new_key;
-
- png_debug(1, "in png_write_tEXt\n");
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in tEXt chunk");
- return;
- }
-
- if (text == NULL || *text == '\0')
- text_len = 0;
- else
- text_len = png_strlen(text);
-
- /* make sure we include the 0 after the key */
- png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1);
- /*
- * We leave it to the application to meet PNG-1.0 requirements on the
- * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
- * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
- * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
- */
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
- if (text_len)
- png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_key);
-}
-#endif
-
-#if defined(PNG_WRITE_zTXt_SUPPORTED)
-/* write a compressed text chunk */
-void /* PRIVATE */
-png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
- png_size_t text_len, int compression)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_zTXt;
-#endif
- png_size_t key_len;
- char buf[1];
- png_charp new_key;
- compression_state comp;
-
- png_debug(1, "in png_write_zTXt\n");
-
- comp.num_output_ptr = 0;
- comp.max_output_ptr = 0;
- comp.output_ptr = NULL;
- comp.input = NULL;
- comp.input_len = 0;
-
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in zTXt chunk");
- return;
- }
-
- if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
- {
- png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
- png_free(png_ptr, new_key);
- return;
- }
-
- text_len = png_strlen(text);
-
- /* compute the compressed data; do it now for the length */
- text_len = png_text_compress(png_ptr, text, text_len, compression,
- &comp);
-
- /* write start of chunk */
- png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32)
- (key_len+text_len+2));
- /* write key */
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
- png_free(png_ptr, new_key);
-
- buf[0] = (png_byte)compression;
- /* write compression */
- png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
- /* write the compressed data */
- png_write_compressed_data_out(png_ptr, &comp);
-
- /* close the chunk */
- png_write_chunk_end(png_ptr);
-}
-#endif
-
-#if defined(PNG_WRITE_iTXt_SUPPORTED)
-/* write an iTXt chunk */
-void /* PRIVATE */
-png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
- png_charp lang, png_charp lang_key, png_charp text)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_iTXt;
-#endif
- png_size_t lang_len, key_len, lang_key_len, text_len;
- png_charp new_lang, new_key;
- png_byte cbuf[2];
- compression_state comp;
-
- png_debug(1, "in png_write_iTXt\n");
-
- comp.num_output_ptr = 0;
- comp.max_output_ptr = 0;
- comp.output_ptr = NULL;
- comp.input = NULL;
-
- if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
- {
- png_warning(png_ptr, "Empty keyword in iTXt chunk");
- return;
- }
- if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
- {
- png_warning(png_ptr, "Empty language field in iTXt chunk");
- new_lang = NULL;
- lang_len = 0;
- }
-
- if (lang_key == NULL)
- lang_key_len = 0;
- else
- lang_key_len = png_strlen(lang_key);
-
- if (text == NULL)
- text_len = 0;
- else
- text_len = png_strlen(text);
-
- /* compute the compressed data; do it now for the length */
- text_len = png_text_compress(png_ptr, text, text_len, compression-2,
- &comp);
-
-
- /* make sure we include the compression flag, the compression byte,
- * and the NULs after the key, lang, and lang_key parts */
-
- png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
- (png_uint_32)(
- 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
- + key_len
- + lang_len
- + lang_key_len
- + text_len));
-
- /*
- * We leave it to the application to meet PNG-1.0 requirements on the
- * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
- * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
- * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
- */
- png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
-
- /* set the compression flag */
- if (compression == PNG_ITXT_COMPRESSION_NONE || \
- compression == PNG_TEXT_COMPRESSION_NONE)
- cbuf[0] = 0;
- else /* compression == PNG_ITXT_COMPRESSION_zTXt */
- cbuf[0] = 1;
- /* set the compression method */
- cbuf[1] = 0;
- png_write_chunk_data(png_ptr, cbuf, 2);
-
- cbuf[0] = 0;
- png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1);
- png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1);
- png_write_compressed_data_out(png_ptr, &comp);
-
- png_write_chunk_end(png_ptr);
- png_free(png_ptr, new_key);
- if (new_lang)
- png_free(png_ptr, new_lang);
-}
-#endif
-
-#if defined(PNG_WRITE_oFFs_SUPPORTED)
-/* write the oFFs chunk */
-void /* PRIVATE */
-png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
- int unit_type)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_oFFs;
-#endif
- png_byte buf[9];
-
- png_debug(1, "in png_write_oFFs\n");
- if (unit_type >= PNG_OFFSET_LAST)
- png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
-
- png_save_int_32(buf, x_offset);
- png_save_int_32(buf + 4, y_offset);
- buf[8] = (png_byte)unit_type;
-
- png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
-}
-#endif
-#if defined(PNG_WRITE_pCAL_SUPPORTED)
-/* write the pCAL chunk (described in the PNG extensions document) */
-void /* PRIVATE */
-png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
- png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_pCAL;
-#endif
- png_size_t purpose_len, units_len, total_len;
- png_uint_32p params_len;
- png_byte buf[10];
- png_charp new_purpose;
- int i;
-
- png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
- if (type >= PNG_EQUATION_LAST)
- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
-
- purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
- png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
- units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
- png_debug1(3, "pCAL units length = %d\n", (int)units_len);
- total_len = purpose_len + units_len + 10;
-
- params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
- *png_sizeof(png_uint_32)));
-
- /* Find the length of each parameter, making sure we don't count the
- null terminator for the last parameter. */
- for (i = 0; i < nparams; i++)
- {
- params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
- png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
- total_len += (png_size_t)params_len[i];
- }
-
- png_debug1(3, "pCAL total length = %d\n", (int)total_len);
- png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
- png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
- png_save_int_32(buf, X0);
- png_save_int_32(buf + 4, X1);
- buf[8] = (png_byte)type;
- buf[9] = (png_byte)nparams;
- png_write_chunk_data(png_ptr, buf, (png_size_t)10);
- png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
-
- png_free(png_ptr, new_purpose);
-
- for (i = 0; i < nparams; i++)
- {
- png_write_chunk_data(png_ptr, (png_bytep)params[i],
- (png_size_t)params_len[i]);
- }
-
- png_free(png_ptr, params_len);
- png_write_chunk_end(png_ptr);
-}
-#endif
-
-#if defined(PNG_WRITE_sCAL_SUPPORTED)
-/* write the sCAL chunk */
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
-void /* PRIVATE */
-png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sCAL;
-#endif
- char buf[64];
- png_size_t total_len;
-
- png_debug(1, "in png_write_sCAL\n");
-
- buf[0] = (char)unit;
-#if defined(_WIN32_WCE)
-/* sprintf() function is not supported on WindowsCE */
- {
- wchar_t wc_buf[32];
- size_t wc_len;
- swprintf(wc_buf, TEXT("%12.12e"), width);
- wc_len = wcslen(wc_buf);
- WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL);
- total_len = wc_len + 2;
- swprintf(wc_buf, TEXT("%12.12e"), height);
- wc_len = wcslen(wc_buf);
- WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
- NULL, NULL);
- total_len += wc_len;
- }
-#else
- png_snprintf(buf + 1, 63, "%12.12e", width);
- total_len = 1 + png_strlen(buf + 1) + 1;
- png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
- total_len += png_strlen(buf + total_len);
-#endif
-
- png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
- png_write_chunk(png_ptr, png_sCAL, (png_bytep)buf, total_len);
-}
-#else
-#ifdef PNG_FIXED_POINT_SUPPORTED
-void /* PRIVATE */
-png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
- png_charp height)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_sCAL;
-#endif
- png_byte buf[64];
- png_size_t wlen, hlen, total_len;
-
- png_debug(1, "in png_write_sCAL_s\n");
-
- wlen = png_strlen(width);
- hlen = png_strlen(height);
- total_len = wlen + hlen + 2;
- if (total_len > 64)
- {
- png_warning(png_ptr, "Can't write sCAL (buffer too small)");
- return;
- }
-
- buf[0] = (png_byte)unit;
- png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */
- png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */
-
- png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
- png_write_chunk(png_ptr, png_sCAL, buf, total_len);
-}
-#endif
-#endif
-#endif
-
-#if defined(PNG_WRITE_pHYs_SUPPORTED)
-/* write the pHYs chunk */
-void /* PRIVATE */
-png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
- png_uint_32 y_pixels_per_unit,
- int unit_type)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_pHYs;
-#endif
- png_byte buf[9];
-
- png_debug(1, "in png_write_pHYs\n");
- if (unit_type >= PNG_RESOLUTION_LAST)
- png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
-
- png_save_uint_32(buf, x_pixels_per_unit);
- png_save_uint_32(buf + 4, y_pixels_per_unit);
- buf[8] = (png_byte)unit_type;
-
- png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
-}
-#endif
-
-#if defined(PNG_WRITE_tIME_SUPPORTED)
-/* Write the tIME chunk. Use either png_convert_from_struct_tm()
- * or png_convert_from_time_t(), or fill in the structure yourself.
- */
-void /* PRIVATE */
-png_write_tIME(png_structp png_ptr, png_timep mod_time)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_tIME;
-#endif
- png_byte buf[7];
-
- png_debug(1, "in png_write_tIME\n");
- if (mod_time->month > 12 || mod_time->month < 1 ||
- mod_time->day > 31 || mod_time->day < 1 ||
- mod_time->hour > 23 || mod_time->second > 60)
- {
- png_warning(png_ptr, "Invalid time specified for tIME chunk");
- return;
- }
-
- png_save_uint_16(buf, mod_time->year);
- buf[2] = mod_time->month;
- buf[3] = mod_time->day;
- buf[4] = mod_time->hour;
- buf[5] = mod_time->minute;
- buf[6] = mod_time->second;
-
- png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
-}
-#endif
-
-/* initializes the row writing capability of libpng */
-void /* PRIVATE */
-png_write_start_row(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
- png_size_t buf_size;
-
- png_debug(1, "in png_write_start_row\n");
- buf_size = (png_size_t)(PNG_ROWBYTES(
- png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1);
-
- /* set up row buffer */
- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
- png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
-
-#ifndef PNG_NO_WRITE_FILTERING
- /* set up filtering buffer, if using this filter */
- if (png_ptr->do_filter & PNG_FILTER_SUB)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- /* We only need to keep the previous row if we are using one of these. */
- if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
- {
- /* set up previous row buffer */
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
- png_memset(png_ptr->prev_row, 0, buf_size);
-
- if (png_ptr->do_filter & PNG_FILTER_UP)
- {
- png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_AVG)
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
-
- if (png_ptr->do_filter & PNG_FILTER_PAETH)
- {
- png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
- (png_ptr->rowbytes + 1));
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
-#endif /* PNG_NO_WRITE_FILTERING */
- }
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* if interlaced, we need to set up width and height of pass */
- if (png_ptr->interlaced)
- {
- if (!(png_ptr->transformations & PNG_INTERLACE))
- {
- png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
- png_pass_ystart[0]) / png_pass_yinc[0];
- png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
- png_pass_start[0]) / png_pass_inc[0];
- }
- else
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->usr_width = png_ptr->width;
- }
- }
- else
-#endif
- {
- png_ptr->num_rows = png_ptr->height;
- png_ptr->usr_width = png_ptr->width;
- }
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- png_ptr->zstream.next_out = png_ptr->zbuf;
-}
-
-/* Internal use only. Called when finished processing a row of data. */
-void /* PRIVATE */
-png_write_finish_row(png_structp png_ptr)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-
- /* start of interlace block in the y direction */
- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-
- /* offset to next interlace block in the y direction */
- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-#endif
-
- int ret;
-
- png_debug(1, "in png_write_finish_row\n");
- /* next row */
- png_ptr->row_number++;
-
- /* see if we are done */
- if (png_ptr->row_number < png_ptr->num_rows)
- return;
-
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* if interlaced, go to next pass */
- if (png_ptr->interlaced)
- {
- png_ptr->row_number = 0;
- if (png_ptr->transformations & PNG_INTERLACE)
- {
- png_ptr->pass++;
- }
- else
- {
- /* loop until we find a non-zero width or height pass */
- do
- {
- png_ptr->pass++;
- if (png_ptr->pass >= 7)
- break;
- png_ptr->usr_width = (png_ptr->width +
- png_pass_inc[png_ptr->pass] - 1 -
- png_pass_start[png_ptr->pass]) /
- png_pass_inc[png_ptr->pass];
- png_ptr->num_rows = (png_ptr->height +
- png_pass_yinc[png_ptr->pass] - 1 -
- png_pass_ystart[png_ptr->pass]) /
- png_pass_yinc[png_ptr->pass];
- if (png_ptr->transformations & PNG_INTERLACE)
- break;
- } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
-
- }
-
- /* reset the row above the image for the next pass */
- if (png_ptr->pass < 7)
- {
- if (png_ptr->prev_row != NULL)
- png_memset(png_ptr->prev_row, 0,
- (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
- png_ptr->usr_bit_depth,png_ptr->width))+1);
- return;
- }
- }
-#endif
-
- /* if we get here, we've just written the last row, so we need
- to flush the compressor */
- do
- {
- /* tell the compressor we are done */
- ret = deflate(&png_ptr->zstream, Z_FINISH);
- /* check for an error */
- if (ret == Z_OK)
- {
- /* check to see if we need more room */
- if (!(png_ptr->zstream.avail_out))
- {
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- }
- else if (ret != Z_STREAM_END)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
- } while (ret != Z_STREAM_END);
-
- /* write any extra space */
- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
- {
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
- png_ptr->zstream.avail_out);
- }
-
- deflateReset(&png_ptr->zstream);
- png_ptr->zstream.data_type = Z_BINARY;
-}
-
-#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
-/* Pick out the correct pixels for the interlace pass.
- * The basic idea here is to go through the row with a source
- * pointer and a destination pointer (sp and dp), and copy the
- * correct pixels for the pass. As the row gets compacted,
- * sp will always be >= dp, so we should never overwrite anything.
- * See the default: case for the easiest code to understand.
- */
-void /* PRIVATE */
-png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
-{
-#ifdef PNG_USE_LOCAL_ARRAYS
- /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* start of interlace block */
- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-
- /* offset to next interlace block */
- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-#endif
-
- png_debug(1, "in png_do_write_interlace\n");
- /* we don't have to do anything on the last pass (6) */
-#if defined(PNG_USELESS_TESTS_SUPPORTED)
- if (row != NULL && row_info != NULL && pass < 6)
-#else
- if (pass < 6)
-#endif
- {
- /* each pixel depth is handled separately */
- switch (row_info->pixel_depth)
- {
- case 1:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- d = 0;
- shift = 7;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 3);
- value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 7;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift--;
-
- }
- if (shift != 7)
- *dp = (png_byte)d;
- break;
- }
- case 2:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- shift = 6;
- d = 0;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 2);
- value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 6;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift -= 2;
- }
- if (shift != 6)
- *dp = (png_byte)d;
- break;
- }
- case 4:
- {
- png_bytep sp;
- png_bytep dp;
- int shift;
- int d;
- int value;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
-
- dp = row;
- shift = 4;
- d = 0;
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- sp = row + (png_size_t)(i >> 1);
- value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
- d |= (value << shift);
-
- if (shift == 0)
- {
- shift = 4;
- *dp++ = (png_byte)d;
- d = 0;
- }
- else
- shift -= 4;
- }
- if (shift != 4)
- *dp = (png_byte)d;
- break;
- }
- default:
- {
- png_bytep sp;
- png_bytep dp;
- png_uint_32 i;
- png_uint_32 row_width = row_info->width;
- png_size_t pixel_bytes;
-
- /* start at the beginning */
- dp = row;
- /* find out how many bytes each pixel takes up */
- pixel_bytes = (row_info->pixel_depth >> 3);
- /* loop through the row, only looking at the pixels that
- matter */
- for (i = png_pass_start[pass]; i < row_width;
- i += png_pass_inc[pass])
- {
- /* find out where the original pixel is */
- sp = row + (png_size_t)i * pixel_bytes;
- /* move the pixel */
- if (dp != sp)
- png_memcpy(dp, sp, pixel_bytes);
- /* next pixel */
- dp += pixel_bytes;
- }
- break;
- }
- }
- /* set new row width */
- row_info->width = (row_info->width +
- png_pass_inc[pass] - 1 -
- png_pass_start[pass]) /
- png_pass_inc[pass];
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_info->width);
- }
-}
-#endif
-
-/* This filters the row, chooses which filter to use, if it has not already
- * been specified by the application, and then writes the row out with the
- * chosen filter.
- */
-#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
-#define PNG_HISHIFT 10
-#define PNG_LOMASK ((png_uint_32)0xffffL)
-#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
-void /* PRIVATE */
-png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
-{
- png_bytep prev_row, best_row, row_buf;
- png_uint_32 mins, bpp;
- png_byte filter_to_do = png_ptr->do_filter;
- png_uint_32 row_bytes = row_info->rowbytes;
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- int num_p_filters = (int)png_ptr->num_prev_filters;
-#endif
-
- png_debug(1, "in png_write_find_filter\n");
- /* find out how many bytes offset each pixel is */
- bpp = (row_info->pixel_depth + 7) >> 3;
-
- prev_row = png_ptr->prev_row;
- best_row = row_buf = png_ptr->row_buf;
-#ifndef PNG_NO_WRITE_FILTER
- mins = PNG_MAXSUM;
-
- /* The prediction method we use is to find which method provides the
- * smallest value when summing the absolute values of the distances
- * from zero, using anything >= 128 as negative numbers. This is known
- * as the "minimum sum of absolute differences" heuristic. Other
- * heuristics are the "weighted minimum sum of absolute differences"
- * (experimental and can in theory improve compression), and the "zlib
- * predictive" method (not implemented yet), which does test compressions
- * of lines using different filter methods, and then chooses the
- * (series of) filter(s) that give minimum compressed data size (VERY
- * computationally expensive).
- *
- * GRR 980525: consider also
- * (1) minimum sum of absolute differences from running average (i.e.,
- * keep running sum of non-absolute differences & count of bytes)
- * [track dispersion, too? restart average if dispersion too large?]
- * (1b) minimum sum of absolute differences from sliding average, probably
- * with window size <= deflate window (usually 32K)
- * (2) minimum sum of squared differences from zero or running average
- * (i.e., ~ root-mean-square approach)
- */
-
-
- /* We don't need to test the 'no filter' case if this is the only filter
- * that has been chosen, as it doesn't actually do anything to the data.
- */
- if ((filter_to_do & PNG_FILTER_NONE) &&
- filter_to_do != PNG_FILTER_NONE)
- {
- png_bytep rp;
- png_uint_32 sum = 0;
- png_uint_32 i;
- int v;
-
- for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
- {
- v = *rp;
- sum += (v < 128) ? v : 256 - v;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- png_uint_32 sumhi, sumlo;
- int j;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
-
- /* Reduce the sum if we match any of the previous rows */
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- /* Factor in the cost of this filter (this is here for completeness,
- * but it makes no sense to have a "cost" for the NONE filter, as
- * it has the minimum possible computational cost - none).
- */
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
- mins = sum;
- }
-
- /* sub filter */
- if (filter_to_do == PNG_FILTER_SUB)
- /* it's the only filter so no testing is needed */
- {
- png_bytep rp, lp, dp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- *dp = *rp;
- }
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
- }
- best_row = png_ptr->sub_row;
- }
-
- else if (filter_to_do & PNG_FILTER_SUB)
- {
- png_bytep rp, dp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- /* We temporarily increase the "minimum sum" by the factor we
- * would reduce the sum of this filter, so that we can do the
- * early exit comparison without scaling the sum each time.
- */
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- v = *dp = *rp;
-
- sum += (v < 128) ? v : 256 - v;
- }
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->sub_row;
- }
- }
-
- /* up filter */
- if (filter_to_do == PNG_FILTER_UP)
- {
- png_bytep rp, dp, pp;
- png_uint_32 i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes;
- i++, rp++, pp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
- }
- best_row = png_ptr->up_row;
- }
-
- else if (filter_to_do & PNG_FILTER_UP)
- {
- png_bytep rp, dp, pp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->up_row;
- }
- }
-
- /* avg filter */
- if (filter_to_do == PNG_FILTER_AVG)
- {
- png_bytep rp, dp, pp, lp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
- }
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
- & 0xff);
- }
- best_row = png_ptr->avg_row;
- }
-
- else if (filter_to_do & PNG_FILTER_AVG)
- {
- png_bytep rp, dp, pp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- v = *dp++ =
- (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- mins = sum;
- best_row = png_ptr->avg_row;
- }
- }
-
- /* Paeth filter */
- if (filter_to_do == PNG_FILTER_PAETH)
- {
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 i;
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
- }
- best_row = png_ptr->paeth_row;
- }
-
- else if (filter_to_do & PNG_FILTER_PAETH)
- {
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_uint_32 i;
- int v;
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
-#ifndef PNG_SLOW_PAETH
- p = b - c;
- pc = a - c;
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-#else /* PNG_SLOW_PAETH */
- p = a + b - c;
- pa = abs(p - a);
- pb = abs(p - b);
- pc = abs(p - c);
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
-#endif /* PNG_SLOW_PAETH */
-
- v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
-
- if (sum < mins)
- {
- best_row = png_ptr->paeth_row;
- }
- }
-#endif /* PNG_NO_WRITE_FILTER */
- /* Do the actual writing of the filtered row data from the chosen filter. */
-
- png_write_filtered_row(png_ptr, best_row);
-
-#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
- /* Save the type of filter we picked this time for future calculations */
- if (png_ptr->num_prev_filters > 0)
- {
- int j;
- for (j = 1; j < num_p_filters; j++)
- {
- png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
- }
- png_ptr->prev_filters[j] = best_row[0];
- }
-#endif
-}
-
-
-/* Do the actual writing of a previously filtered row. */
-void /* PRIVATE */
-png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
-{
- png_debug(1, "in png_write_filtered_row\n");
- png_debug1(2, "filter = %d\n", filtered_row[0]);
- /* set up the zlib input buffer */
-
- png_ptr->zstream.next_in = filtered_row;
- png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
- /* repeat until we have compressed all the data */
- do
- {
- int ret; /* return of zlib */
-
- /* compress the data */
- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
- /* check for compression errors */
- if (ret != Z_OK)
- {
- if (png_ptr->zstream.msg != NULL)
- png_error(png_ptr, png_ptr->zstream.msg);
- else
- png_error(png_ptr, "zlib error");
- }
-
- /* see if it is time to write another IDAT */
- if (!(png_ptr->zstream.avail_out))
- {
- /* write the IDAT and reset the zlib output buffer */
- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
- }
- /* repeat until all data has been compressed */
- } while (png_ptr->zstream.avail_in);
-
- /* swap the current and previous rows */
- if (png_ptr->prev_row != NULL)
- {
- png_bytep tptr;
-
- tptr = png_ptr->prev_row;
- png_ptr->prev_row = png_ptr->row_buf;
- png_ptr->row_buf = tptr;
- }
-
- /* finish row - updates counters and flushes zlib if last row */
- png_write_finish_row(png_ptr);
-
-#if defined(PNG_WRITE_FLUSH_SUPPORTED)
- png_ptr->flush_rows++;
-
- if (png_ptr->flush_dist > 0 &&
- png_ptr->flush_rows >= png_ptr->flush_dist)
- {
- png_write_flush(png_ptr);
- }
-#endif
-}
-#endif /* PNG_WRITE_SUPPORTED */
diff --git a/distrib/libpng-1.2.19/sources.make b/distrib/libpng-1.2.19/sources.make
deleted file mode 100644
index d8088c7..0000000
--- a/distrib/libpng-1.2.19/sources.make
+++ /dev/null
@@ -1,14 +0,0 @@
-# this file is included by various Makefiles and defines the set of sources used by our version of LibPng
-#
-LIBPNG_SOURCES := png.c pngerror.c pngget.c pngmem.c pngpread.c pngread.c \
- pngrio.c pngrtran.c pngrutil.c pngset.c pngtrans.c pngvcrd.c pngwio.c \
- pngwrite.c pngwtran.c pngwutil.c
-
-ifeq ($(HOST_OS),darwin)
- LIBPNG_CFLAGS += -DPNG_NO_MMX_CODE
-else
- LIBPNG_SOURCES += pnggccrd.c
-endif
-
-LIBPNG_SOURCES := $(LIBPNG_SOURCES:%=$(LIBPNG_DIR)/%)
-
diff --git a/distrib/make-distrib.sh b/distrib/make-distrib.sh
deleted file mode 100755
index f53d766..0000000
--- a/distrib/make-distrib.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/bash
-#
-# this script is used to build a source distribution package for the Android emulator
-# the package includes:
-# - the sources of our patched SDL library
-# - the sources of our patched QEMU emulator
-# - appropriate scripts to rebuild the emulator binary
-#
-
-# create temporary directory
-TMPROOT=/tmp/android-package
-DATE=$(date +%Y%m%d)
-PACKAGE=android-emulator-$DATE
-TMPDIR=$TMPROOT/$PACKAGE
-if ! ( rm -rf $TMPROOT && mkdir -p $TMPDIR ) then
- echo "could not create temporary directory $TMPDIR"
- exit 3
-fi
-
-locate_qemu_viewpath ()
-{
- viewpath=$(p4 files $0 | sed -e "s/\(.*\)#.*/\\1/g")
- # assumes that this program is in the 'distrib' directory of the QEMU sources
- echo $(dirname $(dirname $viewpath))
-}
-
-locate_depot_files ()
-{
- root=$(p4 where $1) || (
- echo "you need to map $1 into your workspace to build an emulator source release package"
- exit 3
- )
- root=$(echo $root | cut -d" " -f3 | sed -e "s%/\.\.\.%%")
- echo $root
-}
-
-locate_source_files ()
-{
- files=$(p4 files $1/... | grep -v "delete change" | sed -e "s/\(.*\)#.*/\\1/g")
- files=$(echo $files | sed -e "s%$1/%%g")
- echo $files
-}
-
-# locate SDL root directory in client workspace
-if [ -z "$SDLROOT" ] ; then
- SDLROOT=$(locate_depot_files //toolchain/sdl/...)
- echo "SDLROOT is $SDLROOT"
-fi
-
-if [ ! -x "$SDLROOT" ] ; then
- if [ -z "$TOP" ] ; then
- echo "please define the TOP variable"
- exit 3
- fi
- echo "unable to find $SDLROOT as the SDL root directory"
- echo "please define SDLROOT to point to the correct location"
- exit 3
-fi
-
-# locate QEMU root directory
-if [ -z "$QEMUROOT" ] ; then
- QEMUVIEW=$(locate_qemu_viewpath)
- echo "QEMUVIEW is $QEMUVIEW"
- QEMUROOT=$(locate_depot_files $QEMUVIEW/...)
- echo "QEMUROOT is $QEMUROOT"
-fi
-
-if [ ! -x "$QEMUROOT" ] ; then
- if [ -z "$TOP" ] ; then
- echo "please define the TOP variable"
- exit 3
- fi
- echo "unable to find $QEMUROOT as the QEMU root directory"
- echo "please define QEMUROOT to point to the correct location"
- exit 3
-fi
-
-copy_source_files ()
-{
- DSTDIR=$1
- SRCDIR=$2
- files=$(locate_source_files $3)
- mkdir $DSTDIR && for f in $files; do
- mkdir -p $(dirname $DSTDIR/$f);
- cp $SRCDIR/$f $DSTDIR/$f
- done
-}
-
-# copy and cleanup the SDL sources
-echo "copying SDL sources"
-SDLDIR=$TMPDIR/sdl
-copy_source_files $SDLDIR $SDLROOT //toolchain/sdl
-
-# copy and cleanup the QEMU sources
-echo "copying QEMU sources"
-QEMUDIR=$TMPDIR/qemu
-copy_source_files $QEMUDIR $QEMUROOT $QEMUVIEW
-
-echo "copying control scripts"
-cp $QEMUDIR/distrib/build-emulator.sh $TMPDIR/build-emulator.sh
-cp $QEMUDIR/distrib/README $TMPDIR/README
-
-echo "packaging release into a tarball"
-cd $TMPROOT
-tar cjf $PACKAGE.tar.bz2 $PACKAGE
-
-echo "cleaning up"
-rm -rf $TMPDIR
-
-echo "please grab $TMPROOT/$PACKAGE.tar.bz2"
diff --git a/distrib/update-audio.sh b/distrib/update-audio.sh
deleted file mode 100755
index 56bada2..0000000
--- a/distrib/update-audio.sh
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/bin/bash
-#
-# this script is used to update the prebuilt libqemu-audio.a file in the Android source tree
-# we use a prebuilt package because we don't want to force the installation of the ALSA / EsounD / Whatever
-# development packages on every developer machine, or every build server.
-#
-
-# assumes this script is located in the 'distrib' sub-directory
-cd `dirname $0`
-cd ..
-
-locate_depot_files ()
-{
- root=$(p4 where $1) || (
- echo "you need to map $1 into your workspace to build an emulator source release package"
- exit 3
- )
- root=$(echo $root | cut -d" " -f3 | sed -e "s%/\.\.\.%%")
- echo $root
-}
-
-# find the prebuilt directory
-OS=`uname -s`
-EXE=""
-case "$OS" in
- Darwin)
- CPU=`uname -p`
- if [ "$CPU" == "i386" ] ; then
- OS=darwin-x86
- else
- OS=darwin-ppc
- fi
- ;;
- Linux)
- CPU=`uname -m`
- case "$CPU" in
- i?86|x86_64|amd64)
- CPU=x86
- ;;
- esac
- OS=linux-$CPU
- ;;
- *_NT-*)
- OS=windows
- EXE=.exe
- ;;
-esac
-
-PREBUILT=$(locate_depot_files //branches/cupcake/android/prebuilt/$OS)
-
-# find the GNU Make program
-is_gnu_make ()
-{
- version=$($1 -v | grep GNU)
- if test -n "$version"; then
- echo "$1"
- else
- echo ""
- fi
-}
-
-if test -z "$GNUMAKE"; then
- GNUMAKE=`which make` && GNUMAKE=$(is_gnu_make $GNUMAKE)
-fi
-
-if test -z "$GNUMAKE"; then
- GNUMAKE=`which gmake` && GNUMAKE=$(is_gnu_make $GNUMAKE)
-fi
-
-if test -z "$GNUMAKE"; then
- echo "could not find GNU Make on this machine. please define GNUMAKE to point to it"
- exit 3
-fi
-
-TEST=$(is_gnu_make $GNUMAKE)
-if test -z "$TEST"; then
- echo "it seems that '$GNUMAKE' is not a working GNU Make binary. please check the definition of GNUMAKE"
- exit 3
-fi
-
-# ensure we have a recent audio library built
-#
-#echo "GNUMAKE is $GNUMAKE"
-source=objs/libqemu-audio.a
-./android-configure.sh
-$GNUMAKE $source BUILD_QEMU_AUDIO_LIB=true || (echo "could not build the audio library. Aborting" && exit 1)
-
-# now do a p4 edit, a copy and ask for submission
-#
-TARGET=$PREBUILT/emulator/libqemu-audio.a
-
-p4 edit $TARGET || (echo "could not p4 edit $TARGET" && exit 3)
-cp -f $source $TARGET
-echo "please do: p4 submit $TARGET"
-
diff --git a/distrib/zlib-1.2.3/Makefile b/distrib/zlib-1.2.3/Makefile
deleted file mode 100644
index 9cf80c9..0000000
--- a/distrib/zlib-1.2.3/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Makefile used to compile zlib statically
-#
-ZLIB_LIB := $(SRC_PATH)/libz.a
-ZLIB_CFLAGS := -I$(ZLIB_DIR)
-
-include $(ZLIB_DIR)/sources.make
-ZLIB_OBJS := $(ZLIB_SOURCES:%.c=%.o)
-
-$(ZLIB_LIB): $(ZLIB_OBJS)
- ar ru $(ZLIB_LIB) $(ZLIB_OBJS)
-
-$(ZLIB_OBJS): CFLAGS += $(ZLIB_CFLAGS)
-
-clean-zlib:
- rm -f $(ZLIB_OBJS) $(zlib_lib)
diff --git a/distrib/zlib-1.2.3/adler32.c b/distrib/zlib-1.2.3/adler32.c
deleted file mode 100644
index 007ba26..0000000
--- a/distrib/zlib-1.2.3/adler32.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#define BASE 65521UL /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware */
-#ifdef NO_DIVIDE
-# define MOD(a) \
- do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-# define MOD4(a) \
- do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-#else
-# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long sum2;
- unsigned n;
-
- /* split Adler-32 into component sums */
- sum2 = (adler >> 16) & 0xffff;
- adler &= 0xffff;
-
- /* in case user likes doing a byte at a time, keep it fast */
- if (len == 1) {
- adler += buf[0];
- if (adler >= BASE)
- adler -= BASE;
- sum2 += adler;
- if (sum2 >= BASE)
- sum2 -= BASE;
- return adler | (sum2 << 16);
- }
-
- /* initial Adler-32 value (deferred check for len == 1 speed) */
- if (buf == Z_NULL)
- return 1L;
-
- /* in case short lengths are provided, keep it somewhat fast */
- if (len < 16) {
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- if (adler >= BASE)
- adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
- return adler | (sum2 << 16);
- }
-
- /* do length NMAX blocks -- requires just one modulo operation */
- while (len >= NMAX) {
- len -= NMAX;
- n = NMAX / 16; /* NMAX is divisible by 16 */
- do {
- DO16(buf); /* 16 sums unrolled */
- buf += 16;
- } while (--n);
- MOD(adler);
- MOD(sum2);
- }
-
- /* do remaining bytes (less than NMAX, still just one modulo) */
- if (len) { /* avoid modulos if none remaining */
- while (len >= 16) {
- len -= 16;
- DO16(buf);
- buf += 16;
- }
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- MOD(adler);
- MOD(sum2);
- }
-
- /* return recombined sums */
- return adler | (sum2 << 16);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off_t len2;
-{
- unsigned long sum1;
- unsigned long sum2;
- unsigned rem;
-
- /* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
- sum1 = adler1 & 0xffff;
- sum2 = rem * sum1;
- MOD(sum2);
- sum1 += (adler2 & 0xffff) + BASE - 1;
- sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
- return sum1 | (sum2 << 16);
-}
diff --git a/distrib/zlib-1.2.3/compress.c b/distrib/zlib-1.2.3/compress.c
deleted file mode 100644
index df04f01..0000000
--- a/distrib/zlib-1.2.3/compress.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
-
-/* ===========================================================================
- If the default memLevel or windowBits for deflateInit() is changed, then
- this function needs to be updated.
- */
-uLong ZEXPORT compressBound (sourceLen)
- uLong sourceLen;
-{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
-}
diff --git a/distrib/zlib-1.2.3/configure b/distrib/zlib-1.2.3/configure
deleted file mode 100755
index d7ffdc3..0000000
--- a/distrib/zlib-1.2.3/configure
+++ /dev/null
@@ -1,459 +0,0 @@
-#!/bin/sh
-# configure script for zlib. This script is needed only if
-# you wish to build a shared library and your system supports them,
-# of if you need special compiler, flags or install directory.
-# Otherwise, you can just use directly "make test; make install"
-#
-# To create a shared library, use "configure --shared"; by default a static
-# library is created. If the primitive shared library support provided here
-# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
-#
-# To impose specific compiler or flags or install directory, use for example:
-# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
-# or for csh/tcsh users:
-# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
-# LDSHARED is the command to be used to create a shared library
-
-# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
-# If you have problems, try without defining CC and CFLAGS before reporting
-# an error.
-
-LIBS=libz.a
-LDFLAGS="-L. ${LIBS}"
-VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
-VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
-VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
-AR=${AR-"ar rc"}
-RANLIB=${RANLIB-"ranlib"}
-prefix=${prefix-/usr/local}
-exec_prefix=${exec_prefix-'${prefix}'}
-libdir=${libdir-'${exec_prefix}/lib'}
-includedir=${includedir-'${prefix}/include'}
-mandir=${mandir-'${prefix}/share/man'}
-shared_ext='.so'
-shared=0
-gcc=0
-old_cc="$CC"
-old_cflags="$CFLAGS"
-
-while test $# -ge 1
-do
-case "$1" in
- -h* | --h*)
- echo 'usage:'
- echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]'
- echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]'
- exit 0;;
- -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
- -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
- -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
- -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;;
- -p* | --p*) prefix="$2"; shift; shift;;
- -e* | --e*) exec_prefix="$2"; shift; shift;;
- -l* | --l*) libdir="$2"; shift; shift;;
- -i* | --i*) includedir="$2"; shift; shift;;
- -s* | --s*) shared=1; shift;;
- *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;;
- esac
-done
-
-test=ztest$$
-cat > $test.c <<EOF
-extern int getchar();
-int hello() {return getchar();}
-EOF
-
-test -z "$CC" && echo Checking for gcc...
-cc=${CC-gcc}
-cflags=${CFLAGS-"-O3"}
-# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
-case "$cc" in
- *gcc*) gcc=1;;
-esac
-
-if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
- CC="$cc"
- SFLAGS=${CFLAGS-"-fPIC -O3"}
- CFLAGS="$cflags"
- case `(uname -s || echo unknown) 2>/dev/null` in
- Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};;
- CYGWIN* | Cygwin* | cygwin* | OS/2* )
- EXE='.exe';;
- QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
- # (alain.bonnefoy@icbt.com)
- LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};;
- HP-UX*)
- LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
- case `(uname -m || echo unknown) 2>/dev/null` in
- ia64)
- shared_ext='.so'
- SHAREDLIB='libz.so';;
- *)
- shared_ext='.sl'
- SHAREDLIB='libz.sl';;
- esac;;
- Darwin*) shared_ext='.dylib'
- SHAREDLIB=libz$shared_ext
- SHAREDLIBV=libz.$VER$shared_ext
- SHAREDLIBM=libz.$VER1$shared_ext
- LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};;
- *) LDSHARED=${LDSHARED-"$cc -shared"};;
- esac
-else
- # find system name and corresponding cc options
- CC=${CC-cc}
- case `(uname -sr || echo unknown) 2>/dev/null` in
- HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
- CFLAGS=${CFLAGS-"-O"}
-# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
- LDSHARED=${LDSHARED-"ld -b"}
- case `(uname -m || echo unknown) 2>/dev/null` in
- ia64)
- shared_ext='.so'
- SHAREDLIB='libz.so';;
- *)
- shared_ext='.sl'
- SHAREDLIB='libz.sl';;
- esac;;
- IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
- CFLAGS=${CFLAGS-"-ansi -O2"}
- LDSHARED=${LDSHARED-"cc -shared"};;
- OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
- CFLAGS=${CFLAGS-"-O -std1"}
- LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};;
- OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
- CFLAGS=${CFLAGS-"-O -std1"}
- LDSHARED=${LDSHARED-"cc -shared"};;
- QNX*) SFLAGS=${CFLAGS-"-4 -O"}
- CFLAGS=${CFLAGS-"-4 -O"}
- LDSHARED=${LDSHARED-"cc"}
- RANLIB=${RANLIB-"true"}
- AR="cc -A";;
- SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
- CFLAGS=${CFLAGS-"-O3"}
- LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
- SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
- CFLAGS=${CFLAGS-"-fast -xcg89"}
- LDSHARED=${LDSHARED-"cc -G"};;
- SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
- CFLAGS=${CFLAGS-"-O2"}
- LDSHARED=${LDSHARED-"ld"};;
- SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
- CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
- LDSHARED=${LDSHARED-"cc -xarch=v9b"};;
- UNIX_System_V\ 4.2.0)
- SFLAGS=${CFLAGS-"-KPIC -O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -G"};;
- UNIX_SV\ 4.2MP)
- SFLAGS=${CFLAGS-"-Kconform_pic -O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -G"};;
- OpenUNIX\ 5)
- SFLAGS=${CFLAGS-"-KPIC -O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -G"};;
- AIX*) # Courtesy of dbakker@arrayasolutions.com
- SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
- CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
- LDSHARED=${LDSHARED-"xlc -G"};;
- # send working options for other systems to support@gzip.org
- *) SFLAGS=${CFLAGS-"-O"}
- CFLAGS=${CFLAGS-"-O"}
- LDSHARED=${LDSHARED-"cc -shared"};;
- esac
-fi
-
-SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
-SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
-SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
-
-if test $shared -eq 1; then
- echo Checking for shared library support...
- # we must test in two steps (cc then ld), required at least on SunOS 4.x
- if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
- test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
- CFLAGS="$SFLAGS"
- LIBS="$SHAREDLIBV"
- echo Building shared library $SHAREDLIBV with $CC.
- elif test -z "$old_cc" -a -z "$old_cflags"; then
- echo No shared library support.
- shared=0;
- else
- echo 'No shared library support; try without defining CC and CFLAGS'
- shared=0;
- fi
-fi
-if test $shared -eq 0; then
- LDSHARED="$CC"
- echo Building static library $LIBS version $VER with $CC.
-else
- LDFLAGS="-L. ${SHAREDLIBV}"
-fi
-
-cat > $test.c <<EOF
-#include <unistd.h>
-int main() { return 0; }
-EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h
- echo "Checking for unistd.h... Yes."
-else
- cp -p zconf.in.h zconf.h
- echo "Checking for unistd.h... No."
-fi
-
-cat > $test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-#include "zconf.h"
-
-int main()
-{
-#ifndef STDC
- choke me
-#endif
-
- return 0;
-}
-EOF
-
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()"
-
- cat > $test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-
-int mytest(char *fmt, ...)
-{
- char buf[20];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- return 0;
-}
-
-int main()
-{
- return (mytest("Hello%d\n", 1));
-}
-EOF
-
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for vsnprintf() in stdio.h... Yes."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-
-int mytest(char *fmt, ...)
-{
- int n;
- char buf[20];
- va_list ap;
-
- va_start(ap, fmt);
- n = vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- return n;
-}
-
-int main()
-{
- return (mytest("Hello%d\n", 1));
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of vsnprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
- echo "Checking for return value of vsnprintf()... No."
- echo " WARNING: apparently vsnprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- else
- CFLAGS="$CFLAGS -DNO_vsnprintf"
- echo "Checking for vsnprintf() in stdio.h... No."
- echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
- echo " can build but will be open to possible buffer-overflow security"
- echo " vulnerabilities."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-#include <stdarg.h>
-
-int mytest(char *fmt, ...)
-{
- int n;
- char buf[20];
- va_list ap;
-
- va_start(ap, fmt);
- n = vsprintf(buf, fmt, ap);
- va_end(ap);
- return n;
-}
-
-int main()
-{
- return (mytest("Hello%d\n", 1));
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of vsprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_vsprintf_void"
- echo "Checking for return value of vsprintf()... No."
- echo " WARNING: apparently vsprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- fi
-else
- echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()"
-
- cat >$test.c <<EOF
-#include <stdio.h>
-
-int mytest()
-{
- char buf[20];
-
- snprintf(buf, sizeof(buf), "%s", "foo");
- return 0;
-}
-
-int main()
-{
- return (mytest());
-}
-EOF
-
- if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
- echo "Checking for snprintf() in stdio.h... Yes."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-
-int mytest()
-{
- char buf[20];
-
- return snprintf(buf, sizeof(buf), "%s", "foo");
-}
-
-int main()
-{
- return (mytest());
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of snprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_snprintf_void"
- echo "Checking for return value of snprintf()... No."
- echo " WARNING: apparently snprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- else
- CFLAGS="$CFLAGS -DNO_snprintf"
- echo "Checking for snprintf() in stdio.h... No."
- echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
- echo " can build but will be open to possible buffer-overflow security"
- echo " vulnerabilities."
-
- cat >$test.c <<EOF
-#include <stdio.h>
-
-int mytest()
-{
- char buf[20];
-
- return sprintf(buf, "%s", "foo");
-}
-
-int main()
-{
- return (mytest());
-}
-EOF
-
- if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for return value of sprintf()... Yes."
- else
- CFLAGS="$CFLAGS -DHAS_sprintf_void"
- echo "Checking for return value of sprintf()... No."
- echo " WARNING: apparently sprintf() does not return a value. zlib"
- echo " can build but will be open to possible string-format security"
- echo " vulnerabilities."
- fi
- fi
-fi
-
-cat >$test.c <<EOF
-#include <errno.h>
-int main() { return 0; }
-EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- echo "Checking for errno.h... Yes."
-else
- echo "Checking for errno.h... No."
- CFLAGS="$CFLAGS -DNO_ERRNO_H"
-fi
-
-cat > $test.c <<EOF
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-caddr_t hello() {
- return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0);
-}
-EOF
-if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
- CFLAGS="$CFLAGS -DUSE_MMAP"
- echo Checking for mmap support... Yes.
-else
- echo Checking for mmap support... No.
-fi
-
-CPP=${CPP-"$CC -E"}
-case $CFLAGS in
- *ASMV*)
- if test "`nm $test.o | grep _hello`" = ""; then
- CPP="$CPP -DNO_UNDERLINE"
- echo Checking for underline in external names... No.
- else
- echo Checking for underline in external names... Yes.
- fi;;
-esac
-
-rm -f $test.[co] $test $test$shared_ext
-
-# udpate Makefile
-sed < Makefile.in "
-/^CC *=/s#=.*#=$CC#
-/^CFLAGS *=/s#=.*#=$CFLAGS#
-/^CPP *=/s#=.*#=$CPP#
-/^LDSHARED *=/s#=.*#=$LDSHARED#
-/^LIBS *=/s#=.*#=$LIBS#
-/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
-/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
-/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
-/^AR *=/s#=.*#=$AR#
-/^RANLIB *=/s#=.*#=$RANLIB#
-/^EXE *=/s#=.*#=$EXE#
-/^prefix *=/s#=.*#=$prefix#
-/^exec_prefix *=/s#=.*#=$exec_prefix#
-/^libdir *=/s#=.*#=$libdir#
-/^includedir *=/s#=.*#=$includedir#
-/^mandir *=/s#=.*#=$mandir#
-/^LDFLAGS *=/s#=.*#=$LDFLAGS#
-" > Makefile
diff --git a/distrib/zlib-1.2.3/crc32.c b/distrib/zlib-1.2.3/crc32.c
deleted file mode 100644
index f658a9e..0000000
--- a/distrib/zlib-1.2.3/crc32.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id$ */
-
-/*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
- */
-
-#ifdef MAKECRCH
-# include <stdio.h>
-# ifndef DYNAMIC_CRC_TABLE
-# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h" /* for STDC and FAR definitions */
-
-#define local static
-
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include <limits.h>
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
-/* Definitions for doing the crc four data bytes at a time. */
-#ifdef BYFOUR
-# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
-# define TBLS 8
-#else
-# define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
-#endif /* MAKECRCH */
-/*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
- unsigned long c;
- int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
-#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
-#endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
-#ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
-# ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
-# endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
- FILE *out;
- const unsigned long FAR *table;
-{
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const unsigned long FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
-#endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
-}
-
-#ifdef BYFOUR
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = (u4)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = REV((u4)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf4++;
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(REV(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
- unsigned long *mat;
- unsigned long vec;
-{
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
- unsigned long *square;
- unsigned long *mat;
-{
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off_t len2;
-{
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case */
- if (len2 == 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
-}
diff --git a/distrib/zlib-1.2.3/crc32.h b/distrib/zlib-1.2.3/crc32.h
deleted file mode 100644
index 8053b61..0000000
--- a/distrib/zlib-1.2.3/crc32.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/* crc32.h -- tables for rapid CRC calculation
- * Generated automatically by crc32.c
- */
-
-local const unsigned long FAR crc_table[TBLS][256] =
-{
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
-#ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
-#endif
- }
-};
diff --git a/distrib/zlib-1.2.3/deflate.c b/distrib/zlib-1.2.3/deflate.c
deleted file mode 100644
index 29ce1f6..0000000
--- a/distrib/zlib-1.2.3/deflate.c
+++ /dev/null
@@ -1,1736 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id$ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-#ifndef FASTEST
-local block_state deflate_slow OF((deflate_state *s, int flush));
-#endif
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifndef FASTEST
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-#endif
-local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-#ifdef FASTEST
-local const config configuration_table[2] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
-#else
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
-#endif
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-
- if (windowBits < 0) { /* suppress zlib wrapper */
- wrap = 0;
- windowBits = -windowBits;
- }
-#ifdef GZIP
- else if (windowBits > 15) {
- wrap = 2; /* write gzip wrapper instead */
- windowBits -= 16;
- }
-#endif
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->wrap = wrap;
- s->gzhead = Z_NULL;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
- return Z_STREAM_ERROR;
-
- s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
- dictionary += dictLength - length; /* use the tail of the dictionary */
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
- return Z_STREAM_ERROR;
- }
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
- }
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
- strm->adler =
-#ifdef GZIP
- s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
-#endif
- adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetHeader (strm, head)
- z_streamp strm;
- gz_headerp head;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
- strm->state->gzhead = head;
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePrime (strm, bits, value)
- z_streamp strm;
- int bits;
- int value;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
- z_streamp strm;
- int good_length;
- int max_lazy;
- int nice_length;
- int max_chain;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
- s->nice_match = nice_length;
- s->max_chain_length = max_chain;
- return Z_OK;
-}
-
-/* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well. The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
- */
-uLong ZEXPORT deflateBound(strm, sourceLen)
- z_streamp strm;
- uLong sourceLen;
-{
- deflate_state *s;
- uLong destLen;
-
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
-
- /* if can't get parameters, return conservative bound */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
-
- /* if not default parameters, return conservative bound */
- s = strm->state;
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
-
- /* default settings: return tight bound for that case */
- return compressBound(sourceLen);
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the header */
- if (s->status == INIT_STATE) {
-#ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
- else
-#endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = adler32(0L, Z_NULL, 0);
- }
- }
-#ifdef GZIP
- if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
- }
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
- }
- }
- else
- s->status = NAME_STATE;
- }
- if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->name[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
- }
- else
- s->status = COMMENT_STATE;
- }
- if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->comment[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
- }
- else
- s->status = HCRC_STATE;
- }
- if (s->status == HCRC_STATE) {
- if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
- flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
- }
- }
- else
- s->status = BUSY_STATE;
- }
-#endif
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
-
- /* Write the trailer */
-#ifdef GZIP
- if (s->wrap == 2) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
- put_byte(s, (Byte)(strm->total_in & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
- }
- else
-#endif
- {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- zmemcpy(dest, source, sizeof(z_stream));
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif /* MAXSEG_64K */
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
-#ifdef GZIP
- else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
- }
-#endif
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifndef FASTEST
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-#endif
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
- * for insufficient lookahead only occur occasionally for performance
- * reasons. Therefore uninitialized memory will be accessed, and
- * conditional jumps will be made that depend on those values.
- * However the length of the match is limited to the lookahead, so
- * the output of deflate is not affected by the uninitialized values.
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-#endif /* ASMV */
-#endif /* FASTEST */
-
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
- */
-local uInt longest_match_fast(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
-}
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif /* DEBUG */
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (sizeof(int) <= 2) {
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if
- * strstart == 0 && lookahead == 1 (input done a byte at time)
- */
- more--;
- }
- }
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- /* %%% avoid this when Z_RLE */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
-#ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#endif
- /* longest_match() or longest_match_fast() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-#if TOO_FAR <= 32767
- || (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR)
-#endif
- )) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif /* FASTEST */
-
-#if 0
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one. Do not maintain a hash table. (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-local block_state deflate_rle(s, flush)
- deflate_state *s;
- int flush;
-{
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
- */
- if (s->lookahead < MAX_MATCH) {
- fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
- scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
- }
-
- /* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif
diff --git a/distrib/zlib-1.2.3/deflate.h b/distrib/zlib-1.2.3/deflate.h
deleted file mode 100644
index 05a5ab3..0000000
--- a/distrib/zlib-1.2.3/deflate.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2004 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef DEFLATE_H
-#define DEFLATE_H
-
-#include "zutil.h"
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer creation by deflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip encoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GZIP
-#endif
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define EXTRA_STATE 69
-#define NAME_STATE 73
-#define COMMENT_STATE 91
-#define HCRC_STATE 103
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif /* DEFLATE_H */
diff --git a/distrib/zlib-1.2.3/gzio.c b/distrib/zlib-1.2.3/gzio.c
deleted file mode 100644
index 7e90f49..0000000
--- a/distrib/zlib-1.2.3/gzio.c
+++ /dev/null
@@ -1,1026 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
- */
-
-/* @(#) $Id$ */
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-#ifdef NO_DEFLATE /* for compatibility with old definition */
-# define NO_GZCOMPRESS
-#endif
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#ifdef __MVS__
-# pragma map (fdopen , "\174\174FDOPEN")
- FILE *fdopen(int, const char *);
-#endif
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- z_off_t start; /* start of compressed data in file (header skipped) */
- z_off_t in; /* bytes into deflate or inflate */
- z_off_t out; /* bytes out of deflate or inflate */
- int back; /* one character push-back */
- int last; /* true if push-back is last character */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->in = 0;
- s->out = 0;
- s->back = EOF;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else if (*p == 'R') {
- strategy = Z_RLE;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->start = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * start anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->start = ftell(s->file) - s->stream.avail_in;
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[46]; /* allow for up to 128-bit integers */
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Assure two bytes in the buffer so we can peek ahead -- handle case
- where first byte of header is at the end of the buffer after the last
- gzip segment */
- len = s->stream.avail_in;
- if (len < 2) {
- if (len) s->inbuf[0] = s->stream.next_in[0];
- errno = 0;
- len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
- if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
- s->stream.avail_in += len;
- s->stream.next_in = s->inbuf;
- if (s->stream.avail_in < 2) {
- s->transparent = s->stream.avail_in;
- return;
- }
- }
-
- /* Peek ahead to check the gzip magic header */
- if (s->stream.next_in[0] != gz_magic[0] ||
- s->stream.next_in[1] != gz_magic[1]) {
- s->transparent = 1;
- return;
- }
- s->stream.avail_in -= 2;
- s->stream.next_in += 2;
-
- /* Check the rest of the gzip header */
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- if (s->stream.avail_out && s->back != EOF) {
- *next_out++ = s->back;
- s->stream.next_out++;
- s->stream.avail_out--;
- s->back = EOF;
- s->out++;
- start++;
- if (s->last) {
- s->z_err = Z_STREAM_END;
- return 1;
- }
- }
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -=
- (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
- }
- len -= s->stream.avail_out;
- s->in += len;
- s->out += len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may be
- * different from s->out in case of concatenated .gz files.
- * Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- inflateReset(&(s->stream));
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- if (len == s->stream.avail_out &&
- (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
- return -1;
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Push one byte back onto the stream.
-*/
-int ZEXPORT gzungetc(c, file)
- int c;
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
- s->back = c;
- s->out--;
- s->last = (s->z_err == Z_STREAM_END);
- if (s->last) s->z_err = Z_OK;
- s->z_eof = 0;
- return c;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_GZCOMPRESS
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- voidpc buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- buf[sizeof(buf) - 1] = 0;
- va_start(va, format);
-#ifdef NO_vsnprintf
-# ifdef HAS_vsprintf_void
- (void)vsprintf(buf, format, va);
- va_end(va);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = vsprintf(buf, format, va);
- va_end(va);
-# endif
-#else
-# ifdef HAS_vsnprintf_void
- (void)vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
- len = strlen(buf);
-# else
- len = vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-# endif
-#endif
- if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
- buf[sizeof(buf) - 1] = 0;
-#ifdef NO_snprintf
-# ifdef HAS_sprintf_void
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#else
-# ifdef HAS_snprintf_void
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(buf);
-# else
- len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#endif
- if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), flush);
- s->out -= s->stream.avail_out;
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_GZCOMPRESS */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- if (s->inbuf == Z_NULL) return -1L;
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return s->in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->in = s->out = offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if (offset >= s->out) {
- offset -= s->out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- if (s->outbuf == Z_NULL) return -1L;
- }
- if (offset && s->back != EOF) {
- s->back = EOF;
- s->out++;
- offset--;
- if (s->last) s->z_err = Z_STREAM_END;
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return s->out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
- if (!s->transparent) (void)inflateReset(&s->stream);
- s->in = 0;
- s->out = 0;
- return fseek(s->file, s->start, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- /* With concatenated compressed files that can have embedded
- * crc trailers, z_eof is no longer the only/best indicator of EOF
- * on a gz_stream. Handle end-of-stream error explicitly here.
- */
- if (s == NULL || s->mode != 'r') return 0;
- if (s->z_eof) return 1;
- return s->z_err == Z_STREAM_END;
-}
-
-/* ===========================================================================
- Returns 1 if reading and doing so transparently, otherwise zero.
-*/
-int ZEXPORT gzdirect (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return 0;
- return s->transparent;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return Z_STREAM_ERROR;
-#else
- if (do_flush (file, Z_FINISH) != Z_OK)
- return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, (uLong)(s->in & 0xffffffff));
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-#ifdef STDC
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-/* ===========================================================================
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char * ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
-
-/* ===========================================================================
- Clear the error and end-of-file flags, and do the same for the real file.
-*/
-void ZEXPORT gzclearerr (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return;
- if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
- s->z_eof = 0;
- clearerr(s->file);
-}
diff --git a/distrib/zlib-1.2.3/infback.c b/distrib/zlib-1.2.3/infback.c
deleted file mode 100644
index 455dbc9..0000000
--- a/distrib/zlib-1.2.3/infback.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- This code is largely copied from inflate.c. Normally either infback.o or
- inflate.o would be linked into an application--not both. The interface
- with inffast.c is retained so that optimized assembler-coded versions of
- inflate_fast() can be used with either inflate.c or infback.c.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-
-/*
- strm provides memory allocation functions in zalloc and zfree, or
- Z_NULL to use the library memory allocation functions.
-
- windowBits is in the range 8..15, and window is a user-supplied
- window and output buffer that is 2**windowBits bytes.
- */
-int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_streamp strm;
-int windowBits;
-unsigned char FAR *window;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL || window == Z_NULL ||
- windowBits < 8 || windowBits > 15)
- return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)ZALLOC(strm, 1,
- sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- state->dmax = 32768U;
- state->wbits = windowBits;
- state->wsize = 1U << windowBits;
- state->window = window;
- state->write = 0;
- state->whave = 0;
- return Z_OK;
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-/* Macros for inflateBack(): */
-
-/* Load returned state from inflate_fast() */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Set state from registers for inflate_fast() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Assure that some input is available. If input is requested, but denied,
- then return a Z_BUF_ERROR from inflateBack(). */
-#define PULL() \
- do { \
- if (have == 0) { \
- have = in(in_desc, &next); \
- if (have == 0) { \
- next = Z_NULL; \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflateBack()
- with an error if there is no input available. */
-#define PULLBYTE() \
- do { \
- PULL(); \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflateBack() with
- an error. */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Assure that some output space is available, by writing out the window
- if it's full. If the write fails, return from inflateBack() with a
- Z_BUF_ERROR. */
-#define ROOM() \
- do { \
- if (left == 0) { \
- put = state->window; \
- left = state->wsize; \
- state->whave = left; \
- if (out(out_desc, put, left)) { \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/*
- strm provides the memory allocation functions and window buffer on input,
- and provides information on the unused input on return. For Z_DATA_ERROR
- returns, strm will also provide an error message.
-
- in() and out() are the call-back input and output functions. When
- inflateBack() needs more input, it calls in(). When inflateBack() has
- filled the window with output, or when it completes with data in the
- window, it calls out() to write out the data. The application must not
- change the provided input until in() is called again or inflateBack()
- returns. The application must not change the window/output buffer until
- inflateBack() returns.
-
- in() and out() are called with a descriptor parameter provided in the
- inflateBack() call. This parameter can be a structure that provides the
- information required to do the read or write, as well as accumulated
- information on the input and output such as totals and check values.
-
- in() should return zero on failure. out() should return non-zero on
- failure. If either in() or out() fails, than inflateBack() returns a
- Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
- was in() or out() that caused in the error. Otherwise, inflateBack()
- returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
- error, or Z_MEM_ERROR if it could not allocate memory for the state.
- inflateBack() can also return Z_STREAM_ERROR if the input parameters
- are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
-int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_streamp strm;
-in_func in;
-void FAR *in_desc;
-out_func out;
-void FAR *out_desc;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* Check that the strm exists and that the state was initialized */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* Reset the state */
- strm->msg = Z_NULL;
- state->mode = TYPE;
- state->last = 0;
- state->whave = 0;
- next = strm->next_in;
- have = next != Z_NULL ? strm->avail_in : 0;
- hold = 0;
- bits = 0;
- put = state->window;
- left = state->wsize;
-
- /* Inflate until end of block marked as last */
- for (;;)
- switch (state->mode) {
- case TYPE:
- /* determine and dispatch block type */
- if (state->last) {
- BYTEBITS();
- state->mode = DONE;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
-
- case STORED:
- /* get and verify stored block length */
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
-
- /* copy stored block from input to output */
- while (state->length != 0) {
- copy = state->length;
- PULL();
- ROOM();
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
-
- case TABLE:
- /* get dynamic table entries descriptor */
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
-
- /* get code length code lengths (not a typo) */
- state->have = 0;
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
-
- /* get length and distance code code lengths */
- state->have = 0;
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = (unsigned)(state->lens[state->have - 1]);
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
-
- case LEN:
- /* use inflate_fast() if we have enough input and output */
- if (have >= 6 && left >= 258) {
- RESTORE();
- if (state->whave < state->wsize)
- state->whave = state->wsize - left;
- inflate_fast(strm, state->wsize);
- LOAD();
- break;
- }
-
- /* get a literal, length, or end-of-block code */
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
-
- /* process literal */
- if (this.op == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- ROOM();
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- }
-
- /* process end of block */
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
-
- /* invalid code */
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
-
- /* length code -- get extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
-
- /* get distance code */
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
-
- /* get distance extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
- if (state->offset > state->wsize - (state->whave < state->wsize ?
- left : 0)) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
-
- /* copy match from window to output */
- do {
- ROOM();
- copy = state->wsize - state->offset;
- if (copy < left) {
- from = put + copy;
- copy = left - copy;
- }
- else {
- from = put - state->offset;
- copy = left;
- }
- if (copy > state->length) copy = state->length;
- state->length -= copy;
- left -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- } while (state->length != 0);
- break;
-
- case DONE:
- /* inflate stream terminated properly -- write leftover output */
- ret = Z_STREAM_END;
- if (left < state->wsize) {
- if (out(out_desc, state->window, state->wsize - left))
- ret = Z_BUF_ERROR;
- }
- goto inf_leave;
-
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
-
- default: /* can't happen, but makes compilers happy */
- ret = Z_STREAM_ERROR;
- goto inf_leave;
- }
-
- /* Return unused input */
- inf_leave:
- strm->next_in = next;
- strm->avail_in = have;
- return ret;
-}
-
-int ZEXPORT inflateBackEnd(strm)
-z_streamp strm;
-{
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
diff --git a/distrib/zlib-1.2.3/inffast.c b/distrib/zlib-1.2.3/inffast.c
deleted file mode 100644
index bbee92e..0000000
--- a/distrib/zlib-1.2.3/inffast.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifndef ASMINF
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
-/*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
-void inflate_fast(strm, start)
-z_streamp strm;
-unsigned start; /* inflate()'s starting value for strm->avail_out */
-{
- struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
- unsigned char FAR *out; /* local strm->next_out */
- unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
- unsigned char FAR *end; /* while out < end, enough space available */
-#ifdef INFLATE_STRICT
- unsigned dmax; /* maximum distance from zlib header */
-#endif
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
- unsigned long hold; /* local strm->hold */
- unsigned bits; /* local strm->bits */
- code const FAR *lcode; /* local strm->lencode */
- code const FAR *dcode; /* local strm->distcode */
- unsigned lmask; /* mask for first level of length codes */
- unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
- unsigned op; /* code bits, operation, extra bits, or */
- /* window position, window bytes to copy */
- unsigned len; /* match length, unused bytes */
- unsigned dist; /* match distance */
- unsigned char FAR *from; /* where to copy match from */
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
- last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
- beg = out - (start - strm->avail_out);
- end = out + (strm->avail_out - 257);
-#ifdef INFLATE_STRICT
- dmax = state->dmax;
-#endif
- wsize = state->wsize;
- whave = state->whave;
- write = state->write;
- window = state->window;
- hold = state->hold;
- bits = state->bits;
- lcode = state->lencode;
- dcode = state->distcode;
- lmask = (1U << state->lenbits) - 1;
- dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
- do {
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = lcode[hold & lmask];
- dolen:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
- }
- else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (op) {
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- len += (unsigned)hold & ((1U << op) - 1);
- hold >>= op;
- bits -= op;
- }
- Tracevv((stderr, "inflate: length %u\n", len));
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = dcode[hold & dmask];
- dodist:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- }
- dist += (unsigned)hold & ((1U << op) - 1);
-#ifdef INFLATE_STRICT
- if (dist > dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- hold >>= op;
- bits -= op;
- Tracevv((stderr, "inflate: distance %u\n", dist));
- op = (unsigned)(out - beg); /* max distance in output */
- if (dist > op) { /* see if copy from window */
- op = dist - op; /* distance back in window */
- if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- from = window - OFF;
- if (write == 0) { /* very common case */
- from += wsize - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
- if (op < len) { /* some from end of window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- }
- else { /* contiguous in window */
- from += write - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- }
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- else {
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- }
- else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
- goto dodist;
- }
- else {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- }
- else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
- goto dolen;
- }
- else if (op & 32) { /* end-of-block */
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- else {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- } while (in < last && out < end);
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- len = bits >> 3;
- in -= len;
- bits -= len << 3;
- hold &= (1U << bits) - 1;
-
- /* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
- strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
- strm->avail_out = (unsigned)(out < end ?
- 257 + (end - out) : 257 - (out - end));
- state->hold = hold;
- state->bits = bits;
- return;
-}
-
-/*
- inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- - Using bit fields for code structure
- - Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
- - Special case for distance > 1 copies to do overlapped load and store copy
- - Explicit branch predictions (based on measured branch probabilities)
- - Deferring match copy and interspersed it with decoding subsequent codes
- - Swapping literal/length else
- - Swapping window/direct else
- - Larger unrolled copy loops (three is about right)
- - Moving len -= 3 statement into middle of loop
- */
-
-#endif /* !ASMINF */
diff --git a/distrib/zlib-1.2.3/inffast.h b/distrib/zlib-1.2.3/inffast.h
deleted file mode 100644
index 1e88d2d..0000000
--- a/distrib/zlib-1.2.3/inffast.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/distrib/zlib-1.2.3/inffixed.h b/distrib/zlib-1.2.3/inffixed.h
deleted file mode 100644
index 75ed4b5..0000000
--- a/distrib/zlib-1.2.3/inffixed.h
+++ /dev/null
@@ -1,94 +0,0 @@
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
diff --git a/distrib/zlib-1.2.3/inflate.c b/distrib/zlib-1.2.3/inflate.c
deleted file mode 100644
index 792fdee..0000000
--- a/distrib/zlib-1.2.3/inflate.c
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * Change history:
- *
- * 1.2.beta0 24 Nov 2002
- * - First version -- complete rewrite of inflate to simplify code, avoid
- * creation of window when not needed, minimize use of window when it is
- * needed, make inffast.c even faster, implement gzip decoding, and to
- * improve code readability and style over the previous zlib inflate code
- *
- * 1.2.beta1 25 Nov 2002
- * - Use pointers for available input and output checking in inffast.c
- * - Remove input and output counters in inffast.c
- * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
- * - Remove unnecessary second byte pull from length extra in inffast.c
- * - Unroll direct copy to three copies per loop in inffast.c
- *
- * 1.2.beta2 4 Dec 2002
- * - Change external routine names to reduce potential conflicts
- * - Correct filename to inffixed.h for fixed tables in inflate.c
- * - Make hbuf[] unsigned char to match parameter type in inflate.c
- * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
- * to avoid negation problem on Alphas (64 bit) in inflate.c
- *
- * 1.2.beta3 22 Dec 2002
- * - Add comments on state->bits assertion in inffast.c
- * - Add comments on op field in inftrees.h
- * - Fix bug in reuse of allocated window after inflateReset()
- * - Remove bit fields--back to byte structure for speed
- * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
- * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
- * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
- * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
- * - Use local copies of stream next and avail values, as well as local bit
- * buffer and bit count in inflate()--for speed when inflate_fast() not used
- *
- * 1.2.beta4 1 Jan 2003
- * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
- * - Move a comment on output buffer sizes from inffast.c to inflate.c
- * - Add comments in inffast.c to introduce the inflate_fast() routine
- * - Rearrange window copies in inflate_fast() for speed and simplification
- * - Unroll last copy for window match in inflate_fast()
- * - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
- * - Make op and len in inflate_fast() unsigned for consistency
- * - Add FAR to lcode and dcode declarations in inflate_fast()
- * - Simplified bad distance check in inflate_fast()
- * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
- * source file infback.c to provide a call-back interface to inflate for
- * programs like gzip and unzip -- uses window as output buffer to avoid
- * window copying
- *
- * 1.2.beta5 1 Jan 2003
- * - Improved inflateBack() interface to allow the caller to provide initial
- * input in strm.
- * - Fixed stored blocks bug in inflateBack()
- *
- * 1.2.beta6 4 Jan 2003
- * - Added comments in inffast.c on effectiveness of POSTINC
- * - Typecasting all around to reduce compiler warnings
- * - Changed loops from while (1) or do {} while (1) to for (;;), again to
- * make compilers happy
- * - Changed type of window in inflateBackInit() to unsigned char *
- *
- * 1.2.beta7 27 Jan 2003
- * - Changed many types to unsigned or unsigned short to avoid warnings
- * - Added inflateCopy() function
- *
- * 1.2.0 9 Mar 2003
- * - Changed inflateBack() interface to provide separate opaque descriptors
- * for the in() and out() functions
- * - Changed inflateBack() argument and in_func typedef to swap the length
- * and buffer address return values for the input function
- * - Check next_in and next_out for Z_NULL on entry to inflate()
- *
- * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifdef MAKEFIXED
-# ifndef BUILDFIXED
-# define BUILDFIXED
-# endif
-#endif
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
-#ifdef BUILDFIXED
- void makefixed OF((void));
-#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
- unsigned len));
-
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- strm->total_in = strm->total_out = state->total = 0;
- strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
- state->mode = HEAD;
- state->last = 0;
- state->havedict = 0;
- state->dmax = 32768U;
- state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->write = 0;
- state->hold = 0;
- state->bits = 0;
- state->lencode = state->distcode = state->next = state->codes;
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
-}
-
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL) return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)
- ZALLOC(strm, 1, sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
-#endif
- }
- if (windowBits < 8 || windowBits > 15) {
- ZFREE(strm, state);
- strm->state = Z_NULL;
- return Z_STREAM_ERROR;
- }
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
-}
-
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-#ifdef MAKEFIXED
-#include <stdio.h>
-
-/*
- Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
- defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
- those tables to stdout, which would be piped to inffixed.h. A small program
- can simply call makefixed to do this:
-
- void makefixed(void);
-
- int main(void)
- {
- makefixed();
- return 0;
- }
-
- Then that can be linked with zlib built with MAKEFIXED defined and run:
-
- a.out > inffixed.h
- */
-void makefixed()
-{
- unsigned low, size;
- struct inflate_state state;
-
- fixedtables(&state);
- puts(" /* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by makefixed().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
- state.distcode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
-}
-#endif /* MAKEFIXED */
-
-/*
- Update the window with the last wsize (normally 32K) bytes written before
- returning. If window does not exist yet, create it. This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
-local int updatewindow(strm, out)
-z_streamp strm;
-unsigned out;
-{
- struct inflate_state FAR *state;
- unsigned copy, dist;
-
- state = (struct inflate_state FAR *)strm->state;
-
- /* if it hasn't been done already, allocate space for the window */
- if (state->window == Z_NULL) {
- state->window = (unsigned char FAR *)
- ZALLOC(strm, 1U << state->wbits,
- sizeof(unsigned char));
- if (state->window == Z_NULL) return 1;
- }
-
- /* if window not in use yet, initialize */
- if (state->wsize == 0) {
- state->wsize = 1U << state->wbits;
- state->write = 0;
- state->whave = 0;
- }
-
- /* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
- if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
- state->whave = state->wsize;
- }
- else {
- dist = state->wsize - state->write;
- if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
- copy -= dist;
- if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
- state->whave = state->wsize;
- }
- else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
- if (state->whave < state->wsize) state->whave += dist;
- }
- }
- return 0;
-}
-
-/* Macros for inflate(): */
-
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
- (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
-#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
-#endif
-
-/* check macros for header crc */
-#ifdef GUNZIP
-# define CRC2(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- check = crc32(check, hbuf, 2); \
- } while (0)
-
-# define CRC4(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- hbuf[2] = (unsigned char)((word) >> 16); \
- hbuf[3] = (unsigned char)((word) >> 24); \
- check = crc32(check, hbuf, 4); \
- } while (0)
-#endif
-
-/* Load registers with state in inflate() for speed */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Restore state from registers in inflate() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflate()
- if there is no input available. */
-#define PULLBYTE() \
- do { \
- if (have == 0) goto inf_leave; \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflate(). */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-/*
- inflate() uses a state machine to process as much input data and generate as
- much output data as possible before returning. The state machine is
- structured roughly as follows:
-
- for (;;) switch (state) {
- ...
- case STATEn:
- if (not enough input data or output space to make progress)
- return;
- ... make progress ...
- state = STATEm;
- break;
- ...
- }
-
- so when inflate() is called again, the same case is attempted again, and
- if the appropriate resources are provided, the machine proceeds to the
- next state. The NEEDBITS() macro is usually the way the state evaluates
- whether it can proceed or should return. NEEDBITS() does the return if
- the requested bits are not available. The typical use of the BITS macros
- is:
-
- NEEDBITS(n);
- ... do something with BITS(n) ...
- DROPBITS(n);
-
- where NEEDBITS(n) either returns from inflate() if there isn't enough
- input left to load n bits into the accumulator, or it continues. BITS(n)
- gives the low n bits in the accumulator. When done, DROPBITS(n) drops
- the low n bits off the accumulator. INITBITS() clears the accumulator
- and sets the number of available bits to zero. BYTEBITS() discards just
- enough bits to put the accumulator on a byte boundary. After BYTEBITS()
- and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
- NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
- if there is no input available. The decoding of variable length codes uses
- PULLBYTE() directly in order to pull just enough bytes to decode the next
- code, and no more.
-
- Some states loop until they get enough input, making sure that enough
- state information is maintained to continue the loop where it left off
- if NEEDBITS() returns in the loop. For example, want, need, and keep
- would all have to actually be part of the saved state in case NEEDBITS()
- returns:
-
- case STATEw:
- while (want < need) {
- NEEDBITS(n);
- keep[want++] = BITS(n);
- DROPBITS(n);
- }
- state = STATEx;
- case STATEx:
-
- As shown above, if the next state is also the next case, then the break
- is omitted.
-
- A state may also return if there is not enough output space available to
- complete that state. Those states are copying stored data, writing a
- literal byte, and copying a matching string.
-
- When returning, a "goto inf_leave" is used to update the total counters,
- update the check value, and determine whether any progress has been made
- during that inflate() call in order to return the proper return code.
- Progress is defined as a change in either strm->avail_in or strm->avail_out.
- When there is a window, goto inf_leave will update the window with the last
- output written. If a goto inf_leave occurs in the middle of decompression
- and there is no window currently, goto inf_leave will create one and copy
- output to the window for the next call of inflate().
-
- In this implementation, the flush parameter of inflate() only affects the
- return code (per zlib.h). inflate() always writes as much as possible to
- strm->next_out, given the space available and the provided input--the effect
- documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
- the allocation of and copying into a sliding window until necessary, which
- provides the effect documented in zlib.h for Z_FINISH when the entire input
- stream available. So the only thing the flush parameter actually does is:
- when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
- will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned in, out; /* save starting available input and output */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
-#ifdef GUNZIP
- unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
-#endif
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0))
- return Z_STREAM_ERROR;
-
- state = (struct inflate_state FAR *)strm->state;
- if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
- LOAD();
- in = have;
- out = left;
- ret = Z_OK;
- for (;;)
- switch (state->mode) {
- case HEAD:
- if (state->wrap == 0) {
- state->mode = TYPEDO;
- break;
- }
- NEEDBITS(16);
-#ifdef GUNZIP
- if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
- state->check = crc32(0L, Z_NULL, 0);
- CRC2(state->check, hold);
- INITBITS();
- state->mode = FLAGS;
- break;
- }
- state->flags = 0; /* expect zlib header */
- if (state->head != Z_NULL)
- state->head->done = -1;
- if (!(state->wrap & 1) || /* check if zlib header allowed */
-#else
- if (
-#endif
- ((BITS(8) << 8) + (hold >> 8)) % 31) {
- strm->msg = (char *)"incorrect header check";
- state->mode = BAD;
- break;
- }
- if (BITS(4) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- DROPBITS(4);
- len = BITS(4) + 8;
- if (len > state->wbits) {
- strm->msg = (char *)"invalid window size";
- state->mode = BAD;
- break;
- }
- state->dmax = 1U << len;
- Tracev((stderr, "inflate: zlib header ok\n"));
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = hold & 0x200 ? DICTID : TYPE;
- INITBITS();
- break;
-#ifdef GUNZIP
- case FLAGS:
- NEEDBITS(16);
- state->flags = (int)(hold);
- if ((state->flags & 0xff) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- if (state->flags & 0xe000) {
- strm->msg = (char *)"unknown header flags set";
- state->mode = BAD;
- break;
- }
- if (state->head != Z_NULL)
- state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = TIME;
- case TIME:
- NEEDBITS(32);
- if (state->head != Z_NULL)
- state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
- INITBITS();
- state->mode = OS;
- case OS:
- NEEDBITS(16);
- if (state->head != Z_NULL) {
- state->head->xflags = (int)(hold & 0xff);
- state->head->os = (int)(hold >> 8);
- }
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = EXLEN;
- case EXLEN:
- if (state->flags & 0x0400) {
- NEEDBITS(16);
- state->length = (unsigned)(hold);
- if (state->head != Z_NULL)
- state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- }
- else if (state->head != Z_NULL)
- state->head->extra = Z_NULL;
- state->mode = EXTRA;
- case EXTRA:
- if (state->flags & 0x0400) {
- copy = state->length;
- if (copy > have) copy = have;
- if (copy) {
- if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
- zmemcpy(state->head->extra + len, next,
- len + copy > state->head->extra_max ?
- state->head->extra_max - len : copy);
- }
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- state->length -= copy;
- }
- if (state->length) goto inf_leave;
- }
- state->length = 0;
- state->mode = NAME;
- case NAME:
- if (state->flags & 0x0800) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->name != Z_NULL &&
- state->length < state->head->name_max)
- state->head->name[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->name = Z_NULL;
- state->length = 0;
- state->mode = COMMENT;
- case COMMENT:
- if (state->flags & 0x1000) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->comment != Z_NULL &&
- state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->comment = Z_NULL;
- state->mode = HCRC;
- case HCRC:
- if (state->flags & 0x0200) {
- NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
- strm->msg = (char *)"header crc mismatch";
- state->mode = BAD;
- break;
- }
- INITBITS();
- }
- if (state->head != Z_NULL) {
- state->head->hcrc = (int)((state->flags >> 9) & 1);
- state->head->done = 1;
- }
- strm->adler = state->check = crc32(0L, Z_NULL, 0);
- state->mode = TYPE;
- break;
-#endif
- case DICTID:
- NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
- INITBITS();
- state->mode = DICT;
- case DICT:
- if (state->havedict == 0) {
- RESTORE();
- return Z_NEED_DICT;
- }
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = TYPE;
- case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
- case TYPEDO:
- if (state->last) {
- BYTEBITS();
- state->mode = CHECK;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
- case STORED:
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
- state->mode = COPY;
- case COPY:
- copy = state->length;
- if (copy) {
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- if (copy == 0) goto inf_leave;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- break;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
- case TABLE:
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
- state->have = 0;
- state->mode = LENLENS;
- case LENLENS:
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
- state->have = 0;
- state->mode = CODELENS;
- case CODELENS:
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = state->lens[state->have - 1];
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
- case LEN:
- if (have >= 6 && left >= 258) {
- RESTORE();
- inflate_fast(strm, out);
- LOAD();
- break;
- }
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
- if ((int)(this.op) == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- state->mode = LIT;
- break;
- }
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- state->extra = (unsigned)(this.op) & 15;
- state->mode = LENEXT;
- case LENEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
- state->mode = DIST;
- case DIST:
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
- state->extra = (unsigned)(this.op) & 15;
- state->mode = DISTEXT;
- case DISTEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
-#ifdef INFLATE_STRICT
- if (state->offset > state->dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
- state->mode = MATCH;
- case MATCH:
- if (left == 0) goto inf_leave;
- copy = out - left;
- if (state->offset > copy) { /* copy from window */
- copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
- from = state->window + (state->wsize - copy);
- }
- else
- from = state->window + (state->write - copy);
- if (copy > state->length) copy = state->length;
- }
- else { /* copy from output */
- from = put - state->offset;
- copy = state->length;
- }
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
- case LIT:
- if (left == 0) goto inf_leave;
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- case CHECK:
- if (state->wrap) {
- NEEDBITS(32);
- out -= left;
- strm->total_out += out;
- state->total += out;
- if (out)
- strm->adler = state->check =
- UPDATE(state->check, put - out, out);
- out = left;
- if ((
-#ifdef GUNZIP
- state->flags ? hold :
-#endif
- REVERSE(hold)) != state->check) {
- strm->msg = (char *)"incorrect data check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: check matches trailer\n"));
- }
-#ifdef GUNZIP
- state->mode = LENGTH;
- case LENGTH:
- if (state->wrap && state->flags) {
- NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
- strm->msg = (char *)"incorrect length check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: length matches trailer\n"));
- }
-#endif
- state->mode = DONE;
- case DONE:
- ret = Z_STREAM_END;
- goto inf_leave;
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
- case MEM:
- return Z_MEM_ERROR;
- case SYNC:
- default:
- return Z_STREAM_ERROR;
- }
-
- /*
- Return from inflate(), updating the total counts and the check value.
- If there was no progress during the inflate() call, return a buffer
- error. Call updatewindow() to create and/or update the window state.
- Note: a memory error from inflate() is non-recoverable.
- */
- inf_leave:
- RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- in -= strm->avail_in;
- out -= strm->avail_out;
- strm->total_in += in;
- strm->total_out += out;
- state->total += out;
- if (state->wrap && out)
- strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
- return ret;
-}
-
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
- struct inflate_state FAR *state;
- unsigned long id;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->wrap != 0 && state->mode != DICT)
- return Z_STREAM_ERROR;
-
- /* check for correct dictionary id */
- if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
- return Z_DATA_ERROR;
- }
-
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
- state->havedict = 1;
- Tracev((stderr, "inflate: dictionary set\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
- struct inflate_state FAR *state;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
-
- /* save header structure */
- state->head = head;
- head->done = 0;
- return Z_OK;
-}
-
-/*
- Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
- or when out of input. When called, *have is the number of pattern bytes
- found in order so far, in 0..3. On return *have is updated to the new
- state. If on return *have equals four, then the pattern was found and the
- return value is how many bytes were read including the last byte of the
- pattern. If *have is less than four, then the pattern has not been found
- yet and the return value is len. In the latter case, syncsearch() can be
- called again with more data and the *have state. *have is initialized to
- zero for the first call.
- */
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-unsigned char FAR *buf;
-unsigned len;
-{
- unsigned got;
- unsigned next;
-
- got = *have;
- next = 0;
- while (next < len && got < 4) {
- if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
- got++;
- else if (buf[next])
- got = 0;
- else
- got = 4 - got;
- next++;
- }
- *have = got;
- return next;
-}
-
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
- unsigned len; /* number of bytes to look at or looked at */
- unsigned long in, out; /* temporary to save total_in and total_out */
- unsigned char buf[4]; /* to restore bit buffer to byte string */
- struct inflate_state FAR *state;
-
- /* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
-
- /* if first time, start search in bit buffer */
- if (state->mode != SYNC) {
- state->mode = SYNC;
- state->hold <<= state->bits & 7;
- state->bits -= state->bits & 7;
- len = 0;
- while (state->bits >= 8) {
- buf[len++] = (unsigned char)(state->hold);
- state->hold >>= 8;
- state->bits -= 8;
- }
- state->have = 0;
- syncsearch(&(state->have), buf, len);
- }
-
- /* search available input */
- len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
- strm->avail_in -= len;
- strm->next_in += len;
- strm->total_in += len;
-
- /* return no joy or set up to restart inflate() on a new block */
- if (state->have != 4) return Z_DATA_ERROR;
- in = strm->total_in; out = strm->total_out;
- inflateReset(strm);
- strm->total_in = in; strm->total_out = out;
- state->mode = TYPE;
- return Z_OK;
-}
-
-/*
- Returns true if inflate is currently at the end of a block generated by
- Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- implementation to provide an additional safety check. PPP uses
- Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
- block. When decompressing, PPP checks that at the end of input packet,
- inflate is waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- return state->mode == STORED && state->bits == 0;
-}
-
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
- struct inflate_state FAR *state;
- struct inflate_state FAR *copy;
- unsigned char FAR *window;
- unsigned wsize;
-
- /* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)source->state;
-
- /* allocate space */
- copy = (struct inflate_state FAR *)
- ZALLOC(source, 1, sizeof(struct inflate_state));
- if (copy == Z_NULL) return Z_MEM_ERROR;
- window = Z_NULL;
- if (state->window != Z_NULL) {
- window = (unsigned char FAR *)
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
- if (window == Z_NULL) {
- ZFREE(source, copy);
- return Z_MEM_ERROR;
- }
- }
-
- /* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
- if (state->lencode >= state->codes &&
- state->lencode <= state->codes + ENOUGH - 1) {
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
- }
- copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL) {
- wsize = 1U << state->wbits;
- zmemcpy(window, state->window, wsize);
- }
- copy->window = window;
- dest->state = (struct internal_state FAR *)copy;
- return Z_OK;
-}
diff --git a/distrib/zlib-1.2.3/inflate.h b/distrib/zlib-1.2.3/inflate.h
deleted file mode 100644
index 07bd3e7..0000000
--- a/distrib/zlib-1.2.3/inflate.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip decoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GUNZIP
-#endif
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
- HEAD, /* i: waiting for magic header */
- FLAGS, /* i: waiting for method and flags (gzip) */
- TIME, /* i: waiting for modification time (gzip) */
- OS, /* i: waiting for extra flags and operating system (gzip) */
- EXLEN, /* i: waiting for extra length (gzip) */
- EXTRA, /* i: waiting for extra bytes (gzip) */
- NAME, /* i: waiting for end of file name (gzip) */
- COMMENT, /* i: waiting for end of comment (gzip) */
- HCRC, /* i: waiting for header crc (gzip) */
- DICTID, /* i: waiting for dictionary check value */
- DICT, /* waiting for inflateSetDictionary() call */
- TYPE, /* i: waiting for type bits, including last-flag bit */
- TYPEDO, /* i: same, but skip check to exit inflate on new block */
- STORED, /* i: waiting for stored size (length and complement) */
- COPY, /* i/o: waiting for input or output to copy stored block */
- TABLE, /* i: waiting for dynamic block table lengths */
- LENLENS, /* i: waiting for code length code lengths */
- CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
- LENEXT, /* i: waiting for length extra bits */
- DIST, /* i: waiting for distance code */
- DISTEXT, /* i: waiting for distance extra bits */
- MATCH, /* o: waiting for output space to copy string */
- LIT, /* o: waiting for output space to write literal */
- CHECK, /* i: waiting for 32-bit check value */
- LENGTH, /* i: waiting for 32-bit length (gzip) */
- DONE, /* finished check, done -- remain here until reset */
- BAD, /* got a data error -- remain here until reset */
- MEM, /* got an inflate() memory error -- remain here until reset */
- SYNC /* looking for synchronization bytes to restart inflate() */
-} inflate_mode;
-
-/*
- State transitions between above modes -
-
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
-
- Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
- (zlib) -> DICTID or TYPE
- DICTID -> DICT -> TYPE
- Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
- LEN -> LENEXT or LIT or TYPE
- LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
- LIT -> LEN
- Process trailer:
- CHECK -> LENGTH -> DONE
- */
-
-/* state maintained between inflate() calls. Approximately 7K bytes. */
-struct inflate_state {
- inflate_mode mode; /* current inflate mode */
- int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
- unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
- unsigned long check; /* protected copy of check value */
- unsigned long total; /* protected copy of output count */
- gz_headerp head; /* where to save gzip header information */
- /* sliding window */
- unsigned wbits; /* log base 2 of requested window size */
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* bit accumulator */
- unsigned long hold; /* input bit accumulator */
- unsigned bits; /* number of bits in "in" */
- /* for string and stored block copying */
- unsigned length; /* literal or length of data to copy */
- unsigned offset; /* distance back to copy string from */
- /* for table and code decoding */
- unsigned extra; /* extra bits needed */
- /* fixed and dynamic code tables */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
-};
diff --git a/distrib/zlib-1.2.3/inftrees.c b/distrib/zlib-1.2.3/inftrees.c
deleted file mode 100644
index 8a9c13f..0000000
--- a/distrib/zlib-1.2.3/inftrees.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#define MAXBITS 15
-
-const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
-int inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
- static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577, 0, 0};
- static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
- 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
- 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 28, 28, 29, 29, 64, 64};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) { /* no symbols to code at all */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)1;
- this.val = (unsigned short)0;
- *(*table)++ = this; /* make a table to force an error */
- *(*table)++ = this;
- *bits = 1;
- return 0; /* no symbols, but wait for decoding to report error */
- }
- for (min = 1; min <= MAXBITS; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || max != 1))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- this.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
- }
- else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- min = fill; /* save offset to next table */
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = this;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += min; /* here min is 1 << curr */
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- this.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = this;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
-}
diff --git a/distrib/zlib-1.2.3/inftrees.h b/distrib/zlib-1.2.3/inftrees.h
deleted file mode 100644
index b1104c8..0000000
--- a/distrib/zlib-1.2.3/inftrees.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
-typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
-} code;
-
-/* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 0001eeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
-
-/* Type of code to build for inftable() */
-typedef enum {
- CODES,
- LENS,
- DISTS
-} codetype;
-
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
diff --git a/distrib/zlib-1.2.3/sources.make b/distrib/zlib-1.2.3/sources.make
deleted file mode 100644
index c15fd78..0000000
--- a/distrib/zlib-1.2.3/sources.make
+++ /dev/null
@@ -1,4 +0,0 @@
-# this is included by various Makefiles
-ZLIB_SOURCES := adler32.c compress.c crc32.c deflate.c gzio.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
-ZLIB_SOURCES := $(ZLIB_SOURCES:%=$(ZLIB_DIR)/%)
-
diff --git a/distrib/zlib-1.2.3/trees.c b/distrib/zlib-1.2.3/trees.c
deleted file mode 100644
index 395e4e1..0000000
--- a/distrib/zlib-1.2.3/trees.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id$ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
- s->depth[n] : s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute the block lengths in bytes. */
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n;
-
- for (n = 0; n < 9; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/distrib/zlib-1.2.3/trees.h b/distrib/zlib-1.2.3/trees.h
deleted file mode 100644
index 72facf9..0000000
--- a/distrib/zlib-1.2.3/trees.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
diff --git a/distrib/zlib-1.2.3/uncompr.c b/distrib/zlib-1.2.3/uncompr.c
deleted file mode 100644
index b59e3d0..0000000
--- a/distrib/zlib-1.2.3/uncompr.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
- return Z_DATA_ERROR;
- return err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
diff --git a/distrib/zlib-1.2.3/zconf.h b/distrib/zlib-1.2.3/zconf.h
deleted file mode 100644
index 03a9431..0000000
--- a/distrib/zlib-1.2.3/zconf.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/distrib/zlib-1.2.3/zlib.h b/distrib/zlib-1.2.3/zlib.h
deleted file mode 100644
index 0228179..0000000
--- a/distrib/zlib-1.2.3/zlib.h
+++ /dev/null
@@ -1,1357 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
-
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef ZLIB_H
-#define ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
-*/
-typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
-} gz_header;
-
-typedef gz_header FAR *gz_headerp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-#define Z_BLOCK 5
-/* Allowed flush values; see deflate() and inflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_RLE 3
-#define Z_FIXED 4
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_TEXT 1
-#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
-*/
-
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
-*/
-
-
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
-/*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
-/*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
-*/
-
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
-*/
-
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
-*/
-
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-/*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
-*/
-
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
-/*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
-*/
-
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
-/* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
-/*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
-*/
-
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
-*/
-
-
-typedef voidp gzFile;
-
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
-*/
-
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
-/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
-*/
-
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
-/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
-/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
-/*
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
-*/
-
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
-/*
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZLIB_H */
diff --git a/distrib/zlib-1.2.3/zutil.c b/distrib/zlib-1.2.3/zutil.c
deleted file mode 100644
index d55f594..0000000
--- a/distrib/zlib-1.2.3/zutil.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zutil.h"
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-uLong ZEXPORT zlibCompileFlags()
-{
- uLong flags;
-
- flags = 0;
- switch (sizeof(uInt)) {
- case 2: break;
- case 4: flags += 1; break;
- case 8: flags += 2; break;
- default: flags += 3;
- }
- switch (sizeof(uLong)) {
- case 2: break;
- case 4: flags += 1 << 2; break;
- case 8: flags += 2 << 2; break;
- default: flags += 3 << 2;
- }
- switch (sizeof(voidpf)) {
- case 2: break;
- case 4: flags += 1 << 4; break;
- case 8: flags += 2 << 4; break;
- default: flags += 3 << 4;
- }
- switch (sizeof(z_off_t)) {
- case 2: break;
- case 4: flags += 1 << 6; break;
- case 8: flags += 2 << 6; break;
- default: flags += 3 << 6;
- }
-#ifdef DEBUG
- flags += 1 << 8;
-#endif
-#if defined(ASMV) || defined(ASMINF)
- flags += 1 << 9;
-#endif
-#ifdef ZLIB_WINAPI
- flags += 1 << 10;
-#endif
-#ifdef BUILDFIXED
- flags += 1 << 12;
-#endif
-#ifdef DYNAMIC_CRC_TABLE
- flags += 1 << 13;
-#endif
-#ifdef NO_GZCOMPRESS
- flags += 1L << 16;
-#endif
-#ifdef NO_GZIP
- flags += 1L << 17;
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
- flags += 1L << 20;
-#endif
-#ifdef FASTEST
- flags += 1L << 21;
-#endif
-#ifdef STDC
-# ifdef NO_vsnprintf
- flags += 1L << 25;
-# ifdef HAS_vsprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#else
- flags += 1L << 24;
-# ifdef NO_snprintf
- flags += 1L << 25;
-# ifdef HAS_sprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_snprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#endif
- return flags;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int z_verbose = verbose;
-
-void z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-#if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used.
- */
- int errno = 0;
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-
-#ifdef SYS16BIT
-
-#ifdef __TURBOC__
-/* Turbo C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-
-#endif /* __TURBOC__ */
-
-
-#ifdef M_I86
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* M_I86 */
-
-#endif /* SYS16BIT */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
- (voidpf)calloc(items, size);
-}
-
-void zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
diff --git a/distrib/zlib-1.2.3/zutil.h b/distrib/zlib-1.2.3/zutil.h
deleted file mode 100644
index b7d5eff..0000000
--- a/distrib/zlib-1.2.3/zutil.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZUTIL_H
-#define ZUTIL_H
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#ifdef STDC
-# ifndef _WIN32_WCE
-# include <stddef.h>
-# endif
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-# ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
-# define errno z_errno
-# endif
- extern int errno;
-#else
-# ifndef _WIN32_WCE
-# include <errno.h>
-# endif
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-# ifdef M_I86
- #include <malloc.h>
-# endif
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#ifdef WIN32
-# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
-# define OS_CODE 0x0b
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0f
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# if defined(_WIN32_WCE)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
-# define _PTRDIFF_T_DEFINED
-# endif
-# else
-# define fdopen(fd,type) _fdopen(fd,type)
-# endif
-#endif
-
- /* common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#if defined(__CYGWIN__)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#ifndef HAVE_VSNPRINTF
-# ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
-# define NO_vsnprintf
-# endif
-# ifdef __TURBOC__
-# define NO_vsnprintf
-# endif
-# ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# define vsnprintf _vsnprintf
-# endif
-# endif
-# ifdef __SASC
-# define NO_vsnprintf
-# endif
-#endif
-#ifdef VMS
-# define NO_vsnprintf
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* ZUTIL_H */
diff --git a/dyngen-exec.h b/dyngen-exec.h
deleted file mode 100644
index 9260b6f..0000000
--- a/dyngen-exec.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * dyngen defines for micro operation code
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#if !defined(__DYNGEN_EXEC_H__)
-#define __DYNGEN_EXEC_H__
-
-/* prevent Solaris from trying to typedef FILE in gcc's
- include/floatingpoint.h which will conflict with the
- definition down below */
-#ifdef __sun__
-#define _FILEDEFED
-#endif
-
-/* NOTE: standard headers should be used with special care at this
- point because host CPU registers are used as global variables. Some
- host headers do not allow that. */
-#include <stddef.h>
-
-#ifdef __OpenBSD__
-#include <sys/types.h>
-#else
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-// Linux/Sparc64 defines uint64_t
-#if !(defined (__sparc_v9__) && defined(__linux__)) && !(defined(__APPLE__) && defined(__x86_64__))
-/* XXX may be done for all 64 bits targets ? */
-#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) || defined(__powerpc64__)
-typedef unsigned long uint64_t;
-#else
-typedef unsigned long long uint64_t;
-#endif
-#endif
-
-/* if Solaris/__sun__, don't typedef int8_t, as it will be typedef'd
- prior to this and will cause an error in compliation, conflicting
- with /usr/include/sys/int_types.h, line 75 */
-#ifndef __sun__
-typedef signed char int8_t;
-#endif
-typedef signed short int16_t;
-typedef signed int int32_t;
-// Linux/Sparc64 defines int64_t
-#if !(defined (__sparc_v9__) && defined(__linux__)) && !(defined(__APPLE__) && defined(__x86_64__))
-#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) || defined(__powerpc64__)
-typedef signed long int64_t;
-#else
-typedef signed long long int64_t;
-#endif
-#endif
-#endif
-
-/* XXX: This may be wrong for 64-bit ILP32 hosts. */
-typedef void * host_reg_t;
-
-#define INT8_MIN (-128)
-#define INT16_MIN (-32767-1)
-#define INT32_MIN (-2147483647-1)
-#define INT64_MIN (-(int64_t)(9223372036854775807)-1)
-#define INT8_MAX (127)
-#define INT16_MAX (32767)
-#define INT32_MAX (2147483647)
-#define INT64_MAX ((int64_t)(9223372036854775807))
-#define UINT8_MAX (255)
-#define UINT16_MAX (65535)
-#define UINT32_MAX (4294967295U)
-#define UINT64_MAX ((uint64_t)(18446744073709551615))
-
-#ifdef _BSD
-typedef struct __sFILE FILE;
-#else
-typedef struct FILE FILE;
-#endif
-extern int fprintf(FILE *, const char *, ...);
-extern int fputs(const char *, FILE *);
-extern int printf(const char *, ...);
-#undef NULL
-#define NULL 0
-
-#if defined(__i386__)
-#define AREG0 "ebp"
-#define AREG1 "ebx"
-#define AREG2 "esi"
-#define AREG3 "edi"
-#elif defined(__x86_64__)
-#define AREG0 "r14"
-#define AREG1 "r15"
-#define AREG2 "r12"
-#define AREG3 "r13"
-//#define AREG4 "rbp"
-//#define AREG5 "rbx"
-#elif defined(__powerpc__)
-#define AREG0 "r27"
-#define AREG1 "r24"
-#define AREG2 "r25"
-#define AREG3 "r26"
-/* XXX: suppress this hack */
-#if defined(CONFIG_USER_ONLY)
-#define AREG4 "r16"
-#define AREG5 "r17"
-#define AREG6 "r18"
-#define AREG7 "r19"
-#define AREG8 "r20"
-#define AREG9 "r21"
-#define AREG10 "r22"
-#define AREG11 "r23"
-#endif
-#elif defined(__arm__)
-#define AREG0 "r7"
-#define AREG1 "r4"
-#define AREG2 "r5"
-#define AREG3 "r6"
-#elif defined(__hppa__)
-#define AREG0 "r17"
-#define AREG1 "r14"
-#define AREG2 "r15"
-#define AREG3 "r16"
-#elif defined(__mips__)
-#define AREG0 "fp"
-#define AREG1 "s0"
-#define AREG2 "s1"
-#define AREG3 "s2"
-#define AREG4 "s3"
-#define AREG5 "s4"
-#define AREG6 "s5"
-#define AREG7 "s6"
-#define AREG8 "s7"
-#elif defined(__sparc__)
-#ifdef HOST_SOLARIS
-#define AREG0 "g2"
-#define AREG1 "g3"
-#define AREG2 "g4"
-#define AREG3 "g5"
-#define AREG4 "g6"
-#else
-#ifdef __sparc_v9__
-#define AREG0 "g5"
-#define AREG1 "g6"
-#define AREG2 "g7"
-#else
-#define AREG0 "g6"
-#define AREG1 "g1"
-#define AREG2 "g2"
-#define AREG3 "g3"
-#define AREG4 "l0"
-#define AREG5 "l1"
-#define AREG6 "l2"
-#define AREG7 "l3"
-#define AREG8 "l4"
-#define AREG9 "l5"
-#define AREG10 "l6"
-#define AREG11 "l7"
-#endif
-#endif
-#elif defined(__s390__)
-#define AREG0 "r10"
-#define AREG1 "r7"
-#define AREG2 "r8"
-#define AREG3 "r9"
-#elif defined(__alpha__)
-/* Note $15 is the frame pointer, so anything in op-i386.c that would
- require a frame pointer, like alloca, would probably loose. */
-#define AREG0 "$15"
-#define AREG1 "$9"
-#define AREG2 "$10"
-#define AREG3 "$11"
-#define AREG4 "$12"
-#define AREG5 "$13"
-#define AREG6 "$14"
-#elif defined(__mc68000)
-#define AREG0 "%a5"
-#define AREG1 "%a4"
-#define AREG2 "%d7"
-#define AREG3 "%d6"
-#define AREG4 "%d5"
-#elif defined(__ia64__)
-#define AREG0 "r7"
-#define AREG1 "r4"
-#define AREG2 "r5"
-#define AREG3 "r6"
-#else
-#error unsupported CPU
-#endif
-
-/* force GCC to generate only one epilog at the end of the function */
-#define FORCE_RET() __asm__ __volatile__("" : : : "memory");
-
-#ifndef OPPROTO
-#define OPPROTO
-#endif
-
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-
-#if defined(__alpha__) || defined(__s390__)
-/* the symbols are considered non exported so a br immediate is generated */
-#define __hidden __attribute__((visibility("hidden")))
-#else
-#define __hidden
-#endif
-
-#if defined(__alpha__)
-/* Suggested by Richard Henderson. This will result in code like
- ldah $0,__op_param1($29) !gprelhigh
- lda $0,__op_param1($0) !gprellow
- We can then conveniently change $29 to $31 and adapt the offsets to
- emit the appropriate constant. */
-extern int __op_param1 __hidden;
-extern int __op_param2 __hidden;
-extern int __op_param3 __hidden;
-#define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
-#define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
-#define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
-#elif defined(__s390__)
-extern int __op_param1 __hidden;
-extern int __op_param2 __hidden;
-extern int __op_param3 __hidden;
-#define PARAM1 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param1) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
-#define PARAM2 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param2) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
-#define PARAM3 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param3) "; l %0,0(%0)" : "=r"(_r) : ); _r; })
-#else
-#if defined(__APPLE__)
-static int __op_param1, __op_param2, __op_param3;
-#else
-extern int __op_param1, __op_param2, __op_param3;
-#endif
-#define PARAM1 ((long)(&__op_param1))
-#define PARAM2 ((long)(&__op_param2))
-#define PARAM3 ((long)(&__op_param3))
-#endif /* !defined(__alpha__) */
-
-extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if defined(_WIN32) || defined(__APPLE__)
-#define ASM_NAME(x) "_" #x
-#else
-#define ASM_NAME(x) #x
-#endif
-
-#if defined(__i386__)
-#define EXIT_TB() asm volatile ("ret")
-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#elif defined(__x86_64__)
-#define EXIT_TB() asm volatile ("ret")
-#define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n)
-#elif defined(__powerpc__)
-#define EXIT_TB() asm volatile ("blr")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#elif defined(__s390__)
-#define EXIT_TB() asm volatile ("br %r14")
-#define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; .long " ASM_NAME(__op_gen_label) #n)
-#elif defined(__alpha__)
-#define EXIT_TB() asm volatile ("ret")
-#elif defined(__ia64__)
-#define EXIT_TB() asm volatile ("br.ret.sptk.many b0;;")
-#define GOTO_LABEL_PARAM(n) asm volatile ("br.sptk.many " \
- ASM_NAME(__op_gen_label) #n)
-#elif defined(__sparc__)
-#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
-#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
-#elif defined(__arm__)
-#define EXIT_TB() asm volatile ("b exec_loop")
-#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
-#elif defined(__mc68000)
-#define EXIT_TB() asm volatile ("rts")
-#elif defined(__mips__)
-#define EXIT_TB() asm volatile ("jr $ra")
-#define GOTO_LABEL_PARAM(n) asm volatile (".set noat; la $1, " ASM_NAME(__op_gen_label) #n "; jr $1; .set at")
-#elif defined(__hppa__)
-#define GOTO_LABEL_PARAM(n) asm volatile ("b,n " ASM_NAME(__op_gen_label) #n)
-#else
-#error unsupported CPU
-#endif
-
-/* The return address may point to the start of the next instruction.
- Subtracting one gets us the call instruction itself. */
-#if defined(__s390__)
-# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1))
-#elif defined(__arm__)
-/* Thumb return addresses have the low bit set, so we need to subtract two.
- This is still safe in ARM mode because instructions are 4 bytes. */
-# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2))
-#else
-# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1))
-#endif
-
-#endif /* !defined(__DYNGEN_EXEC_H__) */
diff --git a/dynlink.h b/dynlink.h
deleted file mode 100644
index f156b37..0000000
--- a/dynlink.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (c) 2008 The Android Open Source Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Lazy Dynamic Linking Support
- *
- * This header file is meant to be included multiple times.
- *
- * It is used to define function pointers to symbols in external
- * shared objects (Unix dynamic libraries) which will be lazily resolved
- * at runtime, by calling a specific initialization function.
- *
- * You must define, before including this header, a DYNLINK_FUNCTIONS
- * macro which must contain a sequence of DYNLINK_FUNC(ret,name,sig)
- * statements.
- *
- * In each statement, 'ret' is a function return type, 'name' is
- * the function's name as provided by the library, and 'sig' is
- * the function signature, including enclosing parentheses.
- *
- * Here's an example:
- *
- * #define DYNLINK_FUNCTIONS \
- * DYNLINK_FUNC(int,open,(const char*, int)) \
- * DYNLINK_FUNC(int,read,(int,char*,int)) \
- * DYNLINK_FUNC(int,close,(int)) \
- *
- *
- * You must also define a DYNLINK_FUNCTIONS_INIT macro which contains the
- * name of a generated function used to initialize the function pointers.
- * (see below)
- */
-
-#ifndef DYNLINK_FUNCTIONS
-#error DYNLINK_FUNCTIONS should be defined when including this file
-#endif
-
-#ifndef DYNLINK_FUNCTIONS_INIT
-#error DYNLINK_FUNCTIONS_INIT should be defined when including this file
-#endif
-
-/* just in case */
-#undef DYNLINK_FUNC
-
-/* define pointers to dynamic library functions as static pointers.
- */
-#define DYNLINK_FUNC(ret,name,sig) \
- static ret (*_dynlink_##name) sig ;
-
-#define DYNLINK_STR(name) DYNLINK_STR_(name)
-#define DYNLINK_STR_(name) #name
-
-DYNLINK_FUNCTIONS
-#undef DYNLINK_FUNC
-
-/* now define a function that tries to load all dynlink function
- * pointers. returns 0 on success, or -1 on error (i.e. if any of
- * the functions could not be loaded).
- *
- * 'library' must be the result of a succesful dlopen() call
- *
- * You must define DYNLINK_FUNCTIONS_INIT
- */
-static int
-DYNLINK_FUNCTIONS_INIT(void* library)
-{
-#define DYNLINK_FUNC(ret,name,sig) \
- do { \
- _dynlink_##name = dlsym( library, DYNLINK_STR(name) ); \
- if (_dynlink_##name == NULL) goto Fail; \
- } while (0);
-
- DYNLINK_FUNCTIONS
-#undef DYNLINK_FUNC
-
- return 0;
-Fail:
- return -1;
-}
-
-/* in user code, use FF(function_name) to invoke the
- * corresponding dynamic function named 'function_name'
- * after initialization succeeded.
- */
-#ifndef FF
-#define FF(name) (*_dynlink_##name)
-#endif
-
-/* clear macros */
-#undef DYNLINK_FUNC
-#undef DYNLINK_FUNCTIONS
-#undef DYNLINK_FUNCTIONS_INIT
diff --git a/elf.h b/elf.h
deleted file mode 100644
index 861f1d3..0000000
--- a/elf.h
+++ /dev/null
@@ -1,1172 +0,0 @@
-#ifndef _QEMU_ELF_H
-#define _QEMU_ELF_H
-
-#include <inttypes.h>
-
-/* 32-bit ELF base types. */
-typedef uint32_t Elf32_Addr;
-typedef uint16_t Elf32_Half;
-typedef uint32_t Elf32_Off;
-typedef int32_t Elf32_Sword;
-typedef uint32_t Elf32_Word;
-
-/* 64-bit ELF base types. */
-typedef uint64_t Elf64_Addr;
-typedef uint16_t Elf64_Half;
-typedef int16_t Elf64_SHalf;
-typedef uint64_t Elf64_Off;
-typedef int32_t Elf64_Sword;
-typedef uint32_t Elf64_Word;
-typedef uint64_t Elf64_Xword;
-typedef int64_t Elf64_Sxword;
-
-/* These constants are for the segment types stored in the image headers */
-#define PT_NULL 0
-#define PT_LOAD 1
-#define PT_DYNAMIC 2
-#define PT_INTERP 3
-#define PT_NOTE 4
-#define PT_SHLIB 5
-#define PT_PHDR 6
-#define PT_LOPROC 0x70000000
-#define PT_HIPROC 0x7fffffff
-#define PT_MIPS_REGINFO 0x70000000
-#define PT_MIPS_OPTIONS 0x70000001
-
-/* Flags in the e_flags field of the header */
-/* MIPS architecture level. */
-#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
-#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
-
-/* The ABI of a file. */
-#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
-#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */
-
-#define EF_MIPS_NOREORDER 0x00000001
-#define EF_MIPS_PIC 0x00000002
-#define EF_MIPS_CPIC 0x00000004
-#define EF_MIPS_ABI2 0x00000020
-#define EF_MIPS_OPTIONS_FIRST 0x00000080
-#define EF_MIPS_32BITMODE 0x00000100
-#define EF_MIPS_ABI 0x0000f000
-#define EF_MIPS_ARCH 0xf0000000
-
-/* These constants define the different elf file types */
-#define ET_NONE 0
-#define ET_REL 1
-#define ET_EXEC 2
-#define ET_DYN 3
-#define ET_CORE 4
-#define ET_LOPROC 0xff00
-#define ET_HIPROC 0xffff
-
-/* These constants define the various ELF target machines */
-#define EM_NONE 0
-#define EM_M32 1
-#define EM_SPARC 2
-#define EM_386 3
-#define EM_68K 4
-#define EM_88K 5
-#define EM_486 6 /* Perhaps disused */
-#define EM_860 7
-
-#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
-
-#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
-
-#define EM_PARISC 15 /* HPPA */
-
-#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-
-#define EM_PPC 20 /* PowerPC */
-#define EM_PPC64 21 /* PowerPC64 */
-
-#define EM_ARM 40 /* ARM */
-
-#define EM_SH 42 /* SuperH */
-
-#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-
-#define EM_IA_64 50 /* HP/Intel IA-64 */
-
-#define EM_X86_64 62 /* AMD x86-64 */
-
-#define EM_S390 22 /* IBM S/390 */
-
-#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
-
-#define EM_V850 87 /* NEC v850 */
-
-#define EM_H8_300H 47 /* Hitachi H8/300H */
-#define EM_H8S 48 /* Hitachi H8S */
-
-/*
- * This is an interim value that we will use until the committee comes
- * up with a final number.
- */
-#define EM_ALPHA 0x9026
-
-/* Bogus old v850 magic number, used by old tools. */
-#define EM_CYGNUS_V850 0x9080
-
-/*
- * This is the old interim value for S/390 architecture
- */
-#define EM_S390_OLD 0xA390
-
-/* This is the info that is needed to parse the dynamic section of the file */
-#define DT_NULL 0
-#define DT_NEEDED 1
-#define DT_PLTRELSZ 2
-#define DT_PLTGOT 3
-#define DT_HASH 4
-#define DT_STRTAB 5
-#define DT_SYMTAB 6
-#define DT_RELA 7
-#define DT_RELASZ 8
-#define DT_RELAENT 9
-#define DT_STRSZ 10
-#define DT_SYMENT 11
-#define DT_INIT 12
-#define DT_FINI 13
-#define DT_SONAME 14
-#define DT_RPATH 15
-#define DT_SYMBOLIC 16
-#define DT_REL 17
-#define DT_RELSZ 18
-#define DT_RELENT 19
-#define DT_PLTREL 20
-#define DT_DEBUG 21
-#define DT_TEXTREL 22
-#define DT_JMPREL 23
-#define DT_LOPROC 0x70000000
-#define DT_HIPROC 0x7fffffff
-#define DT_MIPS_RLD_VERSION 0x70000001
-#define DT_MIPS_TIME_STAMP 0x70000002
-#define DT_MIPS_ICHECKSUM 0x70000003
-#define DT_MIPS_IVERSION 0x70000004
-#define DT_MIPS_FLAGS 0x70000005
- #define RHF_NONE 0
- #define RHF_HARDWAY 1
- #define RHF_NOTPOT 2
-#define DT_MIPS_BASE_ADDRESS 0x70000006
-#define DT_MIPS_CONFLICT 0x70000008
-#define DT_MIPS_LIBLIST 0x70000009
-#define DT_MIPS_LOCAL_GOTNO 0x7000000a
-#define DT_MIPS_CONFLICTNO 0x7000000b
-#define DT_MIPS_LIBLISTNO 0x70000010
-#define DT_MIPS_SYMTABNO 0x70000011
-#define DT_MIPS_UNREFEXTNO 0x70000012
-#define DT_MIPS_GOTSYM 0x70000013
-#define DT_MIPS_HIPAGENO 0x70000014
-#define DT_MIPS_RLD_MAP 0x70000016
-
-/* This info is needed when parsing the symbol table */
-#define STB_LOCAL 0
-#define STB_GLOBAL 1
-#define STB_WEAK 2
-
-#define STT_NOTYPE 0
-#define STT_OBJECT 1
-#define STT_FUNC 2
-#define STT_SECTION 3
-#define STT_FILE 4
-
-#define ELF_ST_BIND(x) ((x) >> 4)
-#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
-#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
-#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
-#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
-#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
-
-/* Symbolic values for the entries in the auxiliary table
- put on the initial stack */
-#define AT_NULL 0 /* end of vector */
-#define AT_IGNORE 1 /* entry should be ignored */
-#define AT_EXECFD 2 /* file descriptor of program */
-#define AT_PHDR 3 /* program headers for program */
-#define AT_PHENT 4 /* size of program header entry */
-#define AT_PHNUM 5 /* number of program headers */
-#define AT_PAGESZ 6 /* system page size */
-#define AT_BASE 7 /* base address of interpreter */
-#define AT_FLAGS 8 /* flags */
-#define AT_ENTRY 9 /* entry point of program */
-#define AT_NOTELF 10 /* program is not ELF */
-#define AT_UID 11 /* real uid */
-#define AT_EUID 12 /* effective uid */
-#define AT_GID 13 /* real gid */
-#define AT_EGID 14 /* effective gid */
-#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
-#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
-#define AT_CLKTCK 17 /* frequency at which times() increments */
-
-typedef struct dynamic{
- Elf32_Sword d_tag;
- union{
- Elf32_Sword d_val;
- Elf32_Addr d_ptr;
- } d_un;
-} Elf32_Dyn;
-
-typedef struct {
- Elf64_Sxword d_tag; /* entry tag value */
- union {
- Elf64_Xword d_val;
- Elf64_Addr d_ptr;
- } d_un;
-} Elf64_Dyn;
-
-/* The following are used with relocations */
-#define ELF32_R_SYM(x) ((x) >> 8)
-#define ELF32_R_TYPE(x) ((x) & 0xff)
-
-#define ELF64_R_SYM(i) ((i) >> 32)
-#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-#define ELF64_R_TYPE_DATA(i) (((ELF64_R_TYPE(i) >> 8) ^ 0x00800000) - 0x00800000)
-
-#define R_386_NONE 0
-#define R_386_32 1
-#define R_386_PC32 2
-#define R_386_GOT32 3
-#define R_386_PLT32 4
-#define R_386_COPY 5
-#define R_386_GLOB_DAT 6
-#define R_386_JMP_SLOT 7
-#define R_386_RELATIVE 8
-#define R_386_GOTOFF 9
-#define R_386_GOTPC 10
-#define R_386_NUM 11
-
-#define R_MIPS_NONE 0
-#define R_MIPS_16 1
-#define R_MIPS_32 2
-#define R_MIPS_REL32 3
-#define R_MIPS_26 4
-#define R_MIPS_HI16 5
-#define R_MIPS_LO16 6
-#define R_MIPS_GPREL16 7
-#define R_MIPS_LITERAL 8
-#define R_MIPS_GOT16 9
-#define R_MIPS_PC16 10
-#define R_MIPS_CALL16 11
-#define R_MIPS_GPREL32 12
-/* The remaining relocs are defined on Irix, although they are not
- in the MIPS ELF ABI. */
-#define R_MIPS_UNUSED1 13
-#define R_MIPS_UNUSED2 14
-#define R_MIPS_UNUSED3 15
-#define R_MIPS_SHIFT5 16
-#define R_MIPS_SHIFT6 17
-#define R_MIPS_64 18
-#define R_MIPS_GOT_DISP 19
-#define R_MIPS_GOT_PAGE 20
-#define R_MIPS_GOT_OFST 21
-/*
- * The following two relocation types are specified in the MIPS ABI
- * conformance guide version 1.2 but not yet in the psABI.
- */
-#define R_MIPS_GOTHI16 22
-#define R_MIPS_GOTLO16 23
-#define R_MIPS_SUB 24
-#define R_MIPS_INSERT_A 25
-#define R_MIPS_INSERT_B 26
-#define R_MIPS_DELETE 27
-#define R_MIPS_HIGHER 28
-#define R_MIPS_HIGHEST 29
-/*
- * The following two relocation types are specified in the MIPS ABI
- * conformance guide version 1.2 but not yet in the psABI.
- */
-#define R_MIPS_CALLHI16 30
-#define R_MIPS_CALLLO16 31
-/*
- * This range is reserved for vendor specific relocations.
- */
-#define R_MIPS_LOVENDOR 100
-#define R_MIPS_HIVENDOR 127
-
-
-/*
- * Sparc ELF relocation types
- */
-#define R_SPARC_NONE 0
-#define R_SPARC_8 1
-#define R_SPARC_16 2
-#define R_SPARC_32 3
-#define R_SPARC_DISP8 4
-#define R_SPARC_DISP16 5
-#define R_SPARC_DISP32 6
-#define R_SPARC_WDISP30 7
-#define R_SPARC_WDISP22 8
-#define R_SPARC_HI22 9
-#define R_SPARC_22 10
-#define R_SPARC_13 11
-#define R_SPARC_LO10 12
-#define R_SPARC_GOT10 13
-#define R_SPARC_GOT13 14
-#define R_SPARC_GOT22 15
-#define R_SPARC_PC10 16
-#define R_SPARC_PC22 17
-#define R_SPARC_WPLT30 18
-#define R_SPARC_COPY 19
-#define R_SPARC_GLOB_DAT 20
-#define R_SPARC_JMP_SLOT 21
-#define R_SPARC_RELATIVE 22
-#define R_SPARC_UA32 23
-#define R_SPARC_PLT32 24
-#define R_SPARC_HIPLT22 25
-#define R_SPARC_LOPLT10 26
-#define R_SPARC_PCPLT32 27
-#define R_SPARC_PCPLT22 28
-#define R_SPARC_PCPLT10 29
-#define R_SPARC_10 30
-#define R_SPARC_11 31
-#define R_SPARC_64 32
-#define R_SPARC_OLO10 33
-#define R_SPARC_HH22 34
-#define R_SPARC_HM10 35
-#define R_SPARC_LM22 36
-#define R_SPARC_WDISP16 40
-#define R_SPARC_WDISP19 41
-#define R_SPARC_7 43
-#define R_SPARC_5 44
-#define R_SPARC_6 45
-
-/* Bits present in AT_HWCAP, primarily for Sparc32. */
-
-#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
-#define HWCAP_SPARC_STBAR 2
-#define HWCAP_SPARC_SWAP 4
-#define HWCAP_SPARC_MULDIV 8
-#define HWCAP_SPARC_V9 16
-#define HWCAP_SPARC_ULTRA3 32
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE 0
-#define R_68K_32 1
-#define R_68K_16 2
-#define R_68K_8 3
-#define R_68K_PC32 4
-#define R_68K_PC16 5
-#define R_68K_PC8 6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8 9
-#define R_68K_GOT32O 10
-#define R_68K_GOT16O 11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8 15
-#define R_68K_PLT32O 16
-#define R_68K_PLT16O 17
-#define R_68K_PLT8O 18
-#define R_68K_COPY 19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-
-/*
- * Alpha ELF relocation types
- */
-#define R_ALPHA_NONE 0 /* No reloc */
-#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
-#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
-#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
-#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
-#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
-#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
-#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
-#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
-#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
-#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
-#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
-#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
-#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
-#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
-#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
-#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
-#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
-#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
-#define R_ALPHA_BRSGP 28
-#define R_ALPHA_TLSGD 29
-#define R_ALPHA_TLS_LDM 30
-#define R_ALPHA_DTPMOD64 31
-#define R_ALPHA_GOTDTPREL 32
-#define R_ALPHA_DTPREL64 33
-#define R_ALPHA_DTPRELHI 34
-#define R_ALPHA_DTPRELLO 35
-#define R_ALPHA_DTPREL16 36
-#define R_ALPHA_GOTTPREL 37
-#define R_ALPHA_TPREL64 38
-#define R_ALPHA_TPRELHI 39
-#define R_ALPHA_TPRELLO 40
-#define R_ALPHA_TPREL16 41
-
-#define SHF_ALPHA_GPREL 0x10000000
-
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE 0
-#define R_PPC_ADDR32 1 /* 32bit absolute address */
-#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-#define R_PPC_ADDR16 3 /* 16bit absolute address */
-#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN 8
-#define R_PPC_ADDR14_BRNTAKEN 9
-#define R_PPC_REL24 10 /* PC relative 26 bit */
-#define R_PPC_REL14 11 /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN 12
-#define R_PPC_REL14_BRNTAKEN 13
-#define R_PPC_GOT16 14
-#define R_PPC_GOT16_LO 15
-#define R_PPC_GOT16_HI 16
-#define R_PPC_GOT16_HA 17
-#define R_PPC_PLTREL24 18
-#define R_PPC_COPY 19
-#define R_PPC_GLOB_DAT 20
-#define R_PPC_JMP_SLOT 21
-#define R_PPC_RELATIVE 22
-#define R_PPC_LOCAL24PC 23
-#define R_PPC_UADDR32 24
-#define R_PPC_UADDR16 25
-#define R_PPC_REL32 26
-#define R_PPC_PLT32 27
-#define R_PPC_PLTREL32 28
-#define R_PPC_PLT16_LO 29
-#define R_PPC_PLT16_HI 30
-#define R_PPC_PLT16_HA 31
-#define R_PPC_SDAREL16 32
-#define R_PPC_SECTOFF 33
-#define R_PPC_SECTOFF_LO 34
-#define R_PPC_SECTOFF_HI 35
-#define R_PPC_SECTOFF_HA 36
-/* Keep this the last entry. */
-#define R_PPC_NUM 37
-
-/* ARM specific declarations */
-
-/* Processor specific flags for the ELF header e_flags field. */
-#define EF_ARM_RELEXEC 0x01
-#define EF_ARM_HASENTRY 0x02
-#define EF_ARM_INTERWORK 0x04
-#define EF_ARM_APCS_26 0x08
-#define EF_ARM_APCS_FLOAT 0x10
-#define EF_ARM_PIC 0x20
-#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-#define EF_NEW_ABI 0x80
-#define EF_OLD_ABI 0x100
-
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC 0xd
-
-/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
- in the input to a link step */
-
-/* ARM-specific program header flags */
-#define PF_ARM_SB 0x10000000 /* Segment contains the location
- addressed by the static base */
-
-/* ARM relocs. */
-#define R_ARM_NONE 0 /* No reloc */
-#define R_ARM_PC24 1 /* PC relative 26 bit branch */
-#define R_ARM_ABS32 2 /* Direct 32 bit */
-#define R_ARM_REL32 3 /* PC relative 32 bit */
-#define R_ARM_PC13 4
-#define R_ARM_ABS16 5 /* Direct 16 bit */
-#define R_ARM_ABS12 6 /* Direct 12 bit */
-#define R_ARM_THM_ABS5 7
-#define R_ARM_ABS8 8 /* Direct 8 bit */
-#define R_ARM_SBREL32 9
-#define R_ARM_THM_PC22 10
-#define R_ARM_THM_PC8 11
-#define R_ARM_AMP_VCALL9 12
-#define R_ARM_SWI24 13
-#define R_ARM_THM_SWI8 14
-#define R_ARM_XPC25 15
-#define R_ARM_THM_XPC22 16
-#define R_ARM_COPY 20 /* Copy symbol at runtime */
-#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
-#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
-#define R_ARM_RELATIVE 23 /* Adjust by program base */
-#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
-#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
-#define R_ARM_GOT32 26 /* 32 bit GOT entry */
-#define R_ARM_PLT32 27 /* 32 bit PLT address */
-#define R_ARM_CALL 28
-#define R_ARM_JUMP24 29
-#define R_ARM_GNU_VTENTRY 100
-#define R_ARM_GNU_VTINHERIT 101
-#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
-#define R_ARM_THM_PC9 103 /* thumb conditional branch */
-#define R_ARM_RXPC25 249
-#define R_ARM_RSBREL32 250
-#define R_ARM_THM_RPC22 251
-#define R_ARM_RREL32 252
-#define R_ARM_RABS22 253
-#define R_ARM_RPC24 254
-#define R_ARM_RBASE 255
-/* Keep this the last entry. */
-#define R_ARM_NUM 256
-
-/* s390 relocations defined by the ABIs */
-#define R_390_NONE 0 /* No reloc. */
-#define R_390_8 1 /* Direct 8 bit. */
-#define R_390_12 2 /* Direct 12 bit. */
-#define R_390_16 3 /* Direct 16 bit. */
-#define R_390_32 4 /* Direct 32 bit. */
-#define R_390_PC32 5 /* PC relative 32 bit. */
-#define R_390_GOT12 6 /* 12 bit GOT offset. */
-#define R_390_GOT32 7 /* 32 bit GOT offset. */
-#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
-#define R_390_COPY 9 /* Copy symbol at runtime. */
-#define R_390_GLOB_DAT 10 /* Create GOT entry. */
-#define R_390_JMP_SLOT 11 /* Create PLT entry. */
-#define R_390_RELATIVE 12 /* Adjust by program base. */
-#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
-#define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */
-#define R_390_GOT16 15 /* 16 bit GOT offset. */
-#define R_390_PC16 16 /* PC relative 16 bit. */
-#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
-#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
-#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
-#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
-#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
-#define R_390_64 22 /* Direct 64 bit. */
-#define R_390_PC64 23 /* PC relative 64 bit. */
-#define R_390_GOT64 24 /* 64 bit GOT offset. */
-#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
-#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
-#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
-#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
-#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
-#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
-#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
-#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
-#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
-#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
-#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
-#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
-#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
-#define R_390_TLS_GDCALL 38 /* Tag for function call in general
- dynamic TLS code. */
-#define R_390_TLS_LDCALL 39 /* Tag for function call in local
- dynamic TLS code. */
-#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
- thread local data. */
-#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
- thread local data. */
-#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
- thread local data in LD code. */
-#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
- thread local data in LD code. */
-#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
- static TLS block. */
-#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
- static TLS block. */
-#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
- block. */
-#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
- block. */
-#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
-#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
-#define R_390_TLS_TPOFF 56 /* Negate offset in static TLS
- block. */
-/* Keep this the last entry. */
-#define R_390_NUM 57
-
-/* x86-64 relocation types */
-#define R_X86_64_NONE 0 /* No reloc */
-#define R_X86_64_64 1 /* Direct 64 bit */
-#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
-#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
-#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-#define R_X86_64_COPY 5 /* Copy symbol at runtime */
-#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
-#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
-#define R_X86_64_RELATIVE 8 /* Adjust by program base */
-#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
- offset to GOT */
-#define R_X86_64_32 10 /* Direct 32 bit zero extended */
-#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
-#define R_X86_64_16 12 /* Direct 16 bit zero extended */
-#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-#define R_X86_64_8 14 /* Direct 8 bit sign extended */
-#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
-
-#define R_X86_64_NUM 16
-
-/* Legal values for e_flags field of Elf64_Ehdr. */
-
-#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
-
-/* HPPA specific definitions. */
-
-/* Legal values for e_flags field of Elf32_Ehdr. */
-
-#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
-#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
-#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
-#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
-#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
- prediction. */
-#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
-#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
-
-/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
-
-#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
-#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
-#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-
-/* Additional section indeces. */
-
-#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
- symbols in ANSI C. */
-#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
-
-/* Legal values for sh_type field of Elf32_Shdr. */
-
-#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
-#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
-#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
-
-/* Legal values for sh_flags field of Elf32_Shdr. */
-
-#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
-#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
-#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-
-#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
-
-#define STT_HP_OPAQUE (STT_LOOS + 0x1)
-#define STT_HP_STUB (STT_LOOS + 0x2)
-
-/* HPPA relocs. */
-
-#define R_PARISC_NONE 0 /* No reloc. */
-#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
-#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
-#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
-#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
-#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
-#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
-#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
-#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
-#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
-#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
-#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
-#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
-#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
-#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
-#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
-#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
-#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
-#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
-#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
-#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
-#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
-#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
-#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
-#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
-#define R_PARISC_FPTR64 64 /* 64 bits function address. */
-#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
-#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
-#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
-#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
-#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
-#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
-#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
-#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
-#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
-#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
-#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
-#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
-#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
-#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
-#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
-#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
-#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
-#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
-#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
-#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
-#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
-#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
-#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
-#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
-#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
-#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
-#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
-#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
-#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
-#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
-#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
-#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LORESERVE 128
-#define R_PARISC_COPY 128 /* Copy relocation. */
-#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
-#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
-#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
-#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
-#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
-#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
-#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
-#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
-#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
-#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
-#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_HIRESERVE 255
-
-/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
-
-#define PT_HP_TLS (PT_LOOS + 0x0)
-#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
-#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
-#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
-#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
-#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
-#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
-#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
-#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
-#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
-#define PT_HP_PARALLEL (PT_LOOS + 0x10)
-#define PT_HP_FASTBIND (PT_LOOS + 0x11)
-#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
-#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
-#define PT_HP_STACK (PT_LOOS + 0x14)
-
-#define PT_PARISC_ARCHEXT 0x70000000
-#define PT_PARISC_UNWIND 0x70000001
-
-/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
-
-#define PF_PARISC_SBP 0x08000000
-
-#define PF_HP_PAGE_SIZE 0x00100000
-#define PF_HP_FAR_SHARED 0x00200000
-#define PF_HP_NEAR_SHARED 0x00400000
-#define PF_HP_CODE 0x01000000
-#define PF_HP_MODIFY 0x02000000
-#define PF_HP_LAZYSWAP 0x04000000
-#define PF_HP_SBP 0x08000000
-
-/* IA-64 specific declarations. */
-
-/* Processor specific flags for the Ehdr e_flags field. */
-#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
-#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
-#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
-
-/* Processor specific values for the Phdr p_type field. */
-#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
-#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
-
-/* Processor specific flags for the Phdr p_flags field. */
-#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
-
-/* Processor specific values for the Shdr sh_type field. */
-#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
-#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
-
-/* Processor specific flags for the Shdr sh_flags field. */
-#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
-#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
-
-/* Processor specific values for the Dyn d_tag field. */
-#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
-#define DT_IA_64_NUM 1
-
-/* IA-64 relocations. */
-#define R_IA64_NONE 0x00 /* none */
-#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
-#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
-#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
-#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
-#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
-#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
-#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
-#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
-#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
-#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
-#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
-#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
-#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
-#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
-#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
-#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
-#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
-#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
-#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
-#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
-#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
-#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
-#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
-#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
-#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
-#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
-#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
-#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
-#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
-#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
-#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
-#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
-#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
-#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
-#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
-#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
-#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
-#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
-#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
-#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
-#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
-#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
-#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
-#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
-#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
-#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
-#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
-#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
-#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
-#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
-#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
-#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
-#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
-#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
-#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
-#define R_IA64_COPY 0x84 /* copy relocation */
-#define R_IA64_SUB 0x85 /* Addend and symbol difference */
-#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
-#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
-#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
-#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
-#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
-#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
-#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
-#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
-#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
-#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
-#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
-#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
-#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
-#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
-#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
-#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
-
-typedef struct elf32_rel {
- Elf32_Addr r_offset;
- Elf32_Word r_info;
-} Elf32_Rel;
-
-typedef struct elf64_rel {
- Elf64_Addr r_offset; /* Location at which to apply the action */
- Elf64_Xword r_info; /* index and type of relocation */
-} Elf64_Rel;
-
-typedef struct elf32_rela{
- Elf32_Addr r_offset;
- Elf32_Word r_info;
- Elf32_Sword r_addend;
-} Elf32_Rela;
-
-typedef struct elf64_rela {
- Elf64_Addr r_offset; /* Location at which to apply the action */
- Elf64_Xword r_info; /* index and type of relocation */
- Elf64_Sxword r_addend; /* Constant addend used to compute value */
-} Elf64_Rela;
-
-typedef struct elf32_sym{
- Elf32_Word st_name;
- Elf32_Addr st_value;
- Elf32_Word st_size;
- unsigned char st_info;
- unsigned char st_other;
- Elf32_Half st_shndx;
-} Elf32_Sym;
-
-typedef struct elf64_sym {
- Elf64_Word st_name; /* Symbol name, index in string tbl */
- unsigned char st_info; /* Type and binding attributes */
- unsigned char st_other; /* No defined meaning, 0 */
- Elf64_Half st_shndx; /* Associated section index */
- Elf64_Addr st_value; /* Value of the symbol */
- Elf64_Xword st_size; /* Associated symbol size */
-} Elf64_Sym;
-
-
-#define EI_NIDENT 16
-
-typedef struct elf32_hdr{
- unsigned char e_ident[EI_NIDENT];
- Elf32_Half e_type;
- Elf32_Half e_machine;
- Elf32_Word e_version;
- Elf32_Addr e_entry; /* Entry point */
- Elf32_Off e_phoff;
- Elf32_Off e_shoff;
- Elf32_Word e_flags;
- Elf32_Half e_ehsize;
- Elf32_Half e_phentsize;
- Elf32_Half e_phnum;
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
-} Elf32_Ehdr;
-
-typedef struct elf64_hdr {
- unsigned char e_ident[16]; /* ELF "magic number" */
- Elf64_Half e_type;
- Elf64_Half e_machine;
- Elf64_Word e_version;
- Elf64_Addr e_entry; /* Entry point virtual address */
- Elf64_Off e_phoff; /* Program header table file offset */
- Elf64_Off e_shoff; /* Section header table file offset */
- Elf64_Word e_flags;
- Elf64_Half e_ehsize;
- Elf64_Half e_phentsize;
- Elf64_Half e_phnum;
- Elf64_Half e_shentsize;
- Elf64_Half e_shnum;
- Elf64_Half e_shstrndx;
-} Elf64_Ehdr;
-
-/* These constants define the permissions on sections in the program
- header, p_flags. */
-#define PF_R 0x4
-#define PF_W 0x2
-#define PF_X 0x1
-
-typedef struct elf32_phdr{
- Elf32_Word p_type;
- Elf32_Off p_offset;
- Elf32_Addr p_vaddr;
- Elf32_Addr p_paddr;
- Elf32_Word p_filesz;
- Elf32_Word p_memsz;
- Elf32_Word p_flags;
- Elf32_Word p_align;
-} Elf32_Phdr;
-
-typedef struct elf64_phdr {
- Elf64_Word p_type;
- Elf64_Word p_flags;
- Elf64_Off p_offset; /* Segment file offset */
- Elf64_Addr p_vaddr; /* Segment virtual address */
- Elf64_Addr p_paddr; /* Segment physical address */
- Elf64_Xword p_filesz; /* Segment size in file */
- Elf64_Xword p_memsz; /* Segment size in memory */
- Elf64_Xword p_align; /* Segment alignment, file & memory */
-} Elf64_Phdr;
-
-/* sh_type */
-#define SHT_NULL 0
-#define SHT_PROGBITS 1
-#define SHT_SYMTAB 2
-#define SHT_STRTAB 3
-#define SHT_RELA 4
-#define SHT_HASH 5
-#define SHT_DYNAMIC 6
-#define SHT_NOTE 7
-#define SHT_NOBITS 8
-#define SHT_REL 9
-#define SHT_SHLIB 10
-#define SHT_DYNSYM 11
-#define SHT_NUM 12
-#define SHT_LOPROC 0x70000000
-#define SHT_HIPROC 0x7fffffff
-#define SHT_LOUSER 0x80000000
-#define SHT_HIUSER 0xffffffff
-#define SHT_MIPS_LIST 0x70000000
-#define SHT_MIPS_CONFLICT 0x70000002
-#define SHT_MIPS_GPTAB 0x70000003
-#define SHT_MIPS_UCODE 0x70000004
-
-/* sh_flags */
-#define SHF_WRITE 0x1
-#define SHF_ALLOC 0x2
-#define SHF_EXECINSTR 0x4
-#define SHF_MASKPROC 0xf0000000
-#define SHF_MIPS_GPREL 0x10000000
-
-/* special section indexes */
-#define SHN_UNDEF 0
-#define SHN_LORESERVE 0xff00
-#define SHN_LOPROC 0xff00
-#define SHN_HIPROC 0xff1f
-#define SHN_ABS 0xfff1
-#define SHN_COMMON 0xfff2
-#define SHN_HIRESERVE 0xffff
-#define SHN_MIPS_ACCOMON 0xff00
-
-typedef struct elf32_shdr {
- Elf32_Word sh_name;
- Elf32_Word sh_type;
- Elf32_Word sh_flags;
- Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
- Elf32_Word sh_size;
- Elf32_Word sh_link;
- Elf32_Word sh_info;
- Elf32_Word sh_addralign;
- Elf32_Word sh_entsize;
-} Elf32_Shdr;
-
-typedef struct elf64_shdr {
- Elf64_Word sh_name; /* Section name, index in string tbl */
- Elf64_Word sh_type; /* Type of section */
- Elf64_Xword sh_flags; /* Miscellaneous section attributes */
- Elf64_Addr sh_addr; /* Section virtual addr at execution */
- Elf64_Off sh_offset; /* Section file offset */
- Elf64_Xword sh_size; /* Size of section in bytes */
- Elf64_Word sh_link; /* Index of another section */
- Elf64_Word sh_info; /* Additional section information */
- Elf64_Xword sh_addralign; /* Section alignment */
- Elf64_Xword sh_entsize; /* Entry size if section holds table */
-} Elf64_Shdr;
-
-#define EI_MAG0 0 /* e_ident[] indexes */
-#define EI_MAG1 1
-#define EI_MAG2 2
-#define EI_MAG3 3
-#define EI_CLASS 4
-#define EI_DATA 5
-#define EI_VERSION 6
-#define EI_PAD 7
-
-#define ELFMAG0 0x7f /* EI_MAG */
-#define ELFMAG1 'E'
-#define ELFMAG2 'L'
-#define ELFMAG3 'F'
-#define ELFMAG "\177ELF"
-#define SELFMAG 4
-
-#define ELFCLASSNONE 0 /* EI_CLASS */
-#define ELFCLASS32 1
-#define ELFCLASS64 2
-#define ELFCLASSNUM 3
-
-#define ELFDATANONE 0 /* e_ident[EI_DATA] */
-#define ELFDATA2LSB 1
-#define ELFDATA2MSB 2
-
-#define EV_NONE 0 /* e_version, EI_VERSION */
-#define EV_CURRENT 1
-#define EV_NUM 2
-
-/* Notes used in ET_CORE */
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_TASKSTRUCT 4
-#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
-
-
-/* Note header in a PT_NOTE section */
-typedef struct elf32_note {
- Elf32_Word n_namesz; /* Name size */
- Elf32_Word n_descsz; /* Content size */
- Elf32_Word n_type; /* Content type */
-} Elf32_Nhdr;
-
-/* Note header in a PT_NOTE section */
-typedef struct elf64_note {
- Elf64_Word n_namesz; /* Name size */
- Elf64_Word n_descsz; /* Content size */
- Elf64_Word n_type; /* Content type */
-} Elf64_Nhdr;
-
-#ifdef ELF_CLASS
-#if ELF_CLASS == ELFCLASS32
-
-#define elfhdr elf32_hdr
-#define elf_phdr elf32_phdr
-#define elf_note elf32_note
-#define elf_shdr elf32_shdr
-#define elf_sym elf32_sym
-#define elf_addr_t Elf32_Off
-
-#ifdef ELF_USES_RELOCA
-# define ELF_RELOC Elf32_Rela
-#else
-# define ELF_RELOC Elf32_Rel
-#endif
-
-#else
-
-#define elfhdr elf64_hdr
-#define elf_phdr elf64_phdr
-#define elf_note elf64_note
-#define elf_shdr elf64_shdr
-#define elf_sym elf64_sym
-#define elf_addr_t Elf64_Off
-
-#ifdef ELF_USES_RELOCA
-# define ELF_RELOC Elf64_Rela
-#else
-# define ELF_RELOC Elf64_Rel
-#endif
-
-#endif /* ELF_CLASS */
-
-#ifndef ElfW
-# if ELF_CLASS == ELFCLASS32
-# define ElfW(x) Elf32_ ## x
-# define ELFW(x) ELF32_ ## x
-# else
-# define ElfW(x) Elf64_ ## x
-# define ELFW(x) ELF64_ ## x
-# endif
-#endif
-
-#endif /* ELF_CLASS */
-
-
-#endif /* _QEMU_ELF_H */
diff --git a/elf_ops.h b/elf_ops.h
deleted file mode 100644
index 6126565..0000000
--- a/elf_ops.h
+++ /dev/null
@@ -1,217 +0,0 @@
-static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
-{
- bswap16s(&ehdr->e_type); /* Object file type */
- bswap16s(&ehdr->e_machine); /* Architecture */
- bswap32s(&ehdr->e_version); /* Object file version */
- bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
- bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
- bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
- bswap32s(&ehdr->e_flags); /* Processor-specific flags */
- bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
- bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
- bswap16s(&ehdr->e_phnum); /* Program header table entry count */
- bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
- bswap16s(&ehdr->e_shnum); /* Section header table entry count */
- bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
-}
-
-static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
-{
- bswap32s(&phdr->p_type); /* Segment type */
- bswapSZs(&phdr->p_offset); /* Segment file offset */
- bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
- bswapSZs(&phdr->p_paddr); /* Segment physical address */
- bswapSZs(&phdr->p_filesz); /* Segment size in file */
- bswapSZs(&phdr->p_memsz); /* Segment size in memory */
- bswap32s(&phdr->p_flags); /* Segment flags */
- bswapSZs(&phdr->p_align); /* Segment alignment */
-}
-
-static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
-{
- bswap32s(&shdr->sh_name);
- bswap32s(&shdr->sh_type);
- bswapSZs(&shdr->sh_flags);
- bswapSZs(&shdr->sh_addr);
- bswapSZs(&shdr->sh_offset);
- bswapSZs(&shdr->sh_size);
- bswap32s(&shdr->sh_link);
- bswap32s(&shdr->sh_info);
- bswapSZs(&shdr->sh_addralign);
- bswapSZs(&shdr->sh_entsize);
-}
-
-static void glue(bswap_sym, SZ)(struct elf_sym *sym)
-{
- bswap32s(&sym->st_name);
- bswapSZs(&sym->st_value);
- bswapSZs(&sym->st_size);
- bswap16s(&sym->st_shndx);
-}
-
-static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
- int n, int type)
-{
- int i;
- for(i=0;i<n;i++) {
- if (shdr_table[i].sh_type == type)
- return shdr_table + i;
- }
- return NULL;
-}
-
-static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
-{
- struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
- struct elf_sym *syms = NULL;
-#if (SZ == 64)
- struct elf32_sym *syms32 = NULL;
-#endif
- struct syminfo *s;
- int nsyms, i;
- char *str = NULL;
-
- shdr_table = load_at(fd, ehdr->e_shoff,
- sizeof(struct elf_shdr) * ehdr->e_shnum);
- if (!shdr_table)
- return -1;
-
- if (must_swab) {
- for (i = 0; i < ehdr->e_shnum; i++) {
- glue(bswap_shdr, SZ)(shdr_table + i);
- }
- }
-
- symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
- if (!symtab)
- goto fail;
- syms = load_at(fd, symtab->sh_offset, symtab->sh_size);
- if (!syms)
- goto fail;
-
- nsyms = symtab->sh_size / sizeof(struct elf_sym);
-#if (SZ == 64)
- syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
-#endif
- for (i = 0; i < nsyms; i++) {
- if (must_swab)
- glue(bswap_sym, SZ)(&syms[i]);
-#if (SZ == 64)
- syms32[i].st_name = syms[i].st_name;
- syms32[i].st_info = syms[i].st_info;
- syms32[i].st_other = syms[i].st_other;
- syms32[i].st_shndx = syms[i].st_shndx;
- syms32[i].st_value = syms[i].st_value & 0xffffffff;
- syms32[i].st_size = syms[i].st_size & 0xffffffff;
-#endif
- }
- /* String table */
- if (symtab->sh_link >= ehdr->e_shnum)
- goto fail;
- strtab = &shdr_table[symtab->sh_link];
-
- str = load_at(fd, strtab->sh_offset, strtab->sh_size);
- if (!str)
- goto fail;
-
- /* Commit */
- s = qemu_mallocz(sizeof(*s));
-#if (SZ == 64)
- s->disas_symtab = syms32;
- qemu_free(syms);
-#else
- s->disas_symtab = syms;
-#endif
- s->disas_num_syms = nsyms;
- s->disas_strtab = str;
- s->next = syminfos;
- syminfos = s;
- qemu_free(shdr_table);
- return 0;
- fail:
-#if (SZ == 64)
- qemu_free(syms32);
-#endif
- qemu_free(syms);
- qemu_free(str);
- qemu_free(shdr_table);
- return -1;
-}
-
-static int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
- int must_swab, uint64_t *pentry,
- uint64_t *lowaddr, uint64_t *highaddr)
-{
- struct elfhdr ehdr;
- struct elf_phdr *phdr = NULL, *ph;
- int size, i, total_size;
- elf_word mem_size;
- uint64_t addr, low = 0, high = 0;
- uint8_t *data = NULL;
-
- if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
- goto fail;
- if (must_swab) {
- glue(bswap_ehdr, SZ)(&ehdr);
- }
-
- if (ELF_MACHINE != ehdr.e_machine)
- goto fail;
-
- if (pentry)
- *pentry = (uint64_t)(elf_sword)ehdr.e_entry;
-
- glue(load_symbols, SZ)(&ehdr, fd, must_swab);
-
- size = ehdr.e_phnum * sizeof(phdr[0]);
- lseek(fd, ehdr.e_phoff, SEEK_SET);
- phdr = qemu_mallocz(size);
- if (!phdr)
- goto fail;
- if (read(fd, phdr, size) != size)
- goto fail;
- if (must_swab) {
- for(i = 0; i < ehdr.e_phnum; i++) {
- ph = &phdr[i];
- glue(bswap_phdr, SZ)(ph);
- }
- }
-
- total_size = 0;
- for(i = 0; i < ehdr.e_phnum; i++) {
- ph = &phdr[i];
- if (ph->p_type == PT_LOAD) {
- mem_size = ph->p_memsz;
- /* XXX: avoid allocating */
- data = qemu_mallocz(mem_size);
- if (ph->p_filesz > 0) {
- if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
- goto fail;
- if (read(fd, data, ph->p_filesz) != ph->p_filesz)
- goto fail;
- }
- addr = ph->p_vaddr + virt_to_phys_addend;
-
- cpu_physical_memory_write_rom(addr, data, mem_size);
-
- total_size += mem_size;
- if (!low || addr < low)
- low = addr;
- if (!high || (addr + mem_size) > high)
- high = addr + mem_size;
-
- qemu_free(data);
- data = NULL;
- }
- }
- qemu_free(phdr);
- if (lowaddr)
- *lowaddr = (uint64_t)(elf_sword)low;
- if (highaddr)
- *highaddr = (uint64_t)(elf_sword)high;
- return total_size;
- fail:
- qemu_free(data);
- qemu_free(phdr);
- return -1;
-}
diff --git a/exec-all.h b/exec-all.h
deleted file mode 100644
index a223bff..0000000
--- a/exec-all.h
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * internal execution defines for qemu
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* allow to see translation results - the slowdown should be negligible, so we leave it */
-#define DEBUG_DISAS
-
-/* is_jmp field values */
-#define DISAS_NEXT 0 /* next instruction can be analyzed */
-#define DISAS_JUMP 1 /* only pc was modified dynamically */
-#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
-
-typedef struct TranslationBlock TranslationBlock;
-
-/* XXX: make safe guess about sizes */
-#define MAX_OP_PER_INSTR 64
-/* A Call op needs up to 6 + 2N parameters (N = number of arguments). */
-#define MAX_OPC_PARAM 10
-#define OPC_BUF_SIZE 512
-#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
-
-/* Maximum size a TCG op can expand to. This is complicated because a
- single op may require several host instructions and regirster reloads.
- For now take a wild guess at 128 bytes, which should allow at least
- a couple of fixup instructions per argument. */
-#define TCG_MAX_OP_SIZE 128
-
-#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
-
-extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
-extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
-extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
-extern target_ulong gen_opc_jump_pc[2];
-extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-
-typedef void (GenOpFunc)(void);
-typedef void (GenOpFunc1)(long);
-typedef void (GenOpFunc2)(long, long);
-typedef void (GenOpFunc3)(long, long, long);
-
-#include "qemu-log.h"
-
-void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
-void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc);
-
-unsigned long code_gen_max_block_size(void);
-void cpu_gen_init(void);
-int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
- int *gen_code_size_ptr);
-int cpu_restore_state(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
-int cpu_restore_state_copy(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
-void cpu_resume_from_signal(CPUState *env1, void *puc);
-void cpu_io_recompile(CPUState *env, void *retaddr);
-TranslationBlock *tb_gen_code(CPUState *env,
- target_ulong pc, target_ulong cs_base, int flags,
- int cflags);
-void cpu_exec_init(CPUState *env);
-int page_unprotect(target_ulong address, unsigned long pc, void *puc);
-void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
- int is_cpu_write_access);
-void tb_invalidate_page_range(target_ulong start, target_ulong end);
-void tlb_flush_page(CPUState *env, target_ulong addr);
-void tlb_flush(CPUState *env, int flush_global);
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu);
-static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
-{
- if (prot & PAGE_READ)
- prot |= PAGE_EXEC;
- return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu);
-}
-
-#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
-
-#define CODE_GEN_PHYS_HASH_BITS 15
-#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS)
-
-#define MIN_CODE_GEN_BUFFER_SIZE (1024 * 1024)
-
-/* estimated block size for TB allocation */
-/* XXX: use a per code average code fragment size and modulate it
- according to the host CPU */
-#if defined(CONFIG_SOFTMMU)
-#define CODE_GEN_AVG_BLOCK_SIZE 128
-#else
-#define CODE_GEN_AVG_BLOCK_SIZE 64
-#endif
-
-#if defined(__powerpc__) || defined(__x86_64__) || defined(__arm__)
-#define USE_DIRECT_JUMP
-#endif
-#if defined(__i386__) && !defined(_WIN32)
-#define USE_DIRECT_JUMP
-#endif
-
-struct TranslationBlock {
- target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
- target_ulong cs_base; /* CS base for this block */
- uint64_t flags; /* flags defining in which context the code was generated */
- uint16_t size; /* size of target code for this block (1 <=
- size <= TARGET_PAGE_SIZE) */
- uint16_t cflags; /* compile flags */
-#define CF_COUNT_MASK 0x7fff
-#define CF_LAST_IO 0x8000 /* Last insn may be an IO access. */
-
- uint8_t *tc_ptr; /* pointer to the translated code */
- /* next matching tb for physical address. */
- struct TranslationBlock *phys_hash_next;
- /* first and second physical page containing code. The lower bit
- of the pointer tells the index in page_next[] */
- struct TranslationBlock *page_next[2];
- target_ulong page_addr[2];
-
- /* the following data are used to directly call another TB from
- the code of this one. */
- uint16_t tb_next_offset[2]; /* offset of original jump target */
-#ifdef USE_DIRECT_JUMP
- uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
-#else
- unsigned long tb_next[2]; /* address of jump generated code */
-#endif
- /* list of TBs jumping to this one. This is a circular list using
- the two least significant bits of the pointers to tell what is
- the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
- jmp_first */
- struct TranslationBlock *jmp_next[2];
- struct TranslationBlock *jmp_first;
-
-#ifdef CONFIG_TRACE
- struct BBRec *bb_rec;
- uint64_t prev_time;
-#endif
- uint32_t icount;
-};
-
-static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
-{
- target_ulong tmp;
- tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
- return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
-}
-
-static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
-{
- target_ulong tmp;
- tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
- return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
- | (tmp & TB_JMP_ADDR_MASK));
-}
-
-static inline unsigned int tb_phys_hash_func(unsigned long pc)
-{
- return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
-}
-
-TranslationBlock *tb_alloc(target_ulong pc);
-void tb_free(TranslationBlock *tb);
-void tb_flush(CPUState *env);
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2);
-void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr);
-
-extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-extern uint8_t *code_gen_ptr;
-extern int code_gen_max_blocks;
-
-#if defined(USE_DIRECT_JUMP)
-
-#if defined(__powerpc__)
-extern void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
-#define tb_set_jmp_target1 ppc_tb_set_jmp_target
-#elif defined(__i386__) || defined(__x86_64__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
-{
- /* patch the branch destination */
- *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
- /* no need to flush icache explicitly */
-}
-#elif defined(__arm__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
-{
- register unsigned long _beg __asm ("a1");
- register unsigned long _end __asm ("a2");
- register unsigned long _flg __asm ("a3");
-
- /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
- *(uint32_t *)jmp_addr |= ((addr - (jmp_addr + 8)) >> 2) & 0xffffff;
-
- /* flush icache */
- _beg = jmp_addr;
- _end = jmp_addr + 4;
- _flg = 0;
- __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-}
-#endif
-
-static inline void tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-{
- unsigned long offset;
-
- offset = tb->tb_jmp_offset[n];
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
- offset = tb->tb_jmp_offset[n + 2];
- if (offset != 0xffff)
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
-}
-
-#else
-
-/* set the jump target */
-static inline void tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-{
- tb->tb_next[n] = addr;
-}
-
-#endif
-
-static inline void tb_add_jump(TranslationBlock *tb, int n,
- TranslationBlock *tb_next)
-{
- /* NOTE: this test is only needed for thread safety */
- if (!tb->jmp_next[n]) {
- /* patch the native jump address */
- tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
-
- /* add in TB jmp circular list */
- tb->jmp_next[n] = tb_next->jmp_first;
- tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
- }
-}
-
-TranslationBlock *tb_find_pc(unsigned long pc_ptr);
-
-#if defined(_WIN32)
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".section .text\n"
-#elif defined(__APPLE__)
-#define ASM_DATA_SECTION ".data\n"
-#define ASM_PREVIOUS_SECTION ".text\n"
-#else
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".previous\n"
-#endif
-
-#define ASM_OP_LABEL_NAME(n, opname) \
- ASM_NAME(__op_label) #n "." ASM_NAME(opname)
-
-extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-
-#include "qemu-lock.h"
-
-extern spinlock_t tb_lock;
-
-extern int tb_invalidated_flag;
-
-#if !defined(CONFIG_USER_ONLY)
-
-void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
- void *retaddr);
-
-#include "softmmu_defs.h"
-
-#define ACCESS_TYPE (NB_MMU_MODES + 1)
-#define MEMSUFFIX _code
-#define env cpu_single_env
-
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-#undef env
-
-#endif
-
-#if defined(CONFIG_USER_ONLY)
-static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
-{
- return addr;
-}
-#else
-/* NOTE: this function can trigger an exception */
-/* NOTE2: the returned address is not exactly the physical address: it
- is the offset relative to phys_ram_base */
-static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
-{
- int mmu_idx, page_index, pd;
-
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- mmu_idx = cpu_mmu_index(env1);
- if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
- (addr & TARGET_PAGE_MASK))) {
- ldub_code(addr);
- }
- pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
- if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
-#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
- do_unassigned_access(addr, 0, 1, 0);
-#else
- cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
-#endif
- }
- return addr + env1->tlb_table[mmu_idx][page_index].addend - (unsigned long)phys_ram_base;
-}
-
-/* Deterministic execution requires that IO only be performed on the last
- instruction of a TB so that interrupts take effect immediately. */
-static inline int can_do_io(CPUState *env)
-{
- if (!use_icount)
- return 1;
-
- /* If not executing code then assume we are ok. */
- if (!env->current_tb)
- return 1;
-
- return env->can_do_io != 0;
-}
-#endif
-
-#ifdef USE_KQEMU
-#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
-
-#define MSR_QPI_COMMBASE 0xfabe0010
-
-int kqemu_init(CPUState *env);
-int kqemu_cpu_exec(CPUState *env);
-void kqemu_flush_page(CPUState *env, target_ulong addr);
-void kqemu_flush(CPUState *env, int global);
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
-void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size,
- ram_addr_t phys_offset);
-void kqemu_cpu_interrupt(CPUState *env);
-void kqemu_record_dump(void);
-
-extern uint32_t kqemu_comm_base;
-
-static inline int kqemu_is_ok(CPUState *env)
-{
- return(env->kqemu_enabled &&
- (env->cr[0] & CR0_PE_MASK) &&
- !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
- (env->eflags & IF_MASK) &&
- !(env->eflags & VM_MASK) &&
- (env->kqemu_enabled == 2 ||
- ((env->hflags & HF_CPL_MASK) == 3 &&
- (env->eflags & IOPL_MASK) != IOPL_MASK)));
-}
-
-#endif
diff --git a/exec.c b/exec.c
deleted file mode 100644
index 547801b..0000000
--- a/exec.c
+++ /dev/null
@@ -1,3201 +0,0 @@
-/*
- * virtual page mapping and translated block handling
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#else
-#include <sys/types.h>
-#include <sys/mman.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "qemu-common.h"
-#include "tcg.h"
-#include "hw/hw.h"
-#if defined(CONFIG_USER_ONLY)
-#include <qemu.h>
-#endif
-
-//#define DEBUG_TB_INVALIDATE
-//#define DEBUG_FLUSH
-//#define DEBUG_TLB
-//#define DEBUG_UNASSIGNED
-
-/* make various TB consistency checks */
-//#define DEBUG_TB_CHECK
-//#define DEBUG_TLB_CHECK
-
-//#define DEBUG_IOPORT
-//#define DEBUG_SUBPAGE
-
-#if !defined(CONFIG_USER_ONLY)
-/* TB consistency checks only implemented for usermode emulation. */
-#undef DEBUG_TB_CHECK
-#endif
-
-#define SMC_BITMAP_USE_THRESHOLD 10
-
-#define MMAP_AREA_START 0x00000000
-#define MMAP_AREA_END 0xa8000000
-
-#if defined(TARGET_SPARC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 41
-#elif defined(TARGET_SPARC)
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#elif defined(TARGET_ALPHA)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#define TARGET_VIRT_ADDR_SPACE_BITS 42
-#elif defined(TARGET_PPC64)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#elif defined(TARGET_X86_64) && !defined(USE_KQEMU)
-#define TARGET_PHYS_ADDR_SPACE_BITS 42
-#elif defined(TARGET_I386) && !defined(USE_KQEMU)
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#else
-/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#endif
-
-TranslationBlock *tbs;
-int code_gen_max_blocks;
-TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-int nb_tbs;
-/* any access to the tbs or the page table must use this lock */
-spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
-
-#if defined(__arm__) || defined(__sparc_v9__)
-/* The prologue must be reachable with a direct jump. ARM and Sparc64
- have limited branch ranges (possibly also PPC) so place it in a
- section close to code segment. */
-#define code_gen_section \
- __attribute__((__section__(".gen_code"))) \
- __attribute__((aligned (32)))
-#else
-#define code_gen_section \
- __attribute__((aligned (32)))
-#endif
-
-uint8_t code_gen_prologue[1024] code_gen_section;
-uint8_t *code_gen_buffer;
-unsigned long code_gen_buffer_size;
-/* threshold to flush the translated code buffer */
-unsigned long code_gen_buffer_max_size;
-uint8_t *code_gen_ptr;
-
-#if !defined(CONFIG_USER_ONLY)
-ram_addr_t phys_ram_size;
-int phys_ram_fd;
-uint8_t *phys_ram_base;
-uint8_t *phys_ram_dirty;
-static ram_addr_t phys_ram_alloc_offset = 0;
-#endif
-
-CPUState *first_cpu;
-/* current CPU in the current thread. It is only valid inside
- cpu_exec() */
-CPUState *cpu_single_env;
-/* 0 = Do not count executed instructions.
- 1 = Precise instruction counting.
- 2 = Adaptive rate instruction counting. */
-int use_icount = 0;
-/* Current instruction counter. While executing translated code this may
- include some instructions that have not yet been executed. */
-int64_t qemu_icount;
-
-typedef struct PageDesc {
- /* list of TBs intersecting this ram page */
- TranslationBlock *first_tb;
- /* in order to optimize self modifying code, we count the number
- of lookups we do to a given page to use a bitmap */
- unsigned int code_write_count;
- uint8_t *code_bitmap;
-#if defined(CONFIG_USER_ONLY)
- unsigned long flags;
-#endif
-} PageDesc;
-
-typedef struct PhysPageDesc {
- /* offset in host memory of the page + io_index in the low bits */
- ram_addr_t phys_offset;
-} PhysPageDesc;
-
-#define L2_BITS 10
-#if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
-/* XXX: this is a temporary hack for alpha target.
- * In the future, this is to be replaced by a multi-level table
- * to actually be able to handle the complete 64 bits address space.
- */
-#define L1_BITS (TARGET_VIRT_ADDR_SPACE_BITS - L2_BITS - TARGET_PAGE_BITS)
-#else
-#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
-#endif
-
-#define L1_SIZE (1 << L1_BITS)
-#define L2_SIZE (1 << L2_BITS)
-
-unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_bits;
-unsigned long qemu_host_page_size;
-unsigned long qemu_host_page_mask;
-
-/* XXX: for system emulation, it could just be an array */
-static PageDesc *l1_map[L1_SIZE];
-PhysPageDesc **l1_phys_map;
-
-#if !defined(CONFIG_USER_ONLY)
-static void io_mem_init(void);
-
-/* io memory support */
-CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb;
-static int io_mem_watch;
-#endif
-
-/* log support */
-const char *logfilename = "/tmp/qemu.log";
-FILE *logfile;
-int loglevel;
-static int log_append = 0;
-
-/* statistics */
-static int tlb_flush_count;
-static int tb_flush_count;
-static int tb_phys_invalidate_count;
-
-#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
-typedef struct subpage_t {
- target_phys_addr_t base;
- CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE][4];
- CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE][4];
- void *opaque[TARGET_PAGE_SIZE][2][4];
-} subpage_t;
-
-#ifdef _WIN32
-static void map_exec(void *addr, long size)
-{
- DWORD old_protect;
- VirtualProtect(addr, size,
- PAGE_EXECUTE_READWRITE, &old_protect);
-
-}
-#else
-static void map_exec(void *addr, long size)
-{
- unsigned long start, end, page_size;
-
- page_size = getpagesize();
- start = (unsigned long)addr;
- start &= ~(page_size - 1);
-
- end = (unsigned long)addr + size;
- end += page_size - 1;
- end &= ~(page_size - 1);
-
- mprotect((void *)start, end - start,
- PROT_READ | PROT_WRITE | PROT_EXEC);
-}
-#endif
-
-static void page_init(void)
-{
- /* NOTE: we can always suppose that qemu_host_page_size >=
- TARGET_PAGE_SIZE */
-#ifdef _WIN32
- {
- SYSTEM_INFO system_info;
- DWORD old_protect;
-
- GetSystemInfo(&system_info);
- qemu_real_host_page_size = system_info.dwPageSize;
- }
-#else
- qemu_real_host_page_size = getpagesize();
-#endif
- if (qemu_host_page_size == 0)
- qemu_host_page_size = qemu_real_host_page_size;
- if (qemu_host_page_size < TARGET_PAGE_SIZE)
- qemu_host_page_size = TARGET_PAGE_SIZE;
- qemu_host_page_bits = 0;
- while ((1 << qemu_host_page_bits) < qemu_host_page_size)
- qemu_host_page_bits++;
- qemu_host_page_mask = ~(qemu_host_page_size - 1);
- l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
- memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
-
-#if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
- {
- long long startaddr, endaddr;
- FILE *f;
- int n;
-
- mmap_lock();
- last_brk = (unsigned long)sbrk(0);
- f = fopen("/proc/self/maps", "r");
- if (f) {
- do {
- n = fscanf (f, "%llx-%llx %*[^\n]\n", &startaddr, &endaddr);
- if (n == 2) {
- startaddr = MIN(startaddr,
- (1ULL << TARGET_PHYS_ADDR_SPACE_BITS) - 1);
- endaddr = MIN(endaddr,
- (1ULL << TARGET_PHYS_ADDR_SPACE_BITS) - 1);
- page_set_flags(startaddr & TARGET_PAGE_MASK,
- TARGET_PAGE_ALIGN(endaddr),
- PAGE_RESERVED);
- }
- } while (!feof(f));
- fclose(f);
- }
- mmap_unlock();
- }
-#endif
-}
-
-static inline PageDesc **page_l1_map(target_ulong index)
-{
-#if TARGET_LONG_BITS > 32
- /* Host memory outside guest VM. For 32-bit targets we have already
- excluded high addresses. */
- if (index > ((target_ulong)L2_SIZE * L1_SIZE))
- return NULL;
-#endif
- return &l1_map[index >> L2_BITS];
-}
-
-static inline PageDesc *page_find_alloc(target_ulong index)
-{
- PageDesc **lp, *p;
- lp = page_l1_map(index);
- if (!lp)
- return NULL;
-
- p = *lp;
- if (!p) {
- /* allocate if not found */
-#if defined(CONFIG_USER_ONLY)
- unsigned long addr;
- size_t len = sizeof(PageDesc) * L2_SIZE;
- /* Don't use qemu_malloc because it may recurse. */
- p = mmap(0, len, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- *lp = p;
- addr = h2g(p);
- if (addr == (target_ulong)addr) {
- page_set_flags(addr & TARGET_PAGE_MASK,
- TARGET_PAGE_ALIGN(addr + len),
- PAGE_RESERVED);
- }
-#else
- p = qemu_mallocz(sizeof(PageDesc) * L2_SIZE);
- *lp = p;
-#endif
- }
- return p + (index & (L2_SIZE - 1));
-}
-
-static inline PageDesc *page_find(target_ulong index)
-{
- PageDesc **lp, *p;
- lp = page_l1_map(index);
- if (!lp)
- return NULL;
-
- p = *lp;
- if (!p)
- return 0;
- return p + (index & (L2_SIZE - 1));
-}
-
-static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
-{
- void **lp, **p;
- PhysPageDesc *pd;
-
- p = (void **)l1_phys_map;
-#if TARGET_PHYS_ADDR_SPACE_BITS > 32
-
-#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
-#error unsupported TARGET_PHYS_ADDR_SPACE_BITS
-#endif
- lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
- p = *lp;
- if (!p) {
- /* allocate if not found */
- if (!alloc)
- return NULL;
- p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
- memset(p, 0, sizeof(void *) * L1_SIZE);
- *lp = p;
- }
-#endif
- lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
- pd = *lp;
- if (!pd) {
- int i;
- /* allocate if not found */
- if (!alloc)
- return NULL;
- pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
- *lp = pd;
- for (i = 0; i < L2_SIZE; i++)
- pd[i].phys_offset = IO_MEM_UNASSIGNED;
- }
- return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
-}
-
-static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
-{
- return phys_page_find_alloc(index, 0);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void tlb_protect_code(ram_addr_t ram_addr);
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
- target_ulong vaddr);
-#define mmap_lock() do { } while(0)
-#define mmap_unlock() do { } while(0)
-#endif
-
-#define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024)
-
-#if defined(CONFIG_USER_ONLY)
-/* Currently it is not recommanded to allocate big chunks of data in
- user mode. It will change when a dedicated libc will be used */
-#define USE_STATIC_CODE_GEN_BUFFER
-#endif
-
-#ifdef USE_STATIC_CODE_GEN_BUFFER
-static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE];
-#endif
-
-static void code_gen_alloc(unsigned long tb_size)
-{
-#ifdef USE_STATIC_CODE_GEN_BUFFER
- code_gen_buffer = static_code_gen_buffer;
- code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
- map_exec(code_gen_buffer, code_gen_buffer_size);
-#else
- code_gen_buffer_size = tb_size;
- if (code_gen_buffer_size == 0) {
-#if defined(CONFIG_USER_ONLY)
- /* in user mode, phys_ram_size is not meaningful */
- code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
-#else
- /* XXX: needs ajustments */
- code_gen_buffer_size = (int)(phys_ram_size / 4);
-#endif
- }
- if (code_gen_buffer_size < MIN_CODE_GEN_BUFFER_SIZE)
- code_gen_buffer_size = MIN_CODE_GEN_BUFFER_SIZE;
- /* The code gen buffer location may have constraints depending on
- the host cpu and OS */
-#if defined(__linux__)
- {
- int flags;
- void *start = NULL;
-
- flags = MAP_PRIVATE | MAP_ANONYMOUS;
-#if defined(__x86_64__)
- flags |= MAP_32BIT;
- /* Cannot map more than that */
- if (code_gen_buffer_size > (800 * 1024 * 1024))
- code_gen_buffer_size = (800 * 1024 * 1024);
-#elif defined(__sparc_v9__)
- // Map the buffer below 2G, so we can use direct calls and branches
- flags |= MAP_FIXED;
- start = (void *) 0x60000000UL;
- if (code_gen_buffer_size > (512 * 1024 * 1024))
- code_gen_buffer_size = (512 * 1024 * 1024);
-#endif
- code_gen_buffer = mmap(start, code_gen_buffer_size,
- PROT_WRITE | PROT_READ | PROT_EXEC,
- flags, -1, 0);
- if (code_gen_buffer == MAP_FAILED) {
- fprintf(stderr, "Could not allocate dynamic translator buffer\n");
- exit(1);
- }
- }
-#else
- code_gen_buffer = qemu_malloc(code_gen_buffer_size);
- if (!code_gen_buffer) {
- fprintf(stderr, "Could not allocate dynamic translator buffer\n");
- exit(1);
- }
- map_exec(code_gen_buffer, code_gen_buffer_size);
-#endif
-#endif /* !USE_STATIC_CODE_GEN_BUFFER */
- map_exec(code_gen_prologue, sizeof(code_gen_prologue));
- code_gen_buffer_max_size = code_gen_buffer_size -
- code_gen_max_block_size();
- code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
- tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
-}
-
-/* Must be called before using the QEMU cpus. 'tb_size' is the size
- (in bytes) allocated to the translation buffer. Zero means default
- size. */
-void cpu_exec_init_all(unsigned long tb_size)
-{
- cpu_gen_init();
- code_gen_alloc(tb_size);
- code_gen_ptr = code_gen_buffer;
- page_init();
-#if !defined(CONFIG_USER_ONLY)
- io_mem_init();
-#endif
-}
-
-#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-
-#define CPU_COMMON_SAVE_VERSION 1
-
-static void cpu_common_save(QEMUFile *f, void *opaque)
-{
- CPUState *env = opaque;
-
- qemu_put_be32s(f, &env->halted);
- qemu_put_be32s(f, &env->interrupt_request);
-}
-
-static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUState *env = opaque;
-
- if (version_id != CPU_COMMON_SAVE_VERSION)
- return -EINVAL;
-
- qemu_get_be32s(f, &env->halted);
- qemu_get_be32s(f, &env->interrupt_request);
- tlb_flush(env, 1);
-
- return 0;
-}
-#endif
-
-void cpu_exec_init(CPUState *env)
-{
- CPUState **penv;
- int cpu_index;
-
- env->next_cpu = NULL;
- penv = &first_cpu;
- cpu_index = 0;
- while (*penv != NULL) {
- penv = (CPUState **)&(*penv)->next_cpu;
- cpu_index++;
- }
- env->cpu_index = cpu_index;
- env->nb_watchpoints = 0;
- *penv = env;
-#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
- register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
- cpu_common_save, cpu_common_load, env);
- register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
- cpu_save, cpu_load, env);
-#endif
-}
-
-static inline void invalidate_page_bitmap(PageDesc *p)
-{
- if (p->code_bitmap) {
- qemu_free(p->code_bitmap);
- p->code_bitmap = NULL;
- }
- p->code_write_count = 0;
-}
-
-/* set to NULL all the 'first_tb' fields in all PageDescs */
-static void page_flush_tb(void)
-{
- int i, j;
- PageDesc *p;
-
- for(i = 0; i < L1_SIZE; i++) {
- p = l1_map[i];
- if (p) {
- for(j = 0; j < L2_SIZE; j++) {
- p->first_tb = NULL;
- invalidate_page_bitmap(p);
- p++;
- }
- }
- }
-}
-
-/* flush all the translation blocks */
-/* XXX: tb_flush is currently not thread safe */
-void tb_flush(CPUState *env1)
-{
- CPUState *env;
-#if defined(DEBUG_FLUSH)
- printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
- (unsigned long)(code_gen_ptr - code_gen_buffer),
- nb_tbs, nb_tbs > 0 ?
- ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
-#endif
- if ((unsigned long)(code_gen_ptr - code_gen_buffer) > code_gen_buffer_size)
- cpu_abort(env1, "Internal error: code buffer overflow\n");
-
- nb_tbs = 0;
-
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
- }
-
- memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
- page_flush_tb();
-
- code_gen_ptr = code_gen_buffer;
- /* XXX: flush processor icache at this point if cache flush is
- expensive */
- tb_flush_count++;
-}
-
-#ifdef DEBUG_TB_CHECK
-
-static void tb_invalidate_check(target_ulong address)
-{
- TranslationBlock *tb;
- int i;
- address &= TARGET_PAGE_MASK;
- for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
- for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
- if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
- address >= tb->pc + tb->size)) {
- printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
- address, (long)tb->pc, tb->size);
- }
- }
- }
-}
-
-/* verify that all the pages have correct rights for code */
-static void tb_page_check(void)
-{
- TranslationBlock *tb;
- int i, flags1, flags2;
-
- for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
- for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
- flags1 = page_get_flags(tb->pc);
- flags2 = page_get_flags(tb->pc + tb->size - 1);
- if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
- printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
- (long)tb->pc, tb->size, flags1, flags2);
- }
- }
- }
-}
-
-void tb_jmp_check(TranslationBlock *tb)
-{
- TranslationBlock *tb1;
- unsigned int n1;
-
- /* suppress any remaining jumps to this TB */
- tb1 = tb->jmp_first;
- for(;;) {
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == 2)
- break;
- tb1 = tb1->jmp_next[n1];
- }
- /* check end of list */
- if (tb1 != tb) {
- printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
- }
-}
-
-#endif
-
-/* invalidate one TB */
-static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
- int next_offset)
-{
- TranslationBlock *tb1;
- for(;;) {
- tb1 = *ptb;
- if (tb1 == tb) {
- *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
- break;
- }
- ptb = (TranslationBlock **)((char *)tb1 + next_offset);
- }
-}
-
-static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
-{
- TranslationBlock *tb1;
- unsigned int n1;
-
- for(;;) {
- tb1 = *ptb;
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (tb1 == tb) {
- *ptb = tb1->page_next[n1];
- break;
- }
- ptb = &tb1->page_next[n1];
- }
-}
-
-static inline void tb_jmp_remove(TranslationBlock *tb, int n)
-{
- TranslationBlock *tb1, **ptb;
- unsigned int n1;
-
- ptb = &tb->jmp_next[n];
- tb1 = *ptb;
- if (tb1) {
- /* find tb(n) in circular list */
- for(;;) {
- tb1 = *ptb;
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == n && tb1 == tb)
- break;
- if (n1 == 2) {
- ptb = &tb1->jmp_first;
- } else {
- ptb = &tb1->jmp_next[n1];
- }
- }
- /* now we can suppress tb(n) from the list */
- *ptb = tb->jmp_next[n];
-
- tb->jmp_next[n] = NULL;
- }
-}
-
-/* reset the jump entry 'n' of a TB so that it is not chained to
- another TB */
-static inline void tb_reset_jump(TranslationBlock *tb, int n)
-{
- tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
-}
-
-void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr)
-{
- CPUState *env;
- PageDesc *p;
- unsigned int h, n1;
- target_phys_addr_t phys_pc;
- TranslationBlock *tb1, *tb2;
-
- /* remove the TB from the hash list */
- phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
- h = tb_phys_hash_func(phys_pc);
- tb_remove(&tb_phys_hash[h], tb,
- offsetof(TranslationBlock, phys_hash_next));
-
- /* remove the TB from the page list */
- if (tb->page_addr[0] != page_addr) {
- p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
- tb_page_remove(&p->first_tb, tb);
- invalidate_page_bitmap(p);
- }
- if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
- p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
- tb_page_remove(&p->first_tb, tb);
- invalidate_page_bitmap(p);
- }
-
- tb_invalidated_flag = 1;
-
- /* remove the TB from the hash list */
- h = tb_jmp_cache_hash_func(tb->pc);
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- if (env->tb_jmp_cache[h] == tb)
- env->tb_jmp_cache[h] = NULL;
- }
-
- /* suppress this TB from the two jump lists */
- tb_jmp_remove(tb, 0);
- tb_jmp_remove(tb, 1);
-
- /* suppress any remaining jumps to this TB */
- tb1 = tb->jmp_first;
- for(;;) {
- n1 = (long)tb1 & 3;
- if (n1 == 2)
- break;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- tb2 = tb1->jmp_next[n1];
- tb_reset_jump(tb1, n1);
- tb1->jmp_next[n1] = NULL;
- tb1 = tb2;
- }
- tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
-
- tb_phys_invalidate_count++;
-}
-
-static inline void set_bits(uint8_t *tab, int start, int len)
-{
- int end, mask, end1;
-
- end = start + len;
- tab += start >> 3;
- mask = 0xff << (start & 7);
- if ((start & ~7) == (end & ~7)) {
- if (start < end) {
- mask &= ~(0xff << (end & 7));
- *tab |= mask;
- }
- } else {
- *tab++ |= mask;
- start = (start + 8) & ~7;
- end1 = end & ~7;
- while (start < end1) {
- *tab++ = 0xff;
- start += 8;
- }
- if (start < end) {
- mask = ~(0xff << (end & 7));
- *tab |= mask;
- }
- }
-}
-
-static void build_page_bitmap(PageDesc *p)
-{
- int n, tb_start, tb_end;
- TranslationBlock *tb;
-
- p->code_bitmap = qemu_mallocz(TARGET_PAGE_SIZE / 8);
- if (!p->code_bitmap)
- return;
-
- tb = p->first_tb;
- while (tb != NULL) {
- n = (long)tb & 3;
- tb = (TranslationBlock *)((long)tb & ~3);
- /* NOTE: this is subtle as a TB may span two physical pages */
- if (n == 0) {
- /* NOTE: tb_end may be after the end of the page, but
- it is not a problem */
- tb_start = tb->pc & ~TARGET_PAGE_MASK;
- tb_end = tb_start + tb->size;
- if (tb_end > TARGET_PAGE_SIZE)
- tb_end = TARGET_PAGE_SIZE;
- } else {
- tb_start = 0;
- tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
- }
- set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
- tb = tb->page_next[n];
- }
-}
-
-TranslationBlock *tb_gen_code(CPUState *env,
- target_ulong pc, target_ulong cs_base,
- int flags, int cflags)
-{
- TranslationBlock *tb;
- uint8_t *tc_ptr;
- target_ulong phys_pc, phys_page2, virt_page2;
- int code_gen_size;
-
- phys_pc = get_phys_addr_code(env, pc);
- tb = tb_alloc(pc);
- if (!tb) {
- /* flush must be done */
- tb_flush(env);
- /* cannot fail at this point */
- tb = tb_alloc(pc);
- /* Don't forget to invalidate previous TB info. */
- tb_invalidated_flag = 1;
- }
- tc_ptr = code_gen_ptr;
- tb->tc_ptr = tc_ptr;
- tb->cs_base = cs_base;
- tb->flags = flags;
- tb->cflags = cflags;
-#ifdef CONFIG_TRACE
- tb->bb_rec = NULL;
- tb->prev_time = 0;
-#endif
- cpu_gen_code(env, tb, &code_gen_size);
- code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-
- /* check next page if needed */
- virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
- phys_page2 = -1;
- if ((pc & TARGET_PAGE_MASK) != virt_page2) {
- phys_page2 = get_phys_addr_code(env, virt_page2);
- }
- tb_link_phys(tb, phys_pc, phys_page2);
- return tb;
-}
-
-/* invalidate all TBs which intersect with the target physical page
- starting in range [start;end[. NOTE: start and end must refer to
- the same physical page. 'is_cpu_write_access' should be true if called
- from a real cpu write access: the virtual CPU will exit the current
- TB if code is modified inside this TB. */
-void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
- int is_cpu_write_access)
-{
- int n, current_tb_modified, current_tb_not_found, current_flags;
- CPUState *env = cpu_single_env;
- PageDesc *p;
- TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
- target_ulong tb_start, tb_end;
- target_ulong current_pc, current_cs_base;
-
- p = page_find(start >> TARGET_PAGE_BITS);
- if (!p)
- return;
- if (!p->code_bitmap &&
- ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
- is_cpu_write_access) {
- /* build code bitmap */
- build_page_bitmap(p);
- }
-
- /* we remove all the TBs in the range [start, end[ */
- /* XXX: see if in some cases it could be faster to invalidate all the code */
- current_tb_not_found = is_cpu_write_access;
- current_tb_modified = 0;
- current_tb = NULL; /* avoid warning */
- current_pc = 0; /* avoid warning */
- current_cs_base = 0; /* avoid warning */
- current_flags = 0; /* avoid warning */
- tb = p->first_tb;
- while (tb != NULL) {
- n = (long)tb & 3;
- tb = (TranslationBlock *)((long)tb & ~3);
- tb_next = tb->page_next[n];
- /* NOTE: this is subtle as a TB may span two physical pages */
- if (n == 0) {
- /* NOTE: tb_end may be after the end of the page, but
- it is not a problem */
- tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
- tb_end = tb_start + tb->size;
- } else {
- tb_start = tb->page_addr[1];
- tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
- }
- if (!(tb_end <= start || tb_start >= end)) {
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_not_found) {
- current_tb_not_found = 0;
- current_tb = NULL;
- if (env->mem_io_pc) {
- /* now we have a real cpu fault */
- current_tb = tb_find_pc(env->mem_io_pc);
- }
- }
- if (current_tb == tb &&
- (current_tb->cflags & CF_COUNT_MASK) != 1) {
- /* If we are modifying the current TB, we must stop
- its execution. We could be more precise by checking
- that the modification is after the current PC, but it
- would require a specialized function to partially
- restore the CPU state */
-
- current_tb_modified = 1;
- cpu_restore_state(current_tb, env,
- env->mem_io_pc, NULL);
-#if defined(TARGET_I386)
- current_flags = env->hflags;
- current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- current_cs_base = (target_ulong)env->segs[R_CS].base;
- current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
- }
-#endif /* TARGET_HAS_PRECISE_SMC */
- /* we need to do that to handle the case where a signal
- occurs while doing tb_phys_invalidate() */
- saved_tb = NULL;
- if (env) {
- saved_tb = env->current_tb;
- env->current_tb = NULL;
- }
- tb_phys_invalidate(tb, -1);
- if (env) {
- env->current_tb = saved_tb;
- if (env->interrupt_request && env->current_tb)
- cpu_interrupt(env, env->interrupt_request);
- }
- }
- tb = tb_next;
- }
-#if !defined(CONFIG_USER_ONLY)
- /* if no code remaining, no need to continue to use slow writes */
- if (!p->first_tb) {
- invalidate_page_bitmap(p);
- if (is_cpu_write_access) {
- tlb_unprotect_code_phys(env, start, env->mem_io_vaddr);
- }
- }
-#endif
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_modified) {
- /* we generate a block containing just the instruction
- modifying the memory. It will ensure that it cannot modify
- itself */
- env->current_tb = NULL;
- tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
- cpu_resume_from_signal(env, NULL);
- }
-#endif
-}
-
-/* len must be <= 8 and start must be a multiple of len */
-static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int len)
-{
- PageDesc *p;
- int offset, b;
-#if 0
- if (1) {
- if (loglevel) {
- fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
- cpu_single_env->mem_io_vaddr, len,
- cpu_single_env->eip,
- cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
- }
- }
-#endif
- p = page_find(start >> TARGET_PAGE_BITS);
- if (!p)
- return;
- if (p->code_bitmap) {
- offset = start & ~TARGET_PAGE_MASK;
- b = p->code_bitmap[offset >> 3] >> (offset & 7);
- if (b & ((1 << len) - 1))
- goto do_invalidate;
- } else {
- do_invalidate:
- tb_invalidate_phys_page_range(start, start + len, 1);
- }
-}
-
-#if !defined(CONFIG_SOFTMMU)
-static void tb_invalidate_phys_page(target_phys_addr_t addr,
- unsigned long pc, void *puc)
-{
- int n, current_flags, current_tb_modified;
- target_ulong current_pc, current_cs_base;
- PageDesc *p;
- TranslationBlock *tb, *current_tb;
-#ifdef TARGET_HAS_PRECISE_SMC
- CPUState *env = cpu_single_env;
-#endif
-
- addr &= TARGET_PAGE_MASK;
- p = page_find(addr >> TARGET_PAGE_BITS);
- if (!p)
- return;
- tb = p->first_tb;
- current_tb_modified = 0;
- current_tb = NULL;
- current_pc = 0; /* avoid warning */
- current_cs_base = 0; /* avoid warning */
- current_flags = 0; /* avoid warning */
-#ifdef TARGET_HAS_PRECISE_SMC
- if (tb && pc != 0) {
- current_tb = tb_find_pc(pc);
- }
-#endif
- while (tb != NULL) {
- n = (long)tb & 3;
- tb = (TranslationBlock *)((long)tb & ~3);
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb == tb &&
- (current_tb->cflags & CF_COUNT_MASK) != 1) {
- /* If we are modifying the current TB, we must stop
- its execution. We could be more precise by checking
- that the modification is after the current PC, but it
- would require a specialized function to partially
- restore the CPU state */
-
- current_tb_modified = 1;
- cpu_restore_state(current_tb, env, pc, puc);
-#if defined(TARGET_I386)
- current_flags = env->hflags;
- current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
- current_cs_base = (target_ulong)env->segs[R_CS].base;
- current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
- }
-#endif /* TARGET_HAS_PRECISE_SMC */
- tb_phys_invalidate(tb, addr);
- tb = tb->page_next[n];
- }
- p->first_tb = NULL;
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_modified) {
- /* we generate a block containing just the instruction
- modifying the memory. It will ensure that it cannot modify
- itself */
- env->current_tb = NULL;
- tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
- cpu_resume_from_signal(env, puc);
- }
-#endif
-}
-#endif
-
-/* add the tb in the target page and protect it if necessary */
-static inline void tb_alloc_page(TranslationBlock *tb,
- unsigned int n, target_ulong page_addr)
-{
- PageDesc *p;
- TranslationBlock *last_first_tb;
-
- tb->page_addr[n] = page_addr;
- p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
- tb->page_next[n] = p->first_tb;
- last_first_tb = p->first_tb;
- p->first_tb = (TranslationBlock *)((long)tb | n);
- invalidate_page_bitmap(p);
-
-#if defined(TARGET_HAS_SMC) || 1
-
-#if defined(CONFIG_USER_ONLY)
- if (p->flags & PAGE_WRITE) {
- target_ulong addr;
- PageDesc *p2;
- int prot;
-
- /* force the host page as non writable (writes will have a
- page fault + mprotect overhead) */
- page_addr &= qemu_host_page_mask;
- prot = 0;
- for(addr = page_addr; addr < page_addr + qemu_host_page_size;
- addr += TARGET_PAGE_SIZE) {
-
- p2 = page_find (addr >> TARGET_PAGE_BITS);
- if (!p2)
- continue;
- prot |= p2->flags;
- p2->flags &= ~PAGE_WRITE;
- page_get_flags(addr);
- }
- mprotect(g2h(page_addr), qemu_host_page_size,
- (prot & PAGE_BITS) & ~PAGE_WRITE);
-#ifdef DEBUG_TB_INVALIDATE
- printf("protecting code page: 0x" TARGET_FMT_lx "\n",
- page_addr);
-#endif
- }
-#else
- /* if some code is already present, then the pages are already
- protected. So we handle the case where only the first TB is
- allocated in a physical page */
- if (!last_first_tb) {
- tlb_protect_code(page_addr);
- }
-#endif
-
-#endif /* TARGET_HAS_SMC */
-}
-
-/* Allocate a new translation block. Flush the translation buffer if
- too many translation blocks or too much generated code. */
-TranslationBlock *tb_alloc(target_ulong pc)
-{
- TranslationBlock *tb;
-
- if (nb_tbs >= code_gen_max_blocks ||
- (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size)
- return NULL;
- tb = &tbs[nb_tbs++];
- tb->pc = pc;
- tb->cflags = 0;
- return tb;
-}
-
-void tb_free(TranslationBlock *tb)
-{
- /* In practice this is mostly used for single use temporary TB
- Ignore the hard cases and just back up if this TB happens to
- be the last one generated. */
- if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) {
- code_gen_ptr = tb->tc_ptr;
- nb_tbs--;
- }
-}
-
-/* add a new TB and link it to the physical page tables. phys_page2 is
- (-1) to indicate that only one page contains the TB. */
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2)
-{
- unsigned int h;
- TranslationBlock **ptb;
-
- /* Grab the mmap lock to stop another thread invalidating this TB
- before we are done. */
- mmap_lock();
- /* add in the physical hash table */
- h = tb_phys_hash_func(phys_pc);
- ptb = &tb_phys_hash[h];
- tb->phys_hash_next = *ptb;
- *ptb = tb;
-
- /* add in the page list */
- tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
- if (phys_page2 != -1)
- tb_alloc_page(tb, 1, phys_page2);
- else
- tb->page_addr[1] = -1;
-
- tb->jmp_first = (TranslationBlock *)((long)tb | 2);
- tb->jmp_next[0] = NULL;
- tb->jmp_next[1] = NULL;
-
- /* init original jump addresses */
- if (tb->tb_next_offset[0] != 0xffff)
- tb_reset_jump(tb, 0);
- if (tb->tb_next_offset[1] != 0xffff)
- tb_reset_jump(tb, 1);
-
-#ifdef DEBUG_TB_CHECK
- tb_page_check();
-#endif
- mmap_unlock();
-}
-
-/* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
- tb[1].tc_ptr. Return NULL if not found */
-TranslationBlock *tb_find_pc(unsigned long tc_ptr)
-{
- int m_min, m_max, m;
- unsigned long v;
- TranslationBlock *tb;
-
- if (nb_tbs <= 0)
- return NULL;
- if (tc_ptr < (unsigned long)code_gen_buffer ||
- tc_ptr >= (unsigned long)code_gen_ptr)
- return NULL;
- /* binary search (cf Knuth) */
- m_min = 0;
- m_max = nb_tbs - 1;
- while (m_min <= m_max) {
- m = (m_min + m_max) >> 1;
- tb = &tbs[m];
- v = (unsigned long)tb->tc_ptr;
- if (v == tc_ptr)
- return tb;
- else if (tc_ptr < v) {
- m_max = m - 1;
- } else {
- m_min = m + 1;
- }
- }
- return &tbs[m_max];
-}
-
-static void tb_reset_jump_recursive(TranslationBlock *tb);
-
-static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
-{
- TranslationBlock *tb1, *tb_next, **ptb;
- unsigned int n1;
-
- tb1 = tb->jmp_next[n];
- if (tb1 != NULL) {
- /* find head of list */
- for(;;) {
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == 2)
- break;
- tb1 = tb1->jmp_next[n1];
- }
- /* we are now sure now that tb jumps to tb1 */
- tb_next = tb1;
-
- /* remove tb from the jmp_first list */
- ptb = &tb_next->jmp_first;
- for(;;) {
- tb1 = *ptb;
- n1 = (long)tb1 & 3;
- tb1 = (TranslationBlock *)((long)tb1 & ~3);
- if (n1 == n && tb1 == tb)
- break;
- ptb = &tb1->jmp_next[n1];
- }
- *ptb = tb->jmp_next[n];
- tb->jmp_next[n] = NULL;
-
- /* suppress the jump to next tb in generated code */
- tb_reset_jump(tb, n);
-
- /* suppress jumps in the tb on which we could have jumped */
- tb_reset_jump_recursive(tb_next);
- }
-}
-
-static void tb_reset_jump_recursive(TranslationBlock *tb)
-{
- tb_reset_jump_recursive2(tb, 0);
- tb_reset_jump_recursive2(tb, 1);
-}
-
-#if defined(TARGET_HAS_ICE)
-static void breakpoint_invalidate(CPUState *env, target_ulong pc)
-{
- target_phys_addr_t addr;
- target_ulong pd;
- ram_addr_t ram_addr;
- PhysPageDesc *p;
-
- addr = cpu_get_phys_page_debug(env, pc);
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
- ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
- tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
-}
-#endif
-
-/* Add a watchpoint. */
-int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type)
-{
- int i;
-
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (addr == env->watchpoint[i].vaddr)
- return 0;
- }
- if (env->nb_watchpoints >= MAX_WATCHPOINTS)
- return -1;
-
- i = env->nb_watchpoints++;
- env->watchpoint[i].vaddr = addr;
- env->watchpoint[i].type = type;
- tlb_flush_page(env, addr);
- /* FIXME: This flush is needed because of the hack to make memory ops
- terminate the TB. It can be removed once the proper IO trap and
- re-execute bits are in. */
- tb_flush(env);
- return i;
-}
-
-/* Remove a watchpoint. */
-int cpu_watchpoint_remove(CPUState *env, target_ulong addr)
-{
- int i;
-
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (addr == env->watchpoint[i].vaddr) {
- env->nb_watchpoints--;
- env->watchpoint[i] = env->watchpoint[env->nb_watchpoints];
- tlb_flush_page(env, addr);
- return 0;
- }
- }
- return -1;
-}
-
-/* Remove all watchpoints. */
-void cpu_watchpoint_remove_all(CPUState *env) {
- int i;
-
- for (i = 0; i < env->nb_watchpoints; i++) {
- tlb_flush_page(env, env->watchpoint[i].vaddr);
- }
- env->nb_watchpoints = 0;
-}
-
-/* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
- breakpoint is reached */
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
-{
-#if defined(TARGET_HAS_ICE)
- int i;
-
- for(i = 0; i < env->nb_breakpoints; i++) {
- if (env->breakpoints[i] == pc)
- return 0;
- }
-
- if (env->nb_breakpoints >= MAX_BREAKPOINTS)
- return -1;
- env->breakpoints[env->nb_breakpoints++] = pc;
-
- breakpoint_invalidate(env, pc);
- return 0;
-#else
- return -1;
-#endif
-}
-
-/* remove all breakpoints */
-void cpu_breakpoint_remove_all(CPUState *env) {
-#if defined(TARGET_HAS_ICE)
- int i;
- for(i = 0; i < env->nb_breakpoints; i++) {
- breakpoint_invalidate(env, env->breakpoints[i]);
- }
- env->nb_breakpoints = 0;
-#endif
-}
-
-/* remove a breakpoint */
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
-{
-#if defined(TARGET_HAS_ICE)
- int i;
- for(i = 0; i < env->nb_breakpoints; i++) {
- if (env->breakpoints[i] == pc)
- goto found;
- }
- return -1;
- found:
- env->nb_breakpoints--;
- if (i < env->nb_breakpoints)
- env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
-
- breakpoint_invalidate(env, pc);
- return 0;
-#else
- return -1;
-#endif
-}
-
-/* enable or disable single step mode. EXCP_DEBUG is returned by the
- CPU loop after each instruction */
-void cpu_single_step(CPUState *env, int enabled)
-{
-#if defined(TARGET_HAS_ICE)
- if (env->singlestep_enabled != enabled) {
- env->singlestep_enabled = enabled;
- /* must flush all the translated code to avoid inconsistancies */
- /* XXX: only flush what is necessary */
- tb_flush(env);
- }
-#endif
-}
-
-/* enable or disable low levels log */
-void cpu_set_log(int log_flags)
-{
- loglevel = log_flags;
- if (loglevel && !logfile) {
- logfile = fopen(logfilename, log_append ? "a" : "w");
- if (!logfile) {
- perror(logfilename);
- _exit(1);
- }
-#if !defined(CONFIG_SOFTMMU)
- /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
- {
- static uint8_t logfile_buf[4096];
- setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
- }
-#else
- setvbuf(logfile, NULL, _IOLBF, 0);
-#endif
- log_append = 1;
- }
- if (!loglevel && logfile) {
- fclose(logfile);
- logfile = NULL;
- }
-}
-
-void cpu_set_log_filename(const char *filename)
-{
- logfilename = strdup(filename);
- if (logfile) {
- fclose(logfile);
- logfile = NULL;
- }
- cpu_set_log(loglevel);
-}
-
-/* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
-{
-#if !defined(USE_NPTL)
- TranslationBlock *tb;
- static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
-#endif
- int old_mask;
-
- old_mask = env->interrupt_request;
- /* FIXME: This is probably not threadsafe. A different thread could
- be in the middle of a read-modify-write operation. */
- env->interrupt_request |= mask;
-#if defined(USE_NPTL)
- /* FIXME: TB unchaining isn't SMP safe. For now just ignore the
- problem and hope the cpu will stop of its own accord. For userspace
- emulation this often isn't actually as bad as it sounds. Often
- signals are used primarily to interrupt blocking syscalls. */
-#else
- if (use_icount) {
- env->icount_decr.u16.high = 0xffff;
-#ifndef CONFIG_USER_ONLY
- /* CPU_INTERRUPT_EXIT isn't a real interrupt. It just means
- an async event happened and we need to process it. */
- if (!can_do_io(env)
- && (mask & ~(old_mask | CPU_INTERRUPT_EXIT)) != 0) {
- cpu_abort(env, "Raised interrupt while not in I/O function");
- }
-#endif
- } else {
- tb = env->current_tb;
- /* if the cpu is currently executing code, we must unlink it and
- all the potentially executing TB */
- if (tb && !testandset(&interrupt_lock)) {
- env->current_tb = NULL;
- tb_reset_jump_recursive(tb);
- resetlock(&interrupt_lock);
- }
- }
-#endif
-}
-
-void cpu_reset_interrupt(CPUState *env, int mask)
-{
- env->interrupt_request &= ~mask;
-}
-
-CPULogItem cpu_log_items[] = {
- { CPU_LOG_TB_OUT_ASM, "out_asm",
- "show generated host assembly code for each compiled TB" },
- { CPU_LOG_TB_IN_ASM, "in_asm",
- "show target assembly code for each compiled TB" },
- { CPU_LOG_TB_OP, "op",
- "show micro ops for each compiled TB" },
- { CPU_LOG_TB_OP_OPT, "op_opt",
- "show micro ops "
-#ifdef TARGET_I386
- "before eflags optimization and "
-#endif
- "after liveness analysis" },
- { CPU_LOG_INT, "int",
- "show interrupts/exceptions in short format" },
- { CPU_LOG_EXEC, "exec",
- "show trace before each executed TB (lots of logs)" },
- { CPU_LOG_TB_CPU, "cpu",
- "show CPU state before block translation" },
-#ifdef TARGET_I386
- { CPU_LOG_PCALL, "pcall",
- "show protected mode far calls/returns/exceptions" },
-#endif
-#ifdef DEBUG_IOPORT
- { CPU_LOG_IOPORT, "ioport",
- "show all i/o ports accesses" },
-#endif
- { 0, NULL, NULL },
-};
-
-static int cmp1(const char *s1, int n, const char *s2)
-{
- if (strlen(s2) != n)
- return 0;
- return memcmp(s1, s2, n) == 0;
-}
-
-/* takes a comma separated list of log masks. Return 0 if error. */
-int cpu_str_to_log_mask(const char *str)
-{
- CPULogItem *item;
- int mask;
- const char *p, *p1;
-
- p = str;
- mask = 0;
- for(;;) {
- p1 = strchr(p, ',');
- if (!p1)
- p1 = p + strlen(p);
- if(cmp1(p,p1-p,"all")) {
- for(item = cpu_log_items; item->mask != 0; item++) {
- mask |= item->mask;
- }
- } else {
- for(item = cpu_log_items; item->mask != 0; item++) {
- if (cmp1(p, p1 - p, item->name))
- goto found;
- }
- return 0;
- }
- found:
- mask |= item->mask;
- if (*p1 != ',')
- break;
- p = p1 + 1;
- }
- return mask;
-}
-
-void cpu_abort(CPUState *env, const char *fmt, ...)
-{
- va_list ap;
- va_list ap2;
-
- va_start(ap, fmt);
- va_copy(ap2, ap);
- fprintf(stderr, "qemu: fatal: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
-#ifdef TARGET_I386
- cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
-#else
- cpu_dump_state(env, stderr, fprintf, 0);
-#endif
- if (logfile) {
- fprintf(logfile, "qemu: fatal: ");
- vfprintf(logfile, fmt, ap2);
- fprintf(logfile, "\n");
-#ifdef TARGET_I386
- cpu_dump_state(env, logfile, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
-#else
- cpu_dump_state(env, logfile, fprintf, 0);
-#endif
- fflush(logfile);
- fclose(logfile);
- }
- va_end(ap2);
- va_end(ap);
- abort();
-}
-
-CPUState *cpu_copy(CPUState *env)
-{
- CPUState *new_env = cpu_init(env->cpu_model_str);
- /* preserve chaining and index */
- CPUState *next_cpu = new_env->next_cpu;
- int cpu_index = new_env->cpu_index;
- memcpy(new_env, env, sizeof(CPUState));
- new_env->next_cpu = next_cpu;
- new_env->cpu_index = cpu_index;
- return new_env;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr)
-{
- unsigned int i;
-
- /* Discard jump cache entries for any tb which might potentially
- overlap the flushed page. */
- i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
- memset (&env->tb_jmp_cache[i], 0,
- TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
-
- i = tb_jmp_cache_hash_page(addr);
- memset (&env->tb_jmp_cache[i], 0,
- TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
-}
-
-/* NOTE: if flush_global is true, also flush global entries (not
- implemented yet) */
-void tlb_flush(CPUState *env, int flush_global)
-{
- int i;
-
-#if defined(DEBUG_TLB)
- printf("tlb_flush:\n");
-#endif
- /* must reset current TB so that interrupts cannot modify the
- links while we are modifying them */
- env->current_tb = NULL;
-
- for(i = 0; i < CPU_TLB_SIZE; i++) {
- env->tlb_table[0][i].addr_read = -1;
- env->tlb_table[0][i].addr_write = -1;
- env->tlb_table[0][i].addr_code = -1;
- env->tlb_table[1][i].addr_read = -1;
- env->tlb_table[1][i].addr_write = -1;
- env->tlb_table[1][i].addr_code = -1;
-#if (NB_MMU_MODES >= 3)
- env->tlb_table[2][i].addr_read = -1;
- env->tlb_table[2][i].addr_write = -1;
- env->tlb_table[2][i].addr_code = -1;
-#if (NB_MMU_MODES == 4)
- env->tlb_table[3][i].addr_read = -1;
- env->tlb_table[3][i].addr_write = -1;
- env->tlb_table[3][i].addr_code = -1;
-#endif
-#endif
- }
-
- memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
-
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_flush(env, flush_global);
- }
-#endif
- tlb_flush_count++;
-}
-
-static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
-{
- if (addr == (tlb_entry->addr_read &
- (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
- addr == (tlb_entry->addr_write &
- (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
- addr == (tlb_entry->addr_code &
- (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- tlb_entry->addr_read = -1;
- tlb_entry->addr_write = -1;
- tlb_entry->addr_code = -1;
- }
-}
-
-void tlb_flush_page(CPUState *env, target_ulong addr)
-{
- int i;
-
-#if defined(DEBUG_TLB)
- printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
-#endif
- /* must reset current TB so that interrupts cannot modify the
- links while we are modifying them */
- env->current_tb = NULL;
-
- addr &= TARGET_PAGE_MASK;
- i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- tlb_flush_entry(&env->tlb_table[0][i], addr);
- tlb_flush_entry(&env->tlb_table[1][i], addr);
-#if (NB_MMU_MODES >= 3)
- tlb_flush_entry(&env->tlb_table[2][i], addr);
-#if (NB_MMU_MODES == 4)
- tlb_flush_entry(&env->tlb_table[3][i], addr);
-#endif
-#endif
-
- tlb_flush_jmp_cache(env, addr);
-
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_flush_page(env, addr);
- }
-#endif
-}
-
-/* update the TLBs so that writes to code in the virtual page 'addr'
- can be detected */
-static void tlb_protect_code(ram_addr_t ram_addr)
-{
- cpu_physical_memory_reset_dirty(ram_addr,
- ram_addr + TARGET_PAGE_SIZE,
- CODE_DIRTY_FLAG);
-}
-
-/* update the TLB so that writes in physical page 'phys_addr' are no longer
- tested for self modifying code */
-static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
- target_ulong vaddr)
-{
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
-}
-
-static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
- unsigned long start, unsigned long length)
-{
- unsigned long addr;
- if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
- addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
- if ((addr - start) < length) {
- tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
- }
- }
-}
-
-void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
- int dirty_flags)
-{
- CPUState *env;
- unsigned long length, start1;
- int i, mask, len;
- uint8_t *p;
-
- start &= TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
-
- length = end - start;
- if (length == 0)
- return;
- len = length >> TARGET_PAGE_BITS;
-#ifdef USE_KQEMU
- /* XXX: should not depend on cpu context */
- env = first_cpu;
- if (env->kqemu_enabled) {
- ram_addr_t addr;
- addr = start;
- for(i = 0; i < len; i++) {
- kqemu_set_notdirty(env, addr);
- addr += TARGET_PAGE_SIZE;
- }
- }
-#endif
- mask = ~dirty_flags;
- p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
- for(i = 0; i < len; i++)
- p[i] &= mask;
-
- /* we modify the TLB cache so that the dirty bit will be set again
- when accessing the range */
- start1 = start + (unsigned long)phys_ram_base;
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
-#if (NB_MMU_MODES >= 3)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[2][i], start1, length);
-#if (NB_MMU_MODES == 4)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_reset_dirty_range(&env->tlb_table[3][i], start1, length);
-#endif
-#endif
- }
-}
-
-static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
-{
- ram_addr_t ram_addr;
-
- if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
- ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
- tlb_entry->addend - (unsigned long)phys_ram_base;
- if (!cpu_physical_memory_is_dirty(ram_addr)) {
- tlb_entry->addr_write |= TLB_NOTDIRTY;
- }
- }
-}
-
-/* update the TLB according to the current state of the dirty bits */
-void cpu_tlb_update_dirty(CPUState *env)
-{
- int i;
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[0][i]);
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[1][i]);
-#if (NB_MMU_MODES >= 3)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[2][i]);
-#if (NB_MMU_MODES == 4)
- for(i = 0; i < CPU_TLB_SIZE; i++)
- tlb_update_dirty(&env->tlb_table[3][i]);
-#endif
-#endif
-}
-
-static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
-{
- if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY))
- tlb_entry->addr_write = vaddr;
-}
-
-/* update the TLB corresponding to virtual page vaddr
- so that it is no longer dirty */
-static inline void tlb_set_dirty(CPUState *env, target_ulong vaddr)
-{
- int i;
-
- vaddr &= TARGET_PAGE_MASK;
- i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- tlb_set_dirty1(&env->tlb_table[0][i], vaddr);
- tlb_set_dirty1(&env->tlb_table[1][i], vaddr);
-#if (NB_MMU_MODES >= 3)
- tlb_set_dirty1(&env->tlb_table[2][i], vaddr);
-#if (NB_MMU_MODES == 4)
- tlb_set_dirty1(&env->tlb_table[3][i], vaddr);
-#endif
-#endif
-}
-
-/* add a new TLB entry. At most one entry for a given virtual address
- is permitted. Return 0 if OK or 2 if the page could not be mapped
- (can only happen in non SOFTMMU mode for I/O pages or pages
- conflicting with the host address space). */
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
-{
- PhysPageDesc *p;
- unsigned long pd;
- unsigned int index;
- target_ulong address;
- target_ulong code_address;
- target_phys_addr_t addend;
- int ret;
- CPUTLBEntry *te;
- int i;
- target_phys_addr_t iotlb;
-
- p = phys_page_find(paddr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-#if defined(DEBUG_TLB)
- printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
- vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
-#endif
-
- ret = 0;
- address = vaddr;
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
- /* IO memory case (romd handled later) */
- address |= TLB_MMIO;
- }
- addend = (target_phys_addr_t)phys_ram_base + (pd & TARGET_PAGE_MASK);
- if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) {
- /* Normal RAM. */
- iotlb = pd & TARGET_PAGE_MASK;
- if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
- iotlb |= IO_MEM_NOTDIRTY;
- else
- iotlb |= IO_MEM_ROM;
- } else {
- /* IO handlers are currently passed a phsical address.
- It would be nice to pass an offset from the base address
- of that region. This would avoid having to special case RAM,
- and avoid full address decoding in every device.
- We can't use the high bits of pd for this because
- IO_MEM_ROMD uses these as a ram address. */
- iotlb = (pd & ~TARGET_PAGE_MASK) + paddr;
- }
-
- code_address = address;
- /* Make accesses to pages with watchpoints go via the
- watchpoint trap routines. */
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) {
- iotlb = io_mem_watch + paddr;
- /* TODO: The memory case can be optimized by not trapping
- reads of pages with a write breakpoint. */
- address |= TLB_MMIO;
- }
- }
-
- index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- env->iotlb[mmu_idx][index] = iotlb - vaddr;
- te = &env->tlb_table[mmu_idx][index];
- te->addend = addend - vaddr;
- if (prot & PAGE_READ) {
- te->addr_read = address;
- } else {
- te->addr_read = -1;
- }
-
- if (prot & PAGE_EXEC) {
- te->addr_code = code_address;
- } else {
- te->addr_code = -1;
- }
- if (prot & PAGE_WRITE) {
- if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
- (pd & IO_MEM_ROMD)) {
- /* Write access calls the I/O callback. */
- te->addr_write = address | TLB_MMIO;
- } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
- !cpu_physical_memory_is_dirty(pd)) {
- te->addr_write = address | TLB_NOTDIRTY;
- } else {
- te->addr_write = address;
- }
- } else {
- te->addr_write = -1;
- }
- return ret;
-}
-
-#else
-
-void tlb_flush(CPUState *env, int flush_global)
-{
-}
-
-void tlb_flush_page(CPUState *env, target_ulong addr)
-{
-}
-
-int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int mmu_idx, int is_softmmu)
-{
- return 0;
-}
-
-/* dump memory mappings */
-void page_dump(FILE *f)
-{
- unsigned long start, end;
- int i, j, prot, prot1;
- PageDesc *p;
-
- fprintf(f, "%-8s %-8s %-8s %s\n",
- "start", "end", "size", "prot");
- start = -1;
- end = -1;
- prot = 0;
- for(i = 0; i <= L1_SIZE; i++) {
- if (i < L1_SIZE)
- p = l1_map[i];
- else
- p = NULL;
- for(j = 0;j < L2_SIZE; j++) {
- if (!p)
- prot1 = 0;
- else
- prot1 = p[j].flags;
- if (prot1 != prot) {
- end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
- if (start != -1) {
- fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
- start, end, end - start,
- prot & PAGE_READ ? 'r' : '-',
- prot & PAGE_WRITE ? 'w' : '-',
- prot & PAGE_EXEC ? 'x' : '-');
- }
- if (prot1 != 0)
- start = end;
- else
- start = -1;
- prot = prot1;
- }
- if (!p)
- break;
- }
- }
-}
-
-int page_get_flags(target_ulong address)
-{
- PageDesc *p;
-
- p = page_find(address >> TARGET_PAGE_BITS);
- if (!p)
- return 0;
- return p->flags;
-}
-
-/* modify the flags of a page and invalidate the code if
- necessary. The flag PAGE_WRITE_ORG is positionned automatically
- depending on PAGE_WRITE */
-void page_set_flags(target_ulong start, target_ulong end, int flags)
-{
- PageDesc *p;
- target_ulong addr;
-
- /* mmap_lock should already be held. */
- start = start & TARGET_PAGE_MASK;
- end = TARGET_PAGE_ALIGN(end);
- if (flags & PAGE_WRITE)
- flags |= PAGE_WRITE_ORG;
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- p = page_find_alloc(addr >> TARGET_PAGE_BITS);
- /* We may be called for host regions that are outside guest
- address space. */
- if (!p)
- return;
- /* if the write protection is set, then we invalidate the code
- inside */
- if (!(p->flags & PAGE_WRITE) &&
- (flags & PAGE_WRITE) &&
- p->first_tb) {
- tb_invalidate_phys_page(addr, 0, NULL);
- }
- p->flags = flags;
- }
-}
-
-int page_check_range(target_ulong start, target_ulong len, int flags)
-{
- PageDesc *p;
- target_ulong end;
- target_ulong addr;
-
- end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
- start = start & TARGET_PAGE_MASK;
-
- if( end < start )
- /* we've wrapped around */
- return -1;
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- p = page_find(addr >> TARGET_PAGE_BITS);
- if( !p )
- return -1;
- if( !(p->flags & PAGE_VALID) )
- return -1;
-
- if ((flags & PAGE_READ) && !(p->flags & PAGE_READ))
- return -1;
- if (flags & PAGE_WRITE) {
- if (!(p->flags & PAGE_WRITE_ORG))
- return -1;
- /* unprotect the page if it was put read-only because it
- contains translated code */
- if (!(p->flags & PAGE_WRITE)) {
- if (!page_unprotect(addr, 0, NULL))
- return -1;
- }
- return 0;
- }
- }
- return 0;
-}
-
-/* called from signal handler: invalidate the code and unprotect the
- page. Return TRUE if the fault was succesfully handled. */
-int page_unprotect(target_ulong address, unsigned long pc, void *puc)
-{
- unsigned int page_index, prot, pindex;
- PageDesc *p, *p1;
- target_ulong host_start, host_end, addr;
-
- /* Technically this isn't safe inside a signal handler. However we
- know this only ever happens in a synchronous SEGV handler, so in
- practice it seems to be ok. */
- mmap_lock();
-
- host_start = address & qemu_host_page_mask;
- page_index = host_start >> TARGET_PAGE_BITS;
- p1 = page_find(page_index);
- if (!p1) {
- mmap_unlock();
- return 0;
- }
- host_end = host_start + qemu_host_page_size;
- p = p1;
- prot = 0;
- for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
- prot |= p->flags;
- p++;
- }
- /* if the page was really writable, then we change its
- protection back to writable */
- if (prot & PAGE_WRITE_ORG) {
- pindex = (address - host_start) >> TARGET_PAGE_BITS;
- if (!(p1[pindex].flags & PAGE_WRITE)) {
- mprotect((void *)g2h(host_start), qemu_host_page_size,
- (prot & PAGE_BITS) | PAGE_WRITE);
- p1[pindex].flags |= PAGE_WRITE;
- /* and since the content will be modified, we must invalidate
- the corresponding translated code. */
- tb_invalidate_phys_page(address, pc, puc);
-#ifdef DEBUG_TB_CHECK
- tb_invalidate_check(address);
-#endif
- mmap_unlock();
- return 1;
- }
- }
- mmap_unlock();
- return 0;
-}
-
-static inline void tlb_set_dirty(CPUState *env,
- unsigned long addr, target_ulong vaddr)
-{
-}
-#endif /* defined(CONFIG_USER_ONLY) */
-
-#if !defined(CONFIG_USER_ONLY)
-static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
- ram_addr_t memory);
-static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
- ram_addr_t orig_memory);
-#define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \
- need_subpage) \
- do { \
- if (addr > start_addr) \
- start_addr2 = 0; \
- else { \
- start_addr2 = start_addr & ~TARGET_PAGE_MASK; \
- if (start_addr2 > 0) \
- need_subpage = 1; \
- } \
- \
- if ((start_addr + orig_size) - addr >= TARGET_PAGE_SIZE) \
- end_addr2 = TARGET_PAGE_SIZE - 1; \
- else { \
- end_addr2 = (start_addr + orig_size - 1) & ~TARGET_PAGE_MASK; \
- if (end_addr2 < TARGET_PAGE_SIZE - 1) \
- need_subpage = 1; \
- } \
- } while (0)
-
-/* register physical memory. 'size' must be a multiple of the target
- page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
- io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- ram_addr_t size,
- ram_addr_t phys_offset)
-{
- target_phys_addr_t addr, end_addr;
- PhysPageDesc *p;
- CPUState *env;
- ram_addr_t orig_size = size;
- void *subpage;
-
-#ifdef USE_KQEMU
- /* XXX: should not depend on cpu context */
- env = first_cpu;
- if (env->kqemu_enabled) {
- kqemu_set_phys_mem(start_addr, size, phys_offset);
- }
-#endif
- size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
- end_addr = start_addr + (target_phys_addr_t)size;
- for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (p && p->phys_offset != IO_MEM_UNASSIGNED) {
- ram_addr_t orig_memory = p->phys_offset;
- target_phys_addr_t start_addr2, end_addr2;
- int need_subpage = 0;
-
- CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
- need_subpage);
- if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
- if (!(orig_memory & IO_MEM_SUBPAGE)) {
- subpage = subpage_init((addr & TARGET_PAGE_MASK),
- &p->phys_offset, orig_memory);
- } else {
- subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK)
- >> IO_MEM_SHIFT];
- }
- subpage_register(subpage, start_addr2, end_addr2, phys_offset);
- } else {
- p->phys_offset = phys_offset;
- if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
- (phys_offset & IO_MEM_ROMD))
- phys_offset += TARGET_PAGE_SIZE;
- }
- } else {
- p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
- p->phys_offset = phys_offset;
- if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
- (phys_offset & IO_MEM_ROMD))
- phys_offset += TARGET_PAGE_SIZE;
- else {
- target_phys_addr_t start_addr2, end_addr2;
- int need_subpage = 0;
-
- CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
- end_addr2, need_subpage);
-
- if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
- subpage = subpage_init((addr & TARGET_PAGE_MASK),
- &p->phys_offset, IO_MEM_UNASSIGNED);
- subpage_register(subpage, start_addr2, end_addr2,
- phys_offset);
- }
- }
- }
- }
-
- /* since each CPU stores ram addresses in its TLB cache, we must
- reset the modified entries */
- /* XXX: slow ! */
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- tlb_flush(env, 1);
- }
-}
-
-/* XXX: temporary until new memory mapping API */
-ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
-{
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p)
- return IO_MEM_UNASSIGNED;
- return p->phys_offset;
-}
-
-/* XXX: better than nothing */
-ram_addr_t qemu_ram_alloc(ram_addr_t size)
-{
- ram_addr_t addr;
- if ((phys_ram_alloc_offset + size) > phys_ram_size) {
- fprintf(stderr, "Not enough memory (requested_size = %" PRIu64 ", max memory = %" PRIu64 "\n",
- (uint64_t)size, (uint64_t)phys_ram_size);
- abort();
- }
- addr = phys_ram_alloc_offset;
- phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
- return addr;
-}
-
-void qemu_ram_free(ram_addr_t addr)
-{
-}
-
-static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
-{
-#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
-#endif
-#ifdef TARGET_SPARC
- do_unassigned_access(addr, 0, 0, 0);
-#elif defined(TARGET_CRIS)
- do_unassigned_access(addr, 0, 0, 0);
-#endif
- return 0;
-}
-
-static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef DEBUG_UNASSIGNED
- printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
-#endif
-#ifdef TARGET_SPARC
- do_unassigned_access(addr, 1, 0, 0);
-#elif defined(TARGET_CRIS)
- do_unassigned_access(addr, 1, 0, 0);
-#endif
-}
-
-static CPUReadMemoryFunc *unassigned_mem_read[3] = {
- unassigned_mem_readb,
- unassigned_mem_readb,
- unassigned_mem_readb,
-};
-
-static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
- unassigned_mem_writeb,
- unassigned_mem_writeb,
- unassigned_mem_writeb,
-};
-
-static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
- uint32_t val)
-{
- int dirty_flags;
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
- if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
- tb_invalidate_phys_page_fast(ram_addr, 1);
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
-#endif
- }
- stb_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
- dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
- /* we remove the notdirty callback only if the code has been
- flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
-}
-
-static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
- uint32_t val)
-{
- int dirty_flags;
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
- if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
- tb_invalidate_phys_page_fast(ram_addr, 2);
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
-#endif
- }
- stw_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
- dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
- /* we remove the notdirty callback only if the code has been
- flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
-}
-
-static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
- uint32_t val)
-{
- int dirty_flags;
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
- if (!(dirty_flags & CODE_DIRTY_FLAG)) {
-#if !defined(CONFIG_USER_ONLY)
- tb_invalidate_phys_page_fast(ram_addr, 4);
- dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
-#endif
- }
- stl_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
- if (cpu_single_env->kqemu_enabled &&
- (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
- kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
- dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
- phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
- /* we remove the notdirty callback only if the code has been
- flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
-}
-
-static CPUReadMemoryFunc *error_mem_read[3] = {
- NULL, /* never used */
- NULL, /* never used */
- NULL, /* never used */
-};
-
-static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
- notdirty_mem_writeb,
- notdirty_mem_writew,
- notdirty_mem_writel,
-};
-
-/* Generate a debug exception if a watchpoint has been hit. */
-static void check_watchpoint(int offset, int flags)
-{
- CPUState *env = cpu_single_env;
- target_ulong vaddr;
- int i;
-
- vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
- for (i = 0; i < env->nb_watchpoints; i++) {
- if (vaddr == env->watchpoint[i].vaddr
- && (env->watchpoint[i].type & flags)) {
- env->watchpoint_hit = i + 1;
- cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
- break;
- }
- }
-}
-
-/* Watchpoint access routines. Watchpoints are inserted using TLB tricks,
- so these check for a hit then pass through to the normal out-of-line
- phys routines. */
-static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ);
- return ldub_phys(addr);
-}
-
-static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ);
- return lduw_phys(addr);
-}
-
-static uint32_t watch_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ);
- return ldl_phys(addr);
-}
-
-static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE);
- stb_phys(addr, val);
-}
-
-static void watch_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE);
- stw_phys(addr, val);
-}
-
-static void watch_mem_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE);
- stl_phys(addr, val);
-}
-
-static CPUReadMemoryFunc *watch_mem_read[3] = {
- watch_mem_readb,
- watch_mem_readw,
- watch_mem_readl,
-};
-
-static CPUWriteMemoryFunc *watch_mem_write[3] = {
- watch_mem_writeb,
- watch_mem_writew,
- watch_mem_writel,
-};
-
-static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
- unsigned int len)
-{
- uint32_t ret;
- unsigned int idx;
-
- idx = SUBPAGE_IDX(addr - mmio->base);
-#if defined(DEBUG_SUBPAGE)
- printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
- mmio, len, addr, idx);
-#endif
- ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr);
-
- return ret;
-}
-
-static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
- uint32_t value, unsigned int len)
-{
- unsigned int idx;
-
- idx = SUBPAGE_IDX(addr - mmio->base);
-#if defined(DEBUG_SUBPAGE)
- printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
- mmio, len, addr, idx, value);
-#endif
- (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr, value);
-}
-
-static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
-{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-
- return subpage_readlen(opaque, addr, 0);
-}
-
-static void subpage_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
-#endif
- subpage_writelen(opaque, addr, value, 0);
-}
-
-static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
-{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-
- return subpage_readlen(opaque, addr, 1);
-}
-
-static void subpage_writew (void *opaque, target_phys_addr_t addr,
- uint32_t value)
-{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
-#endif
- subpage_writelen(opaque, addr, value, 1);
-}
-
-static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
-{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-
- return subpage_readlen(opaque, addr, 2);
-}
-
-static void subpage_writel (void *opaque,
- target_phys_addr_t addr, uint32_t value)
-{
-#if defined(DEBUG_SUBPAGE)
- printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
-#endif
- subpage_writelen(opaque, addr, value, 2);
-}
-
-static CPUReadMemoryFunc *subpage_read[] = {
- &subpage_readb,
- &subpage_readw,
- &subpage_readl,
-};
-
-static CPUWriteMemoryFunc *subpage_write[] = {
- &subpage_writeb,
- &subpage_writew,
- &subpage_writel,
-};
-
-static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
- ram_addr_t memory)
-{
- int idx, eidx;
- unsigned int i;
-
- if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
- return -1;
- idx = SUBPAGE_IDX(start);
- eidx = SUBPAGE_IDX(end);
-#if defined(DEBUG_SUBPAGE)
- printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %d\n", __func__,
- mmio, start, end, idx, eidx, memory);
-#endif
- memory >>= IO_MEM_SHIFT;
- for (; idx <= eidx; idx++) {
- for (i = 0; i < 4; i++) {
- if (io_mem_read[memory][i]) {
- mmio->mem_read[idx][i] = &io_mem_read[memory][i];
- mmio->opaque[idx][0][i] = io_mem_opaque[memory];
- }
- if (io_mem_write[memory][i]) {
- mmio->mem_write[idx][i] = &io_mem_write[memory][i];
- mmio->opaque[idx][1][i] = io_mem_opaque[memory];
- }
- }
- }
-
- return 0;
-}
-
-static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
- ram_addr_t orig_memory)
-{
- subpage_t *mmio;
- int subpage_memory;
-
- mmio = qemu_mallocz(sizeof(subpage_t));
- if (mmio != NULL) {
- mmio->base = base;
- subpage_memory = cpu_register_io_memory(0, subpage_read, subpage_write, mmio);
-#if defined(DEBUG_SUBPAGE)
- printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
- mmio, base, TARGET_PAGE_SIZE, subpage_memory);
-#endif
- *phys = subpage_memory | IO_MEM_SUBPAGE;
- subpage_register(mmio, 0, TARGET_PAGE_SIZE - 1, orig_memory);
- }
-
- return mmio;
-}
-
-static void io_mem_init(void)
-{
- cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
- cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
- cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
- io_mem_nb = 5;
-
- io_mem_watch = cpu_register_io_memory(0, watch_mem_read,
- watch_mem_write, NULL);
- /* alloc dirty bits array */
- phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
- memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
-}
-
-/* mem_read and mem_write are arrays of functions containing the
- function to access byte (index 0), word (index 1) and dword (index
- 2). Functions can be omitted with a NULL function pointer. The
- registered functions may be modified dynamically later.
- If io_index is non zero, the corresponding io zone is
- modified. If it is zero, a new io zone is allocated. The return
- value can be used with cpu_register_physical_memory(). (-1) is
- returned if error. */
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
-{
- int i, subwidth = 0;
-
- if (io_index <= 0) {
- if (io_mem_nb >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
- } else {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- }
-
- for(i = 0;i < 3; i++) {
- if (!mem_read[i] || !mem_write[i])
- subwidth = IO_MEM_SUBWIDTH;
- io_mem_read[io_index][i] = mem_read[i];
- io_mem_write[io_index][i] = mem_write[i];
- }
- io_mem_opaque[io_index] = opaque;
- return (io_index << IO_MEM_SHIFT) | subwidth;
-}
-
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
-{
- return io_mem_write[io_index >> IO_MEM_SHIFT];
-}
-
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
-{
- return io_mem_read[io_index >> IO_MEM_SHIFT];
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-/* physical memory access (slow version, mainly for debug) */
-#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, flags;
- target_ulong page;
- void * p;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- flags = page_get_flags(page);
- if (!(flags & PAGE_VALID))
- return;
- if (is_write) {
- if (!(flags & PAGE_WRITE))
- return;
- /* XXX: this code should not depend on lock_user */
- if (!(p = lock_user(VERIFY_WRITE, addr, l, 0)))
- /* FIXME - should this return an error rather than just fail? */
- return;
- memcpy(p, buf, l);
- unlock_user(p, addr, l);
- } else {
- if (!(flags & PAGE_READ))
- return;
- /* XXX: this code should not depend on lock_user */
- if (!(p = lock_user(VERIFY_READ, addr, l, 1)))
- /* FIXME - should this return an error rather than just fail? */
- return;
- memcpy(buf, p, l);
- unlock_user(p, addr, 0);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-#else
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, io_index;
- uint8_t *ptr;
- uint32_t val;
- target_phys_addr_t page;
- unsigned long pd;
- PhysPageDesc *p;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- p = phys_page_find(page >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if (is_write) {
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- /* XXX: could force cpu_single_env to NULL to avoid
- potential bugs */
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit write access */
- val = ldl_p(buf);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit write access */
- val = lduw_p(buf);
- io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
- l = 2;
- } else {
- /* 8 bit write access */
- val = ldub_p(buf);
- io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
- l = 1;
- }
- } else {
- unsigned long addr1;
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* RAM case */
- ptr = phys_ram_base + addr1;
- memcpy(ptr, buf, l);
- if (!cpu_physical_memory_is_dirty(addr1)) {
- /* invalidate code */
- tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
- /* set dirty bit */
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
- }
- }
- } else {
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* I/O case */
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit read access */
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- stl_p(buf, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit read access */
- val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
- stw_p(buf, val);
- l = 2;
- } else {
- /* 8 bit read access */
- val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
- stb_p(buf, val);
- l = 1;
- }
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- memcpy(buf, ptr, l);
- }
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-/* used for ROM loading : can write in RAM and ROM */
-void cpu_physical_memory_write_rom(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-{
- int l;
- uint8_t *ptr;
- target_phys_addr_t page;
- unsigned long pd;
- PhysPageDesc *p;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- p = phys_page_find(page >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
- (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* do nothing */
- } else {
- unsigned long addr1;
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* ROM/RAM case */
- ptr = phys_ram_base + addr1;
- memcpy(ptr, buf, l);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-
-
-/* warning: addr must be aligned */
-uint32_t ldl_phys(target_phys_addr_t addr)
-{
- int io_index;
- uint8_t *ptr;
- uint32_t val;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* I/O case */
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- val = ldl_p(ptr);
- }
- return val;
-}
-
-/* warning: addr must be aligned */
-uint64_t ldq_phys(target_phys_addr_t addr)
-{
- int io_index;
- uint8_t *ptr;
- uint64_t val;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
- !(pd & IO_MEM_ROMD)) {
- /* I/O case */
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
- val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
-#else
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
-#endif
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- val = ldq_p(ptr);
- }
- return val;
-}
-
-/* XXX: optimize */
-uint32_t ldub_phys(target_phys_addr_t addr)
-{
- uint8_t val;
- cpu_physical_memory_read(addr, &val, 1);
- return val;
-}
-
-/* XXX: optimize */
-uint32_t lduw_phys(target_phys_addr_t addr)
-{
- uint16_t val;
- cpu_physical_memory_read(addr, (uint8_t *)&val, 2);
- return tswap16(val);
-}
-
-/* warning: addr must be aligned. The ram page is not masked as dirty
- and the code inside is not invalidated. It is useful if the dirty
- bits are used to track modified PTEs */
-void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
-{
- int io_index;
- uint8_t *ptr;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- } else {
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- stl_p(ptr, val);
- }
-}
-
-void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
-{
- int io_index;
- uint8_t *ptr;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-#ifdef TARGET_WORDS_BIGENDIAN
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val);
-#else
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32);
-#endif
- } else {
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- stq_p(ptr, val);
- }
-}
-
-/* warning: addr must be aligned */
-void stl_phys(target_phys_addr_t addr, uint32_t val)
-{
- int io_index;
- uint8_t *ptr;
- unsigned long pd;
- PhysPageDesc *p;
-
- p = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!p) {
- pd = IO_MEM_UNASSIGNED;
- } else {
- pd = p->phys_offset;
- }
-
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
- io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- } else {
- unsigned long addr1;
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* RAM case */
- ptr = phys_ram_base + addr1;
- stl_p(ptr, val);
- if (!cpu_physical_memory_is_dirty(addr1)) {
- /* invalidate code */
- tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
- /* set dirty bit */
- phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
- (0xff & ~CODE_DIRTY_FLAG);
- }
- }
-}
-
-/* XXX: optimize */
-void stb_phys(target_phys_addr_t addr, uint32_t val)
-{
- uint8_t v = val;
- cpu_physical_memory_write(addr, &v, 1);
-}
-
-/* XXX: optimize */
-void stw_phys(target_phys_addr_t addr, uint32_t val)
-{
- uint16_t v = tswap16(val);
- cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
-}
-
-/* XXX: optimize */
-void stq_phys(target_phys_addr_t addr, uint64_t val)
-{
- val = tswap64(val);
- cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
-}
-
-#endif
-
-/* virtual memory access for debug */
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write)
-{
- int l;
- target_phys_addr_t phys_addr;
- target_ulong page;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- phys_addr = cpu_get_phys_page_debug(env, page);
- /* if no physical page mapped, return an error */
- if (phys_addr == -1)
- return -1;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
- buf, l, is_write);
- len -= l;
- buf += l;
- addr += l;
- }
- return 0;
-}
-
-/* in deterministic execution mode, instructions doing device I/Os
- must be at the end of the TB */
-void cpu_io_recompile(CPUState *env, void *retaddr)
-{
- TranslationBlock *tb;
- uint32_t n, cflags;
- target_ulong pc, cs_base;
- uint64_t flags;
-
- tb = tb_find_pc((unsigned long)retaddr);
- if (!tb) {
- cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p",
- retaddr);
- }
- n = env->icount_decr.u16.low + tb->icount;
- cpu_restore_state(tb, env, (unsigned long)retaddr, NULL);
- /* Calculate how many instructions had been executed before the fault
- occurred. */
- n = n - env->icount_decr.u16.low;
- /* Generate a new TB ending on the I/O insn. */
- n++;
- /* On MIPS and SH, delay slot instructions can only be restarted if
- they were already the first instruction in the TB. If this is not
- the first instruction in a TB then re-execute the preceding
- branch. */
-#if defined(TARGET_MIPS)
- if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
- env->active_tc.PC -= 4;
- env->icount_decr.u16.low++;
- env->hflags &= ~MIPS_HFLAG_BMASK;
- }
-#elif defined(TARGET_SH4)
- if ((env->flags & ((DELAY_SLOT | DELAY_SLOT_CONDITIONAL))) != 0
- && n > 1) {
- env->pc -= 2;
- env->icount_decr.u16.low++;
- env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
- }
-#endif
- /* This should never happen. */
- if (n > CF_COUNT_MASK)
- cpu_abort(env, "TB too big during recompile");
-
- cflags = n | CF_LAST_IO;
- pc = tb->pc;
- cs_base = tb->cs_base;
- flags = tb->flags;
- tb_phys_invalidate(tb, -1);
- /* FIXME: In theory this could raise an exception. In practice
- we have already translated the block once so it's probably ok. */
- tb_gen_code(env, pc, cs_base, flags, cflags);
- /* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
- the first in the TB) then we end up generating a whole new TB and
- repeating the fault, which is horribly inefficient.
- Better would be to execute just this insn uncached, or generate a
- second new TB. */
- cpu_resume_from_signal(env, NULL);
-}
-
-void dump_exec_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
- int i, target_code_size, max_target_code_size;
- int direct_jmp_count, direct_jmp2_count, cross_page;
- TranslationBlock *tb;
-
- target_code_size = 0;
- max_target_code_size = 0;
- cross_page = 0;
- direct_jmp_count = 0;
- direct_jmp2_count = 0;
- for(i = 0; i < nb_tbs; i++) {
- tb = &tbs[i];
- target_code_size += tb->size;
- if (tb->size > max_target_code_size)
- max_target_code_size = tb->size;
- if (tb->page_addr[1] != -1)
- cross_page++;
- if (tb->tb_next_offset[0] != 0xffff) {
- direct_jmp_count++;
- if (tb->tb_next_offset[1] != 0xffff) {
- direct_jmp2_count++;
- }
- }
- }
- /* XXX: avoid using doubles ? */
- cpu_fprintf(f, "Translation buffer state:\n");
- cpu_fprintf(f, "gen code size %ld/%ld\n",
- code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
- cpu_fprintf(f, "TB count %d/%d\n",
- nb_tbs, code_gen_max_blocks);
- cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
- nb_tbs ? target_code_size / nb_tbs : 0,
- max_target_code_size);
- cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
- nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
- target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
- cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
- cross_page,
- nb_tbs ? (cross_page * 100) / nb_tbs : 0);
- cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
- direct_jmp_count,
- nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
- direct_jmp2_count,
- nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
- cpu_fprintf(f, "\nStatistics:\n");
- cpu_fprintf(f, "TB flush count %d\n", tb_flush_count);
- cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
- cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
- tcg_dump_info(f, cpu_fprintf);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-#define MMUSUFFIX _cmmu
-#define GETPC() NULL
-#define env cpu_single_env
-#define SOFTMMU_CODE_ACCESS
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-#undef env
-
-#endif
diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
deleted file mode 100644
index 2c8f18b..0000000
--- a/fpu/softfloat-macros.h
+++ /dev/null
@@ -1,720 +0,0 @@
-
-/*============================================================================
-
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 32, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-| The result is stored in the location pointed to by `zPtr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
-{
- bits32 z;
-
- if ( count == 0 ) {
- z = a;
- }
- else if ( count < 32 ) {
- z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
- }
- else {
- z = ( a != 0 );
- }
- *zPtr = z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 64, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-| The result is stored in the location pointed to by `zPtr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
-{
- bits64 z;
-
- if ( count == 0 ) {
- z = a;
- }
- else if ( count < 64 ) {
- z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
- }
- else {
- z = ( a != 0 );
- }
- *zPtr = z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
-| _plus_ the number of bits given in `count'. The shifted result is at most
-| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
-| bits shifted off form a second 64-bit result as follows: The _last_ bit
-| shifted off is the most-significant bit of the extra result, and the other
-| 63 bits of the extra result are all zero if and only if _all_but_the_last_
-| bits shifted off were all zero. This extra result is stored in the location
-| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0' and `a1' are considered to form
-| a fixed-point value with binary point between `a0' and `a1'. This fixed-
-| point value is shifted right by the number of bits given in `count', and
-| the integer part of the result is returned at the location pointed to by
-| `z0Ptr'. The fractional part of the result may be slightly corrupted as
-| described above, and is returned at the location pointed to by `z1Ptr'.)
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift64ExtraRightJamming(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z0, z1;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z1 = a1;
- z0 = a0;
- }
- else if ( count < 64 ) {
- z1 = ( a0<<negCount ) | ( a1 != 0 );
- z0 = a0>>count;
- }
- else {
- if ( count == 64 ) {
- z1 = a0 | ( a1 != 0 );
- }
- else {
- z1 = ( ( a0 | a1 ) != 0 );
- }
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. Any bits shifted off are lost. The value
-| of `count' can be arbitrarily large; in particular, if `count' is greater
-| than 128, the result will be 0. The result is broken into two 64-bit pieces
-| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift128Right(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z0, z1;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z1 = a1;
- z0 = a0;
- }
- else if ( count < 64 ) {
- z1 = ( a0<<negCount ) | ( a1>>count );
- z0 = a0>>count;
- }
- else {
- z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. If any nonzero bits are shifted off, they
-| are ``jammed'' into the least significant bit of the result by setting the
-| least significant bit to 1. The value of `count' can be arbitrarily large;
-| in particular, if `count' is greater than 128, the result will be either
-| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
-| nonzero. The result is broken into two 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift128RightJamming(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z0, z1;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z1 = a1;
- z0 = a0;
- }
- else if ( count < 64 ) {
- z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
- z0 = a0>>count;
- }
- else {
- if ( count == 64 ) {
- z1 = a0 | ( a1 != 0 );
- }
- else if ( count < 128 ) {
- z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
- }
- else {
- z1 = ( ( a0 | a1 ) != 0 );
- }
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
-| by 64 _plus_ the number of bits given in `count'. The shifted result is
-| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
-| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
-| off form a third 64-bit result as follows: The _last_ bit shifted off is
-| the most-significant bit of the extra result, and the other 63 bits of the
-| extra result are all zero if and only if _all_but_the_last_ bits shifted off
-| were all zero. This extra result is stored in the location pointed to by
-| `z2Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0', `a1', and `a2' are considered
-| to form a fixed-point value with binary point between `a1' and `a2'. This
-| fixed-point value is shifted right by the number of bits given in `count',
-| and the integer part of the result is returned at the locations pointed to
-| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
-| corrupted as described above, and is returned at the location pointed to by
-| `z2Ptr'.)
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shift128ExtraRightJamming(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- int16 count,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 negCount = ( - count ) & 63;
-
- if ( count == 0 ) {
- z2 = a2;
- z1 = a1;
- z0 = a0;
- }
- else {
- if ( count < 64 ) {
- z2 = a1<<negCount;
- z1 = ( a0<<negCount ) | ( a1>>count );
- z0 = a0>>count;
- }
- else {
- if ( count == 64 ) {
- z2 = a1;
- z1 = a0;
- }
- else {
- a2 |= a1;
- if ( count < 128 ) {
- z2 = a0<<negCount;
- z1 = a0>>( count & 63 );
- }
- else {
- z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
- z1 = 0;
- }
- }
- z0 = 0;
- }
- z2 |= ( a2 != 0 );
- }
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
-| number of bits given in `count'. Any bits shifted off are lost. The value
-| of `count' must be less than 64. The result is broken into two 64-bit
-| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shortShift128Left(
- bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
-{
-
- *z1Ptr = a1<<count;
- *z0Ptr =
- ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
-| by the number of bits given in `count'. Any bits shifted off are lost.
-| The value of `count' must be less than 64. The result is broken into three
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
-| `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- shortShift192Left(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- int16 count,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 negCount;
-
- z2 = a2<<count;
- z1 = a1<<count;
- z0 = a0<<count;
- if ( 0 < count ) {
- negCount = ( ( - count ) & 63 );
- z1 |= a2>>negCount;
- z0 |= a1>>negCount;
- }
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
-| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
-| any carry out is lost. The result is broken into two 64-bit pieces which
-| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- add128(
- bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits64 z1;
-
- z1 = a1 + b1;
- *z1Ptr = z1;
- *z0Ptr = a0 + b0 + ( z1 < a1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
-| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
-| modulo 2^192, so any carry out is lost. The result is broken into three
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
-| `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- add192(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- bits64 b0,
- bits64 b1,
- bits64 b2,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 carry0, carry1;
-
- z2 = a2 + b2;
- carry1 = ( z2 < a2 );
- z1 = a1 + b1;
- carry0 = ( z1 < a1 );
- z0 = a0 + b0;
- z1 += carry1;
- z0 += ( z1 < carry1 );
- z0 += carry0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
-| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
-| 2^128, so any borrow out (carry out) is lost. The result is broken into two
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
-| `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- sub128(
- bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
-{
-
- *z1Ptr = a1 - b1;
- *z0Ptr = a0 - b0 - ( a1 < b1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
-| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
-| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
-| result is broken into three 64-bit pieces which are stored at the locations
-| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- sub192(
- bits64 a0,
- bits64 a1,
- bits64 a2,
- bits64 b0,
- bits64 b1,
- bits64 b2,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2;
- int8 borrow0, borrow1;
-
- z2 = a2 - b2;
- borrow1 = ( a2 < b2 );
- z1 = a1 - b1;
- borrow0 = ( a1 < b1 );
- z0 = a0 - b0;
- z0 -= ( z1 < borrow1 );
- z1 -= borrow1;
- z0 -= borrow0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
-| into two 64-bit pieces which are stored at the locations pointed to by
-| `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
-{
- bits32 aHigh, aLow, bHigh, bLow;
- bits64 z0, zMiddleA, zMiddleB, z1;
-
- aLow = a;
- aHigh = a>>32;
- bLow = b;
- bHigh = b>>32;
- z1 = ( (bits64) aLow ) * bLow;
- zMiddleA = ( (bits64) aLow ) * bHigh;
- zMiddleB = ( (bits64) aHigh ) * bLow;
- z0 = ( (bits64) aHigh ) * bHigh;
- zMiddleA += zMiddleB;
- z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
- zMiddleA <<= 32;
- z1 += zMiddleA;
- z0 += ( z1 < zMiddleA );
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
-| `b' to obtain a 192-bit product. The product is broken into three 64-bit
-| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
-| `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- mul128By64To192(
- bits64 a0,
- bits64 a1,
- bits64 b,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr
- )
-{
- bits64 z0, z1, z2, more1;
-
- mul64To128( a1, b, &z1, &z2 );
- mul64To128( a0, b, &z0, &more1 );
- add128( z0, more1, 0, z1, &z0, &z1 );
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
-| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
-| product. The product is broken into four 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
-*----------------------------------------------------------------------------*/
-
-INLINE void
- mul128To256(
- bits64 a0,
- bits64 a1,
- bits64 b0,
- bits64 b1,
- bits64 *z0Ptr,
- bits64 *z1Ptr,
- bits64 *z2Ptr,
- bits64 *z3Ptr
- )
-{
- bits64 z0, z1, z2, z3;
- bits64 more1, more2;
-
- mul64To128( a1, b1, &z2, &z3 );
- mul64To128( a1, b0, &z1, &more2 );
- add128( z1, more2, 0, z2, &z1, &z2 );
- mul64To128( a0, b0, &z0, &more1 );
- add128( z0, more1, 0, z1, &z0, &z1 );
- mul64To128( a0, b1, &more1, &more2 );
- add128( more1, more2, 0, z2, &more1, &z2 );
- add128( z0, z1, 0, more1, &z0, &z1 );
- *z3Ptr = z3;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the 64-bit integer quotient obtained by dividing
-| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
-| divisor `b' must be at least 2^63. If q is the exact quotient truncated
-| toward zero, the approximation returned lies between q and q + 2 inclusive.
-| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
-| unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
-{
- bits64 b0, b1;
- bits64 rem0, rem1, term0, term1;
- bits64 z;
-
- if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
- b0 = b>>32;
- z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
- mul64To128( b, z, &term0, &term1 );
- sub128( a0, a1, term0, term1, &rem0, &rem1 );
- while ( ( (sbits64) rem0 ) < 0 ) {
- z -= LIT64( 0x100000000 );
- b1 = b<<32;
- add128( rem0, rem1, b0, b1, &rem0, &rem1 );
- }
- rem0 = ( rem0<<32 ) | ( rem1>>32 );
- z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the square root of the 32-bit significand given
-| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
-| `aExp' (the least significant bit) is 1, the integer returned approximates
-| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
-| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
-| case, the approximation returned lies strictly within +/-2 of the exact
-| value.
-*----------------------------------------------------------------------------*/
-
-static bits32 estimateSqrt32( int16 aExp, bits32 a )
-{
- static const bits16 sqrtOddAdjustments[] = {
- 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
- 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
- };
- static const bits16 sqrtEvenAdjustments[] = {
- 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
- 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
- };
- int8 index;
- bits32 z;
-
- index = ( a>>27 ) & 15;
- if ( aExp & 1 ) {
- z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
- z = ( ( a / z )<<14 ) + ( z<<15 );
- a >>= 1;
- }
- else {
- z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
- z = a / z + z;
- z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
- if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
- }
- return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 32 is returned.
-*----------------------------------------------------------------------------*/
-
-static int8 countLeadingZeros32( bits32 a )
-{
- static const int8 countLeadingZerosHigh[] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- int8 shiftCount;
-
- shiftCount = 0;
- if ( a < 0x10000 ) {
- shiftCount += 16;
- a <<= 16;
- }
- if ( a < 0x1000000 ) {
- shiftCount += 8;
- a <<= 8;
- }
- shiftCount += countLeadingZerosHigh[ a>>24 ];
- return shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 64 is returned.
-*----------------------------------------------------------------------------*/
-
-static int8 countLeadingZeros64( bits64 a )
-{
- int8 shiftCount;
-
- shiftCount = 0;
- if ( a < ( (bits64) 1 )<<32 ) {
- shiftCount += 32;
- }
- else {
- a >>= 32;
- }
- shiftCount += countLeadingZeros32( a );
- return shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
-| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 == b0 ) && ( a1 == b1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
-| returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
-| not equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
-{
-
- return ( a0 != b0 ) || ( a1 != b1 );
-
-}
-
diff --git a/fpu/softfloat-native.c b/fpu/softfloat-native.c
deleted file mode 100644
index e58551f..0000000
--- a/fpu/softfloat-native.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/* Native implementation of soft float functions. Only a single status
- context is supported */
-#include "softfloat.h"
-#include <math.h>
-
-void set_float_rounding_mode(int val STATUS_PARAM)
-{
- STATUS(float_rounding_mode) = val;
-#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
- fpsetround(val);
-#elif defined(__arm__)
- /* nothing to do */
-#else
- fesetround(val);
-#endif
-}
-
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM)
-{
- STATUS(floatx80_rounding_precision) = val;
-}
-#endif
-
-#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
-#define lrint(d) ((int32_t)rint(d))
-#define llrint(d) ((int64_t)rint(d))
-#define lrintf(f) ((int32_t)rint(f))
-#define llrintf(f) ((int64_t)rint(f))
-#define sqrtf(f) ((float)sqrt(f))
-#define remainderf(fa, fb) ((float)remainder(fa, fb))
-#define rintf(f) ((float)rint(f))
-#if !defined(__sparc__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
-extern long double rintl(long double);
-extern long double scalbnl(long double, int);
-
-long long
-llrintl(long double x) {
- return ((long long) rintl(x));
-}
-
-long
-lrintl(long double x) {
- return ((long) rintl(x));
-}
-
-long double
-ldexpl(long double x, int n) {
- return (scalbnl(x, n));
-}
-#endif
-#endif
-
-#if defined(__powerpc__)
-
-/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
-double qemu_rint(double x)
-{
- double y = 4503599627370496.0;
- if (fabs(x) >= y)
- return x;
- if (x < 0)
- y = -y;
- y = (x + y) - y;
- if (y == 0.0)
- y = copysign(y, x);
- return y;
-}
-
-#define rint qemu_rint
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32(int v STATUS_PARAM)
-{
- return (float32)v;
-}
-
-float32 uint32_to_float32(unsigned int v STATUS_PARAM)
-{
- return (float32)v;
-}
-
-float64 int32_to_float64(int v STATUS_PARAM)
-{
- return (float64)v;
-}
-
-float64 uint32_to_float64(unsigned int v STATUS_PARAM)
-{
- return (float64)v;
-}
-
-#ifdef FLOATX80
-floatx80 int32_to_floatx80(int v STATUS_PARAM)
-{
- return (floatx80)v;
-}
-#endif
-float32 int64_to_float32( int64_t v STATUS_PARAM)
-{
- return (float32)v;
-}
-float32 uint64_to_float32( uint64_t v STATUS_PARAM)
-{
- return (float32)v;
-}
-float64 int64_to_float64( int64_t v STATUS_PARAM)
-{
- return (float64)v;
-}
-float64 uint64_to_float64( uint64_t v STATUS_PARAM)
-{
- return (float64)v;
-}
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
-{
- return (floatx80)v;
-}
-#endif
-
-/* XXX: this code implements the x86 behaviour, not the IEEE one. */
-#if HOST_LONG_BITS == 32
-static inline int long_to_int32(long a)
-{
- return a;
-}
-#else
-static inline int long_to_int32(long a)
-{
- if (a != (int32_t)a)
- a = 0x80000000;
- return a;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 a STATUS_PARAM)
-{
- return long_to_int32(lrintf(a));
-}
-int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
-{
- return (int)a;
-}
-int64_t float32_to_int64( float32 a STATUS_PARAM)
-{
- return llrintf(a);
-}
-
-int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
-{
- return (int64_t)a;
-}
-
-float64 float32_to_float64( float32 a STATUS_PARAM)
-{
- return a;
-}
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
-{
- return a;
-}
-#endif
-
-unsigned int float32_to_uint32( float32 a STATUS_PARAM)
-{
- int64_t v;
- unsigned int res;
-
- v = llrintf(a);
- if (v < 0) {
- res = 0;
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- } else {
- res = v;
- }
- return res;
-}
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM)
-{
- int64_t v;
- unsigned int res;
-
- v = (int64_t)a;
- if (v < 0) {
- res = 0;
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- } else {
- res = v;
- }
- return res;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 a STATUS_PARAM)
-{
- return rintf(a);
-}
-
-float32 float32_rem( float32 a, float32 b STATUS_PARAM)
-{
- return remainderf(a, b);
-}
-
-float32 float32_sqrt( float32 a STATUS_PARAM)
-{
- return sqrtf(a);
-}
-int float32_compare( float32 a, float32 b STATUS_PARAM )
-{
- if (a < b) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (a > b) {
- return 1;
- } else {
- return 2;
- }
-}
-int float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
-{
- if (isless(a, b)) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (isgreater(a, b)) {
- return 1;
- } else {
- return 2;
- }
-}
-int float32_is_signaling_nan( float32 a1)
-{
- float32u u;
- uint32_t a;
- u.f = a1;
- a = u.i;
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 a STATUS_PARAM)
-{
- return long_to_int32(lrint(a));
-}
-int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
-{
- return (int)a;
-}
-int64_t float64_to_int64( float64 a STATUS_PARAM)
-{
- return llrint(a);
-}
-int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
-{
- return (int64_t)a;
-}
-float32 float64_to_float32( float64 a STATUS_PARAM)
-{
- return a;
-}
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
-{
- return a;
-}
-#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 a STATUS_PARAM)
-{
- return a;
-}
-#endif
-
-unsigned int float64_to_uint32( float64 a STATUS_PARAM)
-{
- int64_t v;
- unsigned int res;
-
- v = llrint(a);
- if (v < 0) {
- res = 0;
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- } else {
- res = v;
- }
- return res;
-}
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM)
-{
- int64_t v;
- unsigned int res;
-
- v = (int64_t)a;
- if (v < 0) {
- res = 0;
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- } else {
- res = v;
- }
- return res;
-}
-uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
-{
- int64_t v;
-
- v = llrint(a + (float64)INT64_MIN);
-
- return v - INT64_MIN;
-}
-uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
-{
- int64_t v;
-
- v = (int64_t)(a + (float64)INT64_MIN);
-
- return v - INT64_MIN;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-#if defined(__sun__) && defined(HOST_SOLARIS) && HOST_SOLARIS < 10
-static inline float64 trunc(float64 x)
-{
- return x < 0 ? -floor(-x) : floor(x);
-}
-#endif
-float64 float64_trunc_to_int( float64 a STATUS_PARAM )
-{
- return trunc(a);
-}
-
-float64 float64_round_to_int( float64 a STATUS_PARAM )
-{
-#if defined(__arm__)
- switch(STATUS(float_rounding_mode)) {
- default:
- case float_round_nearest_even:
- asm("rndd %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_down:
- asm("rnddm %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_up:
- asm("rnddp %0, %1" : "=f" (a) : "f"(a));
- break;
- case float_round_to_zero:
- asm("rnddz %0, %1" : "=f" (a) : "f"(a));
- break;
- }
-#else
- return rint(a);
-#endif
-}
-
-float64 float64_rem( float64 a, float64 b STATUS_PARAM)
-{
- return remainder(a, b);
-}
-
-float64 float64_sqrt( float64 a STATUS_PARAM)
-{
- return sqrt(a);
-}
-int float64_compare( float64 a, float64 b STATUS_PARAM )
-{
- if (a < b) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (a > b) {
- return 1;
- } else {
- return 2;
- }
-}
-int float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
-{
- if (isless(a, b)) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (isgreater(a, b)) {
- return 1;
- } else {
- return 2;
- }
-}
-int float64_is_signaling_nan( float64 a1)
-{
- float64u u;
- uint64_t a;
- u.f = a1;
- a = u.i;
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-
-}
-
-int float64_is_nan( float64 a1 )
-{
- float64u u;
- uint64_t a;
- u.f = a1;
- a = u.i;
-
- return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 a STATUS_PARAM)
-{
- return long_to_int32(lrintl(a));
-}
-int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
-{
- return (int)a;
-}
-int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
-{
- return llrintl(a);
-}
-int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
-{
- return (int64_t)a;
-}
-float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
-{
- return a;
-}
-float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
-{
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
-{
- return rintl(a);
-}
-floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return remainderl(a, b);
-}
-floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
-{
- return sqrtl(a);
-}
-int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
-{
- if (a < b) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (a > b) {
- return 1;
- } else {
- return 2;
- }
-}
-int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
- if (isless(a, b)) {
- return -1;
- } else if (a == b) {
- return 0;
- } else if (isgreater(a, b)) {
- return 1;
- } else {
- return 2;
- }
-}
-int floatx80_is_signaling_nan( floatx80 a1)
-{
- floatx80u u;
- u.f = a1;
- return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
-}
-
-#endif
diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h
deleted file mode 100644
index 379d49d..0000000
--- a/fpu/softfloat-native.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* Native implementation of soft float functions */
-#include <math.h>
-
-#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
-#include <ieeefp.h>
-#define fabsf(f) ((float)fabs(f))
-#else
-#include <fenv.h>
-#endif
-
-#ifdef __OpenBSD__
-/* Get OpenBSD version number */
-#include <sys/param.h>
-#endif
-
-/*
- * Define some C99-7.12.3 classification macros and
- * some C99-.12.4 for Solaris systems OS less than 10,
- * or Solaris 10 systems running GCC 3.x or less.
- * Solaris 10 with GCC4 does not need these macros as they
- * are defined in <iso/math_c99.h> with a compiler directive
- */
-#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) \
- && (__GNUC__ <= 4))) \
- || (defined(__OpenBSD__) && (OpenBSD < 200811))
-/*
- * C99 7.12.3 classification macros
- * and
- * C99 7.12.14 comparison macros
- *
- * ... do not work on Solaris 10 using GNU CC 3.4.x.
- * Try to workaround the missing / broken C99 math macros.
- */
-#if defined(__OpenBSD__)
-#define unordered(x, y) (isnan(x) || isnan(y))
-#endif
-
-#define isnormal(x) (fpclass(x) >= FP_NZERO)
-#define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y)))
-#define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y)))
-#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
-#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
-#define isunordered(x,y) unordered(x, y)
-#endif
-
-#if defined(__sun__) && !defined(NEED_LIBSUNMATH)
-
-#ifndef isnan
-# define isnan(x) \
- (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
- : sizeof (x) == sizeof (double) ? isnan_d (x) \
- : isnan_f (x))
-static inline int isnan_f (float x) { return x != x; }
-static inline int isnan_d (double x) { return x != x; }
-static inline int isnan_ld (long double x) { return x != x; }
-#endif
-
-#ifndef isinf
-# define isinf(x) \
- (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
- : sizeof (x) == sizeof (double) ? isinf_d (x) \
- : isinf_f (x))
-static inline int isinf_f (float x) { return isnan (x - x); }
-static inline int isinf_d (double x) { return isnan (x - x); }
-static inline int isinf_ld (long double x) { return isnan (x - x); }
-#endif
-#endif
-
-typedef float float32;
-typedef double float64;
-#ifdef FLOATX80
-typedef long double floatx80;
-#endif
-
-typedef union {
- float32 f;
- uint32_t i;
-} float32u;
-typedef union {
- float64 f;
- uint64_t i;
-} float64u;
-#ifdef FLOATX80
-typedef union {
- floatx80 f;
- struct {
- uint64_t low;
- uint16_t high;
- } i;
-} floatx80u;
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
-#if defined(__OpenBSD__)
-#define FE_RM FP_RM
-#define FE_RP FP_RP
-#define FE_RZ FP_RZ
-#endif
-enum {
- float_round_nearest_even = FP_RN,
- float_round_down = FP_RM,
- float_round_up = FP_RP,
- float_round_to_zero = FP_RZ
-};
-#elif defined(__arm__)
-enum {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-#else
-enum {
- float_round_nearest_even = FE_TONEAREST,
- float_round_down = FE_DOWNWARD,
- float_round_up = FE_UPWARD,
- float_round_to_zero = FE_TOWARDZERO
-};
-#endif
-
-typedef struct float_status {
- signed char float_rounding_mode;
-#ifdef FLOATX80
- signed char floatx80_rounding_precision;
-#endif
-} float_status;
-
-void set_float_rounding_mode(int val STATUS_PARAM);
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32( int STATUS_PARAM);
-float32 uint32_to_float32( unsigned int STATUS_PARAM);
-float64 int32_to_float64( int STATUS_PARAM);
-float64 uint32_to_float64( unsigned int STATUS_PARAM);
-#ifdef FLOATX80
-floatx80 int32_to_floatx80( int STATUS_PARAM);
-#endif
-#ifdef FLOAT128
-float128 int32_to_float128( int STATUS_PARAM);
-#endif
-float32 int64_to_float32( int64_t STATUS_PARAM);
-float32 uint64_to_float32( uint64_t STATUS_PARAM);
-float64 int64_to_float64( int64_t STATUS_PARAM);
-float64 uint64_to_float64( uint64_t v STATUS_PARAM);
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
-#endif
-#ifdef FLOAT128
-float128 int64_to_float128( int64_t STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 STATUS_PARAM);
-int float32_to_int32_round_to_zero( float32 STATUS_PARAM);
-unsigned int float32_to_uint32( float32 a STATUS_PARAM);
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM);
-int64_t float32_to_int64( float32 STATUS_PARAM);
-int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM);
-float64 float32_to_float64( float32 STATUS_PARAM);
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 STATUS_PARAM);
-#endif
-#ifdef FLOAT128
-float128 float32_to_float128( float32 STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 STATUS_PARAM);
-INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
-{
- return a + b;
-}
-INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
-{
- return a - b;
-}
-INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
-{
- return a * b;
-}
-INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
-{
- return a / b;
-}
-float32 float32_rem( float32, float32 STATUS_PARAM);
-float32 float32_sqrt( float32 STATUS_PARAM);
-INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
-{
- return a == b;
-}
-INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
-{
- return a <= b;
-}
-INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
-{
- return a < b;
-}
-INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
-{
- return a <= b && a >= b;
-}
-INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
-{
- return islessequal(a, b);
-}
-INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
-{
- return isless(a, b);
-}
-INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
-{
- return isunordered(a, b);
-
-}
-int float32_compare( float32, float32 STATUS_PARAM );
-int float32_compare_quiet( float32, float32 STATUS_PARAM );
-int float32_is_signaling_nan( float32 );
-
-INLINE float32 float32_abs(float32 a)
-{
- return fabsf(a);
-}
-
-INLINE float32 float32_chs(float32 a)
-{
- return -a;
-}
-
-INLINE float32 float32_scalbn(float32 a, int n)
-{
- return scalbnf(a, n);
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 STATUS_PARAM );
-int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
-unsigned int float64_to_uint32( float64 STATUS_PARAM );
-unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
-int64_t float64_to_int64( float64 STATUS_PARAM );
-int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
-uint64_t float64_to_uint64( float64 STATUS_PARAM );
-uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM );
-float32 float64_to_float32( float64 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int( float64 STATUS_PARAM );
-float64 float64_trunc_to_int( float64 STATUS_PARAM );
-INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
-{
- return a + b;
-}
-INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
-{
- return a - b;
-}
-INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
-{
- return a * b;
-}
-INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
-{
- return a / b;
-}
-float64 float64_rem( float64, float64 STATUS_PARAM );
-float64 float64_sqrt( float64 STATUS_PARAM );
-INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
-{
- return a == b;
-}
-INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
-{
- return a <= b;
-}
-INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
-{
- return a < b;
-}
-INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
-{
- return a <= b && a >= b;
-}
-INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
-{
- return islessequal(a, b);
-}
-INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
-{
- return isless(a, b);
-
-}
-INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
-{
- return isunordered(a, b);
-
-}
-int float64_compare( float64, float64 STATUS_PARAM );
-int float64_compare_quiet( float64, float64 STATUS_PARAM );
-int float64_is_signaling_nan( float64 );
-int float64_is_nan( float64 );
-
-INLINE float64 float64_abs(float64 a)
-{
- return fabs(a);
-}
-
-INLINE float64 float64_chs(float64 a)
-{
- return -a;
-}
-
-INLINE float64 float64_scalbn(float64 a, int n)
-{
- return scalbn(a, n);
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 STATUS_PARAM );
-int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
-int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
-int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
-float32 floatx80_to_float32( floatx80 STATUS_PARAM );
-float64 floatx80_to_float64( floatx80 STATUS_PARAM );
-#ifdef FLOAT128
-float128 floatx80_to_float128( floatx80 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
-INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a + b;
-}
-INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a - b;
-}
-INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a * b;
-}
-INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a / b;
-}
-floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a == b;
-}
-INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a <= b;
-}
-INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a < b;
-}
-INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return a <= b && a >= b;
-}
-INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return islessequal(a, b);
-}
-INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return isless(a, b);
-
-}
-INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
-{
- return isunordered(a, b);
-
-}
-int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
-int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_is_signaling_nan( floatx80 );
-
-INLINE floatx80 floatx80_abs(floatx80 a)
-{
- return fabsl(a);
-}
-
-INLINE floatx80 floatx80_chs(floatx80 a)
-{
- return -a;
-}
-
-INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
-{
- return scalbnl(a, n);
-}
-
-#endif
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
deleted file mode 100644
index 93fe06e..0000000
--- a/fpu/softfloat-specialize.h
+++ /dev/null
@@ -1,569 +0,0 @@
-
-/*============================================================================
-
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
-#define SNAN_BIT_IS_ONE 1
-#else
-#define SNAN_BIT_IS_ONE 0
-#endif
-
-/*----------------------------------------------------------------------------
-| Underflow tininess-detection mode, statically initialized to default value.
-| (The declaration in `softfloat.h' must match the `int8' type here.)
-*----------------------------------------------------------------------------*/
-int8 float_detect_tininess = float_tininess_after_rounding;
-
-/*----------------------------------------------------------------------------
-| Raises the exceptions specified by `flags'. Floating-point traps can be
-| defined here if desired. It is currently not possible for such a trap
-| to substitute a result value. If traps are not implemented, this routine
-| should be simply `float_exception_flags |= flags;'.
-*----------------------------------------------------------------------------*/
-
-void float_raise( int8 flags STATUS_PARAM )
-{
- STATUS(float_exception_flags) |= flags;
-}
-
-/*----------------------------------------------------------------------------
-| Internal canonical NaN format.
-*----------------------------------------------------------------------------*/
-typedef struct {
- flag sign;
- bits64 high, low;
-} commonNaNT;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-#if defined(TARGET_SPARC)
-#define float32_default_nan make_float32(0x7FFFFFFF)
-#elif defined(TARGET_POWERPC)
-#define float32_default_nan make_float32(0x7FC00000)
-#elif defined(TARGET_HPPA)
-#define float32_default_nan make_float32(0x7FA00000)
-#elif SNAN_BIT_IS_ONE
-#define float32_default_nan make_float32(0x7FBFFFFF)
-#else
-#define float32_default_nan make_float32(0xFFC00000)
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a quiet
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float32_is_nan( float32 a_ )
-{
- uint32_t a = float32_val(a_);
-#if SNAN_BIT_IS_ONE
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-#else
- return ( 0xFF800000 <= (bits32) ( a<<1 ) );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float32_is_signaling_nan( float32 a_ )
-{
- uint32_t a = float32_val(a_);
-#if SNAN_BIT_IS_ONE
- return ( 0xFF800000 <= (bits32) ( a<<1 ) );
-#else
- return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
-{
- commonNaNT z;
-
- if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
- z.sign = float32_val(a)>>31;
- z.low = 0;
- z.high = ( (bits64) float32_val(a) )<<41;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the single-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float32 commonNaNToFloat32( commonNaNT a )
-{
- bits32 mantissa = a.high>>41;
- if ( mantissa )
- return make_float32(
- ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
- else
- return float32_default_nan;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two single-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
- bits32 av, bv, res;
-
- aIsNaN = float32_is_nan( a );
- aIsSignalingNaN = float32_is_signaling_nan( a );
- bIsNaN = float32_is_nan( b );
- bIsSignalingNaN = float32_is_signaling_nan( b );
- av = float32_val(a);
- bv = float32_val(b);
-#if SNAN_BIT_IS_ONE
- av &= ~0x00400000;
- bv &= ~0x00400000;
-#else
- av |= 0x00400000;
- bv |= 0x00400000;
-#endif
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- res = bIsNaN ? bv : av;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN )
- res = av;
- else {
- returnLargerSignificand:
- if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
- res = bv;
- else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
- res = av;
- else
- res = ( av < bv ) ? av : bv;
- }
- }
- else {
- res = bv;
- }
- return make_float32(res);
-}
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-#if defined(TARGET_SPARC)
-#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
-#elif defined(TARGET_POWERPC)
-#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
-#elif defined(TARGET_HPPA)
-#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
-#elif SNAN_BIT_IS_ONE
-#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
-#else
-#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a quiet
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float64_is_nan( float64 a_ )
-{
- bits64 a = float64_val(a_);
-#if SNAN_BIT_IS_ONE
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-#else
- return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float64_is_signaling_nan( float64 a_ )
-{
- bits64 a = float64_val(a_);
-#if SNAN_BIT_IS_ONE
- return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
-#else
- return
- ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
- && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
-{
- commonNaNT z;
-
- if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = float64_val(a)>>63;
- z.low = 0;
- z.high = float64_val(a)<<12;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the double-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float64 commonNaNToFloat64( commonNaNT a )
-{
- bits64 mantissa = a.high>>12;
-
- if ( mantissa )
- return make_float64(
- ( ( (bits64) a.sign )<<63 )
- | LIT64( 0x7FF0000000000000 )
- | ( a.high>>12 ));
- else
- return float64_default_nan;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two double-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
- bits64 av, bv, res;
-
- aIsNaN = float64_is_nan( a );
- aIsSignalingNaN = float64_is_signaling_nan( a );
- bIsNaN = float64_is_nan( b );
- bIsSignalingNaN = float64_is_signaling_nan( b );
- av = float64_val(a);
- bv = float64_val(b);
-#if SNAN_BIT_IS_ONE
- av &= ~LIT64( 0x0008000000000000 );
- bv &= ~LIT64( 0x0008000000000000 );
-#else
- av |= LIT64( 0x0008000000000000 );
- bv |= LIT64( 0x0008000000000000 );
-#endif
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- res = bIsNaN ? bv : av;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN )
- res = av;
- else {
- returnLargerSignificand:
- if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
- res = bv;
- else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
- res = av;
- else
- res = ( av < bv ) ? av : bv;
- }
- }
- else {
- res = bv;
- }
- return make_float64(res);
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN. The
-| `high' and `low' values hold the most- and least-significant bits,
-| respectively.
-*----------------------------------------------------------------------------*/
-#if SNAN_BIT_IS_ONE
-#define floatx80_default_nan_high 0x7FFF
-#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
-#else
-#define floatx80_default_nan_high 0xFFFF
-#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| quiet NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int floatx80_is_nan( floatx80 a )
-{
-#if SNAN_BIT_IS_ONE
- bits64 aLow;
-
- aLow = a.low & ~ LIT64( 0x4000000000000000 );
- return
- ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (bits64) ( aLow<<1 )
- && ( a.low == aLow );
-#else
- return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int floatx80_is_signaling_nan( floatx80 a )
-{
-#if SNAN_BIT_IS_ONE
- return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
-#else
- bits64 aLow;
-
- aLow = a.low & ~ LIT64( 0x4000000000000000 );
- return
- ( ( a.high & 0x7FFF ) == 0x7FFF )
- && (bits64) ( aLow<<1 )
- && ( a.low == aLow );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
-| invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
-{
- commonNaNT z;
-
- if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a.high>>15;
- z.low = 0;
- z.high = a.low;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the extended
-| double-precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static floatx80 commonNaNToFloatx80( commonNaNT a )
-{
- floatx80 z;
-
- if (a.high)
- z.low = a.high;
- else
- z.low = floatx80_default_nan_low;
- z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = floatx80_is_nan( a );
- aIsSignalingNaN = floatx80_is_signaling_nan( a );
- bIsNaN = floatx80_is_nan( b );
- bIsSignalingNaN = floatx80_is_signaling_nan( b );
-#if SNAN_BIT_IS_ONE
- a.low &= ~LIT64( 0xC000000000000000 );
- b.low &= ~LIT64( 0xC000000000000000 );
-#else
- a.low |= LIT64( 0xC000000000000000 );
- b.low |= LIT64( 0xC000000000000000 );
-#endif
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
- returnLargerSignificand:
- if ( a.low < b.low ) return b;
- if ( b.low < a.low ) return a;
- return ( a.high < b.high ) ? a : b;
- }
- else {
- return b;
- }
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN. The `high' and
-| `low' values hold the most- and least-significant bits, respectively.
-*----------------------------------------------------------------------------*/
-#if SNAN_BIT_IS_ONE
-#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
-#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
-#else
-#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
-#define float128_default_nan_low LIT64( 0x0000000000000000 )
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float128_is_nan( float128 a )
-{
-#if SNAN_BIT_IS_ONE
- return
- ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
- && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
-#else
- return
- ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
- && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-int float128_is_signaling_nan( float128 a )
-{
-#if SNAN_BIT_IS_ONE
- return
- ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
- && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
-#else
- return
- ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
- && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
-#endif
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
-{
- commonNaNT z;
-
- if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
- z.sign = a.high>>63;
- shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the quadruple-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-static float128 commonNaNToFloat128( commonNaNT a )
-{
- float128 z;
-
- shift128Right( a.high, a.low, 16, &z.high, &z.low );
- z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two quadruple-precision floating-point values `a' and `b', one of
-| which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
-{
- flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = float128_is_nan( a );
- aIsSignalingNaN = float128_is_signaling_nan( a );
- bIsNaN = float128_is_nan( b );
- bIsSignalingNaN = float128_is_signaling_nan( b );
-#if SNAN_BIT_IS_ONE
- a.high &= ~LIT64( 0x0000800000000000 );
- b.high &= ~LIT64( 0x0000800000000000 );
-#else
- a.high |= LIT64( 0x0000800000000000 );
- b.high |= LIT64( 0x0000800000000000 );
-#endif
- if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
- if ( aIsSignalingNaN ) {
- if ( bIsSignalingNaN ) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if ( aIsNaN ) {
- if ( bIsSignalingNaN | ! bIsNaN ) return a;
- returnLargerSignificand:
- if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
- if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
- return ( a.high < b.high ) ? a : b;
- }
- else {
- return b;
- }
-}
-
-#endif
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
deleted file mode 100644
index 3ec1e0d..0000000
--- a/fpu/softfloat.c
+++ /dev/null
@@ -1,5541 +0,0 @@
-
-/*============================================================================
-
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-#include "softfloat.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target if
-| desired.)
-*----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-void set_float_rounding_mode(int val STATUS_PARAM)
-{
- STATUS(float_rounding_mode) = val;
-}
-
-void set_float_exception_flags(int val STATUS_PARAM)
-{
- STATUS(float_exception_flags) = val;
-}
-
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM)
-{
- STATUS(floatx80_rounding_precision) = val;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-| and 7, and returns the properly rounded 32-bit integer corresponding to the
-| input. If `zSign' is 1, the input is negated before being converted to an
-| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
-| is simply rounded to an integer, with the inexact exception raised if the
-| input cannot be represented exactly as an integer. However, if the fixed-
-| point input is too large, the invalid exception is raised and the largest
-| positive or negative integer is returned.
-*----------------------------------------------------------------------------*/
-
-static int32 roundAndPackInt32( flag zSign, bits64 absZ STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven;
- int8 roundIncrement, roundBits;
- int32 z;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- roundIncrement = 0x40;
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = 0x7F;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = absZ & 0x7F;
- absZ = ( absZ + roundIncrement )>>7;
- absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
- z = absZ;
- if ( zSign ) z = - z;
- if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit integer corresponding to the input.
-| If `zSign' is 1, the input is negated before being converted to an integer.
-| Ordinarily, the fixed-point input is simply rounded to an integer, with
-| the inexact exception raised if the input cannot be represented exactly as
-| an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the largest positive or negative integer is
-| returned.
-*----------------------------------------------------------------------------*/
-
-static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven, increment;
- int64 z;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- increment = ( (sbits64) absZ1 < 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- increment = 0;
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && absZ1;
- }
- else {
- increment = ( roundingMode == float_round_up ) && absZ1;
- }
- }
- }
- if ( increment ) {
- ++absZ0;
- if ( absZ0 == 0 ) goto overflow;
- absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven );
- }
- z = absZ0;
- if ( zSign ) z = - z;
- if ( z && ( ( z < 0 ) ^ zSign ) ) {
- overflow:
- float_raise( float_flag_invalid STATUS_VAR);
- return
- zSign ? (sbits64) LIT64( 0x8000000000000000 )
- : LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits32 extractFloat32Frac( float32 a )
-{
-
- return float32_val(a) & 0x007FFFFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int16 extractFloat32Exp( float32 a )
-{
-
- return ( float32_val(a)>>23 ) & 0xFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloat32Sign( float32 a )
-{
-
- return float32_val(a)>>31;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal single-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros32( aSig ) - 8;
- *zSigPtr = aSig<<shiftCount;
- *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
-{
-
- return make_float32(
- ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig);
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the single-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal single-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 30
-| and 29, which is 7 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven;
- int8 roundIncrement, roundBits;
- flag isTiny;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- roundIncrement = 0x40;
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = 0x7F;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = zSig & 0x7F;
- if ( 0xFD <= (bits16) zExp ) {
- if ( ( 0xFD < zExp )
- || ( ( zExp == 0xFD )
- && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
- ) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
- }
- if ( zExp < 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < -1 )
- || ( zSig + roundIncrement < 0x80000000 );
- shift32RightJamming( zSig, - zExp, &zSig );
- zExp = 0;
- roundBits = zSig & 0x7F;
- if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
- }
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig = ( zSig + roundIncrement )>>7;
- zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
- if ( zSig == 0 ) zExp = 0;
- return packFloat32( zSign, zExp, zSig );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-static float32
- normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM)
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros32( zSig ) - 1;
- return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloat64Frac( float64 a )
-{
-
- return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int16 extractFloat64Exp( float64 a )
-{
-
- return ( float64_val(a)>>52 ) & 0x7FF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloat64Sign( float64 a )
-{
-
- return float64_val(a)>>63;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal double-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros64( aSig ) - 11;
- *zSigPtr = aSig<<shiftCount;
- *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| double-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
-{
-
- return make_float64(
- ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig);
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the double-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded
-| to a subnormal number, and the underflow and inexact exceptions are raised
-| if the abstract input cannot be represented exactly as a subnormal double-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 62
-| and 61, which is 10 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven;
- int16 roundIncrement, roundBits;
- flag isTiny;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- roundIncrement = 0x200;
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = 0x3FF;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = zSig & 0x3FF;
- if ( 0x7FD <= (bits16) zExp ) {
- if ( ( 0x7FD < zExp )
- || ( ( zExp == 0x7FD )
- && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
- ) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
- }
- if ( zExp < 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < -1 )
- || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
- shift64RightJamming( zSig, - zExp, &zSig );
- zExp = 0;
- roundBits = zSig & 0x3FF;
- if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
- }
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig = ( zSig + roundIncrement )>>10;
- zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
- if ( zSig == 0 ) zExp = 0;
- return packFloat64( zSign, zExp, zSig );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-static float64
- normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM)
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros64( zSig ) - 1;
- return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloatx80Frac( floatx80 a )
-{
-
- return a.low;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int32 extractFloatx80Exp( floatx80 a )
-{
-
- return a.high & 0x7FFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the extended double-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloatx80Sign( floatx80 a )
-{
-
- return a.high>>15;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal extended double-precision floating-point value
-| represented by the denormalized significand `aSig'. The normalized exponent
-| and significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
-{
- int8 shiftCount;
-
- shiftCount = countLeadingZeros64( aSig );
- *zSigPtr = aSig<<shiftCount;
- *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
-| extended double-precision floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
-{
- floatx80 z;
-
- z.low = zSig;
- z.high = ( ( (bits16) zSign )<<15 ) + zExp;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| rounded and packed into the extended double-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal extended
-| double-precision floating-point number.
-| If `roundingPrecision' is 32 or 64, the result is rounded to the same
-| number of bits as single or double precision, respectively. Otherwise, the
-| result is rounded to the full precision of the extended double-precision
-| format.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. The
-| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80
- roundAndPackFloatx80(
- int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
- STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven, increment, isTiny;
- int64 roundIncrement, roundMask, roundBits;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- if ( roundingPrecision == 80 ) goto precision80;
- if ( roundingPrecision == 64 ) {
- roundIncrement = LIT64( 0x0000000000000400 );
- roundMask = LIT64( 0x00000000000007FF );
- }
- else if ( roundingPrecision == 32 ) {
- roundIncrement = LIT64( 0x0000008000000000 );
- roundMask = LIT64( 0x000000FFFFFFFFFF );
- }
- else {
- goto precision80;
- }
- zSig0 |= ( zSig1 != 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- roundIncrement = 0;
- }
- else {
- roundIncrement = roundMask;
- if ( zSign ) {
- if ( roundingMode == float_round_up ) roundIncrement = 0;
- }
- else {
- if ( roundingMode == float_round_down ) roundIncrement = 0;
- }
- }
- }
- roundBits = zSig0 & roundMask;
- if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
- if ( ( 0x7FFE < zExp )
- || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
- ) {
- goto overflow;
- }
- if ( zExp <= 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < 0 )
- || ( zSig0 <= zSig0 + roundIncrement );
- shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
- zExp = 0;
- roundBits = zSig0 & roundMask;
- if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig0 += roundIncrement;
- if ( (sbits64) zSig0 < 0 ) zExp = 1;
- roundIncrement = roundMask + 1;
- if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
- roundMask |= roundIncrement;
- }
- zSig0 &= ~ roundMask;
- return packFloatx80( zSign, zExp, zSig0 );
- }
- }
- if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
- zSig0 += roundIncrement;
- if ( zSig0 < roundIncrement ) {
- ++zExp;
- zSig0 = LIT64( 0x8000000000000000 );
- }
- roundIncrement = roundMask + 1;
- if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
- roundMask |= roundIncrement;
- }
- zSig0 &= ~ roundMask;
- if ( zSig0 == 0 ) zExp = 0;
- return packFloatx80( zSign, zExp, zSig0 );
- precision80:
- increment = ( (sbits64) zSig1 < 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- increment = 0;
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig1;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig1;
- }
- }
- }
- if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
- if ( ( 0x7FFE < zExp )
- || ( ( zExp == 0x7FFE )
- && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
- && increment
- )
- ) {
- roundMask = 0;
- overflow:
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- if ( ( roundingMode == float_round_to_zero )
- || ( zSign && ( roundingMode == float_round_up ) )
- || ( ! zSign && ( roundingMode == float_round_down ) )
- ) {
- return packFloatx80( zSign, 0x7FFE, ~ roundMask );
- }
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( zExp <= 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < 0 )
- || ! increment
- || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
- shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
- zExp = 0;
- if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR);
- if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- if ( roundNearestEven ) {
- increment = ( (sbits64) zSig1 < 0 );
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig1;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig1;
- }
- }
- if ( increment ) {
- ++zSig0;
- zSig0 &=
- ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
- if ( (sbits64) zSig0 < 0 ) zExp = 1;
- }
- return packFloatx80( zSign, zExp, zSig0 );
- }
- }
- if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- if ( increment ) {
- ++zSig0;
- if ( zSig0 == 0 ) {
- ++zExp;
- zSig0 = LIT64( 0x8000000000000000 );
- }
- else {
- zSig0 &= ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
- }
- }
- else {
- if ( zSig0 == 0 ) zExp = 0;
- }
- return packFloatx80( zSign, zExp, zSig0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent
-| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. This routine is just like
-| `roundAndPackFloatx80' except that the input significand does not have to be
-| normalized.
-*----------------------------------------------------------------------------*/
-
-static floatx80
- normalizeRoundAndPackFloatx80(
- int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
- STATUS_PARAM)
-{
- int8 shiftCount;
-
- if ( zSig0 == 0 ) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- shiftCount = countLeadingZeros64( zSig0 );
- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
- zExp -= shiftCount;
- return
- roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 STATUS_VAR);
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the least-significant 64 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloat128Frac1( float128 a )
-{
-
- return a.low;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the most-significant 48 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE bits64 extractFloat128Frac0( float128 a )
-{
-
- return a.high & LIT64( 0x0000FFFFFFFFFFFF );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the quadruple-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE int32 extractFloat128Exp( float128 a )
-{
-
- return ( a.high>>48 ) & 0x7FFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the quadruple-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-INLINE flag extractFloat128Sign( float128 a )
-{
-
- return a.high>>63;
-
-}
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal quadruple-precision floating-point value
-| represented by the denormalized significand formed by the concatenation of
-| `aSig0' and `aSig1'. The normalized exponent is stored at the location
-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
-| significand are stored at the location pointed to by `zSig0Ptr', and the
-| least significant 64 bits of the normalized significand are stored at the
-| location pointed to by `zSig1Ptr'.
-*----------------------------------------------------------------------------*/
-
-static void
- normalizeFloat128Subnormal(
- bits64 aSig0,
- bits64 aSig1,
- int32 *zExpPtr,
- bits64 *zSig0Ptr,
- bits64 *zSig1Ptr
- )
-{
- int8 shiftCount;
-
- if ( aSig0 == 0 ) {
- shiftCount = countLeadingZeros64( aSig1 ) - 15;
- if ( shiftCount < 0 ) {
- *zSig0Ptr = aSig1>>( - shiftCount );
- *zSig1Ptr = aSig1<<( shiftCount & 63 );
- }
- else {
- *zSig0Ptr = aSig1<<shiftCount;
- *zSig1Ptr = 0;
- }
- *zExpPtr = - shiftCount - 63;
- }
- else {
- shiftCount = countLeadingZeros64( aSig0 ) - 15;
- shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
- *zExpPtr = 1 - shiftCount;
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', the exponent `zExp', and the significand formed
-| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
-| floating-point value, returning the result. After being shifted into the
-| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
-| added together to form the most significant 32 bits of the result. This
-| means that any integer portion of `zSig0' will be added into the exponent.
-| Since a properly normalized significand will have an integer portion equal
-| to 1, the `zExp' input should be 1 less than the desired result exponent
-| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-INLINE float128
- packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
-{
- float128 z;
-
- z.low = zSig1;
- z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0', `zSig1',
-| and `zSig2', and returns the proper quadruple-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| simply rounded and packed into the quadruple-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal quadruple-
-| precision floating-point number.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. In the
-| usual case that the input significand is normalized, `zExp' must be 1 less
-| than the ``true'' floating-point exponent. The handling of underflow and
-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128
- roundAndPackFloat128(
- flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 STATUS_PARAM)
-{
- int8 roundingMode;
- flag roundNearestEven, increment, isTiny;
-
- roundingMode = STATUS(float_rounding_mode);
- roundNearestEven = ( roundingMode == float_round_nearest_even );
- increment = ( (sbits64) zSig2 < 0 );
- if ( ! roundNearestEven ) {
- if ( roundingMode == float_round_to_zero ) {
- increment = 0;
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig2;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig2;
- }
- }
- }
- if ( 0x7FFD <= (bits32) zExp ) {
- if ( ( 0x7FFD < zExp )
- || ( ( zExp == 0x7FFD )
- && eq128(
- LIT64( 0x0001FFFFFFFFFFFF ),
- LIT64( 0xFFFFFFFFFFFFFFFF ),
- zSig0,
- zSig1
- )
- && increment
- )
- ) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
- if ( ( roundingMode == float_round_to_zero )
- || ( zSign && ( roundingMode == float_round_up ) )
- || ( ! zSign && ( roundingMode == float_round_down ) )
- ) {
- return
- packFloat128(
- zSign,
- 0x7FFE,
- LIT64( 0x0000FFFFFFFFFFFF ),
- LIT64( 0xFFFFFFFFFFFFFFFF )
- );
- }
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( zExp < 0 ) {
- isTiny =
- ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
- || ( zExp < -1 )
- || ! increment
- || lt128(
- zSig0,
- zSig1,
- LIT64( 0x0001FFFFFFFFFFFF ),
- LIT64( 0xFFFFFFFFFFFFFFFF )
- );
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
- zExp = 0;
- if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
- if ( roundNearestEven ) {
- increment = ( (sbits64) zSig2 < 0 );
- }
- else {
- if ( zSign ) {
- increment = ( roundingMode == float_round_down ) && zSig2;
- }
- else {
- increment = ( roundingMode == float_round_up ) && zSig2;
- }
- }
- }
- }
- if ( zSig2 ) STATUS(float_exception_flags) |= float_flag_inexact;
- if ( increment ) {
- add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
- zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
- }
- else {
- if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
- }
- return packFloat128( zSign, zExp, zSig0, zSig1 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand formed by the concatenation of `zSig0' and `zSig1', and
-| returns the proper quadruple-precision floating-point value corresponding
-| to the abstract input. This routine is just like `roundAndPackFloat128'
-| except that the input significand has fewer bits and does not have to be
-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
-| point exponent.
-*----------------------------------------------------------------------------*/
-
-static float128
- normalizeRoundAndPackFloat128(
- flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 STATUS_PARAM)
-{
- int8 shiftCount;
- bits64 zSig2;
-
- if ( zSig0 == 0 ) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- shiftCount = countLeadingZeros64( zSig0 ) - 15;
- if ( 0 <= shiftCount ) {
- zSig2 = 0;
- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
- }
- else {
- shift128ExtraRightJamming(
- zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
- }
- zExp -= shiftCount;
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR);
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the single-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 int32_to_float32( int32 a STATUS_PARAM )
-{
- flag zSign;
-
- if ( a == 0 ) return float32_zero;
- if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
- zSign = ( a < 0 );
- return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 int32_to_float64( int32 a STATUS_PARAM )
-{
- flag zSign;
- uint32 absA;
- int8 shiftCount;
- bits64 zSig;
-
- if ( a == 0 ) return float64_zero;
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros32( absA ) + 21;
- zSig = absA;
- return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 int32_to_floatx80( int32 a STATUS_PARAM )
-{
- flag zSign;
- uint32 absA;
- int8 shiftCount;
- bits64 zSig;
-
- if ( a == 0 ) return packFloatx80( 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros32( absA ) + 32;
- zSig = absA;
- return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a' to
-| the quadruple-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 int32_to_float128( int32 a STATUS_PARAM )
-{
- flag zSign;
- uint32 absA;
- int8 shiftCount;
- bits64 zSig0;
-
- if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros32( absA ) + 17;
- zSig0 = absA;
- return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a'
-| to the single-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 int64_to_float32( int64 a STATUS_PARAM )
-{
- flag zSign;
- uint64 absA;
- int8 shiftCount;
-
- if ( a == 0 ) return float32_zero;
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros64( absA ) - 40;
- if ( 0 <= shiftCount ) {
- return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
- }
- else {
- shiftCount += 7;
- if ( shiftCount < 0 ) {
- shift64RightJamming( absA, - shiftCount, &absA );
- }
- else {
- absA <<= shiftCount;
- }
- return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
- }
-
-}
-
-float32 uint64_to_float32( uint64 a STATUS_PARAM )
-{
- int8 shiftCount;
-
- if ( a == 0 ) return float32_zero;
- shiftCount = countLeadingZeros64( a ) - 40;
- if ( 0 <= shiftCount ) {
- return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount );
- }
- else {
- shiftCount += 7;
- if ( shiftCount < 0 ) {
- shift64RightJamming( a, - shiftCount, &a );
- }
- else {
- a <<= shiftCount;
- }
- return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR );
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a'
-| to the double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 int64_to_float64( int64 a STATUS_PARAM )
-{
- flag zSign;
-
- if ( a == 0 ) return float64_zero;
- if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) {
- return packFloat64( 1, 0x43E, 0 );
- }
- zSign = ( a < 0 );
- return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
-
-}
-
-float64 uint64_to_float64( uint64 a STATUS_PARAM )
-{
- if ( a == 0 ) return float64_zero;
- return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a'
-| to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 int64_to_floatx80( int64 a STATUS_PARAM )
-{
- flag zSign;
- uint64 absA;
- int8 shiftCount;
-
- if ( a == 0 ) return packFloatx80( 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros64( absA );
- return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a' to
-| the quadruple-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 int64_to_float128( int64 a STATUS_PARAM )
-{
- flag zSign;
- uint64 absA;
- int8 shiftCount;
- int32 zExp;
- bits64 zSig0, zSig1;
-
- if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
- zSign = ( a < 0 );
- absA = zSign ? - a : a;
- shiftCount = countLeadingZeros64( absA ) + 49;
- zExp = 0x406E - shiftCount;
- if ( 64 <= shiftCount ) {
- zSig1 = 0;
- zSig0 = absA;
- shiftCount -= 64;
- }
- else {
- zSig1 = absA;
- zSig0 = 0;
- }
- shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
- return packFloat128( zSign, zExp, zSig0, zSig1 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 float32_to_int32( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- bits64 aSig64;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
- if ( aExp ) aSig |= 0x00800000;
- shiftCount = 0xAF - aExp;
- aSig64 = aSig;
- aSig64 <<= 32;
- if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
- return roundAndPackInt32( aSign, aSig64 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- int32 z;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- shiftCount = aExp - 0x9E;
- if ( 0 <= shiftCount ) {
- if ( float32_val(a) != 0xCF000000 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
- }
- return (sbits32) 0x80000000;
- }
- else if ( aExp <= 0x7E ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig = ( aSig | 0x00800000 )<<8;
- z = aSig>>( - shiftCount );
- if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 float32_to_int64( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- bits64 aSig64, aSigExtra;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- shiftCount = 0xBE - aExp;
- if ( shiftCount < 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- if ( aExp ) aSig |= 0x00800000;
- aSig64 = aSig;
- aSig64 <<= 40;
- shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
- return roundAndPackInt64( aSign, aSig64, aSigExtra STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero. If
-| `a' is a NaN, the largest positive integer is returned. Otherwise, if the
-| conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits32 aSig;
- bits64 aSig64;
- int64 z;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- shiftCount = aExp - 0xBE;
- if ( 0 <= shiftCount ) {
- if ( float32_val(a) != 0xDF000000 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- else if ( aExp <= 0x7E ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig64 = aSig | 0x00800000;
- aSig64 <<= 40;
- z = aSig64>>( - shiftCount );
- if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float32_to_float64( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ));
- return packFloat64( aSign, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- --aExp;
- }
- return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) );
- return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- aSig |= 0x00800000;
- return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float32_to_float128( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) );
- return packFloat128( aSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- --aExp;
- }
- return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the single-precision floating-point value `a' to an integer, and
-| returns the result as a single-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_round_to_int( float32 a STATUS_PARAM)
-{
- flag aSign;
- int16 aExp;
- bits32 lastBitMask, roundBitsMask;
- int8 roundingMode;
- bits32 z;
-
- aExp = extractFloat32Exp( a );
- if ( 0x96 <= aExp ) {
- if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
- return propagateFloat32NaN( a, a STATUS_VAR );
- }
- return a;
- }
- if ( aExp <= 0x7E ) {
- if ( (bits32) ( float32_val(a)<<1 ) == 0 ) return a;
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloat32Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
- return packFloat32( aSign, 0x7F, 0 );
- }
- break;
- case float_round_down:
- return make_float32(aSign ? 0xBF800000 : 0);
- case float_round_up:
- return make_float32(aSign ? 0x80000000 : 0x3F800000);
- }
- return packFloat32( aSign, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x96 - aExp;
- roundBitsMask = lastBitMask - 1;
- z = float32_val(a);
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z += lastBitMask>>1;
- if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) {
- z += roundBitsMask;
- }
- }
- z &= ~ roundBitsMask;
- if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact;
- return make_float32(z);
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the single-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
-{
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 6;
- bSig <<= 6;
- if ( 0 < expDiff ) {
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= 0x20000000;
- }
- shift32RightJamming( bSig, expDiff, &bSig );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= 0x20000000;
- }
- shift32RightJamming( aSig, - expDiff, &aSig );
- zExp = bExp;
- }
- else {
- if ( aExp == 0xFF ) {
- if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
- zSig = 0x40000000 + aSig + bSig;
- zExp = aExp;
- goto roundAndPack;
- }
- aSig |= 0x20000000;
- zSig = ( aSig + bSig )<<1;
- --zExp;
- if ( (sbits32) zSig < 0 ) {
- zSig = aSig + bSig;
- ++zExp;
- }
- roundAndPack:
- return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the single-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
-{
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 7;
- bSig <<= 7;
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0xFF ) {
- if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- if ( bSig < aSig ) goto aBigger;
- if ( aSig < bSig ) goto bBigger;
- return packFloat32( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
- bExpBigger:
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return packFloat32( zSign ^ 1, 0xFF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= 0x40000000;
- }
- shift32RightJamming( aSig, - expDiff, &aSig );
- bSig |= 0x40000000;
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= 0x40000000;
- }
- shift32RightJamming( bSig, expDiff, &bSig );
- aSig |= 0x40000000;
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the single-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_add( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign == bSign ) {
- return addFloat32Sigs( a, b, aSign STATUS_VAR);
- }
- else {
- return subFloat32Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sub( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- if ( aSign == bSign ) {
- return subFloat32Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloat32Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_mul( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig;
- bits64 zSig64;
- bits32 zSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0xFF ) {
- if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
- return propagateFloat32NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
- normalizeFloat32Subnormal( bSig, &bExp, &bSig );
- }
- zExp = aExp + bExp - 0x7F;
- aSig = ( aSig | 0x00800000 )<<7;
- bSig = ( bSig | 0x00800000 )<<8;
- shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
- zSig = zSig64;
- if ( 0 <= (sbits32) ( zSig<<1 ) ) {
- zSig <<= 1;
- --zExp;
- }
- return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the single-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_div( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits32 aSig, bSig, zSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- return packFloat32( zSign, 0xFF, 0 );
- }
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return packFloat32( zSign, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloat32( zSign, 0xFF, 0 );
- }
- normalizeFloat32Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- zExp = aExp - bExp + 0x7D;
- aSig = ( aSig | 0x00800000 )<<7;
- bSig = ( bSig | 0x00800000 )<<8;
- if ( bSig <= ( aSig + aSig ) ) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = ( ( (bits64) aSig )<<32 ) / bSig;
- if ( ( zSig & 0x3F ) == 0 ) {
- zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 );
- }
- return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the single-precision floating-point value `a'
-| with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_rem( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, expDiff;
- bits32 aSig, bSig;
- bits32 q;
- bits64 aSig64, bSig64, q64;
- bits32 alternateASig;
- sbits32 sigMean;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- bSig = extractFloat32Frac( b );
- bExp = extractFloat32Exp( b );
- bSign = extractFloat32Sign( b );
- if ( aExp == 0xFF ) {
- if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
- return propagateFloat32NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( bExp == 0xFF ) {
- if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- normalizeFloat32Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return a;
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- expDiff = aExp - bExp;
- aSig |= 0x00800000;
- bSig |= 0x00800000;
- if ( expDiff < 32 ) {
- aSig <<= 8;
- bSig <<= 8;
- if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
- aSig >>= 1;
- }
- q = ( bSig <= aSig );
- if ( q ) aSig -= bSig;
- if ( 0 < expDiff ) {
- q = ( ( (bits64) aSig )<<32 ) / bSig;
- q >>= 32 - expDiff;
- bSig >>= 2;
- aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
- }
- else {
- aSig >>= 2;
- bSig >>= 2;
- }
- }
- else {
- if ( bSig <= aSig ) aSig -= bSig;
- aSig64 = ( (bits64) aSig )<<40;
- bSig64 = ( (bits64) bSig )<<40;
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q64 = estimateDiv128To64( aSig64, 0, bSig64 );
- q64 = ( 2 < q64 ) ? q64 - 2 : 0;
- aSig64 = - ( ( bSig * q64 )<<38 );
- expDiff -= 62;
- }
- expDiff += 64;
- q64 = estimateDiv128To64( aSig64, 0, bSig64 );
- q64 = ( 2 < q64 ) ? q64 - 2 : 0;
- q = q64>>( 64 - expDiff );
- bSig <<= 6;
- aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
- }
- do {
- alternateASig = aSig;
- ++q;
- aSig -= bSig;
- } while ( 0 <= (sbits32) aSig );
- sigMean = aSig + alternateASig;
- if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
- aSig = alternateASig;
- }
- zSign = ( (sbits32) aSig < 0 );
- if ( zSign ) aSig = - aSig;
- return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the single-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sqrt( float32 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, zExp;
- bits32 aSig, zSig;
- bits64 rem, term;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
- if ( aExp == 0xFF ) {
- if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
- if ( ! aSign ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( aSign ) {
- if ( ( aExp | aSig ) == 0 ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float32_default_nan;
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return float32_zero;
- normalizeFloat32Subnormal( aSig, &aExp, &aSig );
- }
- zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
- aSig = ( aSig | 0x00800000 )<<8;
- zSig = estimateSqrt32( aExp, aSig ) + 2;
- if ( ( zSig & 0x7F ) <= 5 ) {
- if ( zSig < 2 ) {
- zSig = 0x7FFFFFFF;
- goto roundAndPack;
- }
- aSig >>= aExp & 1;
- term = ( (bits64) zSig ) * zSig;
- rem = ( ( (bits64) aSig )<<32 ) - term;
- while ( (sbits64) rem < 0 ) {
- --zSig;
- rem += ( ( (bits64) zSig )<<1 ) | 1;
- }
- zSig |= ( rem != 0 );
- }
- shift32RightJamming( zSig, 1, &zSig );
- roundAndPack:
- return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_eq( float32 a, float32 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return ( float32_val(a) == float32_val(b) ) ||
- ( (bits32) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_le( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits32 av, bv;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- av = float32_val(a);
- bv = float32_val(b);
- if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
- return ( av == bv ) || ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_lt( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits32 av, bv;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- av = float32_val(a);
- bv = float32_val(b);
- if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
- return ( av != bv ) && ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
-{
- bits32 av, bv;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- av = float32_val(a);
- bv = float32_val(b);
- return ( av == bv ) || ( (bits32) ( ( av | bv )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
-| cause an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits32 av, bv;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- av = float32_val(a);
- bv = float32_val(b);
- if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
- return ( av == bv ) || ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
-| exception. Otherwise, the comparison is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits32 av, bv;
-
- if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
- || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
- ) {
- if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat32Sign( a );
- bSign = extractFloat32Sign( b );
- av = float32_val(a);
- bv = float32_val(b);
- if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
- return ( av != bv ) && ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 float64_to_int32( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
- if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
- shiftCount = 0x42C - aExp;
- if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
- return roundAndPackInt32( aSign, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig, savedASig;
- int32 z;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( 0x41E < aExp ) {
- if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
- goto invalid;
- }
- else if ( aExp < 0x3FF ) {
- if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig |= LIT64( 0x0010000000000000 );
- shiftCount = 0x433 - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = aSig;
- if ( aSign ) z = - z;
- if ( ( z < 0 ) ^ aSign ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( ( aSig<<shiftCount ) != savedASig ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 float64_to_int64( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig, aSigExtra;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
- shiftCount = 0x433 - aExp;
- if ( shiftCount <= 0 ) {
- if ( 0x43E < aExp ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FF )
- && ( aSig != LIT64( 0x0010000000000000 ) ) )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- aSigExtra = 0;
- aSig <<= - shiftCount;
- }
- else {
- shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
- }
- return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, shiftCount;
- bits64 aSig;
- int64 z;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
- shiftCount = aExp - 0x433;
- if ( 0 <= shiftCount ) {
- if ( 0x43E <= aExp ) {
- if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FF )
- && ( aSig != LIT64( 0x0010000000000000 ) ) )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- z = aSig<<shiftCount;
- }
- else {
- if ( aExp < 0x3FE ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- z = aSig>>( - shiftCount );
- if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the single-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float64_to_float32( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig;
- bits32 zSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) );
- return packFloat32( aSign, 0xFF, 0 );
- }
- shift64RightJamming( aSig, 22, &aSig );
- zSig = aSig;
- if ( aExp || zSig ) {
- zSig |= 0x40000000;
- aExp -= 0x381;
- }
- return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) );
- return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- return
- packFloatx80(
- aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the quadruple-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float64_to_float128( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig, zSig0, zSig1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) );
- return packFloat128( aSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- --aExp;
- }
- shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
- return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the double-precision floating-point value `a' to an integer, and
-| returns the result as a double-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_round_to_int( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 lastBitMask, roundBitsMask;
- int8 roundingMode;
- bits64 z;
-
- aExp = extractFloat64Exp( a );
- if ( 0x433 <= aExp ) {
- if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
- return propagateFloat64NaN( a, a STATUS_VAR );
- }
- return a;
- }
- if ( aExp < 0x3FF ) {
- if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a;
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloat64Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
- return packFloat64( aSign, 0x3FF, 0 );
- }
- break;
- case float_round_down:
- return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
- case float_round_up:
- return make_float64(
- aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ));
- }
- return packFloat64( aSign, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x433 - aExp;
- roundBitsMask = lastBitMask - 1;
- z = float64_val(a);
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z += lastBitMask>>1;
- if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
- z += roundBitsMask;
- }
- }
- z &= ~ roundBitsMask;
- if ( z != float64_val(a) )
- STATUS(float_exception_flags) |= float_flag_inexact;
- return make_float64(z);
-
-}
-
-float64 float64_trunc_to_int( float64 a STATUS_PARAM)
-{
- int oldmode;
- float64 res;
- oldmode = STATUS(float_rounding_mode);
- STATUS(float_rounding_mode) = float_round_to_zero;
- res = float64_round_to_int(a STATUS_VAR);
- STATUS(float_rounding_mode) = oldmode;
- return res;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the double-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
-{
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 9;
- bSig <<= 9;
- if ( 0 < expDiff ) {
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= LIT64( 0x2000000000000000 );
- }
- shift64RightJamming( bSig, expDiff, &bSig );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= LIT64( 0x2000000000000000 );
- }
- shift64RightJamming( aSig, - expDiff, &aSig );
- zExp = bExp;
- }
- else {
- if ( aExp == 0x7FF ) {
- if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
- zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
- zExp = aExp;
- goto roundAndPack;
- }
- aSig |= LIT64( 0x2000000000000000 );
- zSig = ( aSig + bSig )<<1;
- --zExp;
- if ( (sbits64) zSig < 0 ) {
- zSig = aSig + bSig;
- ++zExp;
- }
- roundAndPack:
- return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
-{
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig;
- int16 expDiff;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- expDiff = aExp - bExp;
- aSig <<= 10;
- bSig <<= 10;
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0x7FF ) {
- if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- if ( bSig < aSig ) goto aBigger;
- if ( aSig < bSig ) goto bBigger;
- return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
- bExpBigger:
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return packFloat64( zSign ^ 1, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig |= LIT64( 0x4000000000000000 );
- }
- shift64RightJamming( aSig, - expDiff, &aSig );
- bSig |= LIT64( 0x4000000000000000 );
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig |= LIT64( 0x4000000000000000 );
- }
- shift64RightJamming( bSig, expDiff, &bSig );
- aSig |= LIT64( 0x4000000000000000 );
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the double-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_add( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign == bSign ) {
- return addFloat64Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return subFloat64Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sub( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- if ( aSign == bSign ) {
- return subFloat64Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloat64Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_mul( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FF ) {
- if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
- return propagateFloat64NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
- normalizeFloat64Subnormal( bSig, &bExp, &bSig );
- }
- zExp = aExp + bExp - 0x3FF;
- aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
- bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
- mul64To128( aSig, bSig, &zSig0, &zSig1 );
- zSig0 |= ( zSig1 != 0 );
- if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
- zSig0 <<= 1;
- --zExp;
- }
- return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the double-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_div( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig;
- bits64 rem0, rem1;
- bits64 term0, term1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- return packFloat64( zSign, 0x7FF, 0 );
- }
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return packFloat64( zSign, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- if ( ( aExp | aSig ) == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloat64( zSign, 0x7FF, 0 );
- }
- normalizeFloat64Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- zExp = aExp - bExp + 0x3FD;
- aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
- bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
- if ( bSig <= ( aSig + aSig ) ) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = estimateDiv128To64( aSig, 0, bSig );
- if ( ( zSig & 0x1FF ) <= 2 ) {
- mul64To128( bSig, zSig, &term0, &term1 );
- sub128( aSig, 0, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig;
- add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
- }
- zSig |= ( rem1 != 0 );
- }
- return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the double-precision floating-point value `a'
-| with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_rem( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int16 aExp, bExp, expDiff;
- bits64 aSig, bSig;
- bits64 q, alternateASig;
- sbits64 sigMean;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- bSig = extractFloat64Frac( b );
- bExp = extractFloat64Exp( b );
- bSign = extractFloat64Sign( b );
- if ( aExp == 0x7FF ) {
- if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
- return propagateFloat64NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( bExp == 0x7FF ) {
- if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- normalizeFloat64Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return a;
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- expDiff = aExp - bExp;
- aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
- bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
- if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
- aSig >>= 1;
- }
- q = ( bSig <= aSig );
- if ( q ) aSig -= bSig;
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig, 0, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- aSig = - ( ( bSig>>2 ) * q );
- expDiff -= 62;
- }
- expDiff += 64;
- if ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig, 0, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- q >>= 64 - expDiff;
- bSig >>= 2;
- aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
- }
- else {
- aSig >>= 2;
- bSig >>= 2;
- }
- do {
- alternateASig = aSig;
- ++q;
- aSig -= bSig;
- } while ( 0 <= (sbits64) aSig );
- sigMean = aSig + alternateASig;
- if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
- aSig = alternateASig;
- }
- zSign = ( (sbits64) aSig < 0 );
- if ( zSign ) aSig = - aSig;
- return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the double-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sqrt( float64 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp, zExp;
- bits64 aSig, zSig, doubleZSig;
- bits64 rem0, rem1, term0, term1;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
- if ( aExp == 0x7FF ) {
- if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
- if ( ! aSign ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( aSign ) {
- if ( ( aExp | aSig ) == 0 ) return a;
- float_raise( float_flag_invalid STATUS_VAR);
- return float64_default_nan;
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return float64_zero;
- normalizeFloat64Subnormal( aSig, &aExp, &aSig );
- }
- zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
- aSig |= LIT64( 0x0010000000000000 );
- zSig = estimateSqrt32( aExp, aSig>>21 );
- aSig <<= 9 - ( aExp & 1 );
- zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
- if ( ( zSig & 0x1FF ) <= 5 ) {
- doubleZSig = zSig<<1;
- mul64To128( zSig, zSig, &term0, &term1 );
- sub128( aSig, 0, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig;
- doubleZSig -= 2;
- add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
- }
- zSig |= ( ( rem0 | rem1 ) != 0 );
- }
- return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_eq( float64 a, float64 b STATUS_PARAM )
-{
- bits64 av, bv;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- av = float64_val(a);
- bv = float64_val(b);
- return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_le( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits64 av, bv;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- av = float64_val(a);
- bv = float64_val(b);
- if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
- return ( av == bv ) || ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_lt( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits64 av, bv;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- av = float64_val(a);
- bv = float64_val(b);
- if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
- return ( av != bv ) && ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is equal to the
-| corresponding value `b', and 0 otherwise. The invalid exception is raised
-| if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
-{
- bits64 av, bv;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- av = float64_val(a);
- bv = float64_val(b);
- return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than or
-| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
-| cause an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits64 av, bv;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- av = float64_val(a);
- bv = float64_val(b);
- if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
- return ( av == bv ) || ( aSign ^ ( av < bv ) );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
-| exception. Otherwise, the comparison is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
-{
- flag aSign, bSign;
- bits64 av, bv;
-
- if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
- || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
- ) {
- if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat64Sign( a );
- bSign = extractFloat64Sign( b );
- av = float64_val(a);
- bv = float64_val(b);
- if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
- return ( av != bv ) && ( aSign ^ ( av < bv ) );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 32-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic---which means in particular that the conversion
-| is rounded according to the current rounding mode. If `a' is a NaN, the
-| largest positive integer is returned. Otherwise, if the conversion
-| overflows, the largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
- shiftCount = 0x4037 - aExp;
- if ( shiftCount <= 0 ) shiftCount = 1;
- shift64RightJamming( aSig, shiftCount, &aSig );
- return roundAndPackInt32( aSign, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 32-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic, except that the conversion is always rounded
-| toward zero. If `a' is a NaN, the largest positive integer is returned.
-| Otherwise, if the conversion overflows, the largest integer with the same
-| sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig, savedASig;
- int32 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( 0x401E < aExp ) {
- if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
- goto invalid;
- }
- else if ( aExp < 0x3FFF ) {
- if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- shiftCount = 0x403E - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = aSig;
- if ( aSign ) z = - z;
- if ( ( z < 0 ) ^ aSign ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( ( aSig<<shiftCount ) != savedASig ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 64-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic---which means in particular that the conversion
-| is rounded according to the current rounding mode. If `a' is a NaN,
-| the largest positive integer is returned. Otherwise, if the conversion
-| overflows, the largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig, aSigExtra;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- shiftCount = 0x403E - aExp;
- if ( shiftCount <= 0 ) {
- if ( shiftCount ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FFF )
- && ( aSig != LIT64( 0x8000000000000000 ) ) )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- aSigExtra = 0;
- }
- else {
- shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
- }
- return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 64-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic, except that the conversion is always rounded
-| toward zero. If `a' is a NaN, the largest positive integer is returned.
-| Otherwise, if the conversion overflows, the largest integer with the same
-| sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig;
- int64 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- shiftCount = aExp - 0x403E;
- if ( 0 <= shiftCount ) {
- aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
- if ( ( a.high != 0xC03E ) || aSig ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- else if ( aExp < 0x3FFF ) {
- if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- z = aSig>>( - shiftCount );
- if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the single-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) {
- return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat32( aSign, 0xFF, 0 );
- }
- shift64RightJamming( aSig, 33, &aSig );
- if ( aExp || aSig ) aExp -= 0x3F81;
- return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig, zSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) {
- return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat64( aSign, 0x7FF, 0 );
- }
- shift64RightJamming( aSig, 1, &zSig );
- if ( aExp || aSig ) aExp -= 0x3C01;
- return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
-
-}
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the quadruple-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig, zSig0, zSig1;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
- return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) );
- }
- shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
- return packFloat128( aSign, aExp, zSig0, zSig1 );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the extended double-precision floating-point value `a' to an integer,
-| and returns the result as an extended quadruple-precision floating-point
-| value. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 lastBitMask, roundBitsMask;
- int8 roundingMode;
- floatx80 z;
-
- aExp = extractFloatx80Exp( a );
- if ( 0x403E <= aExp ) {
- if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
- return propagateFloatx80NaN( a, a STATUS_VAR );
- }
- return a;
- }
- if ( aExp < 0x3FFF ) {
- if ( ( aExp == 0 )
- && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
- return a;
- }
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloatx80Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
- ) {
- return
- packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
- }
- break;
- case float_round_down:
- return
- aSign ?
- packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
- : packFloatx80( 0, 0, 0 );
- case float_round_up:
- return
- aSign ? packFloatx80( 1, 0, 0 )
- : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
- }
- return packFloatx80( aSign, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x403E - aExp;
- roundBitsMask = lastBitMask - 1;
- z = a;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z.low += lastBitMask>>1;
- if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
- z.low += roundBitsMask;
- }
- }
- z.low &= ~ roundBitsMask;
- if ( z.low == 0 ) {
- ++z.high;
- z.low = LIT64( 0x8000000000000000 );
- }
- if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the extended double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
-| negated before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
-{
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- int32 expDiff;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- expDiff = aExp - bExp;
- if ( 0 < expDiff ) {
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) --expDiff;
- shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) ++expDiff;
- shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
- zExp = bExp;
- }
- else {
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- return a;
- }
- zSig1 = 0;
- zSig0 = aSig + bSig;
- if ( aExp == 0 ) {
- normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
- goto roundAndPack;
- }
- zExp = aExp;
- goto shiftRight1;
- }
- zSig0 = aSig + bSig;
- if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
- shiftRight1:
- shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
- zSig0 |= LIT64( 0x8000000000000000 );
- ++zExp;
- roundAndPack:
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the extended
-| double-precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
-{
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- int32 expDiff;
- floatx80 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- expDiff = aExp - bExp;
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- zSig1 = 0;
- if ( bSig < aSig ) goto aBigger;
- if ( aSig < bSig ) goto bBigger;
- return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
- bExpBigger:
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) ++expDiff;
- shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
- bBigger:
- sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) --expDiff;
- shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
- aBigger:
- sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
- zExp = aExp;
- normalizeRoundAndPack:
- return
- normalizeRoundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the extended double-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign == bSign ) {
- return addFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return subFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign == bSign ) {
- return subFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloatx80Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- floatx80 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 )
- || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig ) == 0 ) goto invalid;
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
- normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
- }
- zExp = aExp + bExp - 0x3FFE;
- mul64To128( aSig, bSig, &zSig0, &zSig1 );
- if ( 0 < (sbits64) zSig0 ) {
- shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
- --zExp;
- }
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the extended double-precision floating-point
-| value `a' by the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig, bSig, zSig0, zSig1;
- bits64 rem0, rem1, rem2, term0, term1, term2;
- floatx80 z;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- goto invalid;
- }
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return packFloatx80( zSign, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- if ( ( aExp | aSig ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
- normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
- }
- zExp = aExp - bExp + 0x3FFE;
- rem1 = 0;
- if ( bSig <= aSig ) {
- shift128Right( aSig, 0, 1, &aSig, &rem1 );
- ++zExp;
- }
- zSig0 = estimateDiv128To64( aSig, rem1, bSig );
- mul64To128( bSig, zSig0, &term0, &term1 );
- sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
- }
- zSig1 = estimateDiv128To64( rem1, 0, bSig );
- if ( (bits64) ( zSig1<<1 ) <= 8 ) {
- mul64To128( bSig, zSig1, &term1, &term2 );
- sub128( rem1, 0, term1, term2, &rem1, &rem2 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
- }
- zSig1 |= ( ( rem1 | rem2 ) != 0 );
- }
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the extended double-precision floating-point value
-| `a' with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, expDiff;
- bits64 aSig0, aSig1, bSig;
- bits64 q, term0, term1, alternateASig0, alternateASig1;
- floatx80 z;
-
- aSig0 = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- bSig = extractFloatx80Frac( b );
- bExp = extractFloatx80Exp( b );
- bSign = extractFloatx80Sign( b );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig0<<1 )
- || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
- return propagateFloatx80NaN( a, b STATUS_VAR );
- }
- goto invalid;
- }
- if ( bExp == 0x7FFF ) {
- if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( bSig == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
- }
- if ( aExp == 0 ) {
- if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
- normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
- }
- bSig |= LIT64( 0x8000000000000000 );
- zSign = aSign;
- expDiff = aExp - bExp;
- aSig1 = 0;
- if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
- shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
- expDiff = 0;
- }
- q = ( bSig <= aSig0 );
- if ( q ) aSig0 -= bSig;
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- mul64To128( bSig, q, &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
- shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
- expDiff -= 62;
- }
- expDiff += 64;
- if ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig );
- q = ( 2 < q ) ? q - 2 : 0;
- q >>= 64 - expDiff;
- mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
- shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
- while ( le128( term0, term1, aSig0, aSig1 ) ) {
- ++q;
- sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
- }
- }
- else {
- term1 = 0;
- term0 = bSig;
- }
- sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
- if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
- || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
- && ( q & 1 ) )
- ) {
- aSig0 = alternateASig0;
- aSig1 = alternateASig1;
- zSign = ! zSign;
- }
- return
- normalizeRoundAndPackFloatx80(
- 80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the extended double-precision floating-point
-| value `a'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, zExp;
- bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0;
- bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
- floatx80 z;
-
- aSig0 = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
- if ( ! aSign ) return a;
- goto invalid;
- }
- if ( aSign ) {
- if ( ( aExp | aSig0 ) == 0 ) return a;
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = floatx80_default_nan_low;
- z.high = floatx80_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
- normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
- }
- zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
- zSig0 = estimateSqrt32( aExp, aSig0>>32 );
- shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
- zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
- doubleZSig0 = zSig0<<1;
- mul64To128( zSig0, zSig0, &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- doubleZSig0 -= 2;
- add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
- }
- zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
- if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
- if ( zSig1 == 0 ) zSig1 = 1;
- mul64To128( doubleZSig0, zSig1, &term1, &term2 );
- sub128( rem1, 0, term1, term2, &rem1, &rem2 );
- mul64To128( zSig1, zSig1, &term2, &term3 );
- sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- shortShift128Left( 0, zSig1, 1, &term2, &term3 );
- term3 |= 1;
- term2 |= doubleZSig0;
- add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
- }
- zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
- }
- shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
- zSig0 |= doubleZSig0;
- return
- roundAndPackFloatx80(
- STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| equal to the corresponding value `b', and 0 otherwise. The comparison is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| less than or equal to the corresponding value `b', and 0 otherwise. The
-| comparison is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is
-| less than the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is equal
-| to the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is less
-| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs
-| do not cause an exception. Otherwise, the comparison is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is less
-| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause
-| an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( a )<<1 ) )
- || ( ( extractFloatx80Exp( b ) == 0x7FFF )
- && (bits64) ( extractFloatx80Frac( b )<<1 ) )
- ) {
- if ( floatx80_is_signaling_nan( a )
- || floatx80_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloatx80Sign( a );
- bSign = extractFloatx80Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 32-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int32 float128_to_int32( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
- if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
- aSig0 |= ( aSig1 != 0 );
- shiftCount = 0x4028 - aExp;
- if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
- return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 32-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero. If
-| `a' is a NaN, the largest positive integer is returned. Otherwise, if the
-| conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1, savedASig;
- int32 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- aSig0 |= ( aSig1 != 0 );
- if ( 0x401E < aExp ) {
- if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
- goto invalid;
- }
- else if ( aExp < 0x3FFF ) {
- if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
- return 0;
- }
- aSig0 |= LIT64( 0x0001000000000000 );
- shiftCount = 0x402F - aExp;
- savedASig = aSig0;
- aSig0 >>= shiftCount;
- z = aSig0;
- if ( aSign ) z = - z;
- if ( ( z < 0 ) ^ aSign ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
- }
- if ( ( aSig0<<shiftCount ) != savedASig ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 64-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN, the largest
-| positive integer is returned. Otherwise, if the conversion overflows, the
-| largest integer with the same sign as `a' is returned.
-*----------------------------------------------------------------------------*/
-
-int64 float128_to_int64( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
- shiftCount = 0x402F - aExp;
- if ( shiftCount <= 0 ) {
- if ( 0x403E < aExp ) {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign
- || ( ( aExp == 0x7FFF )
- && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
- )
- ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
- }
- else {
- shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
- }
- return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the 64-bit two's complement integer format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN, the largest positive integer is returned. Otherwise, if
-| the conversion overflows, the largest integer with the same sign as `a' is
-| returned.
-*----------------------------------------------------------------------------*/
-
-int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, shiftCount;
- bits64 aSig0, aSig1;
- int64 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
- shiftCount = aExp - 0x402F;
- if ( 0 < shiftCount ) {
- if ( 0x403E <= aExp ) {
- aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
- if ( ( a.high == LIT64( 0xC03E000000000000 ) )
- && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
- if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
- }
- else {
- float_raise( float_flag_invalid STATUS_VAR);
- if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
- return LIT64( 0x7FFFFFFFFFFFFFFF );
- }
- }
- return (sbits64) LIT64( 0x8000000000000000 );
- }
- z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
- if ( (bits64) ( aSig1<<shiftCount ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- }
- else {
- if ( aExp < 0x3FFF ) {
- if ( aExp | aSig0 | aSig1 ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return 0;
- }
- z = aSig0>>( - shiftCount );
- if ( aSig1
- || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- }
- if ( aSign ) z = - z;
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the single-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float128_to_float32( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
- bits32 zSig;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat32( aSign, 0xFF, 0 );
- }
- aSig0 |= ( aSig1 != 0 );
- shift64RightJamming( aSig0, 18, &aSig0 );
- zSig = aSig0;
- if ( aExp || zSig ) {
- zSig |= 0x40000000;
- aExp -= 0x3F81;
- }
- return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float128_to_float64( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloat64( aSign, 0x7FF, 0 );
- }
- shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
- aSig0 |= ( aSig1 != 0 );
- if ( aExp || aSig0 ) {
- aSig0 |= LIT64( 0x4000000000000000 );
- aExp -= 0x3C01;
- }
- return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
-
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the extended double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) {
- return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) );
- }
- return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- else {
- aSig0 |= LIT64( 0x0001000000000000 );
- }
- shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
- return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
-
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Rounds the quadruple-precision floating-point value `a' to an integer, and
-| returns the result as a quadruple-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_round_to_int( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 lastBitMask, roundBitsMask;
- int8 roundingMode;
- float128 z;
-
- aExp = extractFloat128Exp( a );
- if ( 0x402F <= aExp ) {
- if ( 0x406F <= aExp ) {
- if ( ( aExp == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
- ) {
- return propagateFloat128NaN( a, a STATUS_VAR );
- }
- return a;
- }
- lastBitMask = 1;
- lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
- roundBitsMask = lastBitMask - 1;
- z = a;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- if ( lastBitMask ) {
- add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
- if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
- }
- else {
- if ( (sbits64) z.low < 0 ) {
- ++z.high;
- if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
- }
- }
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat128Sign( z )
- ^ ( roundingMode == float_round_up ) ) {
- add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
- }
- }
- z.low &= ~ roundBitsMask;
- }
- else {
- if ( aExp < 0x3FFF ) {
- if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
- STATUS(float_exception_flags) |= float_flag_inexact;
- aSign = extractFloat128Sign( a );
- switch ( STATUS(float_rounding_mode) ) {
- case float_round_nearest_even:
- if ( ( aExp == 0x3FFE )
- && ( extractFloat128Frac0( a )
- | extractFloat128Frac1( a ) )
- ) {
- return packFloat128( aSign, 0x3FFF, 0, 0 );
- }
- break;
- case float_round_down:
- return
- aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
- : packFloat128( 0, 0, 0, 0 );
- case float_round_up:
- return
- aSign ? packFloat128( 1, 0, 0, 0 )
- : packFloat128( 0, 0x3FFF, 0, 0 );
- }
- return packFloat128( aSign, 0, 0, 0 );
- }
- lastBitMask = 1;
- lastBitMask <<= 0x402F - aExp;
- roundBitsMask = lastBitMask - 1;
- z.low = 0;
- z.high = a.high;
- roundingMode = STATUS(float_rounding_mode);
- if ( roundingMode == float_round_nearest_even ) {
- z.high += lastBitMask>>1;
- if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
- z.high &= ~ lastBitMask;
- }
- }
- else if ( roundingMode != float_round_to_zero ) {
- if ( extractFloat128Sign( z )
- ^ ( roundingMode == float_round_up ) ) {
- z.high |= ( a.low != 0 );
- z.high += roundBitsMask;
- }
- }
- z.high &= ~ roundBitsMask;
- }
- if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
- STATUS(float_exception_flags) |= float_flag_inexact;
- }
- return z;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the quadruple-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
-{
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- int32 expDiff;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- expDiff = aExp - bExp;
- if ( 0 < expDiff ) {
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig0 |= LIT64( 0x0001000000000000 );
- }
- shift128ExtraRightJamming(
- bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
- zExp = aExp;
- }
- else if ( expDiff < 0 ) {
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig0 |= LIT64( 0x0001000000000000 );
- }
- shift128ExtraRightJamming(
- aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
- zExp = bExp;
- }
- else {
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- return a;
- }
- add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
- if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
- zSig2 = 0;
- zSig0 |= LIT64( 0x0002000000000000 );
- zExp = aExp;
- goto shiftRight1;
- }
- aSig0 |= LIT64( 0x0001000000000000 );
- add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
- --zExp;
- if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
- ++zExp;
- shiftRight1:
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
- roundAndPack:
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the quadruple-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
-{
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
- int32 expDiff;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- expDiff = aExp - bExp;
- shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
- shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
- if ( 0 < expDiff ) goto aExpBigger;
- if ( expDiff < 0 ) goto bExpBigger;
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- aExp = 1;
- bExp = 1;
- }
- if ( bSig0 < aSig0 ) goto aBigger;
- if ( aSig0 < bSig0 ) goto bBigger;
- if ( bSig1 < aSig1 ) goto aBigger;
- if ( aSig1 < bSig1 ) goto bBigger;
- return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
- bExpBigger:
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- ++expDiff;
- }
- else {
- aSig0 |= LIT64( 0x4000000000000000 );
- }
- shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
- bSig0 |= LIT64( 0x4000000000000000 );
- bBigger:
- sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- --expDiff;
- }
- else {
- bSig0 |= LIT64( 0x4000000000000000 );
- }
- shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
- aSig0 |= LIT64( 0x4000000000000000 );
- aBigger:
- sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the quadruple-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_add( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign == bSign ) {
- return addFloat128Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return subFloat128Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_sub( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign == bSign ) {
- return subFloat128Sigs( a, b, aSign STATUS_VAR );
- }
- else {
- return addFloat128Sigs( a, b, aSign STATUS_VAR );
- }
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_mul( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( ( aSig0 | aSig1 )
- || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- if ( bExp == 0 ) {
- if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
- }
- zExp = aExp + bExp - 0x4000;
- aSig0 |= LIT64( 0x0001000000000000 );
- shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
- mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
- add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
- zSig2 |= ( zSig3 != 0 );
- if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
- ++zExp;
- }
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the quadruple-precision floating-point value
-| `a' by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_div( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, zExp;
- bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
- zSign = aSign ^ bSign;
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- goto invalid;
- }
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return packFloat128( zSign, 0, 0, 0 );
- }
- if ( bExp == 0 ) {
- if ( ( bSig0 | bSig1 ) == 0 ) {
- if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- float_raise( float_flag_divbyzero STATUS_VAR);
- return packFloat128( zSign, 0x7FFF, 0, 0 );
- }
- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- zExp = aExp - bExp + 0x3FFD;
- shortShift128Left(
- aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
- shortShift128Left(
- bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
- if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
- shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
- ++zExp;
- }
- zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
- mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
- sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
- }
- zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
- if ( ( zSig1 & 0x3FFF ) <= 4 ) {
- mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
- sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
- }
- zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
- }
- shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
- return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the remainder of the quadruple-precision floating-point value `a'
-| with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_rem( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign, zSign;
- int32 aExp, bExp, expDiff;
- bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
- bits64 allZero, alternateASig0, alternateASig1, sigMean1;
- sbits64 sigMean0;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- bSig1 = extractFloat128Frac1( b );
- bSig0 = extractFloat128Frac0( b );
- bExp = extractFloat128Exp( b );
- bSign = extractFloat128Sign( b );
- if ( aExp == 0x7FFF ) {
- if ( ( aSig0 | aSig1 )
- || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
- return propagateFloat128NaN( a, b STATUS_VAR );
- }
- goto invalid;
- }
- if ( bExp == 0x7FFF ) {
- if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
- return a;
- }
- if ( bExp == 0 ) {
- if ( ( bSig0 | bSig1 ) == 0 ) {
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return a;
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- expDiff = aExp - bExp;
- if ( expDiff < -1 ) return a;
- shortShift128Left(
- aSig0 | LIT64( 0x0001000000000000 ),
- aSig1,
- 15 - ( expDiff < 0 ),
- &aSig0,
- &aSig1
- );
- shortShift128Left(
- bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
- q = le128( bSig0, bSig1, aSig0, aSig1 );
- if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
- expDiff -= 64;
- while ( 0 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig0 );
- q = ( 4 < q ) ? q - 4 : 0;
- mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
- shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
- shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
- sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
- expDiff -= 61;
- }
- if ( -64 < expDiff ) {
- q = estimateDiv128To64( aSig0, aSig1, bSig0 );
- q = ( 4 < q ) ? q - 4 : 0;
- q >>= - expDiff;
- shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
- expDiff += 52;
- if ( expDiff < 0 ) {
- shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
- }
- else {
- shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
- }
- mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
- sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
- }
- else {
- shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
- shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
- }
- do {
- alternateASig0 = aSig0;
- alternateASig1 = aSig1;
- ++q;
- sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
- } while ( 0 <= (sbits64) aSig0 );
- add128(
- aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
- if ( ( sigMean0 < 0 )
- || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
- aSig0 = alternateASig0;
- aSig1 = alternateASig1;
- }
- zSign = ( (sbits64) aSig0 < 0 );
- if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
- return
- normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the quadruple-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_sqrt( float128 a STATUS_PARAM )
-{
- flag aSign;
- int32 aExp, zExp;
- bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
- bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
- float128 z;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
- if ( ! aSign ) return a;
- goto invalid;
- }
- if ( aSign ) {
- if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
- invalid:
- float_raise( float_flag_invalid STATUS_VAR);
- z.low = float128_default_nan_low;
- z.high = float128_default_nan_high;
- return z;
- }
- if ( aExp == 0 ) {
- if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
- normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
- }
- zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
- aSig0 |= LIT64( 0x0001000000000000 );
- zSig0 = estimateSqrt32( aExp, aSig0>>17 );
- shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
- zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
- doubleZSig0 = zSig0<<1;
- mul64To128( zSig0, zSig0, &term0, &term1 );
- sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
- while ( (sbits64) rem0 < 0 ) {
- --zSig0;
- doubleZSig0 -= 2;
- add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
- }
- zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
- if ( ( zSig1 & 0x1FFF ) <= 5 ) {
- if ( zSig1 == 0 ) zSig1 = 1;
- mul64To128( doubleZSig0, zSig1, &term1, &term2 );
- sub128( rem1, 0, term1, term2, &rem1, &rem2 );
- mul64To128( zSig1, zSig1, &term2, &term3 );
- sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
- while ( (sbits64) rem1 < 0 ) {
- --zSig1;
- shortShift128Left( 0, zSig1, 1, &term2, &term3 );
- term3 |= 1;
- term2 |= doubleZSig0;
- add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
- }
- zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
- }
- shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
- return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_eq( float128 a, float128 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. The comparison
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_le( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. The comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_lt( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is equal to
-| the corresponding value `b', and 0 otherwise. The invalid exception is
-| raised if either operand is a NaN. Otherwise, the comparison is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
-{
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- float_raise( float_flag_invalid STATUS_VAR);
- return 0;
- }
- return
- ( a.low == b.low )
- && ( ( a.high == b.high )
- || ( ( a.low == 0 )
- && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
- );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
-| cause an exception. Otherwise, the comparison is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- == 0 );
- }
- return
- aSign ? le128( b.high, b.low, a.high, a.low )
- : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is less than
-| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
-| exception. Otherwise, the comparison is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if ( ( ( extractFloat128Exp( a ) == 0x7FFF )
- && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
- || ( ( extractFloat128Exp( b ) == 0x7FFF )
- && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
- ) {
- if ( float128_is_signaling_nan( a )
- || float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return 0;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- return
- aSign
- && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
- != 0 );
- }
- return
- aSign ? lt128( b.high, b.low, a.high, a.low )
- : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-#endif
-
-/* misc functions */
-float32 uint32_to_float32( unsigned int a STATUS_PARAM )
-{
- return int64_to_float32(a STATUS_VAR);
-}
-
-float64 uint32_to_float64( unsigned int a STATUS_PARAM )
-{
- return int64_to_float64(a STATUS_VAR);
-}
-
-unsigned int float32_to_uint32( float32 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float32_to_int64(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float32_to_int64_round_to_zero(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-unsigned int float64_to_uint32( float64 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float64_to_int64(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
-{
- int64_t v;
- unsigned int res;
-
- v = float64_to_int64_round_to_zero(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
- res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
- } else {
- res = v;
- }
- return res;
-}
-
-/* FIXME: This looks broken. */
-uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
-{
- int64_t v;
-
- v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
- v += float64_val(a);
- v = float64_to_int64(make_float64(v) STATUS_VAR);
-
- return v - INT64_MIN;
-}
-
-uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
-{
- int64_t v;
-
- v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
- v += float64_val(a);
- v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
-
- return v - INT64_MIN;
-}
-
-#define COMPARE(s, nan_exp) \
-INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \
- int is_quiet STATUS_PARAM ) \
-{ \
- flag aSign, bSign; \
- bits ## s av, bv; \
- \
- if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) && \
- extractFloat ## s ## Frac( a ) ) || \
- ( ( extractFloat ## s ## Exp( b ) == nan_exp ) && \
- extractFloat ## s ## Frac( b ) )) { \
- if (!is_quiet || \
- float ## s ## _is_signaling_nan( a ) || \
- float ## s ## _is_signaling_nan( b ) ) { \
- float_raise( float_flag_invalid STATUS_VAR); \
- } \
- return float_relation_unordered; \
- } \
- aSign = extractFloat ## s ## Sign( a ); \
- bSign = extractFloat ## s ## Sign( b ); \
- av = float ## s ## _val(a); \
- bv = float ## s ## _val(b); \
- if ( aSign != bSign ) { \
- if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) { \
- /* zero case */ \
- return float_relation_equal; \
- } else { \
- return 1 - (2 * aSign); \
- } \
- } else { \
- if (av == bv) { \
- return float_relation_equal; \
- } else { \
- return 1 - 2 * (aSign ^ ( av < bv )); \
- } \
- } \
-} \
- \
-int float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM ) \
-{ \
- return float ## s ## _compare_internal(a, b, 0 STATUS_VAR); \
-} \
- \
-int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \
-{ \
- return float ## s ## _compare_internal(a, b, 1 STATUS_VAR); \
-}
-
-COMPARE(32, 0xff)
-COMPARE(64, 0x7ff)
-
-INLINE int float128_compare_internal( float128 a, float128 b,
- int is_quiet STATUS_PARAM )
-{
- flag aSign, bSign;
-
- if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
- ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
- ( ( extractFloat128Exp( b ) == 0x7fff ) &&
- ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
- if (!is_quiet ||
- float128_is_signaling_nan( a ) ||
- float128_is_signaling_nan( b ) ) {
- float_raise( float_flag_invalid STATUS_VAR);
- }
- return float_relation_unordered;
- }
- aSign = extractFloat128Sign( a );
- bSign = extractFloat128Sign( b );
- if ( aSign != bSign ) {
- if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
- /* zero case */
- return float_relation_equal;
- } else {
- return 1 - (2 * aSign);
- }
- } else {
- if (a.low == b.low && a.high == b.high) {
- return float_relation_equal;
- } else {
- return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
- }
- }
-}
-
-int float128_compare( float128 a, float128 b STATUS_PARAM )
-{
- return float128_compare_internal(a, b, 0 STATUS_VAR);
-}
-
-int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
-{
- return float128_compare_internal(a, b, 1 STATUS_VAR);
-}
-
-/* Multiply A by 2 raised to the power N. */
-float32 float32_scalbn( float32 a, int n STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits32 aSig;
-
- aSig = extractFloat32Frac( a );
- aExp = extractFloat32Exp( a );
- aSign = extractFloat32Sign( a );
-
- if ( aExp == 0xFF ) {
- return a;
- }
- aExp += n;
- return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
-}
-
-float64 float64_scalbn( float64 a, int n STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig;
-
- aSig = extractFloat64Frac( a );
- aExp = extractFloat64Exp( a );
- aSign = extractFloat64Sign( a );
-
- if ( aExp == 0x7FF ) {
- return a;
- }
- aExp += n;
- return roundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
-}
-
-#ifdef FLOATX80
-floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
-{
- flag aSign;
- int16 aExp;
- bits64 aSig;
-
- aSig = extractFloatx80Frac( a );
- aExp = extractFloatx80Exp( a );
- aSign = extractFloatx80Sign( a );
-
- if ( aExp == 0x7FF ) {
- return a;
- }
- aExp += n;
- return roundAndPackFloatx80( STATUS(floatx80_rounding_precision),
- aSign, aExp, aSig, 0 STATUS_VAR );
-}
-#endif
-
-#ifdef FLOAT128
-float128 float128_scalbn( float128 a, int n STATUS_PARAM )
-{
- flag aSign;
- int32 aExp;
- bits64 aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1( a );
- aSig0 = extractFloat128Frac0( a );
- aExp = extractFloat128Exp( a );
- aSign = extractFloat128Sign( a );
- if ( aExp == 0x7FFF ) {
- return a;
- }
- aExp += n;
- return roundAndPackFloat128( aSign, aExp, aSig0, aSig1, 0 STATUS_VAR );
-
-}
-#endif
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
deleted file mode 100644
index 5f95d06..0000000
--- a/fpu/softfloat.h
+++ /dev/null
@@ -1,444 +0,0 @@
-/*============================================================================
-
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-#ifndef SOFTFLOAT_H
-#define SOFTFLOAT_H
-
-#if defined(HOST_SOLARIS) && defined(NEEDS_LIBSUNMATH)
-#include <sunmath.h>
-#endif
-
-#include <inttypes.h>
-#include "config.h"
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines the most convenient type that holds
-| integers of at least as many bits as specified. For example, `uint8' should
-| be the most convenient type that can hold unsigned integers of as many as
-| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
-| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
-| to the same as `int'.
-*----------------------------------------------------------------------------*/
-typedef uint8_t flag;
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef int uint16;
-typedef int int16;
-typedef unsigned int uint32;
-typedef signed int int32;
-typedef uint64_t uint64;
-typedef int64_t int64;
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines a type that holds integers
-| of _exactly_ the number of bits specified. For instance, for most
-| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
-| `unsigned short int' and `signed short int' (or `short int'), respectively.
-*----------------------------------------------------------------------------*/
-typedef uint8_t bits8;
-typedef int8_t sbits8;
-typedef uint16_t bits16;
-typedef int16_t sbits16;
-typedef uint32_t bits32;
-typedef int32_t sbits32;
-typedef uint64_t bits64;
-typedef int64_t sbits64;
-
-#define LIT64( a ) a##LL
-#define INLINE static inline
-
-/*----------------------------------------------------------------------------
-| The macro `FLOATX80' must be defined to enable the extended double-precision
-| floating-point format `floatx80'. If this macro is not defined, the
-| `floatx80' type will not be defined, and none of the functions that either
-| input or output the `floatx80' type will be defined. The same applies to
-| the `FLOAT128' macro and the quadruple-precision format `float128'.
-*----------------------------------------------------------------------------*/
-#ifdef CONFIG_SOFTFLOAT
-/* bit exact soft float support */
-#define FLOATX80
-#define FLOAT128
-#else
-/* native float support */
-#if (defined(__i386__) || defined(__x86_64__)) && !defined(_BSD)
-#define FLOATX80
-#endif
-#endif /* !CONFIG_SOFTFLOAT */
-
-#define STATUS_PARAM , float_status *status
-#define STATUS(field) status->field
-#define STATUS_VAR , status
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point ordering relations
-*----------------------------------------------------------------------------*/
-enum {
- float_relation_less = -1,
- float_relation_equal = 0,
- float_relation_greater = 1,
- float_relation_unordered = 2
-};
-
-#ifdef CONFIG_SOFTFLOAT
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-/* Use structures for soft-float types. This prevents accidentally mixing
- them with native int/float types. A sufficiently clever compiler and
- sane ABI should be able to see though these structs. However
- x86/gcc 3.x seems to struggle a bit, so leave them disabled by default. */
-//#define USE_SOFTFLOAT_STRUCT_TYPES
-#ifdef USE_SOFTFLOAT_STRUCT_TYPES
-typedef struct {
- uint32_t v;
-} float32;
-/* The cast ensures an error if the wrong type is passed. */
-#define float32_val(x) (((float32)(x)).v)
-#define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
-typedef struct {
- uint64_t v;
-} float64;
-#define float64_val(x) (((float64)(x)).v)
-#define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
-#else
-typedef uint32_t float32;
-typedef uint64_t float64;
-#define float32_val(x) (x)
-#define float64_val(x) (x)
-#define make_float32(x) (x)
-#define make_float64(x) (x)
-#endif
-#ifdef FLOATX80
-typedef struct {
- uint64_t low;
- uint16_t high;
-} floatx80;
-#endif
-#ifdef FLOAT128
-typedef struct {
-#ifdef WORDS_BIGENDIAN
- uint64_t high, low;
-#else
- uint64_t low, high;
-#endif
-} float128;
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point underflow tininess-detection mode.
-*----------------------------------------------------------------------------*/
-enum {
- float_tininess_after_rounding = 0,
- float_tininess_before_rounding = 1
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-enum {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-enum {
- float_flag_invalid = 1,
- float_flag_divbyzero = 4,
- float_flag_overflow = 8,
- float_flag_underflow = 16,
- float_flag_inexact = 32
-};
-
-typedef struct float_status {
- signed char float_detect_tininess;
- signed char float_rounding_mode;
- signed char float_exception_flags;
-#ifdef FLOATX80
- signed char floatx80_rounding_precision;
-#endif
-} float_status;
-
-void set_float_rounding_mode(int val STATUS_PARAM);
-void set_float_exception_flags(int val STATUS_PARAM);
-INLINE int get_float_exception_flags(float_status *status)
-{
- return STATUS(float_exception_flags);
-}
-#ifdef FLOATX80
-void set_floatx80_rounding_precision(int val STATUS_PARAM);
-#endif
-
-/*----------------------------------------------------------------------------
-| Routine to raise any or all of the software IEC/IEEE floating-point
-| exception flags.
-*----------------------------------------------------------------------------*/
-void float_raise( int8 flags STATUS_PARAM);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32( int STATUS_PARAM );
-float64 int32_to_float64( int STATUS_PARAM );
-float32 uint32_to_float32( unsigned int STATUS_PARAM );
-float64 uint32_to_float64( unsigned int STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 int32_to_floatx80( int STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 int32_to_float128( int STATUS_PARAM );
-#endif
-float32 int64_to_float32( int64_t STATUS_PARAM );
-float32 uint64_to_float32( uint64_t STATUS_PARAM );
-float64 int64_to_float64( int64_t STATUS_PARAM );
-float64 uint64_to_float64( uint64_t STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( int64_t STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 int64_to_float128( int64_t STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 STATUS_PARAM );
-int float32_to_int32_round_to_zero( float32 STATUS_PARAM );
-unsigned int float32_to_uint32( float32 STATUS_PARAM );
-unsigned int float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
-int64_t float32_to_int64( float32 STATUS_PARAM );
-int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM );
-float64 float32_to_float64( float32 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 float32_to_float128( float32 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 STATUS_PARAM );
-float32 float32_add( float32, float32 STATUS_PARAM );
-float32 float32_sub( float32, float32 STATUS_PARAM );
-float32 float32_mul( float32, float32 STATUS_PARAM );
-float32 float32_div( float32, float32 STATUS_PARAM );
-float32 float32_rem( float32, float32 STATUS_PARAM );
-float32 float32_sqrt( float32 STATUS_PARAM );
-int float32_eq( float32, float32 STATUS_PARAM );
-int float32_le( float32, float32 STATUS_PARAM );
-int float32_lt( float32, float32 STATUS_PARAM );
-int float32_eq_signaling( float32, float32 STATUS_PARAM );
-int float32_le_quiet( float32, float32 STATUS_PARAM );
-int float32_lt_quiet( float32, float32 STATUS_PARAM );
-int float32_compare( float32, float32 STATUS_PARAM );
-int float32_compare_quiet( float32, float32 STATUS_PARAM );
-int float32_is_nan( float32 );
-int float32_is_signaling_nan( float32 );
-float32 float32_scalbn( float32, int STATUS_PARAM );
-
-INLINE float32 float32_abs(float32 a)
-{
- return make_float32(float32_val(a) & 0x7fffffff);
-}
-
-INLINE float32 float32_chs(float32 a)
-{
- return make_float32(float32_val(a) ^ 0x80000000);
-}
-
-#define float32_zero make_float32(0)
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 STATUS_PARAM );
-int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
-unsigned int float64_to_uint32( float64 STATUS_PARAM );
-unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
-int64_t float64_to_int64( float64 STATUS_PARAM );
-int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
-uint64_t float64_to_uint64 (float64 a STATUS_PARAM);
-uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
-float32 float64_to_float32( float64 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 STATUS_PARAM );
-#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int( float64 STATUS_PARAM );
-float64 float64_trunc_to_int( float64 STATUS_PARAM );
-float64 float64_add( float64, float64 STATUS_PARAM );
-float64 float64_sub( float64, float64 STATUS_PARAM );
-float64 float64_mul( float64, float64 STATUS_PARAM );
-float64 float64_div( float64, float64 STATUS_PARAM );
-float64 float64_rem( float64, float64 STATUS_PARAM );
-float64 float64_sqrt( float64 STATUS_PARAM );
-int float64_eq( float64, float64 STATUS_PARAM );
-int float64_le( float64, float64 STATUS_PARAM );
-int float64_lt( float64, float64 STATUS_PARAM );
-int float64_eq_signaling( float64, float64 STATUS_PARAM );
-int float64_le_quiet( float64, float64 STATUS_PARAM );
-int float64_lt_quiet( float64, float64 STATUS_PARAM );
-int float64_compare( float64, float64 STATUS_PARAM );
-int float64_compare_quiet( float64, float64 STATUS_PARAM );
-int float64_is_nan( float64 a );
-int float64_is_signaling_nan( float64 );
-float64 float64_scalbn( float64, int STATUS_PARAM );
-
-INLINE float64 float64_abs(float64 a)
-{
- return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
-}
-
-INLINE float64 float64_chs(float64 a)
-{
- return make_float64(float64_val(a) ^ 0x8000000000000000LL);
-}
-
-#define float64_zero make_float64(0)
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 STATUS_PARAM );
-int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
-int64_t floatx80_to_int64( floatx80 STATUS_PARAM );
-int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
-float32 floatx80_to_float32( floatx80 STATUS_PARAM );
-float64 floatx80_to_float64( floatx80 STATUS_PARAM );
-#ifdef FLOAT128
-float128 floatx80_to_float128( floatx80 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
-floatx80 floatx80_add( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sub( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
-int floatx80_le( floatx80, floatx80 STATUS_PARAM );
-int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
-int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM );
-int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_is_nan( floatx80 );
-int floatx80_is_signaling_nan( floatx80 );
-floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM );
-
-INLINE floatx80 floatx80_abs(floatx80 a)
-{
- a.high &= 0x7fff;
- return a;
-}
-
-INLINE floatx80 floatx80_chs(floatx80 a)
-{
- a.high ^= 0x8000;
- return a;
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float128_to_int32( float128 STATUS_PARAM );
-int float128_to_int32_round_to_zero( float128 STATUS_PARAM );
-int64_t float128_to_int64( float128 STATUS_PARAM );
-int64_t float128_to_int64_round_to_zero( float128 STATUS_PARAM );
-float32 float128_to_float32( float128 STATUS_PARAM );
-float64 float128_to_float64( float128 STATUS_PARAM );
-#ifdef FLOATX80
-floatx80 float128_to_floatx80( float128 STATUS_PARAM );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision operations.
-*----------------------------------------------------------------------------*/
-float128 float128_round_to_int( float128 STATUS_PARAM );
-float128 float128_add( float128, float128 STATUS_PARAM );
-float128 float128_sub( float128, float128 STATUS_PARAM );
-float128 float128_mul( float128, float128 STATUS_PARAM );
-float128 float128_div( float128, float128 STATUS_PARAM );
-float128 float128_rem( float128, float128 STATUS_PARAM );
-float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq( float128, float128 STATUS_PARAM );
-int float128_le( float128, float128 STATUS_PARAM );
-int float128_lt( float128, float128 STATUS_PARAM );
-int float128_eq_signaling( float128, float128 STATUS_PARAM );
-int float128_le_quiet( float128, float128 STATUS_PARAM );
-int float128_lt_quiet( float128, float128 STATUS_PARAM );
-int float128_compare( float128, float128 STATUS_PARAM );
-int float128_compare_quiet( float128, float128 STATUS_PARAM );
-int float128_is_nan( float128 );
-int float128_is_signaling_nan( float128 );
-float128 float128_scalbn( float128, int STATUS_PARAM );
-
-INLINE float128 float128_abs(float128 a)
-{
- a.high &= 0x7fffffffffffffffLL;
- return a;
-}
-
-INLINE float128 float128_chs(float128 a)
-{
- a.high ^= 0x8000000000000000LL;
- return a;
-}
-
-#endif
-
-#else /* CONFIG_SOFTFLOAT */
-
-#include "softfloat-native.h"
-
-#endif /* !CONFIG_SOFTFLOAT */
-
-#endif /* !SOFTFLOAT_H */
diff --git a/framebuffer.c b/framebuffer.c
deleted file mode 100644
index d0f9b40..0000000
--- a/framebuffer.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "framebuffer.h"
-#include <memory.h>
-#include <stdlib.h>
-
-typedef struct {
- /* client fields, these correspond to code that waits for updates before displaying them */
- /* at the moment, only one client is supported */
- void* fb_opaque;
- QFrameBufferUpdateFunc fb_update;
- QFrameBufferRotateFunc fb_rotate;
- QFrameBufferDoneFunc fb_done;
-
- void* pr_opaque;
- QFrameBufferCheckUpdateFunc pr_check;
- QFrameBufferInvalidateFunc pr_invalidate;
- QFrameBufferDetachFunc pr_detach;
-
-} QFrameBufferExtra;
-
-
-static int
-_get_pitch( int width, QFrameBufferFormat format )
-{
-
- switch (format) {
- case QFRAME_BUFFER_RGB565:
- return width*2;
- default:
- return -1;
- }
-}
-
-
-int
-qframebuffer_init( QFrameBuffer* qfbuff,
- int width,
- int height,
- int rotation,
- QFrameBufferFormat format )
-{
- int pitch;
-
- rotation &= 3;
-
- if (!qfbuff || width < 0 || height < 0)
- return -1;
-
- pitch = _get_pitch( width, format );
- if (pitch < 0)
- return -1;
-
- memset( qfbuff, 0, sizeof(*qfbuff) );
-
- qfbuff->extra = calloc( 1, sizeof(QFrameBufferExtra) );
- if (qfbuff->extra == NULL)
- return -1;
-
- qfbuff->pixels = calloc( pitch, height );
- if (qfbuff->pixels == NULL && (height > 0 && pitch > 0)) {
- free( qfbuff->extra );
- return -1;
- }
-
- qfbuff->width = width;
- qfbuff->height = height;
- qfbuff->pitch = pitch;
- qfbuff->format = format;
-
- qframebuffer_set_dpi( qfbuff, DEFAULT_FRAMEBUFFER_DPI, DEFAULT_FRAMEBUFFER_DPI );
- return 0;
-}
-
-
-void
-qframebuffer_set_dpi( QFrameBuffer* qfbuff,
- int x_dpi,
- int y_dpi )
-{
- /* dpi = dots / inch
- ** inch = dots / dpi
- ** mm / 25.4 = dots / dpi
- ** mm = (dots * 25.4)/dpi
- */
- qfbuff->phys_width_mm = (int)(0.5 + 25.4 * qfbuff->width / x_dpi);
- qfbuff->phys_height_mm = (int)(0.5 + 25.4 * qfbuff->height / y_dpi);
-}
-
-/* alternative to qframebuffer_set_dpi where one can set the physical dimensions directly */
-/* in millimeters. for the record 1 inch = 25.4 mm */
-void
-qframebuffer_set_mm( QFrameBuffer* qfbuff,
- int width_mm,
- int height_mm )
-{
- qfbuff->phys_width_mm = width_mm;
- qfbuff->phys_height_mm = height_mm;
-}
-
-void
-qframebuffer_update( QFrameBuffer* qfbuff, int x, int y, int w, int h )
-{
- QFrameBufferExtra* extra = qfbuff->extra;
-
- if (extra->fb_update)
- extra->fb_update( extra->fb_opaque, x, y, w, h );
-}
-
-
-void
-qframebuffer_add_client( QFrameBuffer* qfbuff,
- void* fb_opaque,
- QFrameBufferUpdateFunc fb_update,
- QFrameBufferRotateFunc fb_rotate,
- QFrameBufferDoneFunc fb_done )
-{
- QFrameBufferExtra* extra = qfbuff->extra;
-
- extra->fb_opaque = fb_opaque;
- extra->fb_update = fb_update;
- extra->fb_rotate = fb_rotate;
- extra->fb_done = fb_done;
-}
-
-void
-qframebuffer_set_producer( QFrameBuffer* qfbuff,
- void* opaque,
- QFrameBufferCheckUpdateFunc pr_check,
- QFrameBufferInvalidateFunc pr_invalidate,
- QFrameBufferDetachFunc pr_detach )
-{
- QFrameBufferExtra* extra = qfbuff->extra;
-
- extra->pr_opaque = opaque;
- extra->pr_check = pr_check;
- extra->pr_invalidate = pr_invalidate;
- extra->pr_detach = pr_detach;
-}
-
-
-void
-qframebuffer_rotate( QFrameBuffer* qfbuff, int rotation )
-{
- QFrameBufferExtra* extra = qfbuff->extra;
-
- if ((rotation ^ qfbuff->rotation) & 1) {
- /* swap width and height if new rotation requires it */
- int temp = qfbuff->width;
- qfbuff->width = qfbuff->height;
- qfbuff->height = temp;
- qfbuff->pitch = _get_pitch( qfbuff->width, qfbuff->format );
-
- temp = qfbuff->phys_width_mm;
- qfbuff->phys_width_mm = qfbuff->phys_height_mm;
- qfbuff->phys_height_mm = temp;
- }
- qfbuff->rotation = rotation;
-
- if (extra->fb_rotate)
- extra->fb_rotate( extra->fb_opaque, rotation );
-}
-
-
-extern void
-qframebuffer_done( QFrameBuffer* qfbuff )
-{
- QFrameBufferExtra* extra = qfbuff->extra;
-
- if (extra) {
- if (extra->pr_detach)
- extra->pr_detach( extra->pr_opaque );
-
- if (extra->fb_done)
- extra->fb_done( extra->fb_opaque );
- }
-
- free( qfbuff->pixels );
- free( qfbuff->extra );
- memset( qfbuff, 0, sizeof(*qfbuff) );
-}
-
-
-#define MAX_FRAME_BUFFERS 8
-
-static QFrameBuffer* framebuffer_fifo[ MAX_FRAME_BUFFERS ];
-static int framebuffer_fifo_rpos;
-static int framebuffer_fifo_count;
-
-void
-qframebuffer_fifo_add( QFrameBuffer* qfbuff )
-{
- if (framebuffer_fifo_count >= MAX_FRAME_BUFFERS)
- return;
-
- framebuffer_fifo[ framebuffer_fifo_count++ ] = qfbuff;
-}
-
-
-QFrameBuffer*
-qframebuffer_fifo_get( void )
-{
- if (framebuffer_fifo_rpos >= framebuffer_fifo_count)
- return NULL;
-
- return framebuffer_fifo[ framebuffer_fifo_rpos++ ];
-}
-
-
-void
-qframebuffer_check_updates( void )
-{
- int nn;
- for (nn = 0; nn < framebuffer_fifo_count; nn++) {
- QFrameBuffer* q = framebuffer_fifo[nn];
- QFrameBufferExtra* extra = q->extra;
-
- if (extra->pr_check)
- extra->pr_check( extra->pr_opaque );
- }
-}
-
-void
-qframebuffer_invalidate_all( void )
-{
- int nn;
- for (nn = 0; nn < framebuffer_fifo_count; nn++) {
- QFrameBuffer* q = framebuffer_fifo[nn];
- QFrameBufferExtra* extra = q->extra;
-
- if (extra->pr_invalidate)
- extra->pr_invalidate( extra->pr_opaque );
- }
-}
diff --git a/framebuffer.h b/framebuffer.h
deleted file mode 100644
index 1dce0d9..0000000
--- a/framebuffer.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _QEMU_FRAMEBUFFER_H_
-#define _QEMU_FRAMEBUFFER_H_
-
-/* A simple abstract interface to framebuffer displays. this is used to
- * de-couple hardware emulation from final display.
- *
- * Each QFrameBuffer object holds a pixel buffer that is shared between
- * one 'Producer' and one or more 'Clients'
- *
- * The Producer is in charge of updating the pixel buffer from the state
- * of the emulated VRAM. A Client listens to updates to the pixel buffer,
- * sent from the producer through qframebuffer_update()/_rotate() and
- * displays them.
- *
- * note the 'rotation' field: it can take values 0, 1, 2 or 3 and corresponds
- * to a rotation that must be performed to the pixels stored in the framebuffer
- * *before* displaying them a value of 1 corresponds to a rotation of
- * 90 clockwise-degrees, when the framebuffer is rotated 90 or 270 degrees,
- * its width/height are swapped automatically
- *
- * phys_width_mm and phys_height_mm are physical dimensions expressed
- * in millimeters
- *
- * More about the client/producer relationships below.
- */
-typedef struct QFrameBuffer QFrameBuffer;
-
-
-typedef enum {
- QFRAME_BUFFER_NONE = 0,
- QFRAME_BUFFER_RGB565 = 1,
- QFRAME_BUFFER_MAX /* do not remove */
-} QFrameBufferFormat;
-
-struct QFrameBuffer {
- int width; /* width in pixels */
- int height; /* height in pixels */
- int pitch; /* bytes per line */
- int rotation; /* rotation to be applied when displaying */
- QFrameBufferFormat format;
- void* pixels; /* pixel buffer */
-
- int phys_width_mm;
- int phys_height_mm;
-
- /* extra data that is handled by the framebuffer implementation */
- void* extra;
-
-};
-
-/* the default dpi resolution of a typical framebuffer. this is an average
- * between various prototypes being used during the development of the
- * Android system...
- */
-#define DEFAULT_FRAMEBUFFER_DPI 165
-
-
-/* initialize a framebuffer object and allocate its pixel buffer */
-/* this computes phys_width_mm and phys_height_mm assuming a 165 dpi screen */
-/* returns -1 in case of error, 0 otherwise */
-extern int
-qframebuffer_init( QFrameBuffer* qfbuff,
- int width,
- int height,
- int rotation,
- QFrameBufferFormat format );
-
-/* recompute phys_width_mm and phys_height_mm according to the emulated
- * screen DPI settings */
-extern void
-qframebuffer_set_dpi( QFrameBuffer* qfbuff,
- int x_dpi,
- int y_dpi );
-
-/* alternative to qframebuffer_set_dpi where one can set the physical
- * dimensions directly in millimeters. for the record 1 inch = 25.4 mm */
-extern void
-qframebuffer_set_mm( QFrameBuffer* qfbuff,
- int width_mm,
- int height_mm );
-
-/* the Client::Update method is called to instruct a client that a given
- * rectangle of the framebuffer pixels was updated and needs to be
- * redrawn.
- */
-typedef void (*QFrameBufferUpdateFunc)( void* opaque, int x, int y,
- int w, int h );
-
-/* the Client::Rotate method is called to instruct the client that a
- * framebuffer's internal rotation has changed. This is the rotation
- * that must be applied before displaying the pixels.
- *
- * Note that it is assumed that all framebuffer pixels have changed too
- * so the client should call its Update method as well.
- */
-typedef void (*QFrameBufferRotateFunc)( void* opaque, int rotation );
-
-/* the Client::Done func tells a client that a framebuffer object was freed.
- * no more reference to its pixels should be done.
- */
-typedef void (*QFrameBufferDoneFunc) ( void* opaque );
-
-/* add one client to a given framebuffer.
- * the current implementation only allows one client per frame-buffer,
- * but we could allow more for various reasons (e.g. displaying the
- * framebuffer + dispatching it through VNC at the same time)
- */
-extern void
-qframebuffer_add_client( QFrameBuffer* qfbuff,
- void* fb_opaque,
- QFrameBufferUpdateFunc fb_update,
- QFrameBufferRotateFunc fb_rotate,
- QFrameBufferDoneFunc fb_done );
-
-/* Producer::CheckUpdate is called to let the producer check the
- * VRAM state (e.g. VRAM dirty pages) to see if anything changed since the
- * last call to the method. When true, the method should call either
- * qframebuffer_update() or qframebuffer_rotate() with the appropriate values.
- */
-typedef void (*QFrameBufferCheckUpdateFunc)( void* opaque );
-
-/* Producer::Invalidate tells the producer that the next call to
- * CheckUpdate should act as if the whole content of VRAM had changed.
- * this is normally done to force client initialization/refreshes.
- */
-typedef void (*QFrameBufferInvalidateFunc) ( void* opaque );
-
-/* the Producer::Detach method is used to tell the producer that the
- * underlying QFrameBuffer object is about to be de-allocated.
- */
-typedef void (*QFrameBufferDetachFunc) ( void* opaque );
-
-/* set the producer of a given framebuffer */
-extern void
-qframebuffer_set_producer( QFrameBuffer* qfbuff,
- void* opaque,
- QFrameBufferCheckUpdateFunc fb_check,
- QFrameBufferInvalidateFunc fb_invalidate,
- QFrameBufferDetachFunc fb_detach );
-
-/* tell a client that a rectangle region has been updated in the framebuffer
- * pixel buffer this is typically called from a Producer::CheckUpdate method
- */
-extern void
-qframebuffer_update( QFrameBuffer* qfbuff, int x, int y, int w, int h );
-
-/* rotate the framebuffer (may swap width/height), and tell all clients.
- * Should be called from a Producer::CheckUpdate method
- */
-extern void
-qframebuffer_rotate( QFrameBuffer* qfbuff, int rotation );
-
-/* finalize a framebuffer, release its pixel buffer. Should be called
- * from the framebuffer object's owner
- */
-extern void
-qframebuffer_done( QFrameBuffer* qfbuff );
-
-
-/* this is called repeatedly by the emulator. for each registered framebuffer,
- * call its producer's CheckUpdate method, if any.
- */
-extern void
-qframebuffer_check_updates( void );
-
-/* this is called by the emulator. for each registered framebuffer, call
- * its producer's Invalidate method, if any
- */
-extern void
-qframebuffer_invalidate_all( void );
-
-/*
- * to completely separate the implementation of clients, producers, and skins,
- * we use a simple global FIFO list of QFrameBuffer objects.
- *
- * qframebuffer_fifo_add() is typically called by the emulator initialization
- * depending on the emulated device's configuration
- *
- * qframebuffer_fifo_get() is typically called by a hardware framebuffer
- * emulation.
- */
-
-/* add a new constructed frame buffer object to our global list */
-extern void
-qframebuffer_fifo_add( QFrameBuffer* qfbuff );
-
-/* retrieve a frame buffer object from the global FIFO list */
-extern QFrameBuffer*
-qframebuffer_fifo_get( void );
-
-/* */
-
-#endif /* _QEMU_FRAMEBUFFER_H_ */
-
diff --git a/gdbstub.c b/gdbstub.c
deleted file mode 100644
index f36e504..0000000
--- a/gdbstub.c
+++ /dev/null
@@ -1,1593 +0,0 @@
-/*
- * gdb server stub
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef CONFIG_USER_ONLY
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "qemu.h"
-#else
-#include "qemu-common.h"
-#include "qemu-char.h"
-#include "sysemu.h"
-#include "cpu.h"
-#include "gdbstub.h"
-#endif
-
-#include "qemu_socket.h"
-#ifdef _WIN32
-/* XXX: these constants may be independent of the host ones even for Unix */
-#ifndef SIGTRAP
-#define SIGTRAP 5
-#endif
-#ifndef SIGINT
-#define SIGINT 2
-#endif
-#else
-#include <signal.h>
-#endif
-
-//#define DEBUG_GDB
-
-enum RSState {
- RS_IDLE,
- RS_GETLINE,
- RS_CHKSUM1,
- RS_CHKSUM2,
- RS_SYSCALL,
-};
-typedef struct GDBState {
- CPUState *env; /* current CPU */
- enum RSState state; /* parsing state */
- char line_buf[4096];
- int line_buf_index;
- int line_csum;
- uint8_t last_packet[4100];
- int last_packet_len;
- int signal;
-#ifdef CONFIG_USER_ONLY
- int fd;
- int running_state;
-#else
- CharDriverState *chr;
-#endif
-} GDBState;
-
-/* By default use no IRQs and no timers while single stepping so as to
- * make single stepping like an ICE HW step.
- */
-static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
-
-#ifdef CONFIG_USER_ONLY
-/* XXX: This is not thread safe. Do we care? */
-static int gdbserver_fd = -1;
-
-/* XXX: remove this hack. */
-static GDBState gdbserver_state;
-
-static int get_char(GDBState *s)
-{
- uint8_t ch;
- int ret;
-
- for(;;) {
- ret = socket_recv(s->fd, &ch, 1);
- if (ret < 0) {
- if (errno == ECONNRESET)
- s->fd = -1;
- if (errno != EINTR && errno != EAGAIN)
- return -1;
- } else if (ret == 0) {
- socket_close(s->fd);
- s->fd = -1;
- return -1;
- } else {
- break;
- }
- }
- return ch;
-}
-#endif
-
-/* GDB stub state for use by semihosting syscalls. */
-static GDBState *gdb_syscall_state;
-static gdb_syscall_complete_cb gdb_current_syscall_cb;
-
-enum {
- GDB_SYS_UNKNOWN,
- GDB_SYS_ENABLED,
- GDB_SYS_DISABLED,
-} gdb_syscall_mode;
-
-/* If gdb is connected when the first semihosting syscall occurs then use
- remote gdb syscalls. Otherwise use native file IO. */
-int use_gdb_syscalls(void)
-{
- if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
- gdb_syscall_mode = (gdb_syscall_state ? GDB_SYS_ENABLED
- : GDB_SYS_DISABLED);
- }
- return gdb_syscall_mode == GDB_SYS_ENABLED;
-}
-
-/* Resume execution. */
-static inline void gdb_continue(GDBState *s)
-{
-#ifdef CONFIG_USER_ONLY
- s->running_state = 1;
-#else
- vm_start();
-#endif
-}
-
-static void put_buffer(GDBState *s, const uint8_t *buf, int len)
-{
-#ifdef CONFIG_USER_ONLY
- int ret;
-
- while (len > 0) {
- ret = socket_send(s->fd, buf, len);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return;
- } else {
- buf += ret;
- len -= ret;
- }
- }
-#else
- qemu_chr_write(s->chr, buf, len);
-#endif
-}
-
-static inline int fromhex(int v)
-{
- if (v >= '0' && v <= '9')
- return v - '0';
- else if (v >= 'A' && v <= 'F')
- return v - 'A' + 10;
- else if (v >= 'a' && v <= 'f')
- return v - 'a' + 10;
- else
- return 0;
-}
-
-static inline int tohex(int v)
-{
- if (v < 10)
- return v + '0';
- else
- return v - 10 + 'a';
-}
-
-static void memtohex(char *buf, const uint8_t *mem, int len)
-{
- int i, c;
- char *q;
- q = buf;
- for(i = 0; i < len; i++) {
- c = mem[i];
- *q++ = tohex(c >> 4);
- *q++ = tohex(c & 0xf);
- }
- *q = '\0';
-}
-
-static void hextomem(uint8_t *mem, const char *buf, int len)
-{
- int i;
-
- for(i = 0; i < len; i++) {
- mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
- buf += 2;
- }
-}
-
-/* return -1 if error, 0 if OK */
-static int put_packet(GDBState *s, const char *buf)
-{
- int len, csum, i;
- uint8_t *p;
-
-#ifdef DEBUG_GDB
- printf("reply='%s'\n", buf);
-#endif
-
- for(;;) {
- p = s->last_packet;
- *(p++) = '$';
- len = strlen(buf);
- memcpy(p, buf, len);
- p += len;
- csum = 0;
- for(i = 0; i < len; i++) {
- csum += buf[i];
- }
- *(p++) = '#';
- *(p++) = tohex((csum >> 4) & 0xf);
- *(p++) = tohex((csum) & 0xf);
-
- s->last_packet_len = p - s->last_packet;
- put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
-
-#ifdef CONFIG_USER_ONLY
- i = get_char(s);
- if (i < 0)
- return -1;
- if (i == '+')
- break;
-#else
- break;
-#endif
- }
- return 0;
-}
-
-#if defined(TARGET_I386)
-
-#ifdef TARGET_X86_64
-static const uint8_t gdb_x86_64_regs[16] = {
- R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP,
- 8, 9, 10, 11, 12, 13, 14, 15,
-};
-#endif
-
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i, fpus, nb_regs;
- uint8_t *p;
-
- p = mem_buf;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- nb_regs = 16;
- for(i = 0; i < 16; i++) {
- *(uint64_t *)p = tswap64(env->regs[gdb_x86_64_regs[i]]);
- p += 8;
- }
- *(uint64_t *)p = tswap64(env->eip);
- p += 8;
- } else
-#endif
- {
- nb_regs = 8;
- for(i = 0; i < 8; i++) {
- *(uint32_t *)p = tswap32(env->regs[i]);
- p += 4;
- }
- *(uint32_t *)p = tswap32(env->eip);
- p += 4;
- }
-
- *(uint32_t *)p = tswap32(env->eflags);
- p += 4;
- *(uint32_t *)p = tswap32(env->segs[R_CS].selector);
- p += 4;
- *(uint32_t *)p = tswap32(env->segs[R_SS].selector);
- p += 4;
- *(uint32_t *)p = tswap32(env->segs[R_DS].selector);
- p += 4;
- *(uint32_t *)p = tswap32(env->segs[R_ES].selector);
- p += 4;
- *(uint32_t *)p = tswap32(env->segs[R_FS].selector);
- p += 4;
- *(uint32_t *)p = tswap32(env->segs[R_GS].selector);
- p += 4;
- for(i = 0; i < 8; i++) {
- /* XXX: convert floats */
-#ifdef USE_X86LDOUBLE
- memcpy(p, &env->fpregs[i], 10);
-#else
- memset(p, 0, 10);
-#endif
- p += 10;
- }
- *(uint32_t *)p = tswap32(env->fpuc); /* fctrl */
- p += 4;
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- *(uint32_t *)p = tswap32(fpus); /* fstat */
- p += 4;
- *(uint32_t *)p = 0; /* ftag */
- p += 4;
- *(uint32_t *)p = 0; /* fiseg */
- p += 4;
- *(uint32_t *)p = 0; /* fioff */
- p += 4;
- *(uint32_t *)p = 0; /* foseg */
- p += 4;
- *(uint32_t *)p = 0; /* fooff */
- p += 4;
- *(uint32_t *)p = 0; /* fop */
- p += 4;
- for(i = 0; i < nb_regs; i++) {
- *(uint64_t *)p = tswap64(env->xmm_regs[i].XMM_Q(0));
- p += 8;
- *(uint64_t *)p = tswap64(env->xmm_regs[i].XMM_Q(1));
- p += 8;
- }
- *(uint32_t *)p = tswap32(env->mxcsr);
- p += 4;
- return p - mem_buf;
-}
-
-static inline void cpu_gdb_load_seg(CPUState *env, const uint8_t **pp,
- int sreg)
-{
- const uint8_t *p;
- uint32_t sel;
- p = *pp;
- sel = tswap32(*(uint32_t *)p);
- p += 4;
- if (sel != env->segs[sreg].selector) {
-#if defined(CONFIG_USER_ONLY)
- cpu_x86_load_seg(env, sreg, sel);
-#else
- /* XXX: do it with a debug function which does not raise an
- exception */
-#endif
- }
- *pp = p;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- const uint8_t *p = mem_buf;
- int i, nb_regs;
- uint16_t fpus;
-
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- nb_regs = 16;
- for(i = 0; i < 16; i++) {
- env->regs[gdb_x86_64_regs[i]] = tswap64(*(uint64_t *)p);
- p += 8;
- }
- env->eip = tswap64(*(uint64_t *)p);
- p += 8;
- } else
-#endif
- {
- nb_regs = 8;
- for(i = 0; i < 8; i++) {
- env->regs[i] = tswap32(*(uint32_t *)p);
- p += 4;
- }
- env->eip = tswap32(*(uint32_t *)p);
- p += 4;
- }
- env->eflags = tswap32(*(uint32_t *)p);
- p += 4;
- cpu_gdb_load_seg(env, &p, R_CS);
- cpu_gdb_load_seg(env, &p, R_SS);
- cpu_gdb_load_seg(env, &p, R_DS);
- cpu_gdb_load_seg(env, &p, R_ES);
- cpu_gdb_load_seg(env, &p, R_FS);
- cpu_gdb_load_seg(env, &p, R_GS);
-
- /* FPU state */
- for(i = 0; i < 8; i++) {
- /* XXX: convert floats */
-#ifdef USE_X86LDOUBLE
- memcpy(&env->fpregs[i], p, 10);
-#endif
- p += 10;
- }
- env->fpuc = tswap32(*(uint32_t *)p); /* fctrl */
- p += 4;
- fpus = tswap32(*(uint32_t *)p);
- p += 4;
- env->fpstt = (fpus >> 11) & 7;
- env->fpus = fpus & ~0x3800;
- p += 4 * 6;
-
- if (size >= ((p - mem_buf) + 16 * nb_regs + 4)) {
- /* SSE state */
- for(i = 0; i < nb_regs; i++) {
- env->xmm_regs[i].XMM_Q(0) = tswap64(*(uint64_t *)p);
- p += 8;
- env->xmm_regs[i].XMM_Q(1) = tswap64(*(uint64_t *)p);
- p += 8;
- }
- env->mxcsr = tswap32(*(uint32_t *)p);
- p += 4;
- }
-}
-
-#elif defined (TARGET_PPC)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint32_t *registers = (uint32_t *)mem_buf, tmp;
- int i;
-
- /* fill in gprs */
- for(i = 0; i < 32; i++) {
- registers[i] = tswapl(env->gpr[i]);
- }
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
- registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
- }
- /* nip, msr, ccr, lnk, ctr, xer, mq */
- registers[96] = tswapl(env->nip);
- registers[97] = tswapl(env->msr);
- tmp = 0;
- for (i = 0; i < 8; i++)
- tmp |= env->crf[i] << (32 - ((i + 1) * 4));
- registers[98] = tswapl(tmp);
- registers[99] = tswapl(env->lr);
- registers[100] = tswapl(env->ctr);
- registers[101] = tswapl(ppc_load_xer(env));
- registers[102] = 0;
-
- return 103 * 4;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint32_t *registers = (uint32_t *)mem_buf;
- int i;
-
- /* fill in gprs */
- for (i = 0; i < 32; i++) {
- env->gpr[i] = tswapl(registers[i]);
- }
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
- *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
- }
- /* nip, msr, ccr, lnk, ctr, xer, mq */
- env->nip = tswapl(registers[96]);
- ppc_store_msr(env, tswapl(registers[97]));
- registers[98] = tswapl(registers[98]);
- for (i = 0; i < 8; i++)
- env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
- env->lr = tswapl(registers[99]);
- env->ctr = tswapl(registers[100]);
- ppc_store_xer(env, tswapl(registers[101]));
-}
-#elif defined (TARGET_SPARC)
-#ifdef TARGET_ABI32
-#define tswap_abi(val) tswap32(val &0xffffffff)
-#else
-#define tswap_abi(val) tswapl(val)
-#endif
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
-#ifdef TARGET_ABI32
- abi_ulong *registers = (abi_ulong *)mem_buf;
-#else
- target_ulong *registers = (target_ulong *)mem_buf;
-#endif
- int i;
-
- /* fill in g0..g7 */
- for(i = 0; i < 8; i++) {
- registers[i] = tswap_abi(env->gregs[i]);
- }
- /* fill in register window */
- for(i = 0; i < 24; i++) {
- registers[i + 8] = tswap_abi(env->regwptr[i]);
- }
-#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- registers[i + 32] = tswap_abi(*((uint32_t *)&env->fpr[i]));
- }
- /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
- registers[64] = tswap_abi(env->y);
- {
- uint32_t tmp;
-
- tmp = GET_PSR(env);
- registers[65] = tswap32(tmp);
- }
- registers[66] = tswap_abi(env->wim);
- registers[67] = tswap_abi(env->tbr);
- registers[68] = tswap_abi(env->pc);
- registers[69] = tswap_abi(env->npc);
- registers[70] = tswap_abi(env->fsr);
- registers[71] = 0; /* csr */
- registers[72] = 0;
- return 73 * sizeof(uint32_t);
-#else
- /* fill in fprs */
- for (i = 0; i < 64; i += 2) {
- uint64_t tmp;
-
- tmp = ((uint64_t)*(uint32_t *)&env->fpr[i]) << 32;
- tmp |= *(uint32_t *)&env->fpr[i + 1];
- registers[i / 2 + 32] = tswap64(tmp);
- }
- registers[64] = tswapl(env->pc);
- registers[65] = tswapl(env->npc);
- registers[66] = tswapl(((uint64_t)GET_CCR(env) << 32) |
- ((env->asi & 0xff) << 24) |
- ((env->pstate & 0xfff) << 8) |
- GET_CWP64(env));
- registers[67] = tswapl(env->fsr);
- registers[68] = tswapl(env->fprs);
- registers[69] = tswapl(env->y);
- return 70 * sizeof(target_ulong);
-#endif
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
-#ifdef TARGET_ABI32
- abi_ulong *registers = (abi_ulong *)mem_buf;
-#else
- target_ulong *registers = (target_ulong *)mem_buf;
-#endif
- int i;
-
- /* fill in g0..g7 */
- for(i = 0; i < 7; i++) {
- env->gregs[i] = tswap_abi(registers[i]);
- }
- /* fill in register window */
- for(i = 0; i < 24; i++) {
- env->regwptr[i] = tswap_abi(registers[i + 8]);
- }
-#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
- /* fill in fprs */
- for (i = 0; i < 32; i++) {
- *((uint32_t *)&env->fpr[i]) = tswap_abi(registers[i + 32]);
- }
- /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
- env->y = tswap_abi(registers[64]);
- PUT_PSR(env, tswap_abi(registers[65]));
- env->wim = tswap_abi(registers[66]);
- env->tbr = tswap_abi(registers[67]);
- env->pc = tswap_abi(registers[68]);
- env->npc = tswap_abi(registers[69]);
- env->fsr = tswap_abi(registers[70]);
-#else
- for (i = 0; i < 64; i += 2) {
- uint64_t tmp;
-
- tmp = tswap64(registers[i / 2 + 32]);
- *((uint32_t *)&env->fpr[i]) = tmp >> 32;
- *((uint32_t *)&env->fpr[i + 1]) = tmp & 0xffffffff;
- }
- env->pc = tswapl(registers[64]);
- env->npc = tswapl(registers[65]);
- {
- uint64_t tmp = tswapl(registers[66]);
-
- PUT_CCR(env, tmp >> 32);
- env->asi = (tmp >> 24) & 0xff;
- env->pstate = (tmp >> 8) & 0xfff;
- PUT_CWP64(env, tmp & 0xff);
- }
- env->fsr = tswapl(registers[67]);
- env->fprs = tswapl(registers[68]);
- env->y = tswapl(registers[69]);
-#endif
-}
-#undef tswap_abi
-#elif defined (TARGET_ARM)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- /* 16 core integer registers (4 bytes each). */
- for (i = 0; i < 16; i++)
- {
- *(uint32_t *)ptr = tswapl(env->regs[i]);
- ptr += 4;
- }
- /* 8 FPA registers (12 bytes each), FPS (4 bytes).
- Not yet implemented. */
- memset (ptr, 0, 8 * 12 + 4);
- ptr += 8 * 12 + 4;
- /* CPSR (4 bytes). */
- *(uint32_t *)ptr = tswapl (cpsr_read(env));
- ptr += 4;
-
- return ptr - mem_buf;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- /* Core integer registers. */
- for (i = 0; i < 16; i++)
- {
- env->regs[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
- /* Ignore FPA regs and scr. */
- ptr += 8 * 12 + 4;
- cpsr_write (env, tswapl(*(uint32_t *)ptr), 0xffffffff);
-}
-#elif defined (TARGET_M68K)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i;
- uint8_t *ptr;
- CPU_DoubleU u;
-
- ptr = mem_buf;
- /* D0-D7 */
- for (i = 0; i < 8; i++) {
- *(uint32_t *)ptr = tswapl(env->dregs[i]);
- ptr += 4;
- }
- /* A0-A7 */
- for (i = 0; i < 8; i++) {
- *(uint32_t *)ptr = tswapl(env->aregs[i]);
- ptr += 4;
- }
- *(uint32_t *)ptr = tswapl(env->sr);
- ptr += 4;
- *(uint32_t *)ptr = tswapl(env->pc);
- ptr += 4;
- /* F0-F7. The 68881/68040 have 12-bit extended precision registers.
- ColdFire has 8-bit double precision registers. */
- for (i = 0; i < 8; i++) {
- u.d = env->fregs[i];
- *(uint32_t *)ptr = tswap32(u.l.upper);
- *(uint32_t *)ptr = tswap32(u.l.lower);
- }
- /* FP control regs (not implemented). */
- memset (ptr, 0, 3 * 4);
- ptr += 3 * 4;
-
- return ptr - mem_buf;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- int i;
- uint8_t *ptr;
- CPU_DoubleU u;
-
- ptr = mem_buf;
- /* D0-D7 */
- for (i = 0; i < 8; i++) {
- env->dregs[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
- /* A0-A7 */
- for (i = 0; i < 8; i++) {
- env->aregs[i] = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
- env->sr = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- env->pc = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- /* F0-F7. The 68881/68040 have 12-bit extended precision registers.
- ColdFire has 8-bit double precision registers. */
- for (i = 0; i < 8; i++) {
- u.l.upper = tswap32(*(uint32_t *)ptr);
- u.l.lower = tswap32(*(uint32_t *)ptr);
- env->fregs[i] = u.d;
- }
- /* FP control regs (not implemented). */
- ptr += 3 * 4;
-}
-#elif defined (TARGET_MIPS)
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- for (i = 0; i < 32; i++)
- {
- *(target_ulong *)ptr = tswapl(env->active_tc.gpr[i]);
- ptr += sizeof(target_ulong);
- }
-
- *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Status);
- ptr += sizeof(target_ulong);
-
- *(target_ulong *)ptr = tswapl(env->active_tc.LO[0]);
- ptr += sizeof(target_ulong);
-
- *(target_ulong *)ptr = tswapl(env->active_tc.HI[0]);
- ptr += sizeof(target_ulong);
-
- *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
- ptr += sizeof(target_ulong);
-
- *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Cause);
- ptr += sizeof(target_ulong);
-
- *(target_ulong *)ptr = tswapl(env->active_tc.PC);
- ptr += sizeof(target_ulong);
-
- if (env->CP0_Config1 & (1 << CP0C1_FP))
- {
- for (i = 0; i < 32; i++)
- {
- if (env->CP0_Status & (1 << CP0St_FR))
- *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].d);
- else
- *(target_ulong *)ptr = tswap32(env->fpu->fpr[i].w[FP_ENDIAN_IDX]);
- ptr += sizeof(target_ulong);
- }
-
- *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr31);
- ptr += sizeof(target_ulong);
-
- *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr0);
- ptr += sizeof(target_ulong);
- }
-
- /* "fp", pseudo frame pointer. Not yet implemented in gdb. */
- *(target_ulong *)ptr = 0;
- ptr += sizeof(target_ulong);
-
- /* Registers for embedded use, we just pad them. */
- for (i = 0; i < 16; i++)
- {
- *(target_ulong *)ptr = 0;
- ptr += sizeof(target_ulong);
- }
-
- /* Processor ID. */
- *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_PRid);
- ptr += sizeof(target_ulong);
-
- return ptr - mem_buf;
-}
-
-/* convert MIPS rounding mode in FCR31 to IEEE library */
-static unsigned int ieee_rm[] =
- {
- float_round_nearest_even,
- float_round_to_zero,
- float_round_up,
- float_round_down
- };
-#define RESTORE_ROUNDING_MODE \
- set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- int i;
- uint8_t *ptr;
-
- ptr = mem_buf;
- for (i = 0; i < 32; i++)
- {
- env->active_tc.gpr[i] = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
- }
-
- env->CP0_Status = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
-
- env->active_tc.LO[0] = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
-
- env->active_tc.HI[0] = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
-
- env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
-
- env->CP0_Cause = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
-
- env->active_tc.PC = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
-
- if (env->CP0_Config1 & (1 << CP0C1_FP))
- {
- for (i = 0; i < 32; i++)
- {
- if (env->CP0_Status & (1 << CP0St_FR))
- env->fpu->fpr[i].d = tswapl(*(target_ulong *)ptr);
- else
- env->fpu->fpr[i].w[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
- }
-
- env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0xFF83FFFF;
- ptr += sizeof(target_ulong);
-
- /* The remaining registers are assumed to be read-only. */
-
- /* set rounding mode */
- RESTORE_ROUNDING_MODE;
-
-#ifndef CONFIG_SOFTFLOAT
- /* no floating point exception for native float */
- SET_FP_ENABLE(env->fcr31, 0);
-#endif
- }
-}
-#elif defined (TARGET_SH4)
-
-/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
-
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint32_t *ptr = (uint32_t *)mem_buf;
- int i;
-
-#define SAVE(x) *ptr++=tswapl(x)
- if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
- for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
- } else {
- for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
- }
- for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
- SAVE (env->pc);
- SAVE (env->pr);
- SAVE (env->gbr);
- SAVE (env->vbr);
- SAVE (env->mach);
- SAVE (env->macl);
- SAVE (env->sr);
- SAVE (env->fpul);
- SAVE (env->fpscr);
- for (i = 0; i < 16; i++)
- SAVE(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
- SAVE (env->ssr);
- SAVE (env->spc);
- for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
- for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
- return ((uint8_t *)ptr - mem_buf);
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint32_t *ptr = (uint32_t *)mem_buf;
- int i;
-
-#define LOAD(x) (x)=*ptr++;
- if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
- for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
- } else {
- for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
- }
- for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
- LOAD (env->pc);
- LOAD (env->pr);
- LOAD (env->gbr);
- LOAD (env->vbr);
- LOAD (env->mach);
- LOAD (env->macl);
- LOAD (env->sr);
- LOAD (env->fpul);
- LOAD (env->fpscr);
- for (i = 0; i < 16; i++)
- LOAD(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
- LOAD (env->ssr);
- LOAD (env->spc);
- for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
- for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
-}
-#elif defined (TARGET_CRIS)
-
-static int cris_save_32 (unsigned char *d, uint32_t value)
-{
- *d++ = (value);
- *d++ = (value >>= 8);
- *d++ = (value >>= 8);
- *d++ = (value >>= 8);
- return 4;
-}
-static int cris_save_16 (unsigned char *d, uint32_t value)
-{
- *d++ = (value);
- *d++ = (value >>= 8);
- return 2;
-}
-static int cris_save_8 (unsigned char *d, uint32_t value)
-{
- *d++ = (value);
- return 1;
-}
-
-/* FIXME: this will bug on archs not supporting unaligned word accesses. */
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint8_t *ptr = mem_buf;
- uint8_t srs;
- int i;
-
- for (i = 0; i < 16; i++)
- ptr += cris_save_32 (ptr, env->regs[i]);
-
- srs = env->pregs[PR_SRS];
-
- ptr += cris_save_8 (ptr, env->pregs[0]);
- ptr += cris_save_8 (ptr, env->pregs[1]);
- ptr += cris_save_32 (ptr, env->pregs[2]);
- ptr += cris_save_8 (ptr, srs);
- ptr += cris_save_16 (ptr, env->pregs[4]);
-
- for (i = 5; i < 16; i++)
- ptr += cris_save_32 (ptr, env->pregs[i]);
-
- ptr += cris_save_32 (ptr, env->pc);
-
- for (i = 0; i < 16; i++)
- ptr += cris_save_32 (ptr, env->sregs[srs][i]);
-
- return ((uint8_t *)ptr - mem_buf);
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint32_t *ptr = (uint32_t *)mem_buf;
- int i;
-
-#define LOAD(x) (x)=*ptr++;
- for (i = 0; i < 16; i++) LOAD(env->regs[i]);
- LOAD (env->pc);
-}
-#else
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- return 0;
-}
-
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
-}
-
-#endif
-
-static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
-{
- const char *p;
- int ch, reg_size, type;
- char buf[4096];
- uint8_t mem_buf[4096];
- uint32_t *registers;
- target_ulong addr, len;
-
-#ifdef DEBUG_GDB
- printf("command='%s'\n", line_buf);
-#endif
- p = line_buf;
- ch = *p++;
- switch(ch) {
- case '?':
- /* TODO: Make this return the correct value for user-mode. */
- snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
- put_packet(s, buf);
- /* Remove all the breakpoints when this query is issued,
- * because gdb is doing and initial connect and the state
- * should be cleaned up.
- */
- cpu_breakpoint_remove_all(env);
- cpu_watchpoint_remove_all(env);
- break;
- case 'c':
- if (*p != '\0') {
- addr = strtoull(p, (char **)&p, 16);
-#if defined(TARGET_I386)
- env->eip = addr;
-#elif defined (TARGET_PPC)
- env->nip = addr;
-#elif defined (TARGET_SPARC)
- env->pc = addr;
- env->npc = addr + 4;
-#elif defined (TARGET_ARM)
- env->regs[15] = addr;
-#elif defined (TARGET_SH4)
- env->pc = addr;
-#elif defined (TARGET_MIPS)
- env->active_tc.PC = addr;
-#elif defined (TARGET_CRIS)
- env->pc = addr;
-#endif
- }
- gdb_continue(s);
- return RS_IDLE;
- case 'C':
- s->signal = strtoul(p, (char **)&p, 16);
- gdb_continue(s);
- return RS_IDLE;
- case 'k':
- /* Kill the target */
- fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
- exit(0);
- case 'D':
- /* Detach packet */
- cpu_breakpoint_remove_all(env);
- cpu_watchpoint_remove_all(env);
- gdb_continue(s);
- put_packet(s, "OK");
- break;
- case 's':
- if (*p != '\0') {
- addr = strtoull(p, (char **)&p, 16);
-#if defined(TARGET_I386)
- env->eip = addr;
-#elif defined (TARGET_PPC)
- env->nip = addr;
-#elif defined (TARGET_SPARC)
- env->pc = addr;
- env->npc = addr + 4;
-#elif defined (TARGET_ARM)
- env->regs[15] = addr;
-#elif defined (TARGET_SH4)
- env->pc = addr;
-#elif defined (TARGET_MIPS)
- env->active_tc.PC = addr;
-#elif defined (TARGET_CRIS)
- env->pc = addr;
-#endif
- }
- cpu_single_step(env, sstep_flags);
- gdb_continue(s);
- return RS_IDLE;
- case 'F':
- {
- target_ulong ret;
- target_ulong err;
-
- ret = strtoull(p, (char **)&p, 16);
- if (*p == ',') {
- p++;
- err = strtoull(p, (char **)&p, 16);
- } else {
- err = 0;
- }
- if (*p == ',')
- p++;
- type = *p;
- if (gdb_current_syscall_cb)
- gdb_current_syscall_cb(s->env, ret, err);
- if (type == 'C') {
- put_packet(s, "T02");
- } else {
- gdb_continue(s);
- }
- }
- break;
- case 'g':
- reg_size = cpu_gdb_read_registers(env, mem_buf);
- memtohex(buf, mem_buf, reg_size);
- put_packet(s, buf);
- break;
- case 'G':
- registers = (void *)mem_buf;
- len = strlen(p) / 2;
- hextomem((uint8_t *)registers, p, len);
- cpu_gdb_write_registers(env, mem_buf, len);
- put_packet(s, "OK");
- break;
- case 'm':
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, NULL, 16);
- if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {
- put_packet (s, "E14");
- } else {
- memtohex(buf, mem_buf, len);
- put_packet(s, buf);
- }
- break;
- case 'M':
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, (char **)&p, 16);
- if (*p == ':')
- p++;
- hextomem(mem_buf, p, len);
- if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
- put_packet(s, "E14");
- else
- put_packet(s, "OK");
- break;
- case 'Z':
- type = strtoul(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, (char **)&p, 16);
- switch (type) {
- case 0:
- case 1:
- if (cpu_breakpoint_insert(env, addr) < 0)
- goto breakpoint_error;
- put_packet(s, "OK");
- break;
-#ifndef CONFIG_USER_ONLY
- case 2:
- type = PAGE_WRITE;
- goto insert_watchpoint;
- case 3:
- type = PAGE_READ;
- goto insert_watchpoint;
- case 4:
- type = PAGE_READ | PAGE_WRITE;
- insert_watchpoint:
- if (cpu_watchpoint_insert(env, addr, type) < 0)
- goto breakpoint_error;
- put_packet(s, "OK");
- break;
-#endif
- default:
- put_packet(s, "");
- break;
- }
- break;
- breakpoint_error:
- put_packet(s, "E22");
- break;
-
- case 'z':
- type = strtoul(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- addr = strtoull(p, (char **)&p, 16);
- if (*p == ',')
- p++;
- len = strtoull(p, (char **)&p, 16);
- if (type == 0 || type == 1) {
- cpu_breakpoint_remove(env, addr);
- put_packet(s, "OK");
-#ifndef CONFIG_USER_ONLY
- } else if (type >= 2 || type <= 4) {
- cpu_watchpoint_remove(env, addr);
- put_packet(s, "OK");
-#endif
- } else {
- put_packet(s, "");
- }
- break;
- case 'q':
- case 'Q':
- /* parse any 'q' packets here */
- if (!strcmp(p,"qemu.sstepbits")) {
- /* Query Breakpoint bit definitions */
- snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
- SSTEP_ENABLE,
- SSTEP_NOIRQ,
- SSTEP_NOTIMER);
- put_packet(s, buf);
- break;
- } else if (strncmp(p,"qemu.sstep",10) == 0) {
- /* Display or change the sstep_flags */
- p += 10;
- if (*p != '=') {
- /* Display current setting */
- snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
- put_packet(s, buf);
- break;
- }
- p++;
- type = strtoul(p, (char **)&p, 16);
- sstep_flags = type;
- put_packet(s, "OK");
- break;
- }
-#ifdef CONFIG_LINUX_USER
- else if (strncmp(p, "Offsets", 7) == 0) {
- TaskState *ts = env->opaque;
-
- snprintf(buf, sizeof(buf),
- "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
- ";Bss=" TARGET_ABI_FMT_lx,
- ts->info->code_offset,
- ts->info->data_offset,
- ts->info->data_offset);
- put_packet(s, buf);
- break;
- }
-#endif
- /* Fall through. */
- default:
- /* put empty packet */
- buf[0] = '\0';
- put_packet(s, buf);
- break;
- }
- return RS_IDLE;
-}
-
-extern void tb_flush(CPUState *env);
-
-#ifndef CONFIG_USER_ONLY
-static void gdb_vm_stopped(void *opaque, int reason)
-{
- GDBState *s = opaque;
- char buf[256];
- int ret;
-
- if (s->state == RS_SYSCALL)
- return;
-
- /* disable single step if it was enable */
- cpu_single_step(s->env, 0);
-
- if (reason == EXCP_DEBUG) {
- if (s->env->watchpoint_hit) {
- snprintf(buf, sizeof(buf), "T%02xwatch:" TARGET_FMT_lx ";",
- SIGTRAP,
- s->env->watchpoint[s->env->watchpoint_hit - 1].vaddr);
- put_packet(s, buf);
- s->env->watchpoint_hit = 0;
- return;
- }
- tb_flush(s->env);
- ret = SIGTRAP;
- } else if (reason == EXCP_INTERRUPT) {
- ret = SIGINT;
- } else {
- ret = 0;
- }
- snprintf(buf, sizeof(buf), "S%02x", ret);
- put_packet(s, buf);
-}
-#endif
-
-/* Send a gdb syscall request.
- This accepts limited printf-style format specifiers, specifically:
- %x - target_ulong argument printed in hex.
- %lx - 64-bit argument printed in hex.
- %s - string pointer (target_ulong) and length (int) pair. */
-void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
-{
- va_list va;
- char buf[256];
- char *p;
- target_ulong addr;
- uint64_t i64;
- GDBState *s;
-
- s = gdb_syscall_state;
- if (!s)
- return;
- gdb_current_syscall_cb = cb;
- s->state = RS_SYSCALL;
-#ifndef CONFIG_USER_ONLY
- vm_stop(EXCP_DEBUG);
-#endif
- s->state = RS_IDLE;
- va_start(va, fmt);
- p = buf;
- *(p++) = 'F';
- while (*fmt) {
- if (*fmt == '%') {
- fmt++;
- switch (*fmt++) {
- case 'x':
- addr = va_arg(va, target_ulong);
- p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx, addr);
- break;
- case 'l':
- if (*(fmt++) != 'x')
- goto bad_format;
- i64 = va_arg(va, uint64_t);
- p += snprintf(p, &buf[sizeof(buf)] - p, "%" PRIx64, i64);
- break;
- case 's':
- addr = va_arg(va, target_ulong);
- p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx "/%x",
- addr, va_arg(va, int));
- break;
- default:
- bad_format:
- fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",
- fmt - 1);
- break;
- }
- } else {
- *(p++) = *(fmt++);
- }
- }
- *p = 0;
- va_end(va);
- put_packet(s, buf);
-#ifdef CONFIG_USER_ONLY
- gdb_handlesig(s->env, 0);
-#else
- cpu_interrupt(s->env, CPU_INTERRUPT_EXIT);
-#endif
-}
-
-static void gdb_read_byte(GDBState *s, int ch)
-{
- CPUState *env = s->env;
- int i, csum;
- uint8_t reply;
-
-#ifndef CONFIG_USER_ONLY
- if (s->last_packet_len) {
- /* Waiting for a response to the last packet. If we see the start
- of a new command then abandon the previous response. */
- if (ch == '-') {
-#ifdef DEBUG_GDB
- printf("Got NACK, retransmitting\n");
-#endif
- put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
- }
-#ifdef DEBUG_GDB
- else if (ch == '+')
- printf("Got ACK\n");
- else
- printf("Got '%c' when expecting ACK/NACK\n", ch);
-#endif
- if (ch == '+' || ch == '$')
- s->last_packet_len = 0;
- if (ch != '$')
- return;
- }
- if (vm_running) {
- /* when the CPU is running, we cannot do anything except stop
- it when receiving a char */
- vm_stop(EXCP_INTERRUPT);
- } else
-#endif
- {
- switch(s->state) {
- case RS_IDLE:
- if (ch == '$') {
- s->line_buf_index = 0;
- s->state = RS_GETLINE;
- }
- break;
- case RS_GETLINE:
- if (ch == '#') {
- s->state = RS_CHKSUM1;
- } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
- s->state = RS_IDLE;
- } else {
- s->line_buf[s->line_buf_index++] = ch;
- }
- break;
- case RS_CHKSUM1:
- s->line_buf[s->line_buf_index] = '\0';
- s->line_csum = fromhex(ch) << 4;
- s->state = RS_CHKSUM2;
- break;
- case RS_CHKSUM2:
- s->line_csum |= fromhex(ch);
- csum = 0;
- for(i = 0; i < s->line_buf_index; i++) {
- csum += s->line_buf[i];
- }
- if (s->line_csum != (csum & 0xff)) {
- reply = '-';
- put_buffer(s, &reply, 1);
- s->state = RS_IDLE;
- } else {
- reply = '+';
- put_buffer(s, &reply, 1);
- s->state = gdb_handle_packet(s, env, s->line_buf);
- }
- break;
- default:
- abort();
- }
- }
-}
-
-#ifdef CONFIG_USER_ONLY
-int
-gdb_handlesig (CPUState *env, int sig)
-{
- GDBState *s;
- char buf[256];
- int n;
-
- s = &gdbserver_state;
- if (gdbserver_fd < 0 || s->fd < 0)
- return sig;
-
- /* disable single step if it was enabled */
- cpu_single_step(env, 0);
- tb_flush(env);
-
- if (sig != 0)
- {
- snprintf(buf, sizeof(buf), "S%02x", sig);
- put_packet(s, buf);
- }
- /* put_packet() might have detected that the peer terminated the
- connection. */
- if (s->fd < 0)
- return sig;
-
- sig = 0;
- s->state = RS_IDLE;
- s->running_state = 0;
- while (s->running_state == 0) {
- n = read (s->fd, buf, 256);
- if (n > 0)
- {
- int i;
-
- for (i = 0; i < n; i++)
- gdb_read_byte (s, buf[i]);
- }
- else if (n == 0 || errno != EAGAIN)
- {
- /* XXX: Connection closed. Should probably wait for annother
- connection before continuing. */
- return sig;
- }
- }
- sig = s->signal;
- s->signal = 0;
- return sig;
-}
-
-/* Tell the remote gdb that the process has exited. */
-void gdb_exit(CPUState *env, int code)
-{
- GDBState *s;
- char buf[4];
-
- s = &gdbserver_state;
- if (gdbserver_fd < 0 || s->fd < 0)
- return;
-
- snprintf(buf, sizeof(buf), "W%02x", code);
- put_packet(s, buf);
-}
-
-
-static void gdb_accept(void *opaque)
-{
- GDBState *s;
- int fd;
-
- for(;;) {
- fd = socket_accept(gdbserver_fd, NULL);
- if (fd < 0) {
- perror("accept");
- return;
- } else if (fd >= 0) {
- break;
- }
- }
-
- /* set short latency */
- socket_set_lowlatency(fd);
-
- s = &gdbserver_state;
- memset (s, 0, sizeof (GDBState));
- s->env = first_cpu; /* XXX: allow to change CPU */
- s->fd = fd;
-
- gdb_syscall_state = s;
-
- socket_set_nonblock(fd);
-}
-
-static int gdbserver_open(int port)
-{
- SockAddress sockaddr;
- int fd, val, ret;
-
- fd = socket_create_inet( SOCKET_STREAM );
- if (fd < 0) {
- perror("socket");
- return -1;
- }
-
- /* allow fast reuse */
- socket_set_xreuseaddr(fd);
-
- sock_address_init_inet( &sockaddr, port, SOCK_ADDRESS_INET_ANY );
- ret = socket_bind(fd, &sockaddr);
- if (ret < 0) {
- perror("bind");
- return -1;
- }
- ret = socket_listen(fd, 0);
- if (ret < 0) {
- perror("listen");
- socket_close(fd);
- return -1;
- }
- return fd;
-}
-
-int gdbserver_start(int port)
-{
- gdbserver_fd = gdbserver_open(port);
- if (gdbserver_fd < 0)
- return -1;
- /* accept connections */
- gdb_accept (NULL);
- return 0;
-}
-#else
-static int gdb_chr_can_receive(void *opaque)
-{
- return 1;
-}
-
-static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
-{
- GDBState *s = opaque;
- int i;
-
- for (i = 0; i < size; i++) {
- gdb_read_byte(s, buf[i]);
- }
-}
-
-static void gdb_chr_event(void *opaque, int event)
-{
- switch (event) {
- case CHR_EVENT_RESET:
- vm_stop(EXCP_INTERRUPT);
- gdb_syscall_state = opaque;
- break;
- default:
- break;
- }
-}
-
-int gdbserver_start(const char *port)
-{
- GDBState *s;
- char gdbstub_port_name[128];
- int port_num;
- char *p;
- CharDriverState *chr;
-
- if (!port || !*port)
- return -1;
-
- port_num = strtol(port, &p, 10);
- if (*p == 0) {
- /* A numeric value is interpreted as a port number. */
- snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
- "tcp::%d,nowait,nodelay,server", port_num);
- port = gdbstub_port_name;
- }
-
- chr = qemu_chr_open(port);
- if (!chr)
- return -1;
-
- s = qemu_mallocz(sizeof(GDBState));
- if (!s) {
- return -1;
- }
- s->env = first_cpu; /* XXX: allow to change CPU */
- s->chr = chr;
- qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
- gdb_chr_event, s);
- qemu_add_vm_stop_handler(gdb_vm_stopped, s);
- return 0;
-}
-#endif
diff --git a/gdbstub.h b/gdbstub.h
deleted file mode 100644
index ba65f93..0000000
--- a/gdbstub.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef GDBSTUB_H
-#define GDBSTUB_H
-
-#define DEFAULT_GDBSTUB_PORT "1234"
-
-typedef void (*gdb_syscall_complete_cb)(CPUState *env,
- target_ulong ret, target_ulong err);
-
-void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
-int use_gdb_syscalls(void);
-#ifdef CONFIG_USER_ONLY
-int gdb_handlesig (CPUState *, int);
-void gdb_exit(CPUState *, int);
-int gdbserver_start(int);
-#else
-int gdbserver_start(const char *port);
-#endif
-
-#endif
diff --git a/gen-charmap.py b/gen-charmap.py
deleted file mode 100644
index 3c86350..0000000
--- a/gen-charmap.py
+++ /dev/null
@@ -1,180 +0,0 @@
-#!/usr/bin/python
-#
-# a python script used to generate some C constant tables from a key charmap file
-#
-# usage:
-# progname file.kcm > charmap-tab.h
-#
-import sys, os, string, re
-
-header = """\
-#include "android_charmap.h"
-
-/* the following is automatically generated by the 'gen-charmap.py' script
- * do not touch. the generation command was:
- * gen-charmap.py\
-"""
-
-header2 = """
- */
-"""
-
-kmap_header = """\
-static const AKeyEntry _%(name)s_keys[] =
-{
- /* keycode base caps fn caps+fn number */
-"""
-
-
-kmap_footer = """\
-};
-
-static const AKeyCharmap _%(name)s_charmap =
-{
- _%(name)s_keys,
- %(count)d,
- "%(name)s"
-};
-"""
-
-
-re_mapname = re.compile( r".*/(\w+).kcm" )
-re_start = re.compile( r"(\w+)\s*(.*)" )
-re_char = re.compile( r"('.')\s*(.*)" )
-re_hex = re.compile( r"(0x\w+)\s*(.*)" )
-
-specials = { 'COMMA': 'Comma',
- 'PERIOD': 'Period',
- 'AT': 'At',
- 'LEFT_BRACKET': 'LeftBracket',
- 'RIGHT_BRACKET': 'RightBracket',
- 'SLASH': 'Slash',
- 'BACKSLASH': 'Backslash',
- 'GRAVE': 'Grave',
- 'MINUS': 'Minus',
- 'EQUALS': 'Equals',
- 'SEMICOLON': 'Semicolon',
- 'APOSTROPHE': 'Apostrophe',
- 'SPACE': 'Space',
- 'ENTER': 'Enter',
- 'TAB': 'Tab'
- }
-
-entries = []
-
-def match_char_or_hex(line):
- m = re_char.match(line)
- if not m:
- m = re_hex.match(line)
- return m
-
-def quote(s):
- if s == "'''":
- s = "'\\''"
- elif s == "'\\'":
- s = "'\\\\'"
- return s
-
-def process_line(line,result):
- m = re_start.match(line)
- if not m:
- print "bad bad line: " + line
- return -1
- keycode = m.group(1)
- line = m.group(2)
- m = match_char_or_hex(line)
- if not m:
- print "character expected in: " + line
- return -1
- base = quote(m.group(1))
- line = m.group(2)
- m = match_char_or_hex(line)
- if not m:
- print "character expected in: " + line
- return -1
- caps = quote(m.group(1))
- line = m.group(2)
- m = match_char_or_hex(line)
- if not m:
- print "character expected in: " + line
- return -1
- fn = quote(m.group(1))
- line = m.group(2)
- m = match_char_or_hex(line)
- if not m:
- print "character expected in: " + line
- return -1
- caps_fn = quote(m.group(1))
- line = m.group(2)
- m = match_char_or_hex(line)
- if not m:
- print "character expected in: " + line
- return -1
- number = quote(m.group(1))
-
- if specials.has_key(keycode):
- keycode = specials[keycode]
- keycode = "kKeyCode" + keycode
-
- result.append( (keycode,base,caps,fn,caps_fn,number) )
- return 0
-
-def process_file( file ):
- result = []
- fp = open(file,"rb")
- for line in fp.xreadlines():
- line = line.strip()
- if not line: # skip empty lines
- continue
- if line[0] == '#' or line[0] == '[': # skip
- continue
- if process_line(line,result) < 0:
- break
- fp.close()
- return result
-
-class KMap:
- def __init__(self,name,results):
- self.name = name
- self.results = results
-
- def dump(self):
- t = { 'name': self.name, 'count':len(self.results) }
- print kmap_header % t
- for item in self.results:
- print " { %-22s, %5s, %5s, %5s, %6s, %5s }," % item
- print kmap_footer % t
-
-kmaps = []
-
-if len(sys.argv) < 2:
- print "usage: progname charmap.kcm [charmap2.kcm ...] > charmap-tab.h"
-else:
- genline = ""
- for filepath in sys.argv[1:]:
- m = re_mapname.match(filepath)
- if not m:
- print "%s is not a keyboard charmap name" % filepath
- os.exit(1)
-
- mapname = m.group(1)
- genline = genline + " " + mapname + ".kcm"
-
- for filepath in sys.argv[1:]:
- m = re_mapname.match(filepath)
- mapname = m.group(1)
- result = process_file( filepath )
- kmap = KMap(mapname,result)
- kmaps.append(kmap)
-
- print header + genline + header2
- for kmap in kmaps:
- kmap.dump()
-
- print "const AKeyCharmap* android_charmaps[%d] = {" % len(kmaps),
- comma = ""
- for kmap in kmaps:
- print "%s&_%s_charmap" % (comma, kmap.name),
- comma = ", "
- print "};"
- print "const int android_charmap_count = %d;" % len(kmaps)
diff --git a/gen-icount.h b/gen-icount.h
deleted file mode 100644
index 61545f1..0000000
--- a/gen-icount.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Helpers for instruction counting code generation. */
-
-static TCGArg *icount_arg;
-static int icount_label;
-
-static inline void gen_icount_start(void)
-{
- TCGv count;
-
- if (!use_icount)
- return;
-
- icount_label = gen_new_label();
- /* FIXME: This generates lousy code. We can't use tcg_new_temp because
- count needs to live over the conditional branch. To workaround this
- we allow the target to supply a convenient register temporary. */
-#ifndef ICOUNT_TEMP
- count = tcg_temp_local_new(TCG_TYPE_I32);
-#else
- count = ICOUNT_TEMP;
-#endif
- tcg_gen_ld_i32(count, cpu_env, offsetof(CPUState, icount_decr.u32));
- /* This is a horrid hack to allow fixing up the value later. */
- icount_arg = gen_opparam_ptr + 1;
- tcg_gen_subi_i32(count, count, 0xdeadbeef);
-
- tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
- tcg_gen_st16_i32(count, cpu_env, offsetof(CPUState, icount_decr.u16.low));
-#ifndef ICOUNT_TEMP
- tcg_temp_free(count);
-#endif
-}
-
-static void gen_icount_end(TranslationBlock *tb, int num_insns)
-{
- if (use_icount) {
- *icount_arg = num_insns;
- gen_set_label(icount_label);
- tcg_gen_exit_tb((long)tb + 2);
- }
-}
-
-static void inline gen_io_start(void)
-{
- TCGv tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
- tcg_temp_free(tmp);
-}
-
-static inline void gen_io_end(void)
-{
- TCGv tmp = tcg_const_i32(0);
- tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io));
- tcg_temp_free(tmp);
-}
-
diff --git a/gen-skin.py b/gen-skin.py
deleted file mode 100755
index f87bde7..0000000
--- a/gen-skin.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/python
-#
-# a python script used to generate the "default-skin.h' header file
-# from a given skin directory
-#
-# usage:
-# progname skin-directory-path > default-skin.h
-#
-import sys, os, string, re
-
-header = """\
-/* automatically generated, do not touch */
-
-"""
-
-
-footer = """\
-
-static const FileEntry _file_entries[] =
-{
-"""
-
-footer2 = """\
- { NULL, NULL, 0 }
-};
-"""
-
-
-entries = []
-
-def process_files( basepath, files ):
- for file in files:
- fp = open(basepath + "/" + file, "rb")
- data = fp.read()
- data_len = len(data)
- data_add = 0
- data_name = "_data_" + string.replace(file,".","_")
-
- entries.append( (file, data_name, len(data)) )
- print "static const unsigned char %s[%d] = {" % (data_name, data_len + data_add)
- comma = " "
- do_line = 0
- do_comma = 0
- count = 0
- line = " "
- for b in data:
- d = ord(b)
-
- if do_comma:
- line = line + ","
- do_comma = 0
-
- if do_line:
- print line
- line = " "
- do_line = 0
-
- line = line + "%3d" % d
- do_comma = 1
- count += 1
- if count == 16:
- count = 0
- do_line = 1
-
- if len(line) > 0:
- print line
- print "};\n"
-
-if len(sys.argv) != 2:
- print "usage: progname skindirpath > default-skin.h"
-else:
- print header
- skindir = sys.argv[1]
- process_files( skindir, os.listdir(skindir) )
- print footer
- for e in entries:
- print " { \"%s\", %s, %d }," % (e[0], e[1], e[2])
- print footer2
diff --git a/host-defs.h b/host-defs.h
deleted file mode 100644
index 686416a..0000000
--- a/host-defs.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _HOST_DEFS_H
-#define _HOST_DEFS_H
-
-/* all host-specific definitions should go here */
-
-#include "config-host.h"
-#include <stdint.h>
-
-#if HOST_LONG_BITS == 32
-typedef int32_t host_long;
-typedef uint32_t host_ulong;
-#elif HOST_LONG_BITS == 64
-typedef int64_t host_long;
-typedef uint64_t host_ulong;
-#endif
-
-#endif /* _HOST_DEFS_H */
-
diff --git a/host-utils.c b/host-utils.c
deleted file mode 100644
index f92c339..0000000
--- a/host-utils.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Utility compute operations used by translated code.
- *
- * Copyright (c) 2003 Fabrice Bellard
- * Copyright (c) 2007 Aurelien Jarno
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "exec.h"
-#include "host-utils.h"
-
-//#define DEBUG_MULDIV
-
-/* Long integer helpers */
-#if !defined(__x86_64__)
-static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- *plow += a;
- /* carry test */
- if (*plow < a)
- (*phigh)++;
- *phigh += b;
-}
-
-static void neg128 (uint64_t *plow, uint64_t *phigh)
-{
- *plow = ~*plow;
- *phigh = ~*phigh;
- add128(plow, phigh, 1, 0);
-}
-
-static void mul64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- uint32_t a0, a1, b0, b1;
- uint64_t v;
-
- a0 = a;
- a1 = a >> 32;
-
- b0 = b;
- b1 = b >> 32;
-
- v = (uint64_t)a0 * (uint64_t)b0;
- *plow = v;
- *phigh = 0;
-
- v = (uint64_t)a0 * (uint64_t)b1;
- add128(plow, phigh, v << 32, v >> 32);
-
- v = (uint64_t)a1 * (uint64_t)b0;
- add128(plow, phigh, v << 32, v >> 32);
-
- v = (uint64_t)a1 * (uint64_t)b1;
- *phigh += v;
-}
-
-/* Unsigned 64x64 -> 128 multiplication */
-void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
-{
- mul64(plow, phigh, a, b);
-#if defined(DEBUG_MULDIV)
- printf("mulu64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
- a, b, *phigh, *plow);
-#endif
-}
-
-/* Signed 64x64 -> 128 multiplication */
-void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
-{
- int sa, sb;
-
- sa = (a < 0);
- if (sa)
- a = -a;
- sb = (b < 0);
- if (sb)
- b = -b;
- mul64(plow, phigh, a, b);
- if (sa ^ sb) {
- neg128(plow, phigh);
- }
-#if defined(DEBUG_MULDIV)
- printf("muls64: 0x%016llx * 0x%016llx = 0x%016llx%016llx\n",
- a, b, *phigh, *plow);
-#endif
-}
-#endif /* !defined(__x86_64__) */
diff --git a/host-utils.h b/host-utils.h
deleted file mode 100644
index b1e799e..0000000
--- a/host-utils.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Utility compute operations used by translated code.
- *
- * Copyright (c) 2007 Thiemo Seufer
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "osdep.h"
-
-#if defined(__x86_64__)
-#define __HAVE_FAST_MULU64__
-static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
- uint64_t a, uint64_t b)
-{
- __asm__ ("mul %0\n\t"
- : "=d" (*phigh), "=a" (*plow)
- : "a" (a), "0" (b));
-}
-#define __HAVE_FAST_MULS64__
-static always_inline void muls64 (uint64_t *plow, uint64_t *phigh,
- int64_t a, int64_t b)
-{
- __asm__ ("imul %0\n\t"
- : "=d" (*phigh), "=a" (*plow)
- : "a" (a), "0" (b));
-}
-#else
-void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
-void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
-#endif
-
-/* Note that some of those functions may end up calling libgcc functions,
- depending on the host machine. It is up to the target emulation to
- cope with that. */
-
-/* Binary search for leading zeros. */
-
-static always_inline int clz32(uint32_t val)
-{
- int cnt = 0;
-
- if (!(val & 0xFFFF0000U)) {
- cnt += 16;
- val <<= 16;
- }
- if (!(val & 0xFF000000U)) {
- cnt += 8;
- val <<= 8;
- }
- if (!(val & 0xF0000000U)) {
- cnt += 4;
- val <<= 4;
- }
- if (!(val & 0xC0000000U)) {
- cnt += 2;
- val <<= 2;
- }
- if (!(val & 0x80000000U)) {
- cnt++;
- val <<= 1;
- }
- if (!(val & 0x80000000U)) {
- cnt++;
- }
- return cnt;
-}
-
-static always_inline int clo32(uint32_t val)
-{
- return clz32(~val);
-}
-
-static always_inline int clz64(uint64_t val)
-{
- int cnt = 0;
-
- if (!(val >> 32)) {
- cnt += 32;
- } else {
- val >>= 32;
- }
-
- return cnt + clz32(val);
-}
-
-static always_inline int clo64(uint64_t val)
-{
- return clz64(~val);
-}
-
-static always_inline int ctz32 (uint32_t val)
-{
- int cnt;
-
- cnt = 0;
- if (!(val & 0x0000FFFFUL)) {
- cnt += 16;
- val >>= 16;
- }
- if (!(val & 0x000000FFUL)) {
- cnt += 8;
- val >>= 8;
- }
- if (!(val & 0x0000000FUL)) {
- cnt += 4;
- val >>= 4;
- }
- if (!(val & 0x00000003UL)) {
- cnt += 2;
- val >>= 2;
- }
- if (!(val & 0x00000001UL)) {
- cnt++;
- val >>= 1;
- }
- if (!(val & 0x00000001UL)) {
- cnt++;
- }
-
- return cnt;
- }
-
-static always_inline int cto32 (uint32_t val)
- {
- return ctz32(~val);
-}
-
-static always_inline int ctz64 (uint64_t val)
-{
- int cnt;
-
- cnt = 0;
- if (!((uint32_t)val)) {
- cnt += 32;
- val >>= 32;
- }
-
- return cnt + ctz32(val);
-}
-
-static always_inline int cto64 (uint64_t val)
-{
- return ctz64(~val);
-}
-
-static always_inline int ctpop8 (uint8_t val)
-{
- val = (val & 0x55) + ((val >> 1) & 0x55);
- val = (val & 0x33) + ((val >> 2) & 0x33);
- val = (val & 0x0f) + ((val >> 4) & 0x0f);
-
- return val;
-}
-
-static always_inline int ctpop16 (uint16_t val)
-{
- val = (val & 0x5555) + ((val >> 1) & 0x5555);
- val = (val & 0x3333) + ((val >> 2) & 0x3333);
- val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
- val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
-
- return val;
-}
-
-static always_inline int ctpop32 (uint32_t val)
-{
- val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
- val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
- val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
- val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
- val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
-
- return val;
-}
-
-static always_inline int ctpop64 (uint64_t val)
-{
- val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
- val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
- val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
- val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL);
- val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
- val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
-
- return val;
-}
diff --git a/hostregs_helper.h b/hostregs_helper.h
deleted file mode 100644
index 4fdf8ad..0000000
--- a/hostregs_helper.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Save/restore host registrs.
- *
- * Copyright (c) 2007 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* The GCC global register vairable extension is used to reserve some
- host registers for use by dyngen. However only the core parts of the
- translation engine are compiled with these settings. We must manually
- save/restore these registers when called from regular code.
- It is not sufficient to save/restore T0 et. al. as these may be declared
- with a datatype smaller than the actual register. */
-
-#if defined(DECLARE_HOST_REGS)
-
-#define DO_REG(REG) \
- register host_reg_t reg_AREG##REG asm(AREG##REG); \
- volatile host_reg_t saved_AREG##REG;
-
-#elif defined(SAVE_HOST_REGS)
-
-#define DO_REG(REG) \
- __asm__ __volatile__ ("" : "=r" (reg_AREG##REG)); \
- saved_AREG##REG = reg_AREG##REG;
-
-#else
-
-#define DO_REG(REG) \
- reg_AREG##REG = saved_AREG##REG; \
- __asm__ __volatile__ ("" : : "r" (reg_AREG##REG));
-
-#endif
-
-#ifdef AREG0
-DO_REG(0)
-#endif
-
-#ifdef AREG1
-DO_REG(1)
-#endif
-
-#ifdef AREG2
-DO_REG(2)
-#endif
-
-#ifdef AREG3
-DO_REG(3)
-#endif
-
-#ifdef AREG4
-DO_REG(4)
-#endif
-
-#ifdef AREG5
-DO_REG(5)
-#endif
-
-#ifdef AREG6
-DO_REG(6)
-#endif
-
-#ifdef AREG7
-DO_REG(7)
-#endif
-
-#ifdef AREG8
-DO_REG(8)
-#endif
-
-#ifdef AREG9
-DO_REG(9)
-#endif
-
-#ifdef AREG10
-DO_REG(10)
-#endif
-
-#ifdef AREG11
-DO_REG(11)
-#endif
-
-#undef SAVE_HOST_REGS
-#undef DECLARE_HOST_REGS
-#undef DO_REG
diff --git a/hpet.h b/hpet.h
deleted file mode 100644
index 754051a..0000000
--- a/hpet.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __HPET__
-#define __HPET__ 1
-
-
-
-struct hpet_info {
- unsigned long hi_ireqfreq; /* Hz */
- unsigned long hi_flags; /* information */
- unsigned short hi_hpet;
- unsigned short hi_timer;
-};
-
-#define HPET_INFO_PERIODIC 0x0001 /* timer is periodic */
-
-#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */
-#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */
-#define HPET_INFO _IOR('h', 0x03, struct hpet_info)
-#define HPET_EPI _IO('h', 0x04) /* enable periodic */
-#define HPET_DPI _IO('h', 0x05) /* disable periodic */
-#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* IRQFREQ usec */
-
-#endif /* !__HPET__ */
diff --git a/hw/android_arm.c b/hw/android_arm.c
deleted file mode 100644
index efc8ba1..0000000
--- a/hw/android_arm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "hw.h"
-#include "boards.h"
-#include "devices.h"
-#include "net.h"
-#include "arm_pic.h"
-#include "sysemu.h"
-#include "goldfish_device.h"
-#include "android/globals.h"
-#include "audio/audio.h"
-#include "arm-misc.h"
-
-#define ARM_CPU_SAVE_VERSION 1
-
-int android_audio_enabled;
-char* audio_input_source = NULL;
-
-void goldfish_memlog_init(uint32_t base);
-
-static struct goldfish_device event0_device = {
- .name = "goldfish_events",
- .id = 0,
- .size = 0x1000,
- .irq_count = 1
-};
-
-static struct goldfish_device nand_device = {
- .name = "goldfish_nand",
- .id = 0,
- .size = 0x1000
-};
-
-static struct goldfish_device trace_device = {
- .name = "qemu_trace",
- .id = -1,
- .size = 0x1000
-};
-
-/* Board init. */
-
-#define TEST_SWITCH 1
-#if TEST_SWITCH
-uint32_t switch_test_write(void *opaque, uint32_t state)
-{
- goldfish_switch_set_state(opaque, state);
- return state;
-}
-#endif
-
-static void android_arm_init(ram_addr_t ram_size, int vga_ram_size,
- const char *boot_device, DisplayState *ds,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *cpu_model)
-{
- CPUState *env;
- qemu_irq *cpu_pic;
- qemu_irq *goldfish_pic;
- int i;
- struct arm_boot_info info;
-
- if (!cpu_model)
- cpu_model = "arm926";
-
- env = cpu_init(cpu_model);
-
- register_savevm( "cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, env );
-
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- cpu_pic = arm_pic_init_cpu(env);
- goldfish_pic = goldfish_interrupt_init(0xff000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ]);
- goldfish_device_init(goldfish_pic, 0xff010000, 0x7f0000, 10, 22);
-
- goldfish_device_bus_init(0xff001000, 1);
-
- goldfish_timer_and_rtc_init(0xff003000, 3);
-
- goldfish_tty_add(serial_hds[0], 0, 0xff002000, 4);
- for(i = 1; i < MAX_SERIAL_PORTS; i++) {
- //printf("android_arm_init serial %d %x\n", i, serial_hds[i]);
- if(serial_hds[i]) {
- goldfish_tty_add(serial_hds[i], i, 0, 0);
- }
- }
-
- for(i = 0; i < MAX_NICS; i++) {
- if (nd_table[i].vlan) {
- if (nd_table[i].model == NULL
- || strcmp(nd_table[i].model, "smc91c111") == 0) {
- struct goldfish_device *smc_device;
- smc_device = qemu_mallocz(sizeof(*smc_device));
- smc_device->name = "smc91x";
- smc_device->id = i;
- smc_device->size = 0x1000;
- smc_device->irq_count = 1;
- goldfish_add_device_no_io(smc_device);
- smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
- exit (1);
- }
- }
- }
-
- goldfish_fb_init(ds, 0);
-#ifdef HAS_AUDIO
- if (android_audio_enabled) {
- AUD_init();
- goldfish_audio_init(0xff004000, 0, audio_input_source);
- }
-#endif
- {
- int idx = drive_get_index( IF_IDE, 0, 0 );
- if (idx >= 0)
- goldfish_mmc_init(0xff005000, 0, drives_table[idx].bdrv);
- }
-
- goldfish_memlog_init(0xff006000);
-
- if (android_hw->hw_battery)
- goldfish_battery_init();
-
- goldfish_add_device_no_io(&event0_device);
- events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]);
-
-#ifdef CONFIG_NAND
- goldfish_add_device_no_io(&nand_device);
- nand_dev_init(nand_device.base);
-#endif
-#ifdef CONFIG_TRACE
- extern const char *trace_filename;
- if(trace_filename != NULL) {
- goldfish_add_device_no_io(&trace_device);
- trace_dev_init(trace_device.base);
- }
-#endif
-
-#if TEST_SWITCH
- {
- void *sw;
- sw = goldfish_switch_add("test", NULL, NULL, 0);
- goldfish_switch_set_state(sw, 1);
- goldfish_switch_add("test2", switch_test_write, sw, 1);
- }
-#endif
-
- memset(&info, 0, sizeof info);
- info.ram_size = ram_size;
- info.kernel_filename = kernel_filename;
- info.kernel_cmdline = kernel_cmdline;
- info.initrd_filename = initrd_filename;
- info.nb_cpus = 1;
- info.board_id = 1441;
-
- arm_load_kernel(env, &info);
-}
-
-QEMUMachine android_arm_machine = {
- "android_arm",
- "ARM Android Emulator",
- android_arm_init,
- NULL
-};
diff --git a/hw/arm-misc.h b/hw/arm-misc.h
deleted file mode 100644
index 707e699..0000000
--- a/hw/arm-misc.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Misc ARM declarations
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- */
-
-#ifndef ARM_MISC_H
-#define ARM_MISC_H 1
-
-#include "cpu.h"
-
-/* The CPU is also modeled as an interrupt controller. */
-#define ARM_PIC_CPU_IRQ 0
-#define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(CPUState *env);
-
-/* armv7m.c */
-qemu_irq *armv7m_init(int flash_size, int sram_size,
- const char *kernel_filename, const char *cpu_model);
-
-/* arm_boot.c */
-struct arm_boot_info {
- int ram_size;
- const char *kernel_filename;
- const char *kernel_cmdline;
- const char *initrd_filename;
- target_phys_addr_t loader_start;
- int nb_cpus;
- int board_id;
- int (*atag_board)(struct arm_boot_info *info, void *p);
-};
-void arm_load_kernel(CPUState *env, struct arm_boot_info *info);
-
-/* armv7m_nvic.c */
-
-/* Multiplication factor to convert from system clock ticks to qemu timer
- ticks. */
-int system_clock_scale;
-qemu_irq *armv7m_nvic_init(CPUState *env);
-
-/* stellaris_enent.c */
-void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq);
-
-#endif /* !ARM_MISC_H */
-
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
deleted file mode 100644
index 5990961..0000000
--- a/hw/arm_boot.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * ARM kernel loader.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "hw.h"
-#include "arm-misc.h"
-#include "sysemu.h"
-
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
-
-/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
-static uint32_t bootloader[] = {
- 0xe3a00000, /* mov r0, #0 */
- 0xe3a01000, /* mov r1, #0x?? */
- 0xe3811c00, /* orr r1, r1, #0x??00 */
- 0xe59f2000, /* ldr r2, [pc, #0] */
- 0xe59ff000, /* ldr pc, [pc, #0] */
- 0, /* Address of kernel args. Set by integratorcp_init. */
- 0 /* Kernel entry point. Set by integratorcp_init. */
-};
-
-/* Entry point for secondary CPUs. Enable interrupt controller and
- Issue WFI until start address is written to system controller. */
-static uint32_t smpboot[] = {
- 0xe3a00201, /* mov r0, #0x10000000 */
- 0xe3800601, /* orr r0, r0, #0x001000000 */
- 0xe3a01001, /* mov r1, #1 */
- 0xe5801100, /* str r1, [r0, #0x100] */
- 0xe3a00201, /* mov r0, #0x10000000 */
- 0xe3800030, /* orr r0, #0x30 */
- 0xe320f003, /* wfi */
- 0xe5901000, /* ldr r1, [r0] */
- 0xe3110003, /* tst r1, #3 */
- 0x1afffffb, /* bne <wfi> */
- 0xe12fff11 /* bx r1 */
-};
-
-static void main_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
-
- cpu_reset(env);
- if (env->boot_info)
- arm_load_kernel(env, env->boot_info);
-
- /* TODO: Reset secondary CPUs. */
-}
-
-static void set_kernel_args(struct arm_boot_info *info,
- int initrd_size, void *base)
-{
- uint32_t *p;
-
- p = (uint32_t *)(base + KERNEL_ARGS_ADDR);
- /* ATAG_CORE */
- stl_raw(p++, 5);
- stl_raw(p++, 0x54410001);
- stl_raw(p++, 1);
- stl_raw(p++, 0x1000);
- stl_raw(p++, 0);
- /* ATAG_MEM */
- /* TODO: handle multiple chips on one ATAG list */
- stl_raw(p++, 4);
- stl_raw(p++, 0x54410002);
- stl_raw(p++, info->ram_size);
- stl_raw(p++, info->loader_start);
- if (initrd_size) {
- /* ATAG_INITRD2 */
- stl_raw(p++, 4);
- stl_raw(p++, 0x54420005);
- stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR);
- stl_raw(p++, initrd_size);
- }
- if (info->kernel_cmdline && *info->kernel_cmdline) {
- /* ATAG_CMDLINE */
- int cmdline_size;
-
- cmdline_size = strlen(info->kernel_cmdline);
- memcpy(p + 2, info->kernel_cmdline, cmdline_size + 1);
- cmdline_size = (cmdline_size >> 2) + 1;
- stl_raw(p++, cmdline_size + 2);
- stl_raw(p++, 0x54410009);
- p += cmdline_size;
- }
- if (info->atag_board) {
- /* ATAG_BOARD */
- int atag_board_len;
-
- atag_board_len = (info->atag_board(info, p + 2) + 3) >> 2;
- stl_raw(p++, 2 + atag_board_len);
- stl_raw(p++, 0x414f4d50);
- p += atag_board_len;
- }
- /* ATAG_END */
- stl_raw(p++, 0);
- stl_raw(p++, 0);
-}
-
-static void set_kernel_args_old(struct arm_boot_info *info,
- int initrd_size, void *base)
-{
- uint32_t *p;
- unsigned char *s;
-
- /* see linux/include/asm-arm/setup.h */
- p = (uint32_t *)(base + KERNEL_ARGS_ADDR);
- /* page_size */
- stl_raw(p++, 4096);
- /* nr_pages */
- stl_raw(p++, info->ram_size / 4096);
- /* ramdisk_size */
- stl_raw(p++, 0);
-#define FLAG_READONLY 1
-#define FLAG_RDLOAD 4
-#define FLAG_RDPROMPT 8
- /* flags */
- stl_raw(p++, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT);
- /* rootdev */
- stl_raw(p++, (31 << 8) | 0); /* /dev/mtdblock0 */
- /* video_num_cols */
- stl_raw(p++, 0);
- /* video_num_rows */
- stl_raw(p++, 0);
- /* video_x */
- stl_raw(p++, 0);
- /* video_y */
- stl_raw(p++, 0);
- /* memc_control_reg */
- stl_raw(p++, 0);
- /* unsigned char sounddefault */
- /* unsigned char adfsdrives */
- /* unsigned char bytes_per_char_h */
- /* unsigned char bytes_per_char_v */
- stl_raw(p++, 0);
- /* pages_in_bank[4] */
- stl_raw(p++, 0);
- stl_raw(p++, 0);
- stl_raw(p++, 0);
- stl_raw(p++, 0);
- /* pages_in_vram */
- stl_raw(p++, 0);
- /* initrd_start */
- if (initrd_size)
- stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR);
- else
- stl_raw(p++, 0);
- /* initrd_size */
- stl_raw(p++, initrd_size);
- /* rd_start */
- stl_raw(p++, 0);
- /* system_rev */
- stl_raw(p++, 0);
- /* system_serial_low */
- stl_raw(p++, 0);
- /* system_serial_high */
- stl_raw(p++, 0);
- /* mem_fclk_21285 */
- stl_raw(p++, 0);
- /* zero unused fields */
- memset(p, 0, 256 + 1024 -
- (p - ((uint32_t *)(base + KERNEL_ARGS_ADDR))));
- s = base + KERNEL_ARGS_ADDR + 256 + 1024;
- if (info->kernel_cmdline)
- strcpy (s, info->kernel_cmdline);
- else
- stb_raw(s, 0);
-}
-
-void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
-{
- int kernel_size;
- int initrd_size;
- int n;
- int is_linux = 0;
- uint64_t elf_entry;
- target_ulong entry;
- uint32_t pd;
- void *loader_phys;
-
- /* Load the kernel. */
- if (!info->kernel_filename) {
- fprintf(stderr, "Kernel image must be specified\n");
- exit(1);
- }
-
- if (!env->boot_info) {
- if (info->nb_cpus == 0)
- info->nb_cpus = 1;
- env->boot_info = info;
- qemu_register_reset(main_cpu_reset, env);
- }
-
- pd = cpu_get_physical_page_desc(info->loader_start);
- loader_phys = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (info->loader_start & ~TARGET_PAGE_MASK);
-
- /* Assume that raw images are linux kernels, and ELF images are not. */
- kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL);
- entry = elf_entry;
- if (kernel_size < 0) {
- kernel_size = load_uboot(info->kernel_filename, &entry, &is_linux);
- }
- if (kernel_size < 0) {
- kernel_size = load_image(info->kernel_filename,
- loader_phys + KERNEL_LOAD_ADDR);
- entry = info->loader_start + KERNEL_LOAD_ADDR;
- is_linux = 1;
- }
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- info->kernel_filename);
- exit(1);
- }
- if (!is_linux) {
- /* Jump to the entry point. */
- env->regs[15] = entry & 0xfffffffe;
- env->thumb = entry & 1;
- } else {
- if (info->initrd_filename) {
- initrd_size = load_image(info->initrd_filename,
- loader_phys + INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initrd '%s'\n",
- info->initrd_filename);
- exit(1);
- }
- } else {
- initrd_size = 0;
- }
- bootloader[1] |= info->board_id & 0xff;
- bootloader[2] |= (info->board_id >> 8) & 0xff;
- bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;
- bootloader[6] = entry;
- for (n = 0; n < sizeof(bootloader) / 4; n++)
- stl_raw(loader_phys + (n * 4), bootloader[n]);
- if (info->nb_cpus > 1)
- for (n = 0; n < sizeof(smpboot) / 4; n++)
- stl_raw(loader_phys + info->ram_size + (n * 4), smpboot[n]);
- if (old_param)
- set_kernel_args_old(info, initrd_size, loader_phys);
- else
- set_kernel_args(info, initrd_size, loader_phys);
- }
-}
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
deleted file mode 100644
index 54e99f4..0000000
--- a/hw/arm_gic.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/*
- * ARM Generic/Distributed Interrupt Controller
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-/* This file contains implementation code for the RealView EB interrupt
- controller, MPCore distributed interrupt controller and ARMv7-M
- Nested Vectored Interrupt Controller. */
-
-//#define DEBUG_GIC
-
-#ifdef DEBUG_GIC
-#define DPRINTF(fmt, args...) \
-do { printf("arm_gic: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-#ifdef NVIC
-static const uint8_t gic_id[] =
-{ 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 };
-#define GIC_DIST_OFFSET 0
-/* The NVIC has 16 internal vectors. However these are not exposed
- through the normal GIC interface. */
-#define GIC_BASE_IRQ 32
-#else
-static const uint8_t gic_id[] =
-{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-#define GIC_DIST_OFFSET 0x1000
-#define GIC_BASE_IRQ 0
-#endif
-
-typedef struct gic_irq_state
-{
- /* ??? The documentation seems to imply the enable bits are global, even
- for per-cpu interrupts. This seems strange. */
- unsigned enabled:1;
- unsigned pending:NCPU;
- unsigned active:NCPU;
- unsigned level:1;
- unsigned model:1; /* 0 = N:N, 1 = 1:N */
- unsigned trigger:1; /* nonzero = edge triggered. */
-} gic_irq_state;
-
-#define ALL_CPU_MASK ((1 << NCPU) - 1)
-
-#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
-#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
-#define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled
-#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm)
-#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm)
-#define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0)
-#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |= (cm)
-#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &= ~(cm)
-#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != 0)
-#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
-#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
-#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
-#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
-#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
-#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
-#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
-#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
-#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
-#define GIC_GET_PRIORITY(irq, cpu) \
- (((irq) < 32) ? s->priority1[irq][cpu] : s->priority2[(irq) - 32])
-#ifdef NVIC
-#define GIC_TARGET(irq) 1
-#else
-#define GIC_TARGET(irq) s->irq_target[irq]
-#endif
-
-typedef struct gic_state
-{
- uint32_t base;
- qemu_irq parent_irq[NCPU];
- int enabled;
- int cpu_enabled[NCPU];
-
- gic_irq_state irq_state[GIC_NIRQ];
-#ifndef NVIC
- int irq_target[GIC_NIRQ];
-#endif
- int priority1[32][NCPU];
- int priority2[GIC_NIRQ - 32];
- int last_active[GIC_NIRQ][NCPU];
-
- int priority_mask[NCPU];
- int running_irq[NCPU];
- int running_priority[NCPU];
- int current_pending[NCPU];
-
- qemu_irq *in;
-#ifdef NVIC
- void *nvic;
-#endif
-} gic_state;
-
-/* TODO: Many places that call this routine could be optimized. */
-/* Update interrupt status after enabled or pending bits have been changed. */
-static void gic_update(gic_state *s)
-{
- int best_irq;
- int best_prio;
- int irq;
- int level;
- int cpu;
- int cm;
-
- for (cpu = 0; cpu < NCPU; cpu++) {
- cm = 1 << cpu;
- s->current_pending[cpu] = 1023;
- if (!s->enabled || !s->cpu_enabled[cpu]) {
- qemu_irq_lower(s->parent_irq[cpu]);
- return;
- }
- best_prio = 0x100;
- best_irq = 1023;
- for (irq = 0; irq < GIC_NIRQ; irq++) {
- if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq, cm)) {
- if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
- best_prio = GIC_GET_PRIORITY(irq, cpu);
- best_irq = irq;
- }
- }
- }
- level = 0;
- if (best_prio <= s->priority_mask[cpu]) {
- s->current_pending[cpu] = best_irq;
- if (best_prio < s->running_priority[cpu]) {
- DPRINTF("Raised pending IRQ %d\n", best_irq);
- level = 1;
- }
- }
- qemu_set_irq(s->parent_irq[cpu], level);
- }
-}
-
-static void __attribute__((unused))
-gic_set_pending_private(gic_state *s, int cpu, int irq)
-{
- int cm = 1 << cpu;
-
- if (GIC_TEST_PENDING(irq, cm))
- return;
-
- DPRINTF("Set %d pending cpu %d\n", irq, cpu);
- GIC_SET_PENDING(irq, cm);
- gic_update(s);
-}
-
-/* Process a change in an external IRQ input. */
-static void gic_set_irq(void *opaque, int irq, int level)
-{
- gic_state *s = (gic_state *)opaque;
- /* The first external input line is internal interrupt 32. */
- irq += 32;
- if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK))
- return;
-
- if (level) {
- GIC_SET_LEVEL(irq, ALL_CPU_MASK);
- if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) {
- DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq));
- GIC_SET_PENDING(irq, GIC_TARGET(irq));
- }
- } else {
- GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK);
- }
- gic_update(s);
-}
-
-static void gic_set_running_irq(gic_state *s, int cpu, int irq)
-{
- s->running_irq[cpu] = irq;
- if (irq == 1023) {
- s->running_priority[cpu] = 0x100;
- } else {
- s->running_priority[cpu] = GIC_GET_PRIORITY(irq, cpu);
- }
- gic_update(s);
-}
-
-static uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
-{
- int new_irq;
- int cm = 1 << cpu;
- new_irq = s->current_pending[cpu];
- if (new_irq == 1023
- || GIC_GET_PRIORITY(new_irq, cpu) >= s->running_priority[cpu]) {
- DPRINTF("ACK no pending IRQ\n");
- return 1023;
- }
- s->last_active[new_irq][cpu] = s->running_irq[cpu];
- /* Clear pending flags for both level and edge triggered interrupts.
- Level triggered IRQs will be reasserted once they become inactive. */
- GIC_CLEAR_PENDING(new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm);
- gic_set_running_irq(s, cpu, new_irq);
- DPRINTF("ACK %d\n", new_irq);
- return new_irq;
-}
-
-static void gic_complete_irq(gic_state * s, int cpu, int irq)
-{
- int update = 0;
- int cm = 1 << cpu;
- DPRINTF("EOI %d\n", irq);
- if (s->running_irq[cpu] == 1023)
- return; /* No active IRQ. */
- if (irq != 1023) {
- /* Mark level triggered interrupts as pending if they are still
- raised. */
- if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq)
- && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) {
- DPRINTF("Set %d pending mask %x\n", irq, cm);
- GIC_SET_PENDING(irq, cm);
- update = 1;
- }
- }
- if (irq != s->running_irq[cpu]) {
- /* Complete an IRQ that is not currently running. */
- int tmp = s->running_irq[cpu];
- while (s->last_active[tmp][cpu] != 1023) {
- if (s->last_active[tmp][cpu] == irq) {
- s->last_active[tmp][cpu] = s->last_active[irq][cpu];
- break;
- }
- tmp = s->last_active[tmp][cpu];
- }
- if (update) {
- gic_update(s);
- }
- } else {
- /* Complete the current running IRQ. */
- gic_set_running_irq(s, cpu, s->last_active[s->running_irq[cpu]][cpu]);
- }
-}
-
-static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
-{
- gic_state *s = (gic_state *)opaque;
- uint32_t res;
- int irq;
- int i;
- int cpu;
- int cm;
- int mask;
-
- cpu = gic_get_current_cpu();
- cm = 1 << cpu;
- offset -= s->base + GIC_DIST_OFFSET;
- if (offset < 0x100) {
-#ifndef NVIC
- if (offset == 0)
- return s->enabled;
- if (offset == 4)
- return ((GIC_NIRQ / 32) - 1) | ((NCPU - 1) << 5);
- if (offset < 0x08)
- return 0;
-#endif
- goto bad_reg;
- } else if (offset < 0x200) {
- /* Interrupt Set/Clear Enable. */
- if (offset < 0x180)
- irq = (offset - 0x100) * 8;
- else
- irq = (offset - 0x180) * 8;
- irq += GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_ENABLED(irq + i)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x300) {
- /* Interrupt Set/Clear Pending. */
- if (offset < 0x280)
- irq = (offset - 0x200) * 8;
- else
- irq = (offset - 0x280) * 8;
- irq += GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- mask = (irq < 32) ? cm : ALL_CPU_MASK;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_PENDING(irq + i, mask)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x400) {
- /* Interrupt Active. */
- irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- mask = (irq < 32) ? cm : ALL_CPU_MASK;
- for (i = 0; i < 8; i++) {
- if (GIC_TEST_ACTIVE(irq + i, mask)) {
- res |= (1 << i);
- }
- }
- } else if (offset < 0x800) {
- /* Interrupt Priority. */
- irq = (offset - 0x400) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = GIC_GET_PRIORITY(irq, cpu);
-#ifndef NVIC
- } else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = (offset - 0x800) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq >= 29 && irq <= 31) {
- res = cm;
- } else {
- res = GIC_TARGET(irq);
- }
- } else if (offset < 0xf00) {
- /* Interrupt Configuration. */
- irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- res = 0;
- for (i = 0; i < 4; i++) {
- if (GIC_TEST_MODEL(irq + i))
- res |= (1 << (i * 2));
- if (GIC_TEST_TRIGGER(irq + i))
- res |= (2 << (i * 2));
- }
-#endif
- } else if (offset < 0xfe0) {
- goto bad_reg;
- } else /* offset >= 0xfe0 */ {
- if (offset & 3) {
- res = 0;
- } else {
- res = gic_id[(offset - 0xfe0) >> 2];
- }
- }
- return res;
-bad_reg:
- cpu_abort(cpu_single_env, "gic_dist_readb: Bad offset %x\n", (int)offset);
- return 0;
-}
-
-static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = gic_dist_readb(opaque, offset);
- val |= gic_dist_readb(opaque, offset + 1) << 8;
- return val;
-}
-
-static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
-#ifdef NVIC
- gic_state *s = (gic_state *)opaque;
- uint32_t addr;
- addr = offset - s->base;
- if (addr < 0x100 || addr > 0xd00)
- return nvic_readl(s->nvic, addr);
-#endif
- val = gic_dist_readw(opaque, offset);
- val |= gic_dist_readw(opaque, offset + 2) << 16;
- return val;
-}
-
-static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
- int irq;
- int i;
- int cpu;
-
- cpu = gic_get_current_cpu();
- offset -= s->base + GIC_DIST_OFFSET;
- if (offset < 0x100) {
-#ifdef NVIC
- goto bad_reg;
-#else
- if (offset == 0) {
- s->enabled = (value & 1);
- DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
- } else if (offset < 4) {
- /* ignored. */
- } else {
- goto bad_reg;
- }
-#endif
- } else if (offset < 0x180) {
- /* Interrupt Set Enable. */
- irq = (offset - 0x100) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 16)
- value = 0xff;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- int mask = (irq < 32) ? (1 << cpu) : GIC_TARGET(irq);
- if (!GIC_TEST_ENABLED(irq + i))
- DPRINTF("Enabled IRQ %d\n", irq + i);
- GIC_SET_ENABLED(irq + i);
- /* If a raised level triggered IRQ enabled then mark
- is as pending. */
- if (GIC_TEST_LEVEL(irq + i, mask)
- && !GIC_TEST_TRIGGER(irq + i)) {
- DPRINTF("Set %d pending mask %x\n", irq + i, mask);
- GIC_SET_PENDING(irq + i, mask);
- }
- }
- }
- } else if (offset < 0x200) {
- /* Interrupt Clear Enable. */
- irq = (offset - 0x180) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 16)
- value = 0;
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- if (GIC_TEST_ENABLED(irq + i))
- DPRINTF("Disabled IRQ %d\n", irq + i);
- GIC_CLEAR_ENABLED(irq + i);
- }
- }
- } else if (offset < 0x280) {
- /* Interrupt Set Pending. */
- irq = (offset - 0x200) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 16)
- irq = 0;
-
- for (i = 0; i < 8; i++) {
- if (value & (1 << i)) {
- GIC_SET_PENDING(irq + i, GIC_TARGET(irq));
- }
- }
- } else if (offset < 0x300) {
- /* Interrupt Clear Pending. */
- irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- for (i = 0; i < 8; i++) {
- /* ??? This currently clears the pending bit for all CPUs, even
- for per-CPU interrupts. It's unclear whether this is the
- corect behavior. */
- if (value & (1 << i)) {
- GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
- }
- }
- } else if (offset < 0x400) {
- /* Interrupt Active. */
- goto bad_reg;
- } else if (offset < 0x800) {
- /* Interrupt Priority. */
- irq = (offset - 0x400) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 32) {
- s->priority1[irq][cpu] = value;
- } else {
- s->priority2[irq - 32] = value;
- }
-#ifndef NVIC
- } else if (offset < 0xc00) {
- /* Interrupt CPU Target. */
- irq = (offset - 0x800) + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 29)
- value = 0;
- else if (irq < 32)
- value = ALL_CPU_MASK;
- s->irq_target[irq] = value & ALL_CPU_MASK;
- } else if (offset < 0xf00) {
- /* Interrupt Configuration. */
- irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
- if (irq >= GIC_NIRQ)
- goto bad_reg;
- if (irq < 32)
- value |= 0xaa;
- for (i = 0; i < 4; i++) {
- if (value & (1 << (i * 2))) {
- GIC_SET_MODEL(irq + i);
- } else {
- GIC_CLEAR_MODEL(irq + i);
- }
- if (value & (2 << (i * 2))) {
- GIC_SET_TRIGGER(irq + i);
- } else {
- GIC_CLEAR_TRIGGER(irq + i);
- }
- }
-#endif
- } else {
- /* 0xf00 is only handled for 32-bit writes. */
- goto bad_reg;
- }
- gic_update(s);
- return;
-bad_reg:
- cpu_abort(cpu_single_env, "gic_dist_writeb: Bad offset %x\n", (int)offset);
-}
-
-static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_dist_writeb(opaque, offset, value & 0xff);
- gic_dist_writeb(opaque, offset + 1, value >> 8);
-}
-
-static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- gic_state *s = (gic_state *)opaque;
-#ifdef NVIC
- uint32_t addr;
- addr = offset - s->base;
- if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
- nvic_writel(s->nvic, addr, value);
- return;
- }
-#endif
- if (offset - s->base == GIC_DIST_OFFSET + 0xf00) {
- int cpu;
- int irq;
- int mask;
-
- cpu = gic_get_current_cpu();
- irq = value & 0x3ff;
- switch ((value >> 24) & 3) {
- case 0:
- mask = (value >> 16) & ALL_CPU_MASK;
- break;
- case 1:
- mask = 1 << cpu;
- break;
- case 2:
- mask = ALL_CPU_MASK ^ (1 << cpu);
- break;
- default:
- DPRINTF("Bad Soft Int target filter\n");
- mask = ALL_CPU_MASK;
- break;
- }
- GIC_SET_PENDING(irq, mask);
- gic_update(s);
- return;
- }
- gic_dist_writew(opaque, offset, value & 0xffff);
- gic_dist_writew(opaque, offset + 2, value >> 16);
-}
-
-static CPUReadMemoryFunc *gic_dist_readfn[] = {
- gic_dist_readb,
- gic_dist_readw,
- gic_dist_readl
-};
-
-static CPUWriteMemoryFunc *gic_dist_writefn[] = {
- gic_dist_writeb,
- gic_dist_writew,
- gic_dist_writel
-};
-
-#ifndef NVIC
-static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
-{
- switch (offset) {
- case 0x00: /* Control */
- return s->cpu_enabled[cpu];
- case 0x04: /* Priority mask */
- return s->priority_mask[cpu];
- case 0x08: /* Binary Point */
- /* ??? Not implemented. */
- return 0;
- case 0x0c: /* Acknowledge */
- return gic_acknowledge_irq(s, cpu);
- case 0x14: /* Runing Priority */
- return s->running_priority[cpu];
- case 0x18: /* Highest Pending Interrupt */
- return s->current_pending[cpu];
- default:
- cpu_abort(cpu_single_env, "gic_cpu_read: Bad offset %x\n",
- (int)offset);
- return 0;
- }
-}
-
-static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
-{
- switch (offset) {
- case 0x00: /* Control */
- s->cpu_enabled[cpu] = (value & 1);
- DPRINTF("CPU %sabled\n", s->cpu_enabled ? "En" : "Dis");
- break;
- case 0x04: /* Priority mask */
- s->priority_mask[cpu] = (value & 0xff);
- break;
- case 0x08: /* Binary Point */
- /* ??? Not implemented. */
- break;
- case 0x10: /* End Of Interrupt */
- return gic_complete_irq(s, cpu, value & 0x3ff);
- default:
- cpu_abort(cpu_single_env, "gic_cpu_write: Bad offset %x\n",
- (int)offset);
- return;
- }
- gic_update(s);
-}
-#endif
-
-static void gic_reset(gic_state *s)
-{
- int i;
- memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
- for (i = 0 ; i < NCPU; i++) {
- s->priority_mask[i] = 0xf0;
- s->current_pending[i] = 1023;
- s->running_irq[i] = 1023;
- s->running_priority[i] = 0x100;
-#ifdef NVIC
- /* The NVIC doesn't have per-cpu interfaces, so enable by default. */
- s->cpu_enabled[i] = 1;
-#else
- s->cpu_enabled[i] = 0;
-#endif
- }
- for (i = 0; i < 16; i++) {
- GIC_SET_ENABLED(i);
- GIC_SET_TRIGGER(i);
- }
-#ifdef NVIC
- /* The NVIC is always enabled. */
- s->enabled = 1;
-#else
- s->enabled = 0;
-#endif
-}
-
-static void gic_save(QEMUFile *f, void *opaque)
-{
- gic_state *s = (gic_state *)opaque;
- int i;
- int j;
-
- qemu_put_be32(f, s->enabled);
- for (i = 0; i < NCPU; i++) {
- qemu_put_be32(f, s->cpu_enabled[i]);
-#ifndef NVIC
- qemu_put_be32(f, s->irq_target[i]);
-#endif
- for (j = 0; j < 32; j++)
- qemu_put_be32(f, s->priority1[j][i]);
- for (j = 0; j < GIC_NIRQ; j++)
- qemu_put_be32(f, s->last_active[j][i]);
- qemu_put_be32(f, s->priority_mask[i]);
- qemu_put_be32(f, s->running_irq[i]);
- qemu_put_be32(f, s->running_priority[i]);
- qemu_put_be32(f, s->current_pending[i]);
- }
- for (i = 0; i < GIC_NIRQ - 32; i++) {
- qemu_put_be32(f, s->priority2[i]);
- }
- for (i = 0; i < GIC_NIRQ; i++) {
- qemu_put_byte(f, s->irq_state[i].enabled);
- qemu_put_byte(f, s->irq_state[i].pending);
- qemu_put_byte(f, s->irq_state[i].active);
- qemu_put_byte(f, s->irq_state[i].level);
- qemu_put_byte(f, s->irq_state[i].model);
- qemu_put_byte(f, s->irq_state[i].trigger);
- }
-}
-
-static int gic_load(QEMUFile *f, void *opaque, int version_id)
-{
- gic_state *s = (gic_state *)opaque;
- int i;
- int j;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->enabled = qemu_get_be32(f);
- for (i = 0; i < NCPU; i++) {
- s->cpu_enabled[i] = qemu_get_be32(f);
-#ifndef NVIC
- s->irq_target[i] = qemu_get_be32(f);
-#endif
- for (j = 0; j < 32; j++)
- s->priority1[j][i] = qemu_get_be32(f);
- for (j = 0; j < GIC_NIRQ; j++)
- s->last_active[j][i] = qemu_get_be32(f);
- s->priority_mask[i] = qemu_get_be32(f);
- s->running_irq[i] = qemu_get_be32(f);
- s->running_priority[i] = qemu_get_be32(f);
- s->current_pending[i] = qemu_get_be32(f);
- }
- for (i = 0; i < GIC_NIRQ - 32; i++) {
- s->priority2[i] = qemu_get_be32(f);
- }
- for (i = 0; i < GIC_NIRQ; i++) {
- s->irq_state[i].enabled = qemu_get_byte(f);
- s->irq_state[i].pending = qemu_get_byte(f);
- s->irq_state[i].active = qemu_get_byte(f);
- s->irq_state[i].level = qemu_get_byte(f);
- s->irq_state[i].model = qemu_get_byte(f);
- s->irq_state[i].trigger = qemu_get_byte(f);
- }
-
- return 0;
-}
-
-static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq)
-{
- gic_state *s;
- int iomemtype;
- int i;
-
- s = (gic_state *)qemu_mallocz(sizeof(gic_state));
- if (!s)
- return NULL;
- s->in = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
- for (i = 0; i < NCPU; i++) {
- s->parent_irq[i] = parent_irq[i];
- }
- iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
- gic_dist_writefn, s);
- cpu_register_physical_memory(base + GIC_DIST_OFFSET, 0x00001000,
- iomemtype);
- s->base = base;
- gic_reset(s);
- register_savevm("arm_gic", -1, 1, gic_save, gic_load, s);
- return s;
-}
diff --git a/hw/arm_pic.c b/hw/arm_pic.c
deleted file mode 100644
index 1fe55b7..0000000
--- a/hw/arm_pic.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL
- */
-
-#include "hw.h"
-#include "arm-misc.h"
-
-/* Stub functions for hardware that doesn't exist. */
-void pic_info(void)
-{
-}
-
-void irq_info(void)
-{
-}
-
-
-/* Input 0 is IRQ and input 1 is FIQ. */
-static void arm_pic_cpu_handler(void *opaque, int irq, int level)
-{
- CPUState *env = (CPUState *)opaque;
- switch (irq) {
- case ARM_PIC_CPU_IRQ:
- if (level)
- cpu_interrupt(env, CPU_INTERRUPT_HARD);
- else
- cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
- break;
- case ARM_PIC_CPU_FIQ:
- if (level)
- cpu_interrupt(env, CPU_INTERRUPT_FIQ);
- else
- cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
- break;
- default:
- cpu_abort(env, "arm_pic_cpu_handler: Bad interrput line %d\n", irq);
- }
-}
-
-qemu_irq *arm_pic_init_cpu(CPUState *env)
-{
- return qemu_allocate_irqs(arm_pic_cpu_handler, env, 2);
-}
diff --git a/hw/arm_pic.h b/hw/arm_pic.h
deleted file mode 100644
index 7886bcf..0000000
--- a/hw/arm_pic.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- * Arm hardware uses a wide variety of interrupt handling hardware.
- * This provides a generic framework for connecting interrupt sources and
- * inputs.
- */
-
-#ifndef ARM_INTERRUPT_H
-#define ARM_INTERRUPT_H 1
-
-#include "irq.h"
-
-/* The CPU is also modeled as an interrupt controller. */
-#define ARM_PIC_CPU_IRQ 0
-#define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(CPUState *env);
-
-#endif /* !ARM_INTERRUPT_H */
-
diff --git a/hw/armv7m.c b/hw/armv7m.c
deleted file mode 100644
index b2bad3c..0000000
--- a/hw/armv7m.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * ARMV7M System emulation.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#include "hw.h"
-#include "arm-misc.h"
-#include "sysemu.h"
-
-/* Bitbanded IO. Each word corresponds to a single bit. */
-
-/* Get the byte address of the real memory for a bitband acess. */
-static inline uint32_t bitband_addr(uint32_t addr)
-{
- uint32_t res;
-
- res = addr & 0xe0000000;
- res |= (addr & 0x1ffffff) >> 5;
- return res;
-
-}
-
-static uint32_t bitband_readb(void *opaque, target_phys_addr_t offset)
-{
- uint8_t v;
- cpu_physical_memory_read(bitband_addr(offset), &v, 1);
- return (v & (1 << ((offset >> 2) & 7))) != 0;
-}
-
-static void bitband_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- uint32_t addr;
- uint8_t mask;
- uint8_t v;
- addr = bitband_addr(offset);
- mask = (1 << ((offset >> 2) & 7));
- cpu_physical_memory_read(addr, &v, 1);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, &v, 1);
-}
-
-static uint32_t bitband_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t addr;
- uint16_t mask;
- uint16_t v;
- addr = bitband_addr(offset) & ~1;
- mask = (1 << ((offset >> 2) & 15));
- mask = tswap16(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
- return (v & mask) != 0;
-}
-
-static void bitband_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- uint32_t addr;
- uint16_t mask;
- uint16_t v;
- addr = bitband_addr(offset) & ~1;
- mask = (1 << ((offset >> 2) & 15));
- mask = tswap16(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, (uint8_t *)&v, 2);
-}
-
-static uint32_t bitband_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t addr;
- uint32_t mask;
- uint32_t v;
- addr = bitband_addr(offset) & ~3;
- mask = (1 << ((offset >> 2) & 31));
- mask = tswap32(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
- return (v & mask) != 0;
-}
-
-static void bitband_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- uint32_t addr;
- uint32_t mask;
- uint32_t v;
- addr = bitband_addr(offset) & ~3;
- mask = (1 << ((offset >> 2) & 31));
- mask = tswap32(mask);
- cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
-}
-
-static CPUReadMemoryFunc *bitband_readfn[] = {
- bitband_readb,
- bitband_readw,
- bitband_readl
-};
-
-static CPUWriteMemoryFunc *bitband_writefn[] = {
- bitband_writeb,
- bitband_writew,
- bitband_writel
-};
-
-static void armv7m_bitband_init(void)
-{
- int iomemtype;
-
- iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,
- NULL);
- cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype);
- cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype);
-}
-
-/* Board init. */
-/* Init CPU and memory for a v7-M based board.
- flash_size and sram_size are in kb.
- Returns the NVIC array. */
-
-qemu_irq *armv7m_init(int flash_size, int sram_size,
- const char *kernel_filename, const char *cpu_model)
-{
- CPUState *env;
- qemu_irq *pic;
- uint32_t pc;
- int image_size;
- uint64_t entry;
- uint64_t lowaddr;
-
- flash_size *= 1024;
- sram_size *= 1024;
-
- if (!cpu_model)
- cpu_model = "cortex-m3";
- env = cpu_init(cpu_model);
- if (!env) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
-#if 0
- /* > 32Mb SRAM gets complicated because it overlaps the bitband area.
- We don't have proper commandline options, so allocate half of memory
- as SRAM, up to a maximum of 32Mb, and the rest as code. */
- if (ram_size > (512 + 32) * 1024 * 1024)
- ram_size = (512 + 32) * 1024 * 1024;
- sram_size = (ram_size / 2) & TARGET_PAGE_MASK;
- if (sram_size > 32 * 1024 * 1024)
- sram_size = 32 * 1024 * 1024;
- code_size = ram_size - sram_size;
-#endif
-
- /* Flash programming is done via the SCU, so pretend it is ROM. */
- cpu_register_physical_memory(0, flash_size, IO_MEM_ROM);
- cpu_register_physical_memory(0x20000000, sram_size,
- flash_size + IO_MEM_RAM);
- armv7m_bitband_init();
-
- pic = armv7m_nvic_init(env);
-
- image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
- if (image_size < 0) {
- image_size = load_image(kernel_filename, phys_ram_base);
- lowaddr = 0;
- }
- if (image_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* If the image was loaded at address zero then assume it is a
- regular ROM image and perform the normal CPU reset sequence.
- Otherwise jump directly to the entry point. */
- if (lowaddr == 0) {
- env->regs[13] = tswap32(*(uint32_t *)phys_ram_base);
- pc = tswap32(*(uint32_t *)(phys_ram_base + 4));
- } else {
- pc = entry;
- }
- env->thumb = pc & 1;
- env->regs[15] = pc & ~1;
-
- /* Hack to map an additional page of ram at the top of the address
- space. This stops qemu complaining about executing code outside RAM
- when returning from an exception. */
- cpu_register_physical_memory(0xfffff000, 0x1000, IO_MEM_RAM + ram_size);
-
- return pic;
-}
-
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
deleted file mode 100644
index c55c958..0000000
--- a/hw/armv7m_nvic.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * ARM Nested Vectored Interrupt Controller
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- *
- * The ARMv7M System controller is fairly tightly tied in with the
- * NVIC. Much of that is also implemented here.
- */
-
-#include "hw.h"
-#include "qemu-timer.h"
-#include "arm-misc.h"
-
-/* 32 internal lines (16 used for system exceptions) plus 64 external
- interrupt lines. */
-#define GIC_NIRQ 96
-#define NCPU 1
-#define NVIC 1
-
-/* Only a single "CPU" interface is present. */
-static inline int
-gic_get_current_cpu(void)
-{
- return 0;
-}
-
-static uint32_t nvic_readl(void *opaque, uint32_t offset);
-static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
-
-#include "arm_gic.c"
-
-typedef struct {
- struct {
- uint32_t control;
- uint32_t reload;
- int64_t tick;
- QEMUTimer *timer;
- } systick;
- gic_state *gic;
-} nvic_state;
-
-/* qemu timers run at 1GHz. We want something closer to 1MHz. */
-#define SYSTICK_SCALE 1000ULL
-
-#define SYSTICK_ENABLE (1 << 0)
-#define SYSTICK_TICKINT (1 << 1)
-#define SYSTICK_CLKSOURCE (1 << 2)
-#define SYSTICK_COUNTFLAG (1 << 16)
-
-/* Conversion factor from qemu timer to SysTick frequencies. */
-static inline int64_t systick_scale(nvic_state *s)
-{
- if (s->systick.control & SYSTICK_CLKSOURCE)
- return system_clock_scale;
- else
- return 1000;
-}
-
-static void systick_reload(nvic_state *s, int reset)
-{
- if (reset)
- s->systick.tick = qemu_get_clock(vm_clock);
- s->systick.tick += (s->systick.reload + 1) * systick_scale(s);
- qemu_mod_timer(s->systick.timer, s->systick.tick);
-}
-
-static void systick_timer_tick(void * opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
- s->systick.control |= SYSTICK_COUNTFLAG;
- if (s->systick.control & SYSTICK_TICKINT) {
- /* Trigger the interrupt. */
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
- }
- if (s->systick.reload == 0) {
- s->systick.control &= ~SYSTICK_ENABLE;
- } else {
- systick_reload(s, 0);
- }
-}
-
-/* The external routines use the hardware vector numbering, ie. the first
- IRQ is #16. The internal GIC routines use #32 as the first IRQ. */
-void armv7m_nvic_set_pending(void *opaque, int irq)
-{
- nvic_state *s = (nvic_state *)opaque;
- if (irq >= 16)
- irq += 16;
- gic_set_pending_private(s->gic, 0, irq);
-}
-
-/* Make pending IRQ active. */
-int armv7m_nvic_acknowledge_irq(void *opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
- uint32_t irq;
-
- irq = gic_acknowledge_irq(s->gic, 0);
- if (irq == 1023)
- cpu_abort(cpu_single_env, "Interrupt but no vector\n");
- if (irq >= 32)
- irq -= 16;
- return irq;
-}
-
-void armv7m_nvic_complete_irq(void *opaque, int irq)
-{
- nvic_state *s = (nvic_state *)opaque;
- if (irq >= 16)
- irq += 16;
- gic_complete_irq(s->gic, 0, irq);
-}
-
-static uint32_t nvic_readl(void *opaque, uint32_t offset)
-{
- nvic_state *s = (nvic_state *)opaque;
- uint32_t val;
- int irq;
-
- switch (offset) {
- case 4: /* Interrupt Control Type. */
- return (GIC_NIRQ / 32) - 1;
- case 0x10: /* SysTick Control and Status. */
- val = s->systick.control;
- s->systick.control &= ~SYSTICK_COUNTFLAG;
- return val;
- case 0x14: /* SysTick Reload Value. */
- return s->systick.reload;
- case 0x18: /* SysTick Current Value. */
- {
- int64_t t;
- if ((s->systick.control & SYSTICK_ENABLE) == 0)
- return 0;
- t = qemu_get_clock(vm_clock);
- if (t >= s->systick.tick)
- return 0;
- val = ((s->systick.tick - (t + 1)) / systick_scale(s)) + 1;
- /* The interrupt in triggered when the timer reaches zero.
- However the counter is not reloaded until the next clock
- tick. This is a hack to return zero during the first tick. */
- if (val > s->systick.reload)
- val = 0;
- return val;
- }
- case 0x1c: /* SysTick Calibration Value. */
- return 10000;
- case 0xd00: /* CPUID Base. */
- return cpu_single_env->cp15.c0_cpuid;
- case 0xd04: /* Interrypt Control State. */
- /* VECTACTIVE */
- val = s->gic->running_irq[0];
- if (val == 1023) {
- val = 0;
- } else if (val >= 32) {
- val -= 16;
- }
- /* RETTOBASE */
- if (s->gic->running_irq[0] == 1023
- || s->gic->last_active[s->gic->running_irq[0]][0] == 1023) {
- val |= (1 << 11);
- }
- /* VECTPENDING */
- if (s->gic->current_pending[0] != 1023)
- val |= (s->gic->current_pending[0] << 12);
- /* ISRPENDING */
- for (irq = 32; irq < GIC_NIRQ; irq++) {
- if (s->gic->irq_state[irq].pending) {
- val |= (1 << 22);
- break;
- }
- }
- /* PENDSTSET */
- if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending)
- val |= (1 << 26);
- /* PENDSVSET */
- if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending)
- val |= (1 << 28);
- /* NMIPENDSET */
- if (s->gic->irq_state[ARMV7M_EXCP_NMI].pending)
- val |= (1 << 31);
- return val;
- case 0xd08: /* Vector Table Offset. */
- return cpu_single_env->v7m.vecbase;
- case 0xd0c: /* Application Interrupt/Reset Control. */
- return 0xfa05000;
- case 0xd10: /* System Control. */
- /* TODO: Implement SLEEPONEXIT. */
- return 0;
- case 0xd14: /* Configuration Control. */
- /* TODO: Implement Configuration Control bits. */
- return 0;
- case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */
- irq = offset - 0xd14;
- val = 0;
- val = s->gic->priority1[irq++][0];
- val = s->gic->priority1[irq++][0] << 8;
- val = s->gic->priority1[irq++][0] << 16;
- val = s->gic->priority1[irq][0] << 24;
- return val;
- case 0xd24: /* System Handler Status. */
- val = 0;
- if (s->gic->irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0);
- if (s->gic->irq_state[ARMV7M_EXCP_BUS].active) val |= (1 << 1);
- if (s->gic->irq_state[ARMV7M_EXCP_USAGE].active) val |= (1 << 3);
- if (s->gic->irq_state[ARMV7M_EXCP_SVC].active) val |= (1 << 7);
- if (s->gic->irq_state[ARMV7M_EXCP_DEBUG].active) val |= (1 << 8);
- if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].active) val |= (1 << 10);
- if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].active) val |= (1 << 11);
- if (s->gic->irq_state[ARMV7M_EXCP_USAGE].pending) val |= (1 << 12);
- if (s->gic->irq_state[ARMV7M_EXCP_MEM].pending) val |= (1 << 13);
- if (s->gic->irq_state[ARMV7M_EXCP_BUS].pending) val |= (1 << 14);
- if (s->gic->irq_state[ARMV7M_EXCP_SVC].pending) val |= (1 << 15);
- if (s->gic->irq_state[ARMV7M_EXCP_MEM].enabled) val |= (1 << 16);
- if (s->gic->irq_state[ARMV7M_EXCP_BUS].enabled) val |= (1 << 17);
- if (s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18);
- return val;
- case 0xd28: /* Configurable Fault Status. */
- /* TODO: Implement Fault Status. */
- cpu_abort(cpu_single_env,
- "Not implemented: Configurable Fault Status.");
- return 0;
- case 0xd2c: /* Hard Fault Status. */
- case 0xd30: /* Debug Fault Status. */
- case 0xd34: /* Mem Manage Address. */
- case 0xd38: /* Bus Fault Address. */
- case 0xd3c: /* Aux Fault Status. */
- /* TODO: Implement fault status registers. */
- goto bad_reg;
- case 0xd40: /* PFR0. */
- return 0x00000030;
- case 0xd44: /* PRF1. */
- return 0x00000200;
- case 0xd48: /* DFR0. */
- return 0x00100000;
- case 0xd4c: /* AFR0. */
- return 0x00000000;
- case 0xd50: /* MMFR0. */
- return 0x00000030;
- case 0xd54: /* MMFR1. */
- return 0x00000000;
- case 0xd58: /* MMFR2. */
- return 0x00000000;
- case 0xd5c: /* MMFR3. */
- return 0x00000000;
- case 0xd60: /* ISAR0. */
- return 0x01141110;
- case 0xd64: /* ISAR1. */
- return 0x02111000;
- case 0xd68: /* ISAR2. */
- return 0x21112231;
- case 0xd6c: /* ISAR3. */
- return 0x01111110;
- case 0xd70: /* ISAR4. */
- return 0x01310102;
- /* TODO: Implement debug registers. */
- default:
- bad_reg:
- cpu_abort(cpu_single_env, "NVIC: Bad read offset 0x%x\n", offset);
- }
-}
-
-static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
-{
- nvic_state *s = (nvic_state *)opaque;
- uint32_t oldval;
- switch (offset) {
- case 0x10: /* SysTick Control and Status. */
- oldval = s->systick.control;
- s->systick.control &= 0xfffffff8;
- s->systick.control |= value & 7;
- if ((oldval ^ value) & SYSTICK_ENABLE) {
- int64_t now = qemu_get_clock(vm_clock);
- if (value & SYSTICK_ENABLE) {
- if (s->systick.tick) {
- s->systick.tick += now;
- qemu_mod_timer(s->systick.timer, s->systick.tick);
- } else {
- systick_reload(s, 1);
- }
- } else {
- qemu_del_timer(s->systick.timer);
- s->systick.tick -= now;
- if (s->systick.tick < 0)
- s->systick.tick = 0;
- }
- } else if ((oldval ^ value) & SYSTICK_CLKSOURCE) {
- /* This is a hack. Force the timer to be reloaded
- when the reference clock is changed. */
- systick_reload(s, 1);
- }
- break;
- case 0x14: /* SysTick Reload Value. */
- s->systick.reload = value;
- break;
- case 0x18: /* SysTick Current Value. Writes reload the timer. */
- systick_reload(s, 1);
- s->systick.control &= ~SYSTICK_COUNTFLAG;
- break;
- case 0xd04: /* Interrupt Control State. */
- if (value & (1 << 31)) {
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI);
- }
- if (value & (1 << 28)) {
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV);
- } else if (value & (1 << 27)) {
- s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending = 0;
- gic_update(s->gic);
- }
- if (value & (1 << 26)) {
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
- } else if (value & (1 << 25)) {
- s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending = 0;
- gic_update(s->gic);
- }
- break;
- case 0xd08: /* Vector Table Offset. */
- cpu_single_env->v7m.vecbase = value & 0xffffff80;
- break;
- case 0xd0c: /* Application Interrupt/Reset Control. */
- if ((value >> 16) == 0x05fa) {
- if (value & 2) {
- cpu_abort(cpu_single_env, "VECTCLRACTIVE not implemented");
- }
- if (value & 5) {
- cpu_abort(cpu_single_env, "System reset");
- }
- }
- break;
- case 0xd10: /* System Control. */
- case 0xd14: /* Configuration Control. */
- /* TODO: Implement control registers. */
- goto bad_reg;
- case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */
- {
- int irq;
- irq = offset - 0xd14;
- s->gic->priority1[irq++][0] = value & 0xff;
- s->gic->priority1[irq++][0] = (value >> 8) & 0xff;
- s->gic->priority1[irq++][0] = (value >> 16) & 0xff;
- s->gic->priority1[irq][0] = (value >> 24) & 0xff;
- gic_update(s->gic);
- }
- break;
- case 0xd24: /* System Handler Control. */
- /* TODO: Real hardware allows you to set/clear the active bits
- under some circumstances. We don't implement this. */
- s->gic->irq_state[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
- s->gic->irq_state[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
- s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
- break;
- case 0xd28: /* Configurable Fault Status. */
- case 0xd2c: /* Hard Fault Status. */
- case 0xd30: /* Debug Fault Status. */
- case 0xd34: /* Mem Manage Address. */
- case 0xd38: /* Bus Fault Address. */
- case 0xd3c: /* Aux Fault Status. */
- goto bad_reg;
- default:
- bad_reg:
- cpu_abort(cpu_single_env, "NVIC: Bad write offset 0x%x\n", offset);
- }
-}
-
-static void nvic_save(QEMUFile *f, void *opaque)
-{
- nvic_state *s = (nvic_state *)opaque;
-
- qemu_put_be32(f, s->systick.control);
- qemu_put_be32(f, s->systick.reload);
- qemu_put_be64(f, s->systick.tick);
- qemu_put_timer(f, s->systick.timer);
-}
-
-static int nvic_load(QEMUFile *f, void *opaque, int version_id)
-{
- nvic_state *s = (nvic_state *)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- s->systick.control = qemu_get_be32(f);
- s->systick.reload = qemu_get_be32(f);
- s->systick.tick = qemu_get_be64(f);
- qemu_get_timer(f, s->systick.timer);
-
- return 0;
-}
-
-qemu_irq *armv7m_nvic_init(CPUState *env)
-{
- nvic_state *s;
- qemu_irq *parent;
-
- parent = arm_pic_init_cpu(env);
- s = (nvic_state *)qemu_mallocz(sizeof(nvic_state));
- s->gic = gic_init(0xe000e000, &parent[ARM_PIC_CPU_IRQ]);
- s->gic->nvic = s;
- s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s);
- if (env->v7m.nvic)
- cpu_abort(env, "CPU can only have one NVIC\n");
- env->v7m.nvic = s;
- register_savevm("armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
- return s->gic->in;
-}
diff --git a/hw/audiodev.h b/hw/audiodev.h
deleted file mode 100644
index 5f4a211..0000000
--- a/hw/audiodev.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* es1370.c */
-int es1370_init (PCIBus *bus, AudioState *s);
-
-/* sb16.c */
-int SB16_init (AudioState *s, qemu_irq *pic);
-
-/* adlib.c */
-int Adlib_init (AudioState *s, qemu_irq *pic);
-
-/* gus.c */
-int GUS_init (AudioState *s, qemu_irq *pic);
-
-/* ac97.c */
-int ac97_init (PCIBus *buf, AudioState *s);
-
-/* cs4231a.c */
-int cs4231a_init (AudioState *s, qemu_irq *pic);
diff --git a/hw/baum.h b/hw/baum.h
deleted file mode 100644
index ac34b30..0000000
--- a/hw/baum.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QEMU Baum
- *
- * Copyright (c) 2008 Samuel Thibault
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* usb device */
-USBDevice *usb_baum_init(void);
-
-/* char device */
-CharDriverState *chr_baum_init(void);
diff --git a/hw/boards.h b/hw/boards.h
deleted file mode 100644
index cfb7c42..0000000
--- a/hw/boards.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Declarations for use by board files for creating devices. */
-
-#ifndef HW_BOARDS_H
-#define HW_BOARDS_H
-
-typedef void QEMUMachineInitFunc(ram_addr_t ram_size, int vga_ram_size,
- const char *boot_device, DisplayState *ds,
- const char *kernel_filename,
- const char *kernel_cmdline,
- const char *initrd_filename,
- const char *cpu_model);
-
-typedef struct QEMUMachine {
- const char *name;
- const char *desc;
- QEMUMachineInitFunc *init;
-#define RAMSIZE_FIXED (1 << 0)
- ram_addr_t ram_require;
- int nodisk_ok;
- struct QEMUMachine *next;
-} QEMUMachine;
-
-int qemu_register_machine(QEMUMachine *m);
-void register_machines(void);
-
-/* Axis ETRAX. */
-extern QEMUMachine bareetraxfs_machine;
-
-/* pc.c */
-extern QEMUMachine pc_machine;
-extern QEMUMachine isapc_machine;
-
-/* ppc.c */
-extern QEMUMachine prep_machine;
-extern QEMUMachine core99_machine;
-extern QEMUMachine heathrow_machine;
-extern QEMUMachine ref405ep_machine;
-extern QEMUMachine taihu_machine;
-
-/* mips_r4k.c */
-extern QEMUMachine mips_machine;
-
-/* mips_jazz.c */
-extern QEMUMachine mips_magnum_machine;
-extern QEMUMachine mips_pica61_machine;
-
-/* mips_malta.c */
-extern QEMUMachine mips_malta_machine;
-
-/* mips_mipssim.c */
-extern QEMUMachine mips_mipssim_machine;
-
-/* shix.c */
-extern QEMUMachine shix_machine;
-
-/* r2d.c */
-extern QEMUMachine r2d_machine;
-
-/* sun4m.c */
-extern QEMUMachine ss5_machine, ss10_machine, ss600mp_machine, ss20_machine;
-extern QEMUMachine voyager_machine, ss_lx_machine, ss4_machine, scls_machine;
-extern QEMUMachine sbook_machine;
-extern QEMUMachine ss2_machine;
-extern QEMUMachine ss1000_machine, ss2000_machine;
-
-/* sun4u.c */
-extern QEMUMachine sun4u_machine;
-extern QEMUMachine sun4v_machine;
-
-/* integratorcp.c */
-extern QEMUMachine integratorcp_machine;
-
-/* versatilepb.c */
-extern QEMUMachine versatilepb_machine;
-extern QEMUMachine versatileab_machine;
-
-/* realview.c */
-extern QEMUMachine realview_machine;
-
-/* spitz.c */
-extern QEMUMachine akitapda_machine;
-extern QEMUMachine spitzpda_machine;
-extern QEMUMachine borzoipda_machine;
-extern QEMUMachine terrierpda_machine;
-
-/* palm.c */
-extern QEMUMachine palmte_machine;
-
-/* nseries.c */
-extern QEMUMachine n800_machine;
-extern QEMUMachine n810_machine;
-
-/* gumstix.c */
-extern QEMUMachine connex_machine;
-extern QEMUMachine verdex_machine;
-
-/* stellaris.c */
-extern QEMUMachine lm3s811evb_machine;
-extern QEMUMachine lm3s6965evb_machine;
-
-/* an5206.c */
-extern QEMUMachine an5206_machine;
-
-/* mcf5208.c */
-extern QEMUMachine mcf5208evb_machine;
-
-/* dummy_m68k.c */
-extern QEMUMachine dummy_m68k_machine;
-
-/* mainstone.c */
-extern QEMUMachine mainstone2_machine;
-
-/* musicpal.c */
-extern QEMUMachine musicpal_machine;
-
-/* tosa.c */
-extern QEMUMachine tosapda_machine;
-
-/* android_arm.c */
-extern QEMUMachine android_arm_machine;
-
-#endif
diff --git a/hw/cdrom.c b/hw/cdrom.c
deleted file mode 100644
index 2aa4d3b..0000000
--- a/hw/cdrom.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * QEMU ATAPI CD-ROM Emulator
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* ??? Most of the ATAPI emulation is still in ide.c. It should be moved
- here. */
-
-#include "qemu-common.h"
-#include "scsi-disk.h"
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
- lba += 150;
- buf[0] = (lba / 75) / 60;
- buf[1] = (lba / 75) % 60;
- buf[2] = lba % 75;
-}
-
-/* same toc as bochs. Return -1 if error or the toc length */
-/* XXX: check this */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
-{
- uint8_t *q;
- int len;
-
- if (start_track > 1 && start_track != 0xaa)
- return -1;
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
- if (start_track <= 1) {
- *q++ = 0; /* reserved */
- *q++ = 0x14; /* ADR, control */
- *q++ = 1; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, 0);
- q += 3;
- } else {
- /* sector 0 */
- cpu_to_be32wu((uint32_t *)q, 0);
- q += 4;
- }
- }
- /* lead out track */
- *q++ = 0; /* reserved */
- *q++ = 0x16; /* ADR, control */
- *q++ = 0xaa; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_be32wu((uint32_t *)q, nb_sectors);
- q += 4;
- }
- len = q - buf;
- cpu_to_be16wu((uint16_t *)buf, len - 2);
- return len;
-}
-
-/* mostly same info as PearPc */
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
-{
- uint8_t *q;
- int len;
-
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa0; /* lead-in */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* first track */
- *q++ = 0x00; /* disk type */
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa1;
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* last track */
- *q++ = 0x00;
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa2; /* lead-out */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_be32wu((uint32_t *)q, nb_sectors);
- q += 4;
- }
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* ADR, control */
- *q++ = 0; /* track number */
- *q++ = 1; /* point */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- if (msf) {
- *q++ = 0;
- lba_to_msf(q, 0);
- q += 3;
- } else {
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- }
-
- len = q - buf;
- cpu_to_be16wu((uint16_t *)buf, len - 2);
- return len;
-}
-
-
diff --git a/hw/devices.h b/hw/devices.h
deleted file mode 100644
index 45fead9..0000000
--- a/hw/devices.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef QEMU_DEVICES_H
-#define QEMU_DEVICES_H
-
-/* Devices that have nowhere better to go. */
-
-/* smc91c111.c */
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
-
-/* ssd0323.c */
-int ssd0323_xfer_ssi(void *opaque, int data);
-void *ssd0323_init(DisplayState *ds, qemu_irq *cmd_p);
-
-/* ads7846.c */
-struct ads7846_state_s;
-uint32_t ads7846_read(void *opaque);
-void ads7846_write(void *opaque, uint32_t value);
-struct ads7846_state_s *ads7846_init(qemu_irq penirq);
-
-/* tsc210x.c */
-struct uwire_slave_s;
-struct mouse_transform_info_s;
-struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio);
-struct uwire_slave_s *tsc2301_init(qemu_irq penirq, qemu_irq kbirq,
- qemu_irq dav, AudioState *audio);
-struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip);
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
-void tsc210x_set_transform(struct uwire_slave_s *chip,
- struct mouse_transform_info_s *info);
-void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down);
-
-/* tsc2005.c */
-void *tsc2005_init(qemu_irq pintdav);
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
-void tsc2005_set_transform(void *opaque, struct mouse_transform_info_s *info);
-
-/* stellaris_input.c */
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
-
-/* blizzard.c */
-void *s1d13745_init(qemu_irq gpio_int, DisplayState *ds);
-void s1d13745_write(void *opaque, int dc, uint16_t value);
-void s1d13745_write_block(void *opaque, int dc,
- void *buf, size_t len, int pitch);
-uint16_t s1d13745_read(void *opaque, int dc);
-
-/* cbus.c */
-struct cbus_s {
- qemu_irq clk;
- qemu_irq dat;
- qemu_irq sel;
-};
-struct cbus_s *cbus_init(qemu_irq dat_out);
-void cbus_attach(struct cbus_s *bus, void *slave_opaque);
-
-void *retu_init(qemu_irq irq, int vilma);
-void *tahvo_init(qemu_irq irq, int betty);
-
-void retu_key_event(void *retu, int state);
-
-/* tusb6010.c */
-struct tusb_s;
-struct tusb_s *tusb6010_init(qemu_irq intr);
-int tusb6010_sync_io(struct tusb_s *s);
-int tusb6010_async_io(struct tusb_s *s);
-void tusb6010_power(struct tusb_s *s, int on);
-
-/* tc6393xb.c */
-struct tc6393xb_s;
-struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq);
-void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line,
- qemu_irq handler);
-qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s);
-
-#endif
diff --git a/hw/dma.c b/hw/dma.c
deleted file mode 100644
index 00c6332..0000000
--- a/hw/dma.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * QEMU DMA emulation
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "isa.h"
-
-/* #define DEBUG_DMA */
-
-#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#ifdef DEBUG_DMA
-#define lwarn(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define linfo(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define ldebug(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#else
-#define lwarn(...)
-#define linfo(...)
-#define ldebug(...)
-#endif
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-struct dma_regs {
- int now[2];
- uint16_t base[2];
- uint8_t mode;
- uint8_t page;
- uint8_t pageh;
- uint8_t dack;
- uint8_t eop;
- DMA_transfer_handler transfer_handler;
- void *opaque;
-};
-
-#define ADDR 0
-#define COUNT 1
-
-static struct dma_cont {
- uint8_t status;
- uint8_t command;
- uint8_t mask;
- uint8_t flip_flop;
- int dshift;
- struct dma_regs regs[4];
-} dma_controllers[2];
-
-enum {
- CMD_MEMORY_TO_MEMORY = 0x01,
- CMD_FIXED_ADDRESS = 0x02,
- CMD_BLOCK_CONTROLLER = 0x04,
- CMD_COMPRESSED_TIME = 0x08,
- CMD_CYCLIC_PRIORITY = 0x10,
- CMD_EXTENDED_WRITE = 0x20,
- CMD_LOW_DREQ = 0x40,
- CMD_LOW_DACK = 0x80,
- CMD_NOT_SUPPORTED = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS
- | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE
- | CMD_LOW_DREQ | CMD_LOW_DACK
-
-};
-
-static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
-
-static void write_page (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].page = data;
-}
-
-static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].pageh = data;
-}
-
-static uint32_t read_page (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].page;
-}
-
-static uint32_t read_pageh (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].pageh;
-}
-
-static inline void init_chan (struct dma_cont *d, int ichan)
-{
- struct dma_regs *r;
-
- r = d->regs + ichan;
- r->now[ADDR] = r->base[ADDR] << d->dshift;
- r->now[COUNT] = 0;
-}
-
-static inline int getff (struct dma_cont *d)
-{
- int ff;
-
- ff = d->flip_flop;
- d->flip_flop = !ff;
- return ff;
-}
-
-static uint32_t read_chan (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan, nreg, iport, ff, val, dir;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
-
- dir = ((r->mode >> 5) & 1) ? -1 : 1;
- ff = getff (d);
- if (nreg)
- val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
- else
- val = r->now[ADDR] + r->now[COUNT] * dir;
-
- ldebug ("read_chan %#x -> %d\n", iport, val);
- return (val >> (d->dshift + (ff << 3))) & 0xff;
-}
-
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan, nreg;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
- if (getff (d)) {
- r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
- init_chan (d, ichan);
- } else {
- r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
- }
-}
-
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan = 0;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* command */
- if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
- dolog ("command %#x not supported\n", data);
- return;
- }
- d->command = data;
- break;
-
- case 0x09:
- ichan = data & 3;
- if (data & 4) {
- d->status |= 1 << (ichan + 4);
- }
- else {
- d->status &= ~(1 << (ichan + 4));
- }
- d->status &= ~(1 << ichan);
- break;
-
- case 0x0a: /* single mask */
- if (data & 4)
- d->mask |= 1 << (data & 3);
- else
- d->mask &= ~(1 << (data & 3));
- break;
-
- case 0x0b: /* mode */
- {
- ichan = data & 3;
-#ifdef DEBUG_DMA
- {
- int op, ai, dir, opmode;
- op = (data >> 2) & 3;
- ai = (data >> 4) & 1;
- dir = (data >> 5) & 1;
- opmode = (data >> 6) & 3;
-
- linfo ("ichan %d, op %d, ai %d, dir %d, opmode %d\n",
- ichan, op, ai, dir, opmode);
- }
-#endif
- d->regs[ichan].mode = data;
- break;
- }
-
- case 0x0c: /* clear flip flop */
- d->flip_flop = 0;
- break;
-
- case 0x0d: /* reset */
- d->flip_flop = 0;
- d->mask = ~0;
- d->status = 0;
- d->command = 0;
- break;
-
- case 0x0e: /* clear mask for all channels */
- d->mask = 0;
- break;
-
- case 0x0f: /* write mask for all channels */
- d->mask = data;
- break;
-
- default:
- dolog ("unknown iport %#x\n", iport);
- break;
- }
-
-#ifdef DEBUG_DMA
- if (0xc != iport) {
- linfo ("write_cont: nport %#06x, ichan % 2d, val %#06x\n",
- nport, ichan, data);
- }
-#endif
-}
-
-static uint32_t read_cont (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int iport, val;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* status */
- val = d->status;
- d->status &= 0xf0;
- break;
- case 0x0f: /* mask */
- val = d->mask;
- break;
- default:
- val = 0;
- break;
- }
-
- ldebug ("read_cont: nport %#06x, iport %#04x val %#x\n", nport, iport, val);
- return val;
-}
-
-int DMA_get_channel_mode (int nchan)
-{
- return dma_controllers[nchan > 3].regs[nchan & 3].mode;
-}
-
-void DMA_hold_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("held cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status |= 1 << (ichan + 4);
-}
-
-void DMA_release_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("released cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status &= ~(1 << (ichan + 4));
-}
-
-static void channel_run (int ncont, int ichan)
-{
- int n;
- struct dma_regs *r = &dma_controllers[ncont].regs[ichan];
-#ifdef DEBUG_DMA
- int dir, opmode;
-
- dir = (r->mode >> 5) & 1;
- opmode = (r->mode >> 6) & 3;
-
- if (dir) {
- dolog ("DMA in address decrement mode\n");
- }
- if (opmode != 1) {
- dolog ("DMA not in single mode select %#x\n", opmode);
- }
-#endif
-
- r = dma_controllers[ncont].regs + ichan;
- n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
- r->now[COUNT], (r->base[COUNT] + 1) << ncont);
- r->now[COUNT] = n;
- ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
-}
-
-void DMA_run (void)
-{
- struct dma_cont *d;
- int icont, ichan;
-
- d = dma_controllers;
-
- for (icont = 0; icont < 2; icont++, d++) {
- for (ichan = 0; ichan < 4; ichan++) {
- int mask;
-
- mask = 1 << ichan;
-
- if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4))))
- channel_run (icont, ichan);
- }
- }
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
- struct dma_regs *r;
- int ichan, ncont;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
-
- r = dma_controllers[ncont].regs + ichan;
- r->transfer_handler = transfer_handler;
- r->opaque = opaque;
-}
-
-int DMA_read_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_read (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len >> 1; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_read (addr + pos, buf, len);
-
- return len;
-}
-
-int DMA_write_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_phys_addr_t addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_write (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_write (addr + pos, buf, len);
-
- return len;
-}
-
-/* request the emulator to transfer a new DMA memory block ASAP */
-void DMA_schedule(int nchan)
-{
- CPUState *env = cpu_single_env;
- if (env)
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-}
-
-static void dma_reset(void *opaque)
-{
- struct dma_cont *d = opaque;
- write_cont (d, (0x0d << d->dshift), 0);
-}
-
-static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
-{
- dolog ("unregistered DMA channel used nchan=%d dma_pos=%d dma_len=%d\n",
- nchan, dma_pos, dma_len);
- return dma_pos;
-}
-
-/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
-static void dma_init2(struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
-{
- static const int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
- int i;
-
- d->dshift = dshift;
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
- register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
- }
- for (i = 0; i < LENOFA (page_port_list); i++) {
- register_ioport_write (page_base + page_port_list[i], 1, 1,
- write_page, d);
- register_ioport_read (page_base + page_port_list[i], 1, 1,
- read_page, d);
- if (pageh_base >= 0) {
- register_ioport_write (pageh_base + page_port_list[i], 1, 1,
- write_pageh, d);
- register_ioport_read (pageh_base + page_port_list[i], 1, 1,
- read_pageh, d);
- }
- }
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + ((i + 8) << dshift), 1, 1,
- write_cont, d);
- register_ioport_read (base + ((i + 8) << dshift), 1, 1,
- read_cont, d);
- }
- qemu_register_reset(dma_reset, d);
- dma_reset(d);
- for (i = 0; i < LENOFA (d->regs); ++i) {
- d->regs[i].transfer_handler = dma_phony_handler;
- }
-}
-
-static void dma_save (QEMUFile *f, void *opaque)
-{
- struct dma_cont *d = opaque;
- int i;
-
- /* qemu_put_8s (f, &d->status); */
- qemu_put_8s (f, &d->command);
- qemu_put_8s (f, &d->mask);
- qemu_put_8s (f, &d->flip_flop);
- qemu_put_be32 (f, d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_put_be32 (f, r->now[0]);
- qemu_put_be32 (f, r->now[1]);
- qemu_put_be16s (f, &r->base[0]);
- qemu_put_be16s (f, &r->base[1]);
- qemu_put_8s (f, &r->mode);
- qemu_put_8s (f, &r->page);
- qemu_put_8s (f, &r->pageh);
- qemu_put_8s (f, &r->dack);
- qemu_put_8s (f, &r->eop);
- }
-}
-
-static int dma_load (QEMUFile *f, void *opaque, int version_id)
-{
- struct dma_cont *d = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- /* qemu_get_8s (f, &d->status); */
- qemu_get_8s (f, &d->command);
- qemu_get_8s (f, &d->mask);
- qemu_get_8s (f, &d->flip_flop);
- d->dshift=qemu_get_be32 (f);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- r->now[0]=qemu_get_be32 (f);
- r->now[1]=qemu_get_be32 (f);
- qemu_get_be16s (f, &r->base[0]);
- qemu_get_be16s (f, &r->base[1]);
- qemu_get_8s (f, &r->mode);
- qemu_get_8s (f, &r->page);
- qemu_get_8s (f, &r->pageh);
- qemu_get_8s (f, &r->dack);
- qemu_get_8s (f, &r->eop);
- }
- return 0;
-}
-
-void DMA_init (int high_page_enable)
-{
- dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
- dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
- register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]);
- register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]);
-}
diff --git a/hw/goldfish_audio.c b/hw/goldfish_audio.c
deleted file mode 100644
index d0a44b5..0000000
--- a/hw/goldfish_audio.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "audio/audio.h"
-#include "qemu_debug.h"
-#include "android/globals.h"
-
-#define DEBUG 1
-
-#if DEBUG
-# define D(...) VERBOSE_PRINT(audio,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-extern void dprint(const char* fmt, ...);
-
-/* define USE_QEMU_AUDIO_IN to 1 to use QEMU's audio subsystem to
- * implement the audio input. if 0, this will try to read a .wav file
- * directly...
- */
-#define USE_QEMU_AUDIO_IN 1
-
-enum {
- /* audio status register */
- AUDIO_INT_STATUS = 0x00,
- /* set this to enable IRQ */
- AUDIO_INT_ENABLE = 0x04,
- /* set these to specify buffer addresses */
- AUDIO_SET_WRITE_BUFFER_1 = 0x08,
- AUDIO_SET_WRITE_BUFFER_2 = 0x0C,
- /* set number of bytes in buffer to write */
- AUDIO_WRITE_BUFFER_1 = 0x10,
- AUDIO_WRITE_BUFFER_2 = 0x14,
-
- /* true if audio input is supported */
- AUDIO_READ_SUPPORTED = 0x18,
- /* buffer to use for audio input */
- AUDIO_SET_READ_BUFFER = 0x1C,
-
- /* driver writes number of bytes to read */
- AUDIO_START_READ = 0x20,
-
- /* number of bytes available in read buffer */
- AUDIO_READ_BUFFER_AVAILABLE = 0x24,
-
- /* AUDIO_INT_STATUS bits */
-
- /* this bit set when it is safe to write more bytes to the buffer */
- AUDIO_INT_WRITE_BUFFER_1_EMPTY = 1U << 0,
- AUDIO_INT_WRITE_BUFFER_2_EMPTY = 1U << 1,
- AUDIO_INT_READ_BUFFER_FULL = 1U << 2,
-};
-
-
-struct goldfish_audio_state {
- struct goldfish_device dev;
- // pointers to our two write buffers
- uint32_t buffer_1, buffer_2;
- uint32_t read_buffer;
- // buffer flags
- uint32_t int_status;
- // irq enable mask for int_status
- uint32_t int_enable;
-
-#if USE_QEMU_AUDIO_IN
- uint32_t read_pos;
- uint32_t read_size;
-#else
- // path to file or device to use for input
- const char* input_source;
- // true if input is a wav file
- int input_is_wav;
- // true if we need to convert stereo -> mono
- int input_is_stereo;
- // file descriptor to use for input
- int input_fd;
-#endif
-
- // number of bytes available in the read buffer
- int read_buffer_available;
-
- // set to 1 or 2 to indicate which buffer we are writing from, or zero if both buffers are empty
- int current_buffer;
-
- // current data to write
- uint8* data_1;
- uint32_t data_1_length;
- uint8* data_2;
- uint32_t data_2_length;
-
-
- // for QEMU sound output
- QEMUSoundCard card;
- SWVoiceOut *voice;
-#if USE_QEMU_AUDIO_IN
- SWVoiceIn* voicein;
-#endif
-};
-
-/* update this whenever you change the goldfish_audio_state structure */
-#define AUDIO_STATE_SAVE_VERSION 1
-
-#define QFIELD_STRUCT struct goldfish_audio_state
-QFIELD_BEGIN(audio_state_fields)
- QFIELD_INT32(buffer_1),
- QFIELD_INT32(buffer_2),
- QFIELD_INT32(read_buffer),
- QFIELD_INT32(int_status),
- QFIELD_INT32(int_enable),
-#if USE_QEMU_AUDIO_IN
- QFIELD_INT32(read_pos),
- QFIELD_INT32(read_size),
-#endif
- QFIELD_INT32(read_buffer_available),
- QFIELD_INT32(current_buffer),
- QFIELD_INT32(data_1_length),
- QFIELD_INT32(data_2_length),
-QFIELD_END
-
-static void audio_state_save( QEMUFile* f, void* opaque )
-{
- struct goldfish_audio_state* s = opaque;
-
- qemu_put_struct(f, audio_state_fields, s);
-
- /* we can't write data_1 and data_2 directly */
- qemu_put_be32( f, s->data_1 - phys_ram_base );
- qemu_put_be32( f, s->data_2 - phys_ram_base );
-}
-
-static int audio_state_load( QEMUFile* f, void* opaque, int version_id )
-{
- struct goldfish_audio_state* s = opaque;
- int ret;
-
- if (version_id != AUDIO_STATE_SAVE_VERSION)
- return -1;
-
- ret = qemu_get_struct(f, audio_state_fields, s);
- if (!ret) {
- s->data_1 = qemu_get_be32(f) + phys_ram_base;
- s->data_2 = qemu_get_be32(f) + phys_ram_base;
- }
- return -1;
-}
-
-static void enable_audio(struct goldfish_audio_state *s, int enable)
-{
- // enable or disable the output voice
- if (s->voice != NULL)
- AUD_set_active_out(s->voice, (enable & (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY)) != 0);
-
- if (s->voicein)
- AUD_set_active_in (s->voicein, (enable & AUDIO_INT_READ_BUFFER_FULL) != 0);
- // reset buffer information
- s->data_1_length = 0;
- s->data_2_length = 0;
- s->current_buffer = 0;
- s->read_pos = 0;
-}
-
-#if USE_QEMU_AUDIO_IN
-static void start_read(struct goldfish_audio_state *s, uint32_t count)
-{
- //printf( "... goldfish audio start_read, count=%d\n", count );
- s->read_size = count;
- s->read_buffer_available = 0;
- s->read_pos = 0;
-}
-#else
-static void start_read(struct goldfish_audio_state *s, uint32_t count)
-{
- uint8 wav_header[44];
- int result;
-
- if (!s->input_source) return;
-
- if (s->input_fd < 0) {
- s->input_fd = open(s->input_source, O_BINARY | O_RDONLY);
-
- if (s->input_fd < 0) {
- fprintf(stderr, "goldfish_audio could not open %s for audio input\n", s->input_source);
- s->input_source = NULL; // set to to avoid endless retries
- return;
- }
-
- // skip WAV header if we have a WAV file
- if (s->input_is_wav) {
- if (read(s->input_fd, wav_header, sizeof(wav_header)) != sizeof(wav_header)) {
- fprintf(stderr, "goldfish_audio could not read WAV file header %s\n", s->input_source);
- s->input_fd = -1;
- s->input_source = NULL; // set to to avoid endless retries
- return;
- }
-
- // is the WAV file stereo?
- s->input_is_stereo = (wav_header[22] == 2);
- } else {
- // assume input from an audio device is stereo
- s->input_is_stereo = 1;
- }
- }
-
- uint8* buffer = (uint8*)phys_ram_base + s->read_buffer;
- if (s->input_is_stereo) {
- // need to read twice as much data
- count *= 2;
- }
-
-try_again:
- result = read(s->input_fd, buffer, count);
- if (result == 0 && s->input_is_wav) {
- // end of file, so seek back to the beginning
- lseek(s->input_fd, sizeof(wav_header), SEEK_SET);
- goto try_again;
- }
-
- if (result > 0 && s->input_is_stereo) {
- // we need to convert stereo to mono
- uint8* src = (uint8*)buffer;
- uint8* dest = src;
- int count = result/2;
- while (count-- > 0) {
- int sample1 = src[0] | (src[1] << 8);
- int sample2 = src[2] | (src[3] << 8);
- int sample = (sample1 + sample2) >> 1;
- dst[0] = (uint8_t) sample;
- dst[1] = (uint8_t)(sample >> 8);
- src += 4;
- dst += 2;
- }
-
- // we reduced the number of bytes by 2
- result /= 2;
- }
-
- s->read_buffer_available = (result > 0 ? result : 0);
- s->int_status |= AUDIO_INT_READ_BUFFER_FULL;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
-}
-#endif
-
-static uint32_t goldfish_audio_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_audio_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case AUDIO_INT_STATUS:
- // return current buffer status flags
- ret = s->int_status & s->int_enable;
- if(ret) {
- goldfish_device_set_irq(&s->dev, 0, 0);
- }
- return ret;
-
- case AUDIO_READ_SUPPORTED:
-#if USE_QEMU_AUDIO_IN
- D("%s: AUDIO_READ_SUPPORTED returns %d", __FUNCTION__,
- (s->voicein != NULL));
- return (s->voicein != NULL);
-#else
- return (s->input_source ? 1 : 0);
-#endif
-
- case AUDIO_READ_BUFFER_AVAILABLE:
- D("%s: AUDIO_READ_BUFFER_AVAILABLE returns %d", __FUNCTION__,
- s->read_buffer_available);
- return s->read_buffer_available;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_audio_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_audio_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- struct goldfish_audio_state *s = opaque;
- offset -= s->dev.base;
-
- switch(offset) {
- case AUDIO_INT_ENABLE:
- /* enable buffer empty interrupts */
- D("%s: AUDIO_INT_ENABLE %d", __FUNCTION__, val );
- enable_audio(s, val);
- s->int_enable = val;
- s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
- case AUDIO_SET_WRITE_BUFFER_1:
- /* save pointer to buffer 1 */
- s->buffer_1 = val;
- break;
- case AUDIO_SET_WRITE_BUFFER_2:
- /* save pointer to buffer 2 */
- s->buffer_2 = val;
- break;
- case AUDIO_WRITE_BUFFER_1:
- /* record that data in buffer 1 is ready to write */
- if (s->current_buffer == 0) s->current_buffer = 1;
- s->data_1 = phys_ram_base + s->buffer_1;
- s->data_1_length = val;
- s->int_status &= ~AUDIO_INT_WRITE_BUFFER_1_EMPTY;
- break;
- case AUDIO_WRITE_BUFFER_2:
- /* record that data in buffer 2 is ready to write */
- if (s->current_buffer == 0) s->current_buffer = 2;
- s->data_2 = phys_ram_base + s->buffer_2;
- s->data_2_length = val;
- s->int_status &= ~AUDIO_INT_WRITE_BUFFER_2_EMPTY;
- break;
-
- case AUDIO_SET_READ_BUFFER:
- /* save pointer to the read buffer */
- s->read_buffer = val;
- D( "%s: AUDIO_SET_READ_BUFFER %p", __FUNCTION__, (void*)val );
- break;
-
- case AUDIO_START_READ:
- D( "%s: AUDIO_START_READ %d", __FUNCTION__, val );
- start_read(s, val);
- s->int_status &= ~AUDIO_INT_READ_BUFFER_FULL;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_audio_write: Bad offset %x\n", offset);
- }
-}
-
-static void goldfish_audio_callback(void *opaque, int free)
-{
- struct goldfish_audio_state *s = opaque;
- int new_status = 0;
-
- /* loop until free is zero or both buffers are empty */
- while (free && s->current_buffer) {
-
- /* write data in buffer 1 */
- while (free && s->current_buffer == 1) {
- int write = s->data_1_length;
- if (write > free) write = free;
-
- int written = AUD_write(s->voice, s->data_1, write);
- if (written) {
- D("%s: sent %d bytes to audio output", __FUNCTION__, write);
- s->data_1 += written;
- s->data_1_length -= written;
- free -= written;
-
- if (s->data_1_length == 0) {
- new_status |= AUDIO_INT_WRITE_BUFFER_1_EMPTY;
- s->current_buffer = (s->data_2_length ? 2 : 0);
- }
- } else {
- break;
- }
- }
-
- /* write data in buffer 2 */
- while (free && s->current_buffer == 2) {
- int write = s->data_2_length;
- if (write > free) write = free;
-
- int written = AUD_write(s->voice, s->data_2, write);
- if (written) {
- D("%s: sent %d bytes to audio output", __FUNCTION__, write);
- s->data_2 += written;
- s->data_2_length -= written;
- free -= written;
-
- if (s->data_2_length == 0) {
- new_status |= AUDIO_INT_WRITE_BUFFER_2_EMPTY;
- s->current_buffer = (s->data_1_length ? 1 : 0);
- }
- } else {
- break;
- }
- }
- }
-
- if (new_status && new_status != s->int_status) {
- s->int_status |= new_status;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- }
-}
-
-#if USE_QEMU_AUDIO_IN
-static void
-goldfish_audio_in_callback(void *opaque, int avail)
-{
- struct goldfish_audio_state *s = opaque;
- int new_status = 0;
-
- if (s->read_pos >= s->read_size)
- return;
-
- if (0 && s->read_size > 0)
- D("%s: in %d (pos=%d size=%d)", __FUNCTION__,
- avail, s->read_pos, s->read_size );
-
- while (avail > 0) {
- int pos = s->read_pos;
- int missing = s->read_size - pos;
- uint8* buffer = (uint8*)phys_ram_base + s->read_buffer + pos;
- int read;
- int avail2 = (avail > missing) ? missing : avail;
-
- read = AUD_read(s->voicein, buffer, avail2);
- if (read == 0)
- break;
-
- if (avail2 > 0)
- D("%s: AUD_read(%d) returned %d", __FUNCTION__, avail2, read);
-
- s->read_buffer_available += read;
-
- avail -= read;
- pos += read;
- if (pos == s->read_size) {
- new_status |= AUDIO_INT_READ_BUFFER_FULL;
- D("%s: AUDIO_INT_READ_BUFFER_FULL available=%d", __FUNCTION__, s->read_buffer_available);
- }
- s->read_pos = pos;
- }
-
- if (new_status && new_status != s->int_status) {
- s->int_status |= new_status;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- }
-}
-#endif /* USE_QEMU_AUDIO_IN */
-
-static CPUReadMemoryFunc *goldfish_audio_readfn[] = {
- goldfish_audio_read,
- goldfish_audio_read,
- goldfish_audio_read
-};
-
-static CPUWriteMemoryFunc *goldfish_audio_writefn[] = {
- goldfish_audio_write,
- goldfish_audio_write,
- goldfish_audio_write
-};
-
-void goldfish_audio_init(uint32_t base, int id, const char* input_source)
-{
- struct goldfish_audio_state *s;
- audsettings_t as;
-
- /* nothing to do if no audio input and output */
- if (!android_hw->hw_audioOutput && !android_hw->hw_audioInput)
- return;
-
- s = (struct goldfish_audio_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_audio";
- s->dev.id = id;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
-
-#ifndef USE_QEMU_AUDIO_IN
- s->input_fd = -1;
- if (input_source) {
- s->input_source = input_source;
- char* extension = strrchr(input_source, '.');
- if (extension && strcasecmp(extension, ".wav") == 0) {
- s->input_is_wav = 1;
- }
- }
-#endif
-
- AUD_register_card( &glob_audio_state, "goldfish_audio", &s->card);
-
- as.freq = 44100;
- as.nchannels = 2;
- as.fmt = AUD_FMT_S16;
- as.endianness = AUDIO_HOST_ENDIANNESS;
-
- if (android_hw->hw_audioOutput) {
- s->voice = AUD_open_out (
- &s->card,
- s->voice,
- "goldfish_audio",
- s,
- goldfish_audio_callback,
- &as
- );
- if (!s->voice) {
- dprint("warning: opening audio output failed\n");
- return;
- }
- }
-
-#if USE_QEMU_AUDIO_IN
- as.freq = 8000;
- as.nchannels = 1;
- as.fmt = AUD_FMT_S16;
- as.endianness = AUDIO_HOST_ENDIANNESS;
-
- if (android_hw->hw_audioInput) {
- s->voicein = AUD_open_in (
- &s->card,
- NULL,
- "goldfish_audio_in",
- s,
- goldfish_audio_in_callback,
- &as
- );
- if (!s->voicein) {
- dprint("warning: opening audio input failed\n");
- }
- }
-#endif
-
- goldfish_device_add(&s->dev, goldfish_audio_readfn, goldfish_audio_writefn, s);
-
- register_savevm( "audio_state", 0, AUDIO_STATE_SAVE_VERSION,
- audio_state_save, audio_state_load, s );
-}
-
diff --git a/hw/goldfish_battery.c b/hw/goldfish_battery.c
deleted file mode 100644
index d9ef785..0000000
--- a/hw/goldfish_battery.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "power_supply.h"
-
-
-enum {
- /* status register */
- BATTERY_INT_STATUS = 0x00,
- /* set this to enable IRQ */
- BATTERY_INT_ENABLE = 0x04,
-
- BATTERY_AC_ONLINE = 0x08,
- BATTERY_STATUS = 0x0C,
- BATTERY_HEALTH = 0x10,
- BATTERY_PRESENT = 0x14,
- BATTERY_CAPACITY = 0x18,
-
- BATTERY_STATUS_CHANGED = 1U << 0,
- AC_STATUS_CHANGED = 1U << 1,
- BATTERY_INT_MASK = BATTERY_STATUS_CHANGED | AC_STATUS_CHANGED,
-};
-
-
-struct goldfish_battery_state {
- struct goldfish_device dev;
- // IRQs
- uint32_t int_status;
- // irq enable mask for int_status
- uint32_t int_enable;
-
- int ac_online;
- int status;
- int health;
- int present;
- int capacity;
-};
-
-/* update this each time you update the battery_state struct */
-#define BATTERY_STATE_SAVE_VERSION 1
-
-#define QFIELD_STRUCT struct goldfish_battery_state
-QFIELD_BEGIN(goldfish_battery_fields)
- QFIELD_INT32(int_status),
- QFIELD_INT32(int_enable),
- QFIELD_INT32(ac_online),
- QFIELD_INT32(status),
- QFIELD_INT32(health),
- QFIELD_INT32(present),
- QFIELD_INT32(capacity),
-QFIELD_END
-
-static void goldfish_battery_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_battery_state* s = opaque;
-
- qemu_put_struct(f, goldfish_battery_fields, s);
-}
-
-static int goldfish_battery_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_battery_state* s = opaque;
-
- if (version_id != BATTERY_STATE_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, goldfish_battery_fields, s);
-}
-
-static struct goldfish_battery_state *battery_state;
-
-static uint32_t goldfish_battery_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_battery_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case BATTERY_INT_STATUS:
- // return current buffer status flags
- ret = s->int_status & s->int_enable;
- if (ret) {
- goldfish_device_set_irq(&s->dev, 0, 0);
- s->int_status = 0;
- }
- return ret;
-
- case BATTERY_INT_ENABLE:
- return s->int_enable;
- case BATTERY_AC_ONLINE:
- return s->ac_online;
- case BATTERY_STATUS:
- return s->status;
- case BATTERY_HEALTH:
- return s->health;
- case BATTERY_PRESENT:
- return s->present;
- case BATTERY_CAPACITY:
- return s->capacity;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_battery_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_battery_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- struct goldfish_battery_state *s = opaque;
- offset -= s->dev.base;
-
- switch(offset) {
- case BATTERY_INT_ENABLE:
- /* enable interrupts */
- s->int_enable = val;
-// s->int_status = (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY);
-// goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_audio_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_battery_readfn[] = {
- goldfish_battery_read,
- goldfish_battery_read,
- goldfish_battery_read
-};
-
-
-static CPUWriteMemoryFunc *goldfish_battery_writefn[] = {
- goldfish_battery_write,
- goldfish_battery_write,
- goldfish_battery_write
-};
-
-void goldfish_battery_init()
-{
- struct goldfish_battery_state *s;
-
- s = (struct goldfish_battery_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish-battery";
- s->dev.base = 0; // will be allocated dynamically
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
-
- // default values for the battery
- s->ac_online = 1;
- s->status = POWER_SUPPLY_STATUS_CHARGING;
- s->health = POWER_SUPPLY_HEALTH_GOOD;
- s->present = 1; // battery is present
- s->capacity = 50; // 50% charged
-
- battery_state = s;
-
- goldfish_device_add(&s->dev, goldfish_battery_readfn, goldfish_battery_writefn, s);
-
- register_savevm( "battery_state", 0, BATTERY_STATE_SAVE_VERSION,
- goldfish_battery_save, goldfish_battery_load, s);
-}
-
-void goldfish_battery_set_prop(int ac, int property, int value)
-{
- int new_status = (ac ? AC_STATUS_CHANGED : BATTERY_STATUS_CHANGED);
-
- if (ac) {
- switch (property) {
- case POWER_SUPPLY_PROP_ONLINE:
- battery_state->ac_online = value;
- break;
- }
- } else {
- switch (property) {
- case POWER_SUPPLY_PROP_STATUS:
- battery_state->status = value;
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- battery_state->health = value;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- battery_state->present = value;
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- battery_state->capacity = value;
- break;
- }
- }
-
- if (new_status != battery_state->int_status) {
- battery_state->int_status |= new_status;
- goldfish_device_set_irq(&battery_state->dev, 0, (battery_state->int_status & battery_state->int_enable));
- }
-}
-
-void goldfish_battery_display(void (* callback)(void *data, const char* string), void *data)
-{
- char buffer[100];
- char* value;
-
- sprintf(buffer, "AC: %s\r\n", (battery_state->ac_online ? "online" : "offline"));
- callback(data, buffer);
-
- switch (battery_state->status) {
- case POWER_SUPPLY_STATUS_CHARGING:
- value = "Charging";
- break;
- case POWER_SUPPLY_STATUS_DISCHARGING:
- value = "Discharging";
- break;
- case POWER_SUPPLY_STATUS_NOT_CHARGING:
- value = "Not charging";
- break;
- case POWER_SUPPLY_STATUS_FULL:
- value = "Full";
- break;
- default:
- value = "Unknown";
- break;
- }
- sprintf(buffer, "status: %s\r\n", value);
- callback(data, buffer);
-
- switch (battery_state->health) {
- case POWER_SUPPLY_HEALTH_GOOD:
- value = "Good";
- break;
- case POWER_SUPPLY_HEALTH_OVERHEAT:
- value = "Overhead";
- break;
- case POWER_SUPPLY_HEALTH_DEAD:
- value = "Dead";
- break;
- case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
- value = "Overvoltage";
- break;
- case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
- value = "Unspecified failure";
- break;
- default:
- value = "Unknown";
- break;
- }
- sprintf(buffer, "health: %s\r\n", value);
- callback(data, buffer);
-
- sprintf(buffer, "present: %s\r\n", (battery_state->present ? "true" : "false"));
- callback(data, buffer);
-
- sprintf(buffer, "capacity: %d\r\n", battery_state->capacity);
- callback(data, buffer);
-}
diff --git a/hw/goldfish_device.c b/hw/goldfish_device.c
deleted file mode 100644
index 2c9dd6e..0000000
--- a/hw/goldfish_device.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "arm_pic.h"
-#include "goldfish_device.h"
-
-#define PDEV_BUS_OP_DONE (0x00)
-#define PDEV_BUS_OP_REMOVE_DEV (0x04)
-#define PDEV_BUS_OP_ADD_DEV (0x08)
-
-#define PDEV_BUS_OP_INIT (0x00)
-
-#define PDEV_BUS_OP (0x00)
-#define PDEV_BUS_GET_NAME (0x04)
-#define PDEV_BUS_NAME_LEN (0x08)
-#define PDEV_BUS_ID (0x0c)
-#define PDEV_BUS_IO_BASE (0x10)
-#define PDEV_BUS_IO_SIZE (0x14)
-#define PDEV_BUS_IRQ (0x18)
-#define PDEV_BUS_IRQ_COUNT (0x1c)
-
-struct bus_state {
- struct goldfish_device dev;
- struct goldfish_device *current;
-};
-
-qemu_irq *goldfish_pic;
-static struct goldfish_device *first_device;
-static struct goldfish_device *last_device;
-uint32_t goldfish_free_base;
-uint32_t goldfish_free_irq;
-
-void goldfish_device_set_irq(struct goldfish_device *dev, int irq, int level)
-{
- if(irq >= dev->irq_count)
- cpu_abort (cpu_single_env, "goldfish_device_set_irq: Bad irq %d >= %d\n", irq, dev->irq_count);
- else
- qemu_set_irq(goldfish_pic[dev->irq + irq], level);
-}
-
-int goldfish_add_device_no_io(struct goldfish_device *dev)
-{
- if(dev->base == 0) {
- dev->base = goldfish_free_base;
- goldfish_free_base += dev->size;
- }
- if(dev->irq == 0 && dev->irq_count > 0) {
- dev->irq = goldfish_free_irq;
- goldfish_free_irq += dev->irq_count;
- }
- //printf("goldfish_add_device: %s, base %x %x, irq %d %d\n",
- // dev->name, dev->base, dev->size, dev->irq, dev->irq_count);
- dev->next = NULL;
- if(last_device) {
- last_device->next = dev;
- }
- else {
- first_device = dev;
- }
- last_device = dev;
- return 0;
-}
-
-int goldfish_device_add(struct goldfish_device *dev,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
-{
- int iomemtype;
- goldfish_add_device_no_io(dev);
- iomemtype = cpu_register_io_memory(0, mem_read,
- mem_write, opaque);
- cpu_register_physical_memory(dev->base, dev->size, iomemtype);
- return 0;
-}
-
-static uint32_t goldfish_bus_read(void *opaque, target_phys_addr_t offset)
-{
- struct bus_state *s = (struct bus_state *)opaque;
- offset -= s->dev.base;
-
- switch (offset) {
- case PDEV_BUS_OP:
- if(s->current) {
- s->current->reported_state = 1;
- s->current = s->current->next;
- }
- else {
- s->current = first_device;
- }
- while(s->current && s->current->reported_state == 1)
- s->current = s->current->next;
- if(s->current)
- return PDEV_BUS_OP_ADD_DEV;
- else {
- goldfish_device_set_irq(&s->dev, 0, 0);
- return PDEV_BUS_OP_DONE;
- }
-
- case PDEV_BUS_NAME_LEN:
- return s->current ? strlen(s->current->name) : 0;
- case PDEV_BUS_ID:
- return s->current ? s->current->id : 0;
- case PDEV_BUS_IO_BASE:
- return s->current ? s->current->base : 0;
- case PDEV_BUS_IO_SIZE:
- return s->current ? s->current->size : 0;
- case PDEV_BUS_IRQ:
- return s->current ? s->current->irq : 0;
- case PDEV_BUS_IRQ_COUNT:
- return s->current ? s->current->irq_count : 0;
- default:
- cpu_abort (cpu_single_env, "goldfish_bus_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_bus_op_init(struct bus_state *s)
-{
- struct goldfish_device *dev = first_device;
- while(dev) {
- dev->reported_state = 0;
- dev = dev->next;
- }
- s->current = NULL;
- goldfish_device_set_irq(&s->dev, 0, first_device != NULL);
-}
-
-static void goldfish_bus_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct bus_state *s = (struct bus_state *)opaque;
- offset -= s->dev.base;
-
- switch(offset) {
- case PDEV_BUS_OP:
- switch(value) {
- case PDEV_BUS_OP_INIT:
- goldfish_bus_op_init(s);
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_bus_write: Bad PDEV_BUS_OP value %x\n", value);
- };
- break;
- case PDEV_BUS_GET_NAME:
- if(s->current)
- pmemcpy(value, s->current->name, strlen(s->current->name));
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_bus_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_bus_readfn[] = {
- goldfish_bus_read,
- goldfish_bus_read,
- goldfish_bus_read
-};
-
-static CPUWriteMemoryFunc *goldfish_bus_writefn[] = {
- goldfish_bus_write,
- goldfish_bus_write,
- goldfish_bus_write
-};
-
-
-static struct bus_state bus_state = {
- .dev = {
- .name = "goldfish_device_bus",
- .id = -1,
- .base = 0x10001000,
- .size = 0x1000,
- .irq = 1,
- .irq_count = 1,
- }
-};
-
-void goldfish_device_init(qemu_irq *pic, uint32_t base, uint32_t size, uint32_t irq, uint32_t irq_count)
-{
- goldfish_pic = pic;
- goldfish_free_base = base;
- goldfish_free_irq = irq;
-}
-
-int goldfish_device_bus_init(uint32_t base, uint32_t irq)
-{
- bus_state.dev.base = base;
- bus_state.dev.irq = irq;
-
- return goldfish_device_add(&bus_state.dev, goldfish_bus_readfn, goldfish_bus_writefn, &bus_state);
-}
-
diff --git a/hw/goldfish_device.h b/hw/goldfish_device.h
deleted file mode 100644
index abe102e..0000000
--- a/hw/goldfish_device.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef GOLDFISH_DEVICE_H
-#define GOLDFISH_DEVICE_H
-
-struct goldfish_device {
- struct goldfish_device *next;
- struct goldfish_device *prev;
- uint32_t reported_state;
- void *cookie;
- const char *name;
- uint32_t id;
- uint32_t base; // filled in by goldfish_device_add if 0
- uint32_t size;
- uint32_t irq; // filled in by goldfish_device_add if 0
- uint32_t irq_count;
-};
-
-
-void goldfish_device_set_irq(struct goldfish_device *dev, int irq, int level);
-int goldfish_device_add(struct goldfish_device *dev,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque);
-
-int goldfish_add_device_no_io(struct goldfish_device *dev);
-
-void goldfish_device_init(qemu_irq *pic, uint32_t base, uint32_t size, uint32_t irq, uint32_t irq_count);
-int goldfish_device_bus_init(uint32_t base, uint32_t irq);
-
-// device init functions:
-qemu_irq *goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq parent_fiq);
-void goldfish_timer_and_rtc_init(uint32_t timerbase, int timerirq);
-int goldfish_tty_add(CharDriverState *cs, int id, uint32_t base, int irq);
-void goldfish_fb_init(DisplayState *ds, int id);
-void goldfish_audio_init(uint32_t base, int id, const char* input_source);
-void goldfish_battery_init();
-void goldfish_battery_set_prop(int ac, int property, int value);
-void goldfish_battery_display(void (* callback)(void *data, const char* string), void *data);
-void goldfish_mmc_init(uint32_t base, int id, BlockDriverState* bs);
-void *goldfish_switch_add(char *name, uint32_t (*writefn)(void *opaque, uint32_t state), void *writeopaque, int id);
-void goldfish_switch_set_state(void *opaque, uint32_t state);
-
-// these do not add a device
-void trace_dev_init(uint32_t base);
-void events_dev_init(uint32_t base, qemu_irq irq);
-void nand_dev_init(uint32_t base);
-
-#endif
diff --git a/hw/goldfish_events_device.c b/hw/goldfish_events_device.c
deleted file mode 100644
index 4cb2904..0000000
--- a/hw/goldfish_events_device.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "android/hw-events.h"
-#include "irq.h"
-
-#if 0
-// From kernel...
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-#define EV_ABS 0x03
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-#define EV_SND 0x12
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-#define EV_FF_STATUS 0x17
-#define EV_MAX 0x1f
-
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-
-#define BTN_GAMEPAD 0x130
-#define BTN_A 0x130
-#define BTN_B 0x131
-#define BTN_C 0x132
-#define BTN_X 0x133
-#define BTN_Y 0x134
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-
-#define REL_X 0x00
-#define REL_Y 0x01
-
-#define ABS_X 0x00
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-#define ABS_RY 0x04
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-#define ABS_WHEEL 0x08
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-#define ABS_HAT0Y 0x11
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-#define ABS_HAT2Y 0x15
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-#define ABS_DISTANCE 0x19
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-#define ABS_VOLUME 0x20
-#define ABS_MISC 0x28
-#define ABS_MAX 0x3f
-#endif
-
-#define MAX_EVENTS 256*4
-
-enum {
- REG_READ = 0x00,
- REG_SET_PAGE = 0x00,
- REG_LEN = 0x04,
- REG_DATA = 0x08,
-
- PAGE_NAME = 0x00000,
- PAGE_EVBITS = 0x10000,
- PAGE_ABSDATA = 0x20000 | EV_ABS,
-};
-
-typedef struct
-{
- uint32_t base;
- qemu_irq irq;
- int pending;
- int page;
-
- unsigned events[MAX_EVENTS];
- unsigned first;
- unsigned last;
-
- const char *name;
- struct {
- size_t len;
- uint8_t *bits;
- } ev_bits[EV_MAX + 1];
- int32_t *abs_info;
- size_t abs_info_count;
-} events_state;
-
-/* modify this each time you change the events_device structure. you
- * will also need to upadte events_state_load and events_state_save
- */
-#define EVENTS_STATE_SAVE_VERSION 1
-
-#undef QFIELD_STRUCT
-#define QFIELD_STRUCT events_state
-
-QFIELD_BEGIN(events_state_fields)
- QFIELD_INT32(pending),
- QFIELD_INT32(page),
- QFIELD_BUFFER(events),
- QFIELD_INT32(first),
- QFIELD_INT32(last),
-QFIELD_END
-
-static void events_state_save(QEMUFile* f, void* opaque)
-{
- events_state* s = opaque;
-
- qemu_put_struct(f, events_state_fields, s);
-}
-
-static int events_state_load(QEMUFile* f, void* opaque, int version_id)
-{
- events_state* s = opaque;
-
- if (version_id != EVENTS_STATE_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, events_state_fields, s);
-}
-
-extern const char* android_skin_keycharmap;
-
-static void enqueue_event(events_state *s, unsigned int type, unsigned int code, int value)
-{
- int enqueued = s->last - s->first;
-
- if (enqueued < 0)
- enqueued += MAX_EVENTS;
-
- if (enqueued + 3 >= MAX_EVENTS-1) {
- fprintf(stderr, "##KBD: Full queue, lose event\n");
- return;
- }
-
- if(s->first == s->last){
- qemu_irq_raise(s->irq);
- }
-
- //fprintf(stderr, "##KBD: type=%d code=%d value=%d\n", type, code, value);
-
- s->events[s->last] = type;
- s->last = (s->last + 1) & (MAX_EVENTS-1);
- s->events[s->last] = code;
- s->last = (s->last + 1) & (MAX_EVENTS-1);
- s->events[s->last] = value;
- s->last = (s->last + 1) & (MAX_EVENTS-1);
-}
-
-static unsigned dequeue_event(events_state *s)
-{
- unsigned n;
-
- if(s->first == s->last) {
- return 0;
- }
-
- n = s->events[s->first];
-
- s->first = (s->first + 1) & (MAX_EVENTS - 1);
-
- if(s->first == s->last) {
- qemu_irq_lower(s->irq);
- }
-
- return n;
-}
-
-static int get_page_len(events_state *s)
-{
- int page = s->page;
- if (page == PAGE_NAME)
- return strlen(s->name);
- if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX)
- return s->ev_bits[page - PAGE_EVBITS].len;
- if (page == PAGE_ABSDATA)
- return s->abs_info_count * sizeof(s->abs_info[0]);
- return 0;
-}
-
-static int get_page_data(events_state *s, int offset)
-{
- int page_len = get_page_len(s);
- int page = s->page;
- if (offset > page_len)
- return 0;
- if (page == PAGE_NAME)
- return s->name[offset];
- if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX)
- return s->ev_bits[page - PAGE_EVBITS].bits[offset];
- if (page == PAGE_ABSDATA)
- return s->abs_info[offset / sizeof(s->abs_info[0])];
- return 0;
-}
-
-static uint32_t events_read(void *x, target_phys_addr_t off)
-{
- events_state *s = (events_state *) x;
- int offset = off - s->base;
- if (offset == REG_READ)
- return dequeue_event(s);
- else if (offset == REG_LEN)
- return get_page_len(s);
- else if (offset >= REG_DATA)
- return get_page_data(s, offset - REG_DATA);
- return 0; // this shouldn't happen, if the driver does the right thing
-}
-
-static void events_write(void *x, target_phys_addr_t off, uint32_t val)
-{
- events_state *s = (events_state *) x;
- int offset = off - s->base;
- if (offset == REG_SET_PAGE)
- s->page = val;
-}
-
-static CPUReadMemoryFunc *events_readfn[] = {
- events_read,
- events_read,
- events_read
-};
-
-static CPUWriteMemoryFunc *events_writefn[] = {
- events_write,
- events_write,
- events_write
-};
-
-static void events_put_keycode(void *x, int keycode)
-{
- events_state *s = (events_state *) x;
-
- enqueue_event(s, EV_KEY, keycode&0x1ff, (keycode&0x200) ? 1 : 0);
-}
-
-static void events_put_mouse(void *opaque, int dx, int dy, int dz, int buttons_state)
-{
- events_state *s = (events_state *) opaque;
- if (dz == 0) {
- enqueue_event(s, EV_ABS, ABS_X, dx);
- enqueue_event(s, EV_ABS, ABS_Y, dy);
- enqueue_event(s, EV_ABS, ABS_Z, dz);
- enqueue_event(s, EV_KEY, BTN_TOUCH, buttons_state&1);
- } else {
- enqueue_event(s, EV_REL, REL_X, dx);
- enqueue_event(s, EV_REL, REL_Y, dy);
- }
- enqueue_event(s, EV_SYN, 0, 0);
-}
-
-static void events_put_generic(void* opaque, int type, int code, int value)
-{
- events_state *s = (events_state *) opaque;
-
- enqueue_event(s, type, code, value);
-}
-
-static int events_set_bits(events_state *s, int type, int bitl, int bith)
-{
- uint8_t *bits;
- uint8_t maskl, maskh;
- int il, ih;
- il = bitl / 8;
- ih = bith / 8;
- if (ih >= s->ev_bits[type].len) {
- bits = qemu_mallocz(ih + 1);
- if (bits == NULL)
- return -ENOMEM;
- memcpy(bits, s->ev_bits[type].bits, s->ev_bits[type].len);
- qemu_free(s->ev_bits[type].bits);
- s->ev_bits[type].bits = bits;
- s->ev_bits[type].len = ih + 1;
- }
- else
- bits = s->ev_bits[type].bits;
- maskl = 0xffU << (bitl & 7);
- maskh = 0xffU >> (7 - (bith & 7));
- if (il >= ih)
- maskh &= maskl;
- else {
- bits[il] |= maskl;
- while (++il < ih)
- bits[il] = 0xff;
- }
- bits[ih] |= maskh;
- return 0;
-}
-
-#if 0
-static int events_set_abs_info(events_state *s, int axis, int32_t min, int32_t max, int32_t fuzz, int32_t flat)
-{
- int32_t *info;
- if (axis * 4 >= s->abs_info_count) {
- info = qemu_mallocz((axis + 1) * 4 * sizeof(int32_t));
- if (info == NULL)
- return -ENOMEM;
- memcpy(info, s->abs_info, s->abs_info_count);
- qemu_free(s->abs_info);
- s->abs_info = info;
- s->abs_info_count = (axis + 1) * 4;
- }
- else
- info = s->abs_info;
- info += axis * 4;
- *info++ = min;
- *info++ = max;
- *info++ = fuzz;
- *info++ = flat;
-}
-#endif
-
-void events_dev_init(uint32_t base, qemu_irq irq)
-{
- events_state *s;
- int iomemtype;
-
- s = (events_state *) qemu_mallocz(sizeof(events_state));
- s->name = android_skin_keycharmap;
- events_set_bits(s, EV_SYN, EV_SYN, EV_ABS);
- events_set_bits(s, EV_SYN, EV_SW, EV_SW);
- events_set_bits(s, EV_KEY, 1, 0x1ff);
- events_set_bits(s, EV_REL, REL_X, REL_Y);
- events_set_bits(s, EV_ABS, ABS_X, ABS_Z);
- events_set_bits(s, EV_SW, 0, 0);
- iomemtype = cpu_register_io_memory(0, events_readfn, events_writefn, s);
-
- cpu_register_physical_memory(base, 0xfff, iomemtype);
-
- qemu_add_kbd_event_handler(events_put_keycode, s);
- qemu_add_mouse_event_handler(events_put_mouse, s, 1);
- qemu_add_generic_event_handler(events_put_generic, s);
-
- s->base = base;
- s->irq = irq;
-
- s->first = 0;
- s->last = 0;
-
- register_savevm( "events_state", 0, EVENTS_STATE_SAVE_VERSION,
- events_state_save, events_state_load, s );
-}
-
diff --git a/hw/goldfish_fb.c b/hw/goldfish_fb.c
deleted file mode 100644
index 71cede2..0000000
--- a/hw/goldfish_fb.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "android/android.h"
-#include "goldfish_device.h"
-#include "framebuffer.h"
-
-enum {
- FB_GET_WIDTH = 0x00,
- FB_GET_HEIGHT = 0x04,
- FB_INT_STATUS = 0x08,
- FB_INT_ENABLE = 0x0c,
- FB_SET_BASE = 0x10,
- FB_SET_ROTATION = 0x14,
- FB_SET_BLANK = 0x18,
- FB_GET_PHYS_WIDTH = 0x1c,
- FB_GET_PHYS_HEIGHT = 0x20,
-
- FB_INT_VSYNC = 1U << 0,
- FB_INT_BASE_UPDATE_DONE = 1U << 1
-};
-
-struct goldfish_fb_state {
- struct goldfish_device dev;
- QFrameBuffer* qfbuff;
- uint32_t fb_base;
- uint32_t base_valid : 1;
- uint32_t need_update : 1;
- uint32_t need_int : 1;
- uint32_t set_rotation : 2;
- uint32_t blank : 1;
- uint32_t int_status;
- uint32_t int_enable;
- int rotation; /* 0, 1, 2 or 3 */
-};
-
-#define GOLDFISH_FB_SAVE_VERSION 1
-
-static void goldfish_fb_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_fb_state* s = opaque;
-
- QFrameBuffer* q = s->qfbuff;
-
- qemu_put_be32(f, q->width);
- qemu_put_be32(f, q->height);
- qemu_put_be32(f, q->pitch);
- qemu_put_byte(f, q->rotation);
-
- qemu_put_be32(f, s->fb_base);
- qemu_put_byte(f, s->base_valid);
- qemu_put_byte(f, s->need_update);
- qemu_put_byte(f, s->need_int);
- qemu_put_byte(f, s->set_rotation);
- qemu_put_byte(f, s->blank);
- qemu_put_be32(f, s->int_status);
- qemu_put_be32(f, s->int_enable);
- qemu_put_be32(f, s->rotation);
-}
-
-static int goldfish_fb_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_fb_state* s = opaque;
-
- QFrameBuffer* q = s->qfbuff;
- int ret = -1;
- int ds_w, ds_h, ds_pitch, ds_rot;
-
- if (version_id != GOLDFISH_FB_SAVE_VERSION)
- goto Exit;
-
- ds_w = qemu_get_be32(f);
- ds_h = qemu_get_be32(f);
- ds_pitch = qemu_get_be32(f);
- ds_rot = qemu_get_byte(f);
-
- if (q->width != ds_w ||
- q->height != ds_h ||
- q->pitch != ds_pitch ||
- q->rotation != ds_rot )
- {
- /* XXX: We should be able to force a resize/rotation from here ? */
- fprintf(stderr, "%s: framebuffer dimensions mismatch\n", __FUNCTION__);
- goto Exit;
- }
-
- s->fb_base = qemu_get_be32(f);
- s->base_valid = qemu_get_byte(f);
- s->need_update = qemu_get_byte(f);
- s->need_int = qemu_get_byte(f);
- s->set_rotation = qemu_get_byte(f);
- s->blank = qemu_get_byte(f);
- s->int_status = qemu_get_be32(f);
- s->int_enable = qemu_get_be32(f);
- s->rotation = qemu_get_be32(f);
-
- /* force a refresh */
- s->need_update = 1;
-
- ret = 0;
-Exit:
- return ret;
-}
-
-
-#define STATS 0
-
-#if STATS
-static int stats_counter;
-static long stats_total;
-static int stats_full_updates;
-static long stats_total_full_updates;
-#endif
-
-static void goldfish_fb_update_display(void *opaque)
-{
- struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
- uint32_t addr;
- uint32_t base;
-
- uint8_t* dst_line;
- uint8_t* src_line;
- int y_first, y_last = 0;
- int full_update = 0;
- int width, height, pitch;
-
- base = s->fb_base;
- if(base == 0)
- return;
-
- if((s->int_enable & FB_INT_VSYNC) && !(s->int_status & FB_INT_VSYNC)) {
- s->int_status |= FB_INT_VSYNC;
- goldfish_device_set_irq(&s->dev, 0, 1);
- }
-
- y_first = -1;
- addr = base;
- if(s->need_update) {
- full_update = 1;
- if(s->need_int) {
- s->int_status |= FB_INT_BASE_UPDATE_DONE;
- if(s->int_enable & FB_INT_BASE_UPDATE_DONE)
- goldfish_device_set_irq(&s->dev, 0, 1);
- }
- s->need_int = 0;
- s->need_update = 0;
- }
-
- src_line = phys_ram_base + base;
- dst_line = s->qfbuff->pixels;
- pitch = s->qfbuff->pitch;
- width = s->qfbuff->width;
- height = s->qfbuff->height;
-
-#if STATS
- if (full_update)
- stats_full_updates += 1;
- if (++stats_counter == 120) {
- stats_total += stats_counter;
- stats_total_full_updates += stats_full_updates;
-
- printf( "full update stats: peak %.2f %% total %.2f %%\n",
- stats_full_updates*100.0/stats_counter,
- stats_total_full_updates*100.0/stats_total );
-
- stats_counter = 0;
- stats_full_updates = 0;
- }
-#endif /* STATS */
-
- if (s->blank)
- {
- memset( dst_line, 0, height*pitch );
- y_first = 0;
- y_last = height-1;
- }
- else if (full_update)
- {
- int yy;
-
- for (yy = 0; yy < height; yy++, dst_line += pitch, src_line += width*2)
- {
- uint16_t* src = (uint16_t*) src_line;
- uint16_t* dst = (uint16_t*) dst_line;
- int nn;
-
- for (nn = 0; nn < width; nn++) {
- unsigned spix = src[nn];
- unsigned dpix = dst[nn];
-#if WORDS_BIGENDIAN
- spix = ((spix << 8) | (spix >> 8)) & 0xffff;
-#else
- if (spix != dpix)
- break;
-#endif
- }
-
- if (nn == width)
- continue;
-
-#if WORDS_BIGENDIAN
- for ( ; nn < width; nn++ ) {
- unsigned spix = src[nn];
- dst[nn] = (uint16_t)((spix << 8) | (spix >> 8));
- }
-#else
- memcpy( dst+nn, src+nn, (width-nn)*2 );
-#endif
-
- y_first = (y_first < 0) ? yy : y_first;
- y_last = yy;
- }
- }
- else /* not a full update, should not happen very often with Android */
- {
- int yy;
-
- for (yy = 0; yy < height; yy++, dst_line += pitch, src_line += width*2)
- {
- uint16_t* src = (uint16_t*) src_line;
- uint16_t* dst = (uint16_t*) dst_line;
- int len = width*2;
-#if WORDS_BIGENDIAN
- int nn;
-#endif
- int dirty = 0;
-
- while (len > 0) {
- int len2 = TARGET_PAGE_SIZE - (addr & (TARGET_PAGE_SIZE-1));
-
- if (len2 > len)
- len2 = len;
-
- dirty |= cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
- addr += len2;
- len -= len2;
- }
-
- if (!dirty)
- continue;
-
-#if WORDS_BIGENDIAN
- for (nn = 0; nn < width; nn++ ) {
- unsigned spix = src[nn];
- dst[nn] = (uint16_t)((spix << 8) | (spix >> 8));
- }
-#else
- memcpy( dst, src, width*2 );
-#endif
-
- y_first = (y_first < 0) ? yy : y_first;
- y_last = yy;
- }
- }
-
- if (y_first < 0)
- return;
-
- y_last += 1;
- //printf("goldfish_fb_update_display %d %d, base %x\n", first, last, base);
-
- cpu_physical_memory_reset_dirty(base + y_first * width * 2,
- base + y_last * width * 2,
- VGA_DIRTY_FLAG);
-
- qframebuffer_update( s->qfbuff, 0, y_first, width, y_last-y_first );
-}
-
-static void goldfish_fb_invalidate_display(void * opaque)
-{
- // is this called?
- struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
- s->need_update = 1;
-}
-
-static void goldfish_fb_detach_display(void* opaque)
-{
- struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque;
- s->qfbuff = NULL;
-}
-
-static uint32_t goldfish_fb_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_fb_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case FB_GET_WIDTH:
- ret = s->qfbuff->width;
- //printf("FB_GET_WIDTH => %d\n", ret);
- return ret;
-
- case FB_GET_HEIGHT:
- ret = s->qfbuff->height;
- //printf( "FB_GET_HEIGHT = %d\n", ret);
- return ret;
-
- case FB_INT_STATUS:
- ret = s->int_status & s->int_enable;
- if(ret) {
- s->int_status &= ~ret;
- goldfish_device_set_irq(&s->dev, 0, 0);
- }
- return ret;
-
- case FB_GET_PHYS_WIDTH:
- ret = s->qfbuff->phys_width_mm;
- //printf( "FB_GET_PHYS_WIDTH => %d\n", ret );
- return ret;
-
- case FB_GET_PHYS_HEIGHT:
- ret = s->qfbuff->phys_height_mm;
- //printf( "FB_GET_PHYS_HEIGHT => %d\n", ret );
- return ret;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_fb_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_fb_write(void *opaque, target_phys_addr_t offset,
- uint32_t val)
-{
- struct goldfish_fb_state *s = opaque;
- offset -= s->dev.base;
- switch(offset) {
- case FB_INT_ENABLE:
- s->int_enable = val;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
- case FB_SET_BASE: {
- int need_resize = !s->base_valid;
- s->fb_base = val;
- s->int_status &= ~FB_INT_BASE_UPDATE_DONE;
- s->need_update = 1;
- s->need_int = 1;
- s->base_valid = 1;
- if(s->set_rotation != s->rotation) {
- //printf("FB_SET_BASE: rotation : %d => %d\n", s->rotation, s->set_rotation);
- s->rotation = s->set_rotation;
- need_resize = 1;
- }
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- if (need_resize) {
- //printf("FB_SET_BASE: need resize (rotation=%d)\n", s->rotation );
- qframebuffer_rotate( s->qfbuff, s->rotation );
- }
- } break;
- case FB_SET_ROTATION:
- //printf( "FB_SET_ROTATION %d\n", val);
- s->set_rotation = val;
- break;
- case FB_SET_BLANK:
- s->blank = val;
- s->need_update = 1;
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_fb_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_fb_readfn[] = {
- goldfish_fb_read,
- goldfish_fb_read,
- goldfish_fb_read
-};
-
-static CPUWriteMemoryFunc *goldfish_fb_writefn[] = {
- goldfish_fb_write,
- goldfish_fb_write,
- goldfish_fb_write
-};
-
-void goldfish_fb_init(DisplayState *ds, int id)
-{
- struct goldfish_fb_state *s;
-
- s = (struct goldfish_fb_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_fb";
- s->dev.id = id;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
-
- s->qfbuff = qframebuffer_fifo_get();
- qframebuffer_set_producer( s->qfbuff, s,
- goldfish_fb_update_display,
- goldfish_fb_invalidate_display,
- goldfish_fb_detach_display );
-
- goldfish_device_add(&s->dev, goldfish_fb_readfn, goldfish_fb_writefn, s);
-
- register_savevm( "goldfish_fb", 0, GOLDFISH_FB_SAVE_VERSION,
- goldfish_fb_save, goldfish_fb_load, s);
-}
-
diff --git a/hw/goldfish_interrupt.c b/hw/goldfish_interrupt.c
deleted file mode 100644
index 2cba649..0000000
--- a/hw/goldfish_interrupt.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "arm_pic.h"
-#include "goldfish_device.h"
-#include "irq.h"
-
-enum {
- INTERRUPT_STATUS = 0x00, // number of pending interrupts
- INTERRUPT_NUMBER = 0x04,
- INTERRUPT_DISABLE_ALL = 0x08,
- INTERRUPT_DISABLE = 0x0c,
- INTERRUPT_ENABLE = 0x10
-};
-
-struct goldfish_int_state {
- struct goldfish_device dev;
- uint32_t level;
- uint32_t pending_count;
- uint32_t irq_enabled;
- uint32_t fiq_enabled;
- qemu_irq parent_irq;
- qemu_irq parent_fiq;
-};
-
-#define GOLDFISH_INT_SAVE_VERSION 1
-
-#define QFIELD_STRUCT struct goldfish_int_state
-QFIELD_BEGIN(goldfish_int_fields)
- QFIELD_INT32(level),
- QFIELD_INT32(pending_count),
- QFIELD_INT32(irq_enabled),
- QFIELD_INT32(fiq_enabled),
-QFIELD_END
-
-static void goldfish_int_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_int_state* s = opaque;
-
- qemu_put_struct(f, goldfish_int_fields, s);
-}
-
-static int goldfish_int_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_int_state* s = opaque;
-
- if (version_id != GOLDFISH_INT_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, goldfish_int_fields, s);
-}
-
-static void goldfish_int_update(struct goldfish_int_state *s)
-{
- uint32_t flags;
-
- flags = (s->level & s->irq_enabled);
- qemu_set_irq(s->parent_irq, flags != 0);
-
- flags = (s->level & s->fiq_enabled);
- qemu_set_irq(s->parent_fiq, flags != 0);
-}
-
-static void goldfish_int_set_irq(void *opaque, int irq, int level)
-{
- struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
- uint32_t mask = (1U << irq);
-
- if(level) {
- if(!(s->level & mask)) {
- if(s->irq_enabled & mask)
- s->pending_count++;
- s->level |= mask;
- }
- }
- else {
- if(s->level & mask) {
- if(s->irq_enabled & mask)
- s->pending_count--;
- s->level &= ~mask;
- }
- }
- goldfish_int_update(s);
-}
-
-static uint32_t goldfish_int_read(void *opaque, target_phys_addr_t offset)
-{
- struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
- offset -= s->dev.base;
-
- switch (offset) {
- case INTERRUPT_STATUS: /* IRQ_STATUS */
- return s->pending_count;
- case INTERRUPT_NUMBER: {
- int i;
- uint32_t pending = s->level & s->irq_enabled;
- for(i = 0; i < 32; i++) {
- if(pending & (1U << i))
- return i;
- }
- return 0;
- }
- default:
- cpu_abort (cpu_single_env, "goldfish_int_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_int_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
- uint32_t mask = (1U << value);
- offset -= s->dev.base;
-
- switch (offset) {
- case INTERRUPT_DISABLE_ALL:
- s->pending_count = 0;
- s->level = 0;
- break;
-
- case INTERRUPT_DISABLE:
- if(s->irq_enabled & mask) {
- if(s->level & mask)
- s->pending_count--;
- s->irq_enabled &= ~mask;
- }
- break;
- case INTERRUPT_ENABLE:
- if(!(s->irq_enabled & mask)) {
- s->irq_enabled |= mask;
- if(s->level & mask)
- s->pending_count++;
- }
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_int_write: Bad offset %x\n", offset);
- return;
- }
- goldfish_int_update(s);
-}
-
-static CPUReadMemoryFunc *goldfish_int_readfn[] = {
- goldfish_int_read,
- goldfish_int_read,
- goldfish_int_read
-};
-
-static CPUWriteMemoryFunc *goldfish_int_writefn[] = {
- goldfish_int_write,
- goldfish_int_write,
- goldfish_int_write
-};
-
-qemu_irq* goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq parent_fiq)
-{
- int ret;
- struct goldfish_int_state *s;
- qemu_irq* qi;
-
- s = qemu_mallocz(sizeof(*s));
- qi = qemu_allocate_irqs(goldfish_int_set_irq, s, 32);
- s->dev.name = "goldfish_interrupt_controller";
- s->dev.id = -1;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->parent_irq = parent_irq;
- s->parent_fiq = parent_fiq;
-
- ret = goldfish_device_add(&s->dev, goldfish_int_readfn, goldfish_int_writefn, s);
- if(ret) {
- qemu_free(s);
- return NULL;
- }
-
- register_savevm( "goldfish_int", 0, GOLDFISH_INT_SAVE_VERSION,
- goldfish_int_save, goldfish_int_load, s);
-
- return qi;
-}
-
diff --git a/hw/goldfish_memlog.c b/hw/goldfish_memlog.c
deleted file mode 100644
index 98fcffc..0000000
--- a/hw/goldfish_memlog.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "audio/audio.h"
-
-extern void dprint(const char* fmt, ...);
-
-int fd = -1;
-
-static uint32_t memlog_read(void *opaque, target_phys_addr_t offset)
-{
- struct goldfish_device *dev = opaque;
- offset -= dev->base;
-
- return 0;
-}
-
-unsigned info[8];
-
-static void memlog_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- char buf[128];
- struct goldfish_device *dev = opaque;
- offset -= dev->base;
-
- info[offset / 4] = val;
-
- if (offset == 0) {
- /* write PID and VADDR to logfile */
- sprintf(buf,"%08x %08x\n", info[0], info[1]);
- write(fd, buf, strlen(buf));
- }
-}
-
-
-static CPUReadMemoryFunc *memlog_readfn[] = {
- memlog_read,
- memlog_read,
- memlog_read
-};
-
-static CPUWriteMemoryFunc *memlog_writefn[] = {
- memlog_write,
- memlog_write,
- memlog_write
-};
-
-struct goldfish_device memlog_dev;
-
-void goldfish_memlog_init(uint32_t base)
-{
- struct goldfish_device *dev = &memlog_dev;
-
- dev->name = "goldfish_memlog";
- dev->id = 0;
- dev->base = base;
- dev->size = 0x1000;
- dev->irq_count = 0;
-
- fd = open("mem.log", /* O_CREAT | */ O_TRUNC | O_WRONLY, 0644);
-
- goldfish_device_add(dev, memlog_readfn, memlog_writefn, dev);
-}
-
diff --git a/hw/goldfish_mmc.c b/hw/goldfish_mmc.c
deleted file mode 100644
index 272f403..0000000
--- a/hw/goldfish_mmc.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-#include "mmc.h"
-#include "sd.h"
-#include "block.h"
-
-enum {
- /* status register */
- MMC_INT_STATUS = 0x00,
- /* set this to enable IRQ */
- MMC_INT_ENABLE = 0x04,
- /* set this to specify buffer address */
- MMC_SET_BUFFER = 0x08,
-
- /* MMC command number */
- MMC_CMD = 0x0C,
-
- /* MMC argument */
- MMC_ARG = 0x10,
-
- /* MMC response (or R2 bits 0 - 31) */
- MMC_RESP_0 = 0x14,
-
- /* MMC R2 response bits 32 - 63 */
- MMC_RESP_1 = 0x18,
-
- /* MMC R2 response bits 64 - 95 */
- MMC_RESP_2 = 0x1C,
-
- /* MMC R2 response bits 96 - 127 */
- MMC_RESP_3 = 0x20,
-
- MMC_BLOCK_LENGTH = 0x24,
- MMC_BLOCK_COUNT = 0x28,
-
- /* MMC state flags */
- MMC_STATE = 0x2C,
-
- /* MMC_INT_STATUS bits */
-
- MMC_STAT_END_OF_CMD = 1U << 0,
- MMC_STAT_END_OF_DATA = 1U << 1,
- MMC_STAT_STATE_CHANGE = 1U << 2,
-
- /* MMC_STATE bits */
- MMC_STATE_INSERTED = 1U << 0,
- MMC_STATE_READ_ONLY = 1U << 1,
-};
-
-
-struct goldfish_mmc_state {
- struct goldfish_device dev;
- BlockDriverState *bs;
- // pointer to our buffer
- uint8_t* buffer;
- // offsets for read and write operations
- uint32_t read_offset, write_offset;
- // buffer status flags
- uint32_t int_status;
- // irq enable mask for int_status
- uint32_t int_enable;
-
- // MMC command argument
- uint32_t arg;
- uint32_t resp[4];
-
- uint32_t block_length;
- uint32_t block_count;
- int is_SDHC;
-};
-
-#define GOLDFISH_MMC_SAVE_VERSION 1
-#define QFIELD_STRUCT struct goldfish_mmc_state
-QFIELD_BEGIN(goldfish_mmc_fields)
- QFIELD_INT32(read_offset),
- QFIELD_INT32(write_offset),
- QFIELD_INT32(int_status),
- QFIELD_INT32(int_enable),
- QFIELD_INT32(arg),
- QFIELD_INT32(resp[0]),
- QFIELD_INT32(resp[1]),
- QFIELD_INT32(resp[2]),
- QFIELD_INT32(resp[3]),
- QFIELD_INT32(block_length),
- QFIELD_INT32(block_count),
- QFIELD_INT32(is_SDHC),
-QFIELD_END
-
-static void goldfish_mmc_save(QEMUFile* f, void* opaque)
-{
- struct goldfish_mmc_state* s = opaque;
-
- qemu_put_be32(f, s->buffer - phys_ram_base);
- qemu_put_struct(f, goldfish_mmc_fields, s);
-}
-
-static int goldfish_mmc_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct goldfish_mmc_state* s = opaque;
-
- if (version_id != GOLDFISH_MMC_SAVE_VERSION)
- return -1;
-
- s->buffer = qemu_get_be32(f) + phys_ram_base;
- return qemu_get_struct(f, goldfish_mmc_fields, s);
-}
-
-struct mmc_opcode {
- const char* name;
- int cmd;
-} mmc_opcodes[] = {
- { "MMC_GO_IDLE_STATE", 0 },
- { "MMC_SEND_OP_COND", 1 },
- { "MMC_ALL_SEND_CID", 2 },
- { "MMC_SET_RELATIVE_ADDR", 3 },
- { "MMC_SET_DSR", 4 },
- { "MMC_SWITCH", 6 },
- { "MMC_SELECT_CARD", 7 },
- { "MMC_SEND_EXT_CSD", 8 },
- { "MMC_SEND_CSD", 9 },
- { "MMC_SEND_CID", 10 },
- { "MMC_READ_DAT_UNTIL_STOP", 11 },
- { "MMC_STOP_TRANSMISSION", 12 },
- { "MMC_SEND_STATUS", 13 },
- { "MMC_GO_INACTIVE_STATE", 15 },
- { "MMC_SET_BLOCKLEN", 16 },
- { "MMC_READ_SINGLE_BLOCK", 17 },
- { "MMC_READ_MULTIPLE_BLOCK", 18 },
- { "MMC_WRITE_DAT_UNTIL_STOP", 20 },
- { "MMC_SET_BLOCK_COUNT", 23 },
- { "MMC_WRITE_BLOCK", 24 },
- { "MMC_WRITE_MULTIPLE_BLOCK", 25 },
- { "MMC_PROGRAM_CID", 26 },
- { "MMC_PROGRAM_CSD", 27 },
- { "MMC_SET_WRITE_PROT", 28 },
- { "MMC_CLR_WRITE_PROT", 29 },
- { "MMC_SEND_WRITE_PROT", 30 },
- { "MMC_ERASE_GROUP_START", 35 },
- { "MMC_ERASE_GROUP_END", 36 },
- { "MMC_ERASE", 38 },
- { "MMC_FAST_IO", 39 },
- { "MMC_GO_IRQ_STATE", 40 },
- { "MMC_LOCK_UNLOCK", 42 },
- { "MMC_APP_CMD", 55 },
- { "MMC_GEN_CMD", 56 },
- { "SD_APP_OP_COND", 41 },
- { "SD_APP_SEND_SCR", 51 },
- { "UNKNOWN", -1 }
-};
-
-#if 0
-static const char* get_command_name(int command)
-{
- struct mmc_opcode* opcode = mmc_opcodes;
-
- while (opcode->cmd != command && opcode->cmd != -1) opcode++;
- return opcode->name;
-}
-#endif
-
-static void goldfish_mmc_do_command(struct goldfish_mmc_state *s, uint32_t cmd, uint32_t arg)
-{
- int result;
- int new_status = MMC_STAT_END_OF_CMD;
- int opcode = cmd & 63;
-
-// fprintf(stderr, "goldfish_mmc_do_command opcode: %s (0x%04X), arg: %d\n", get_command_name(opcode), cmd, arg);
-
- s->resp[0] = 0;
- s->resp[1] = 0;
- s->resp[2] = 0;
- s->resp[3] = 0;
-
-#define SET_R1_CURRENT_STATE(s) ((s << 9) & 0x00001E00) /* sx, b (4 bits) */
-
- switch (opcode) {
- case MMC_SEND_CSD: {
- int64_t sector_count = 0;
- uint64_t capacity;
- uint8_t exponent;
- uint32_t m;
-
- bdrv_get_geometry(s->bs, (uint64_t*)&sector_count);
- capacity = sector_count * 512;
- if (capacity > 2147483648U) {
- // if storages is > 2 gig, then emulate SDHC card
- s->is_SDHC = 1;
-
- // CSD bits borrowed from a real SDHC card, with capacity bits zeroed out
- s->resp[3] = 0x400E0032;
- s->resp[2] = 0x5B590000;
- s->resp[1] = 0x00007F80;
- s->resp[0] = 0x0A4040DF;
-
- // stuff in the real capacity
- // m = UNSTUFF_BITS(resp, 48, 22);
- m = (uint32_t)(capacity / (512*1024)) - 1;
- // m must fit into 22 bits
- if (m & 0xFFC00000) {
- fprintf(stderr, "SD card too big (%lld bytes). Maximum SDHC card size is 128 gigabytes.\n", capacity);
- abort();
- }
-
- // low 16 bits go in high end of resp[1]
- s->resp[1] |= ((m & 0x0000FFFF) << 16);
- // high 6 bits go in low end of resp[2]
- s->resp[2] |= (m >> 16);
- } else {
- // emulate standard SD card
- s->is_SDHC = 0;
-
- // CSD bits borrowed from a real SD card, with capacity bits zeroed out
- s->resp[3] = 0x00260032;
- s->resp[2] = 0x5F5A8000;
- s->resp[1] = 0x3EF84FFF;
- s->resp[0] = 0x928040CB;
-
- // stuff in the real capacity
- // e = UNSTUFF_BITS(resp, 47, 3);
- // m = UNSTUFF_BITS(resp, 62, 12);
- // csd->capacity = (1 + m) << (e + 2);
- // need to reverse the formula and calculate e and m
- exponent = 0;
- capacity = sector_count * 512;
- if (capacity > 2147483648U) {
- fprintf(stderr, "SD card too big (%lld bytes). Maximum SD card size is 2 gigabytes.\n", capacity);
- abort();
- }
- capacity >>= 10; // convert to Kbytes
- while (capacity > 4096) {
- // (capacity - 1) must fit into 12 bits
- exponent++;
- capacity >>= 1;
- }
- capacity -= 1;
- exponent -= 2;
- if (exponent > 7)
- cpu_abort(cpu_single_env, "exponent %d too big\n", exponent);
-
- s->resp[2] |= (((uint32_t)capacity >> 2) & 0x3FF); // high 10 bits to bottom of resp[2]
- s->resp[1] |= (((uint32_t)capacity & 3) << 30); // low 2 bits to top of resp[1]
- s->resp[1] |= (exponent << (47 - 32));
- }
- break;
- }
-
- case MMC_SEND_EXT_CSD:
- s->resp[0] = arg;
- break;
-
- case MMC_APP_CMD:
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA | R1_APP_CMD; //2336
- break;
-
- case SD_APP_OP_COND:
- s->resp[0] = 0x80FF8000;
- break;
-
- case SD_APP_SEND_SCR:
- {
- uint32_t* scr = (uint32_t*)s->buffer;
- scr[0] = 0x00002502;
- scr[1] = 0x00000000;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA | R1_APP_CMD; //2336
- new_status |= MMC_STAT_END_OF_DATA;
- break;
- }
- case MMC_SET_RELATIVE_ADDR:
- s->resp[0] = -518519520;
- break;
-
- case MMC_ALL_SEND_CID:
- s->resp[3] = 55788627;
- s->resp[2] = 1429221959;
- s->resp[1] = -2147479692;
- s->resp[0] = -436179883;
- break;
-
- case MMC_SELECT_CARD:
- s->resp[0] = SET_R1_CURRENT_STATE(3) | R1_READY_FOR_DATA; // 1792
- break;
-
- case MMC_SWITCH:
- if (arg == 0x00FFFFF1 || arg == 0x80FFFFF1) {
- uint8_t* switchbuf = s->buffer;
- memset(switchbuf, 0, 64);
- switchbuf[13] = 2;
- new_status |= MMC_STAT_END_OF_DATA;
- }
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA | R1_APP_CMD; //2336
- break;
-
- case MMC_SET_BLOCKLEN:
- s->block_length = arg;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
-
- case MMC_READ_SINGLE_BLOCK:
- s->block_count = 1;
- // fall through
- case MMC_READ_MULTIPLE_BLOCK: {
- if (s->is_SDHC) {
- // arg is block offset
- } else {
- // arg is byte offset
- if (arg & 511) fprintf(stderr, "offset %d is not multiple of 512 when reading\n", arg);
- arg /= s->block_length;
- }
- result = bdrv_read(s->bs, arg, s->buffer, s->block_count);
- new_status |= MMC_STAT_END_OF_DATA;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
- }
-
- case MMC_WRITE_BLOCK:
- s->block_count = 1;
- // fall through
- case MMC_WRITE_MULTIPLE_BLOCK: {
- if (s->is_SDHC) {
- // arg is block offset
- } else {
- // arg is byte offset
- if (arg & 511) fprintf(stderr, "offset %d is not multiple of 512 when writing\n", arg);
- arg /= s->block_length;
- }
- // arg is byte offset
- result = bdrv_write(s->bs, arg, s->buffer, s->block_count);
-// bdrv_flush(s->bs);
- new_status |= MMC_STAT_END_OF_DATA;
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
- }
-
- case MMC_STOP_TRANSMISSION:
- s->resp[0] = SET_R1_CURRENT_STATE(5) | R1_READY_FOR_DATA; // 2816
- break;
-
- case MMC_SEND_STATUS:
- s->resp[0] = SET_R1_CURRENT_STATE(4) | R1_READY_FOR_DATA; // 2304
- break;
- }
-
- s->int_status |= new_status;
-
- if ((s->int_status & s->int_enable)) {
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- }
-}
-
-static uint32_t goldfish_mmc_read(void *opaque, target_phys_addr_t offset)
-{
- uint32_t ret;
- struct goldfish_mmc_state *s = opaque;
-
- offset -= s->dev.base;
- switch(offset) {
- case MMC_INT_STATUS:
- // return current buffer status flags
- return s->int_status & s->int_enable;
- case MMC_RESP_0:
- return s->resp[0];
- case MMC_RESP_1:
- return s->resp[1];
- case MMC_RESP_2:
- return s->resp[2];
- case MMC_RESP_3:
- return s->resp[3];
- case MMC_STATE: {
- ret = MMC_STATE_INSERTED;
- if (bdrv_is_read_only(s->bs)) {
- ret |= MMC_STATE_READ_ONLY;
- }
- return ret;
- }
- default:
- cpu_abort(cpu_single_env, "goldfish_mmc_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_mmc_write(void *opaque, target_phys_addr_t offset, uint32_t val)
-{
- struct goldfish_mmc_state *s = opaque;
- int status, old_status;
-
- offset -= s->dev.base;
-
- switch(offset) {
-
- case MMC_INT_STATUS:
- status = s->int_status;
- old_status = status;
- status &= ~val;
- s->int_status = status;
- if(status != old_status) {
- goldfish_device_set_irq(&s->dev, 0, status);
- }
- break;
-
- case MMC_INT_ENABLE:
- /* enable buffer interrupts */
- s->int_enable = val;
- s->int_status = 0;
- goldfish_device_set_irq(&s->dev, 0, (s->int_status & s->int_enable));
- break;
- case MMC_SET_BUFFER:
- /* save pointer to buffer 1 */
- s->buffer = phys_ram_base + val;
- break;
- case MMC_CMD:
- goldfish_mmc_do_command(s, val, s->arg);
- break;
- case MMC_ARG:
- s->arg = val;
- break;
- case MMC_BLOCK_LENGTH:
- s->block_length = val + 1;
- break;
- case MMC_BLOCK_COUNT:
- s->block_count = val + 1;
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_mmc_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_mmc_readfn[] = {
- goldfish_mmc_read,
- goldfish_mmc_read,
- goldfish_mmc_read
-};
-
-static CPUWriteMemoryFunc *goldfish_mmc_writefn[] = {
- goldfish_mmc_write,
- goldfish_mmc_write,
- goldfish_mmc_write
-};
-
-void goldfish_mmc_init(uint32_t base, int id, BlockDriverState* bs)
-{
- struct goldfish_mmc_state *s;
-
- s = (struct goldfish_mmc_state *)qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_mmc";
- s->dev.id = id;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
- s->bs = bs;
-
- goldfish_device_add(&s->dev, goldfish_mmc_readfn, goldfish_mmc_writefn, s);
-
- register_savevm( "goldfish_mmc", 0, GOLDFISH_MMC_SAVE_VERSION,
- goldfish_mmc_save, goldfish_mmc_load, s);
-}
-
diff --git a/hw/goldfish_nand.c b/hw/goldfish_nand.c
deleted file mode 100644
index 61b075e..0000000
--- a/hw/goldfish_nand.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_nand_reg.h"
-#include "goldfish_nand.h"
-#include "android/utils/tempfile.h"
-#include "qemu_debug.h"
-#include "android/android.h"
-
-#define DEBUG 1
-#if DEBUG
-# define D(...) VERBOSE_PRINT(nand,__VA_ARGS__)
-# define D_ACTIVE VERBOSE_CHECK(nand)
-# define T(...) VERBOSE_PRINT(nand_limits,__VA_ARGS__)
-# define T_ACTIVE VERBOSE_CHECK(nand_limits)
-#else
-# define D(...) ((void)0)
-# define D_ACTIVE 0
-# define T(...) ((void)0)
-# define T_ACTIVE 0
-#endif
-
-/* lseek uses 64-bit offsets on Darwin. */
-/* prefer lseek64 on Linux */
-#ifdef __APPLE__
-# define llseek lseek
-#elif defined(__linux__)
-# define llseek lseek64
-#endif
-
-#define XLOG xlog
-
-static void
-xlog( const char* format, ... )
-{
- va_list args;
- va_start(args, format);
- fprintf(stderr, "NAND: ");
- vfprintf(stderr, format, args);
- va_end(args);
-}
-
-typedef struct {
- char* devname;
- size_t devname_len;
- char* data;
- int fd;
- uint32_t flags;
- uint32_t page_size;
- uint32_t extra_size;
- uint32_t erase_size;
- uint64_t size;
-} nand_dev;
-
-nand_threshold android_nand_write_threshold;
-nand_threshold android_nand_read_threshold;
-
-#ifdef CONFIG_NAND_THRESHOLD
-
-/* update a threshold, return 1 if limit is hit, 0 otherwise */
-static void
-nand_threshold_update( nand_threshold* t, uint32_t len )
-{
- if (t->counter < t->limit) {
- uint64_t avail = t->limit - t->counter;
- if (avail > len)
- avail = len;
-
- if (t->counter == 0) {
- T("%s: starting threshold counting to %lld",
- __FUNCTION__, t->limit);
- }
- t->counter += avail;
- if (t->counter >= t->limit) {
- /* threshold reach, send a signal to an external process */
- T( "%s: sending signal %d to pid %d !",
- __FUNCTION__, t->signal, t->pid );
-
- kill( t->pid, t->signal );
- }
- }
- return;
-}
-
-#define NAND_UPDATE_READ_THRESHOLD(len) \
- nand_threshold_update( &android_nand_read_threshold, (uint32_t)(len) )
-
-#define NAND_UPDATE_WRITE_THRESHOLD(len) \
- nand_threshold_update( &android_nand_write_threshold, (uint32_t)(len) )
-
-#else /* !NAND_THRESHOLD */
-
-#define NAND_UPDATE_READ_THRESHOLD(len) \
- do {} while (0)
-
-#define NAND_UPDATE_WRITE_THRESHOLD(len) \
- do {} while (0)
-
-#endif /* !NAND_THRESHOLD */
-
-static nand_dev *nand_devs = NULL;
-static uint32_t nand_dev_count = 0;
-
-typedef struct {
- uint32_t base;
-
- // register state
- uint32_t dev;
- uint32_t addr_low;
- uint32_t addr_high;
- uint32_t transfer_size;
- uint32_t data;
- uint32_t result;
-} nand_dev_state;
-
-/* update this everytime you change the nand_dev_state structure */
-#define NAND_DEV_STATE_SAVE_VERSION 1
-
-#define QFIELD_STRUCT nand_dev_state
-QFIELD_BEGIN(nand_dev_state_fields)
- QFIELD_INT32(dev),
- QFIELD_INT32(addr_low),
- QFIELD_INT32(addr_high),
- QFIELD_INT32(transfer_size),
- QFIELD_INT32(data),
- QFIELD_INT32(result),
-QFIELD_END
-
-static void nand_dev_state_save(QEMUFile* f, void* opaque)
-{
- nand_dev_state* s = opaque;
-
- qemu_put_struct(f, nand_dev_state_fields, s);
-}
-
-static int nand_dev_state_load(QEMUFile* f, void* opaque, int version_id)
-{
- nand_dev_state* s = opaque;
-
- if (version_id != NAND_DEV_STATE_SAVE_VERSION)
- return -1;
-
- return qemu_get_struct(f, nand_dev_state_fields, s);
-}
-
-
-static int do_read(int fd, void* buf, size_t size)
-{
- int ret;
- do {
- ret = read(fd, buf, size);
- } while (ret < 0 && errno == EINTR);
-
- return ret;
-}
-
-static int do_write(int fd, const void* buf, size_t size)
-{
- int ret;
- do {
- ret = write(fd, buf, size);
- } while (ret < 0 && errno == EINTR);
-
- return ret;
-}
-
-static uint32_t nand_dev_read_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len)
-{
- uint32_t len = total_len;
- size_t read_len = dev->erase_size;
- int eof = 0;
-
- NAND_UPDATE_READ_THRESHOLD(total_len);
-
- lseek(dev->fd, addr, SEEK_SET);
- while(len > 0) {
- if(read_len < dev->erase_size) {
- memset(dev->data, 0xff, dev->erase_size);
- read_len = dev->erase_size;
- eof = 1;
- }
- if(len < read_len)
- read_len = len;
- if(!eof) {
- read_len = do_read(dev->fd, dev->data, read_len);
- }
- pmemcpy(data, dev->data, read_len);
- data += read_len;
- len -= read_len;
- }
- return total_len;
-}
-
-static uint32_t nand_dev_write_file(nand_dev *dev, uint32_t data, uint64_t addr, uint32_t total_len)
-{
- uint32_t len = total_len;
- size_t write_len = dev->erase_size;
- int ret;
-
- NAND_UPDATE_WRITE_THRESHOLD(total_len);
-
- lseek(dev->fd, addr, SEEK_SET);
- while(len > 0) {
- if(len < write_len)
- write_len = len;
- vmemcpy(data, dev->data, write_len);
- ret = do_write(dev->fd, dev->data, write_len);
- if(ret < write_len) {
- XLOG("nand_dev_write_file, write failed: %s\n", strerror(errno));
- break;
- }
- data += write_len;
- len -= write_len;
- }
- return total_len - len;
-}
-
-static uint32_t nand_dev_erase_file(nand_dev *dev, uint64_t addr, uint32_t total_len)
-{
- uint32_t len = total_len;
- size_t write_len = dev->erase_size;
- int ret;
-
- lseek(dev->fd, addr, SEEK_SET);
- memset(dev->data, 0xff, dev->erase_size);
- while(len > 0) {
- if(len < write_len)
- write_len = len;
- ret = do_write(dev->fd, dev->data, write_len);
- if(ret < write_len) {
- XLOG( "nand_dev_write_file, write failed: %s\n", strerror(errno));
- break;
- }
- len -= write_len;
- }
- return total_len - len;
-}
-
-/* this is a huge hack required to make the PowerPC emulator binary usable
- * on Mac OS X. If you define this function as 'static', the emulated kernel
- * will panic when attempting to mount the /data partition.
- *
- * worse, if you do *not* define the function as static on Linux-x86, the
- * emulated kernel will also panic !?
- *
- * I still wonder if this is a compiler bug, or due to some nasty thing the
- * emulator does with CPU registers during execution of the translated code.
- */
-#if !(defined __APPLE__ && defined __powerpc__)
-static
-#endif
-uint32_t nand_dev_do_cmd(nand_dev_state *s, uint32_t cmd)
-{
- uint32_t size;
- uint64_t addr;
- nand_dev *dev;
-
- addr = s->addr_low | ((uint64_t)s->addr_high << 32);
- size = s->transfer_size;
- if(s->dev >= nand_dev_count)
- return 0;
- dev = nand_devs + s->dev;
-
- switch(cmd) {
- case NAND_CMD_GET_DEV_NAME:
- if(size > dev->devname_len)
- size = dev->devname_len;
- pmemcpy(s->data, dev->devname, size);
- return size;
- case NAND_CMD_READ:
- if(addr >= dev->size)
- return 0;
- if(size + addr > dev->size)
- size = dev->size - addr;
- if(dev->fd >= 0)
- return nand_dev_read_file(dev, s->data, addr, size);
- pmemcpy(s->data, &dev->data[addr], size);
- return size;
- case NAND_CMD_WRITE:
- if(dev->flags & NAND_DEV_FLAG_READ_ONLY)
- return 0;
- if(addr >= dev->size)
- return 0;
- if(size + addr > dev->size)
- size = dev->size - addr;
- if(dev->fd >= 0)
- return nand_dev_write_file(dev, s->data, addr, size);
- vmemcpy(s->data, &dev->data[addr], size);
- return size;
- case NAND_CMD_ERASE:
- if(dev->flags & NAND_DEV_FLAG_READ_ONLY)
- return 0;
- if(addr >= dev->size)
- return 0;
- if(size + addr > dev->size)
- size = dev->size - addr;
- if(dev->fd >= 0)
- return nand_dev_erase_file(dev, addr, size);
- memset(&dev->data[addr], 0xff, size);
- return size;
- case NAND_CMD_BLOCK_BAD_GET: // no bad block support
- return 0;
- case NAND_CMD_BLOCK_BAD_SET:
- if(dev->flags & NAND_DEV_FLAG_READ_ONLY)
- return 0;
- return 0;
- default:
- cpu_abort(cpu_single_env, "nand_dev_do_cmd: Bad command %x\n", cmd);
- return 0;
- }
-}
-
-/* I/O write */
-static void nand_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- nand_dev_state *s = (nand_dev_state *)opaque;
-
- offset -= s->base;
- switch (offset) {
- case NAND_DEV:
- s->dev = value;
- if(s->dev >= nand_dev_count) {
- cpu_abort(cpu_single_env, "nand_dev_write: Bad dev %x\n", value);
- }
- break;
- case NAND_ADDR_HIGH:
- s->addr_high = value;
- break;
- case NAND_ADDR_LOW:
- s->addr_low = value;
- break;
- case NAND_TRANSFER_SIZE:
- s->transfer_size = value;
- break;
- case NAND_DATA:
- s->data = value;
- break;
- case NAND_COMMAND:
- s->result = nand_dev_do_cmd(s, value);
- break;
- default:
- cpu_abort(cpu_single_env, "nand_dev_write: Bad offset %x\n", offset);
- break;
- }
-}
-
-/* I/O read */
-static uint32_t nand_dev_read(void *opaque, target_phys_addr_t offset)
-{
- nand_dev_state *s = (nand_dev_state *)opaque;
- nand_dev *dev;
-
- offset -= s->base;
- switch (offset) {
- case NAND_VERSION:
- return NAND_VERSION_CURRENT;
- case NAND_NUM_DEV:
- return nand_dev_count;
- case NAND_RESULT:
- return s->result;
- }
-
- if(s->dev >= nand_dev_count)
- return 0;
-
- dev = nand_devs + s->dev;
-
- switch (offset) {
- case NAND_DEV_FLAGS:
- return dev->flags;
-
- case NAND_DEV_NAME_LEN:
- return dev->devname_len;
-
- case NAND_DEV_PAGE_SIZE:
- return dev->page_size;
-
- case NAND_DEV_EXTRA_SIZE:
- return dev->extra_size;
-
- case NAND_DEV_ERASE_SIZE:
- return dev->erase_size;
-
- case NAND_DEV_SIZE_LOW:
- return (uint32_t)dev->size;
-
- case NAND_DEV_SIZE_HIGH:
- return (uint32_t)(dev->size >> 32);
-
- default:
- cpu_abort(cpu_single_env, "nand_dev_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static CPUReadMemoryFunc *nand_dev_readfn[] = {
- nand_dev_read,
- nand_dev_read,
- nand_dev_read
-};
-
-static CPUWriteMemoryFunc *nand_dev_writefn[] = {
- nand_dev_write,
- nand_dev_write,
- nand_dev_write
-};
-
-/* initialize the QFB device */
-void nand_dev_init(uint32_t base)
-{
- int iomemtype;
- static int instance_id = 0;
- nand_dev_state *s;
-
- s = (nand_dev_state *)qemu_mallocz(sizeof(nand_dev_state));
- iomemtype = cpu_register_io_memory(0, nand_dev_readfn, nand_dev_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
-
- register_savevm( "nand_dev", instance_id++, NAND_DEV_STATE_SAVE_VERSION,
- nand_dev_state_save, nand_dev_state_load, s);
-}
-
-static int arg_match(const char *a, const char *b, size_t b_len)
-{
- while(*a && b_len--) {
- if(*a++ != *b++)
- return 0;
- }
- return b_len == 0;
-}
-
-void nand_add_dev(const char *arg)
-{
- uint64_t dev_size = 0;
- const char *next_arg;
- const char *value;
- size_t arg_len, value_len;
- nand_dev *new_devs, *dev;
- char *devname = NULL;
- size_t devname_len = 0;
- char *initfilename = NULL;
- char *rwfilename = NULL;
- int initfd = -1;
- int rwfd = -1;
- int read_only = 0;
- int pad;
- ssize_t read_size;
- uint32_t page_size = 2048;
- uint32_t extra_size = 64;
- uint32_t erase_pages = 64;
-
- while(arg) {
- next_arg = strchr(arg, ',');
- value = strchr(arg, '=');
- if(next_arg != NULL) {
- arg_len = next_arg - arg;
- next_arg++;
- if(value >= next_arg)
- value = NULL;
- }
- else
- arg_len = strlen(arg);
- if(value != NULL) {
- size_t new_arg_len = value - arg;
- value_len = arg_len - new_arg_len - 1;
- arg_len = new_arg_len;
- value++;
- }
- else
- value_len = 0;
-
- if(devname == NULL) {
- if(value != NULL)
- goto bad_arg_and_value;
- devname_len = arg_len;
- devname = malloc(arg_len);
- if(devname == NULL)
- goto out_of_memory;
- memcpy(devname, arg, arg_len);
- }
- else if(value == NULL) {
- if(arg_match("readonly", arg, arg_len)) {
- read_only = 1;
- }
- else {
- XLOG("bad arg: %.*s\n", arg_len, arg);
- exit(1);
- }
- }
- else {
- if(arg_match("size", arg, arg_len)) {
- char *ep;
- dev_size = strtoull(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("pagesize", arg, arg_len)) {
- char *ep;
- page_size = strtoul(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("extrasize", arg, arg_len)) {
- char *ep;
- extra_size = strtoul(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("erasepages", arg, arg_len)) {
- char *ep;
- erase_pages = strtoul(value, &ep, 0);
- if(ep != value + value_len)
- goto bad_arg_and_value;
- }
- else if(arg_match("initfile", arg, arg_len)) {
- initfilename = malloc(value_len + 1);
- if(initfilename == NULL)
- goto out_of_memory;
- memcpy(initfilename, value, value_len);
- initfilename[value_len] = '\0';
- }
- else if(arg_match("file", arg, arg_len)) {
- rwfilename = malloc(value_len + 1);
- if(rwfilename == NULL)
- goto out_of_memory;
- memcpy(rwfilename, value, value_len);
- rwfilename[value_len] = '\0';
- }
- else {
- goto bad_arg_and_value;
- }
- }
-
- arg = next_arg;
- }
-
- if (rwfilename == NULL) {
- /* we create a temporary file to store everything */
- TempFile* tmp = tempfile_create();
-
- if (tmp == NULL) {
- XLOG("could not create temp file for %.*s NAND disk image: %s",
- devname_len, devname, strerror(errno));
- exit(1);
- }
- rwfilename = (char*) tempfile_path(tmp);
- if (VERBOSE_CHECK(init))
- dprint( "mapping '%.*s' NAND image to %s", devname_len, devname, rwfilename);
- }
-
- if(rwfilename) {
- rwfd = open(rwfilename, O_BINARY | (read_only ? O_RDONLY : O_RDWR));
- if(rwfd < 0 && read_only) {
- XLOG("could not open file %s, %s\n", rwfilename, strerror(errno));
- exit(1);
- }
- /* this could be a writable temporary file. use atexit_close_fd to ensure
- * that it is properly cleaned up at exit on Win32
- */
- if (!read_only)
- atexit_close_fd(rwfd);
- }
-
- if(initfilename) {
- initfd = open(initfilename, O_BINARY | O_RDONLY);
- if(initfd < 0) {
- XLOG("could not open file %s, %s\n", initfilename, strerror(errno));
- exit(1);
- }
- if(dev_size == 0) {
- dev_size = lseek(initfd, 0, SEEK_END);
- lseek(initfd, 0, SEEK_SET);
- }
- }
-
- new_devs = realloc(nand_devs, sizeof(nand_devs[0]) * (nand_dev_count + 1));
- if(new_devs == NULL)
- goto out_of_memory;
- nand_devs = new_devs;
- dev = &new_devs[nand_dev_count];
-
- dev->page_size = page_size;
- dev->extra_size = extra_size;
- dev->erase_size = erase_pages * (page_size + extra_size);
- pad = dev_size % dev->erase_size;
- if (pad != 0) {
- dev_size += (dev->erase_size - pad);
- XLOG("rounding devsize up to a full eraseunit, now %llx\n", dev_size);
- }
- dev->devname = devname;
- dev->devname_len = devname_len;
- dev->size = dev_size;
- dev->data = malloc(dev->erase_size);
- if(dev->data == NULL)
- goto out_of_memory;
- dev->flags = read_only ? NAND_DEV_FLAG_READ_ONLY : 0;
-
- if (initfd >= 0) {
- do {
- read_size = do_read(initfd, dev->data, dev->erase_size);
- if(read_size < 0) {
- XLOG("could not read file %s, %s\n", initfilename, strerror(errno));
- exit(1);
- }
- if(do_write(rwfd, dev->data, read_size) != read_size) {
- XLOG("could not write file %s, %s\n", initfilename, strerror(errno));
- exit(1);
- }
- } while(read_size == dev->erase_size);
- close(initfd);
- }
- dev->fd = rwfd;
-
- nand_dev_count++;
-
- return;
-
-out_of_memory:
- XLOG("out of memory\n");
- exit(1);
-
-bad_arg_and_value:
- XLOG("bad arg: %.*s=%.*s\n", arg_len, arg, value_len, value);
- exit(1);
-}
-
diff --git a/hw/goldfish_nand.h b/hw/goldfish_nand.h
deleted file mode 100644
index dcc59d8..0000000
--- a/hw/goldfish_nand.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef NAND_DEVICE_H
-#define NAND_DEVICE_H
-
-void nand_dev_init(uint32_t base);
-void nand_add_dev(const char *arg);
-
-typedef struct {
- uint64_t limit;
- uint64_t counter;
- int pid;
- int signal;
-} nand_threshold;
-
-extern nand_threshold android_nand_read_threshold;
-extern nand_threshold android_nand_write_threshold;
-
-#endif
diff --git a/hw/goldfish_nand_reg.h b/hw/goldfish_nand_reg.h
deleted file mode 100644
index ea91461..0000000
--- a/hw/goldfish_nand_reg.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef NAND_DEVICE_REG_H
-#define NAND_DEVICE_REG_H
-
-enum nand_cmd {
- NAND_CMD_GET_DEV_NAME, // Write device name for NAND_DEV to NAND_DATA (vaddr)
- NAND_CMD_READ,
- NAND_CMD_WRITE,
- NAND_CMD_ERASE,
- NAND_CMD_BLOCK_BAD_GET, // NAND_RESULT is 1 if block is bad, 0 if it is not
- NAND_CMD_BLOCK_BAD_SET
-};
-
-enum nand_dev_flags {
- NAND_DEV_FLAG_READ_ONLY = 0x00000001
-};
-
-#define NAND_VERSION_CURRENT (1)
-
-enum nand_reg {
- // Global
- NAND_VERSION = 0x000,
- NAND_NUM_DEV = 0x004,
- NAND_DEV = 0x008,
-
- // Dev info
- NAND_DEV_FLAGS = 0x010,
- NAND_DEV_NAME_LEN = 0x014,
- NAND_DEV_PAGE_SIZE = 0x018,
- NAND_DEV_EXTRA_SIZE = 0x01c,
- NAND_DEV_ERASE_SIZE = 0x020,
- NAND_DEV_SIZE_LOW = 0x028,
- NAND_DEV_SIZE_HIGH = 0x02c,
-
- // Command
- NAND_RESULT = 0x040,
- NAND_COMMAND = 0x044,
- NAND_DATA = 0x048,
- NAND_TRANSFER_SIZE = 0x04c,
- NAND_ADDR_LOW = 0x050,
- NAND_ADDR_HIGH = 0x054,
-};
-
-#endif
diff --git a/hw/goldfish_switch.c b/hw/goldfish_switch.c
deleted file mode 100644
index 8a12d66..0000000
--- a/hw/goldfish_switch.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "goldfish_device.h"
-
-enum {
- SW_NAME_LEN = 0x00,
- SW_NAME_PTR = 0x04,
- SW_FLAGS = 0x08,
- SW_STATE = 0x0c,
- SW_INT_STATUS = 0x10,
- SW_INT_ENABLE = 0x14,
-
- SW_FLAGS_OUTPUT = 1U << 0
-};
-
-
-struct switch_state {
- struct goldfish_device dev;
- char *name;
- uint32_t state;
- uint32_t state_changed : 1;
- uint32_t int_enable : 1;
- uint32_t (*writefn)(void *opaque, uint32_t state);
- void *writeopaque;
-};
-
-#define GOLDFISH_SWITCH_SAVE_VERSION 1
-
-static void goldfish_switch_save(QEMUFile* f, void* opaque)
-{
- struct switch_state* s = opaque;
-
- qemu_put_be32(f, s->state);
- qemu_put_byte(f, s->state_changed);
- qemu_put_byte(f, s->int_enable);
-}
-
-static int goldfish_switch_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct switch_state* s = opaque;
-
- if (version_id != GOLDFISH_SWITCH_SAVE_VERSION)
- return -1;
-
- s->state = qemu_get_be32(f);
- s->state_changed = qemu_get_byte(f);
- s->int_enable = qemu_get_byte(f);
-
- return 0;
-}
-
-static uint32_t goldfish_switch_read(void *opaque, target_phys_addr_t offset)
-{
- struct switch_state *s = (struct switch_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_switch_read %x %x\n", offset, size);
-
- switch (offset) {
- case SW_NAME_LEN:
- return strlen(s->name);
- case SW_FLAGS:
- return s->writefn ? SW_FLAGS_OUTPUT : 0;
- case SW_STATE:
- return s->state;
- case SW_INT_STATUS:
- if(s->state_changed && s->int_enable) {
- s->state_changed = 0;
- goldfish_device_set_irq(&s->dev, 0, 0);
- return 1;
- }
- return 0;
- default:
- cpu_abort (cpu_single_env, "goldfish_switch_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_switch_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct switch_state *s = (struct switch_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_switch_read %x %x %x\n", offset, value, size);
-
- switch(offset) {
- case SW_NAME_PTR:
- pmemcpy(value, s->name, strlen(s->name));
- break;
-
- case SW_STATE:
- if(s->writefn) {
- uint32_t new_state;
- new_state = s->writefn(s->writeopaque, value);
- if(new_state != s->state) {
- goldfish_switch_set_state(s, new_state);
- }
- }
- else
- cpu_abort (cpu_single_env, "goldfish_switch_write: write to SW_STATE on input\n");
- break;
-
- case SW_INT_ENABLE:
- value &= 1;
- if(s->state_changed && s->int_enable != value)
- goldfish_device_set_irq(&s->dev, 0, value);
- s->int_enable = value;
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_switch_write: Bad offset %x\n", offset);
- }
-}
-
-static CPUReadMemoryFunc *goldfish_switch_readfn[] = {
- goldfish_switch_read,
- goldfish_switch_read,
- goldfish_switch_read
-};
-
-static CPUWriteMemoryFunc *goldfish_switch_writefn[] = {
- goldfish_switch_write,
- goldfish_switch_write,
- goldfish_switch_write
-};
-
-void goldfish_switch_set_state(void *opaque, uint32_t state)
-{
- struct switch_state *s = opaque;
- s->state_changed = 1;
- s->state = state;
- if(s->int_enable)
- goldfish_device_set_irq(&s->dev, 0, 1);
-}
-
-void *goldfish_switch_add(char *name, uint32_t (*writefn)(void *opaque, uint32_t state), void *writeopaque, int id)
-{
- int ret;
- struct switch_state *s;
-
- s = qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish-switch";
- s->dev.id = id;
- s->dev.size = 0x1000;
- s->dev.irq_count = 1;
- s->name = name;
- s->writefn = writefn;
- s->writeopaque = writeopaque;
-
-
- ret = goldfish_device_add(&s->dev, goldfish_switch_readfn, goldfish_switch_writefn, s);
- if(ret) {
- qemu_free(s);
- return NULL;
- }
-
- register_savevm( "goldfish_switch", 0, GOLDFISH_SWITCH_SAVE_VERSION,
- goldfish_switch_save, goldfish_switch_load, s);
-
- return s;
-}
-
diff --git a/hw/goldfish_timer.c b/hw/goldfish_timer.c
deleted file mode 100644
index 73f1455..0000000
--- a/hw/goldfish_timer.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu-timer.h"
-#include "cpu.h"
-#include "arm_pic.h"
-#include "goldfish_device.h"
-
-enum {
- TIMER_TIME_LOW = 0x00, // get low bits of current time and update TIMER_TIME_HIGH
- TIMER_TIME_HIGH = 0x04, // get high bits of time at last TIMER_TIME_LOW read
- TIMER_ALARM_LOW = 0x08, // set low bits of alarm and activate it
- TIMER_ALARM_HIGH = 0x0c, // set high bits of next alarm
- TIMER_CLEAR_INTERRUPT = 0x10,
- TIMER_CLEAR_ALARM = 0x14
-};
-
-struct timer_state {
- struct goldfish_device dev;
- uint32_t alarm_low;
- int32_t alarm_high;
- int64_t now;
- int armed;
- QEMUTimer *timer;
-};
-
-#define GOLDFISH_TIMER_SAVE_VERSION 1
-
-static void goldfish_timer_save(QEMUFile* f, void* opaque)
-{
- struct timer_state* s = opaque;
-
- qemu_put_be64(f, s->now); /* in case the kernel is in the middle of a timer read */
- qemu_put_byte(f, s->armed);
- if (s->armed) {
- int64_t now = qemu_get_clock(vm_clock);
- int64_t alarm = muldiv64(s->alarm_low | (int64_t)s->alarm_high << 32, ticks_per_sec, 1000000000);
- qemu_put_be64(f, alarm-now);
- }
-}
-
-static int goldfish_timer_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct timer_state* s = opaque;
-
- if (version_id != GOLDFISH_TIMER_SAVE_VERSION)
- return -1;
-
- s->now = qemu_get_be64(f);
- s->armed = qemu_get_byte(f);
- if (s->armed) {
- int64_t now = qemu_get_clock(vm_clock);
- int64_t diff = qemu_get_be64(f);
- int64_t alarm = now + diff;
-
- if (alarm <= now) {
- goldfish_device_set_irq(&s->dev, 0, 1);
- s->armed = 0;
- } else {
- qemu_mod_timer(s->timer, alarm);
- }
- }
- return 0;
-}
-
-static uint32_t goldfish_timer_read(void *opaque, target_phys_addr_t offset)
-{
- struct timer_state *s = (struct timer_state *)opaque;
- offset -= s->dev.base;
- switch(offset) {
- case TIMER_TIME_LOW:
- s->now = muldiv64(qemu_get_clock(vm_clock), 1000000000, ticks_per_sec);
- return s->now;
- case TIMER_TIME_HIGH:
- return s->now >> 32;
- default:
- cpu_abort (cpu_single_env, "goldfish_timer_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_timer_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct timer_state *s = (struct timer_state *)opaque;
- int64_t alarm, now;
- offset -= s->dev.base;
- switch(offset) {
- case TIMER_ALARM_LOW:
- s->alarm_low = value;
- alarm = muldiv64(s->alarm_low | (int64_t)s->alarm_high << 32, ticks_per_sec, 1000000000);
- now = qemu_get_clock(vm_clock);
- if (alarm <= now) {
- goldfish_device_set_irq(&s->dev, 0, 1);
- } else {
- qemu_mod_timer(s->timer, alarm);
- s->armed = 1;
- }
- break;
- case TIMER_ALARM_HIGH:
- s->alarm_high = value;
- //printf("alarm_high %d\n", s->alarm_high);
- break;
- case TIMER_CLEAR_ALARM:
- qemu_del_timer(s->timer);
- s->armed = 0;
- /* fall through */
- case TIMER_CLEAR_INTERRUPT:
- goldfish_device_set_irq(&s->dev, 0, 0);
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_timer_write: Bad offset %x\n", offset);
- }
-}
-
-static void goldfish_timer_tick(void *opaque)
-{
- struct timer_state *s = (struct timer_state *)opaque;
-
- s->armed = 0;
- goldfish_device_set_irq(&s->dev, 0, 1);
-}
-
-struct rtc_state {
- struct goldfish_device dev;
- uint32_t alarm_low;
- int32_t alarm_high;
- int64_t now;
-};
-
-/* we save the RTC for the case where the kernel is in the middle of a rtc_read
- * (i.e. it has read the low 32-bit of s->now, but not the high 32-bits yet */
-#define GOLDFISH_RTC_SAVE_VERSION 1
-
-static void goldfish_rtc_save(QEMUFile* f, void* opaque)
-{
- struct rtc_state* s = opaque;
-
- qemu_put_be64(f, s->now);
-}
-
-static int goldfish_rtc_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct rtc_state* s = opaque;
-
- if (version_id != GOLDFISH_RTC_SAVE_VERSION)
- return -1;
-
- /* this is an old value that is not correct. but that's ok anyway */
- s->now = qemu_get_be64(f);
- return 0;
-}
-
-static uint32_t goldfish_rtc_read(void *opaque, target_phys_addr_t offset)
-{
- struct rtc_state *s = (struct rtc_state *)opaque;
- offset -= s->dev.base;
- switch(offset) {
- case 0x0:
- s->now = (int64_t)time(NULL) * 1000000000;
- return s->now;
- case 0x4:
- return s->now >> 32;
- default:
- cpu_abort (cpu_single_env, "goldfish_rtc_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct rtc_state *s = (struct rtc_state *)opaque;
- int64_t alarm;
- offset -= s->dev.base;
- switch(offset) {
- case 0x8:
- s->alarm_low = value;
- alarm = s->alarm_low | (int64_t)s->alarm_high << 32;
- //printf("next alarm at %lld, tps %lld\n", alarm, ticks_per_sec);
- //qemu_mod_timer(s->timer, alarm);
- break;
- case 0xc:
- s->alarm_high = value;
- //printf("alarm_high %d\n", s->alarm_high);
- break;
- case 0x10:
- goldfish_device_set_irq(&s->dev, 0, 0);
- break;
- default:
- cpu_abort (cpu_single_env, "goldfish_rtc_write: Bad offset %x\n", offset);
- }
-}
-
-static struct timer_state timer_state = {
- .dev = {
- .name = "goldfish_timer",
- .id = -1,
- .size = 0x1000,
- .irq_count = 1,
- }
-};
-
-static struct timer_state rtc_state = {
- .dev = {
- .name = "goldfish_rtc",
- .id = -1,
- .size = 0x1000,
- .irq_count = 1,
- }
-};
-
-static CPUReadMemoryFunc *goldfish_timer_readfn[] = {
- goldfish_timer_read,
- goldfish_timer_read,
- goldfish_timer_read
-};
-
-static CPUWriteMemoryFunc *goldfish_timer_writefn[] = {
- goldfish_timer_write,
- goldfish_timer_write,
- goldfish_timer_write
-};
-
-static CPUReadMemoryFunc *goldfish_rtc_readfn[] = {
- goldfish_rtc_read,
- goldfish_rtc_read,
- goldfish_rtc_read
-};
-
-static CPUWriteMemoryFunc *goldfish_rtc_writefn[] = {
- goldfish_rtc_write,
- goldfish_rtc_write,
- goldfish_rtc_write
-};
-
-void goldfish_timer_and_rtc_init(uint32_t timerbase, int timerirq)
-{
- timer_state.dev.base = timerbase;
- timer_state.dev.irq = timerirq;
- timer_state.timer = qemu_new_timer(vm_clock, goldfish_timer_tick, &timer_state);
- goldfish_device_add(&timer_state.dev, goldfish_timer_readfn, goldfish_timer_writefn, &timer_state);
- register_savevm( "goldfish_timer", 0, GOLDFISH_TIMER_SAVE_VERSION,
- goldfish_timer_save, goldfish_timer_load, &timer_state);
-
- goldfish_device_add(&rtc_state.dev, goldfish_rtc_readfn, goldfish_rtc_writefn, &rtc_state);
- register_savevm( "goldfish_rtc", 0, GOLDFISH_RTC_SAVE_VERSION,
- goldfish_rtc_save, goldfish_rtc_load, &rtc_state);
-}
-
diff --git a/hw/goldfish_trace.c b/hw/goldfish_trace.c
deleted file mode 100644
index ad0eba5..0000000
--- a/hw/goldfish_trace.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/*
- * Virtual hardware for bridging the FUSE kernel module
- * in the emulated OS and outside file system
- */
-#include "qemu_file.h"
-#include "goldfish_trace.h"
-
-//#define DEBUG 1
-
-extern void cpu_loop_exit(void);
-
-extern int tracing;
-
-/* for execve */
-static char path[CLIENT_PAGE_SIZE];
-static char arg[CLIENT_PAGE_SIZE];
-static unsigned long vstart; // VM start
-static unsigned long vend; // VM end
-static unsigned long eoff; // offset in EXE file
-static unsigned cmdlen; // cmdline length
-static unsigned pid; // PID (really thread id)
-static unsigned tgid; // thread group id (really process id)
-static unsigned long dsaddr; // dynamic symbol address
-static unsigned long unmap_start; // start address to unmap
-
-/* for context switch */
-//static unsigned long cs_pid; // context switch PID
-
-/* I/O write */
-static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- trace_dev_state *s = (trace_dev_state *)opaque;
-
- offset -= s->base;
- switch (offset >> 2) {
- case TRACE_DEV_REG_SWITCH: // context switch, switch to pid
- trace_switch(value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, context switch %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_TGID: // save the tgid for the following fork/clone
- tgid = value;
-#ifdef DEBUG
- printf("QEMU.trace: kernel, tgid %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_FORK: // fork, fork new pid
- trace_fork(tgid, value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, fork %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_CLONE: // fork, clone new pid (i.e. thread)
- trace_clone(tgid, value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, clone %u\n", value);
-#endif
- break;
- case TRACE_DEV_REG_EXECVE_VMSTART: // execve, vstart
- vstart = value;
- break;
- case TRACE_DEV_REG_EXECVE_VMEND: // execve, vend
- vend = value;
- break;
- case TRACE_DEV_REG_EXECVE_OFFSET: // execve, offset in EXE
- eoff = value;
- break;
- case TRACE_DEV_REG_EXECVE_EXEPATH: // init exec, path of EXE
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
- trace_init_exec(vstart, vend, eoff, path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
-#endif
- path[0] = 0;
- break;
- case TRACE_DEV_REG_CMDLINE_LEN: // execve, process cmdline length
- cmdlen = value;
- break;
- case TRACE_DEV_REG_CMDLINE: // execve, process cmdline
- vmemcpy(value, arg, cmdlen);
- trace_execve(arg, cmdlen);
-#ifdef DEBUG
- {
- int i;
- for (i = 0; i < cmdlen; i ++)
- if (i != cmdlen - 1 && arg[i] == 0)
- arg[i] = ' ';
- printf("QEMU.trace: kernel, execve %s[%d]\n", arg, cmdlen);
- }
-#endif
- arg[0] = 0;
- break;
- case TRACE_DEV_REG_EXIT: // exit, exit current process with exit code
- trace_exit(value);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, exit %x\n", value);
-#endif
- break;
- case TRACE_DEV_REG_NAME: // record thread name
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
-
- // Remove the trailing newline if it exists
- int len = strlen(path);
- if (path[len - 1] == '\n') {
- path[len - 1] = 0;
- }
- trace_name(path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, name %s\n", path);
-#endif
- break;
- case TRACE_DEV_REG_MMAP_EXEPATH: // mmap, path of EXE, the others are same as execve
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
- trace_mmap(vstart, vend, eoff, path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
-#endif
- path[0] = 0;
- break;
- case TRACE_DEV_REG_INIT_PID: // init, name the pid that starts before device registered
- pid = value;
- break;
- case TRACE_DEV_REG_INIT_NAME: // init, the comm of the init pid
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
- trace_init_name(tgid, pid, path);
-#ifdef DEBUG
- printf("QEMU.trace: kernel, init name %u [%s]\n", pid, path);
-#endif
- path[0] = 0;
- break;
-
- case TRACE_DEV_REG_DYN_SYM_ADDR: // dynamic symbol address
- dsaddr = value;
- break;
- case TRACE_DEV_REG_DYN_SYM: // add dynamic symbol
- vstrcpy(value, arg, CLIENT_PAGE_SIZE);
- trace_dynamic_symbol_add(dsaddr, arg);
-#ifdef DEBUG
- printf("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, arg);
-#endif
- arg[0] = 0;
- break;
- case TRACE_DEV_REG_REMOVE_ADDR: // remove dynamic symbol addr
- trace_dynamic_symbol_remove(value);
-#ifdef DEBUG
- printf("QEMU.trace: dynamic symbol remove %lx\n", dsaddr);
-#endif
- arg[0] = 0;
- break;
-
- case TRACE_DEV_REG_PRINT_STR: // print string
- vstrcpy(value, arg, CLIENT_PAGE_SIZE);
- printf("%s", arg);
- arg[0] = 0;
- break;
- case TRACE_DEV_REG_PRINT_NUM_DEC: // print number in decimal
- printf("%d", value);
- break;
- case TRACE_DEV_REG_PRINT_NUM_HEX: // print number in hexical
- printf("%x", value);
- break;
-
- case TRACE_DEV_REG_STOP_EMU: // stop the VM execution
- // To ensure that the number of instructions executed in this
- // block is correct, we pretend that there was an exception.
- trace_exception(0);
-
- cpu_single_env->exception_index = EXCP_HLT;
- cpu_single_env->halted = 1;
- qemu_system_shutdown_request();
- cpu_loop_exit();
- break;
-
- case TRACE_DEV_REG_ENABLE: // tracing enable: 0 = stop, 1 = start
- if (value == 1)
- start_tracing();
- else if (value == 0) {
- stop_tracing();
-
- // To ensure that the number of instructions executed in this
- // block is correct, we pretend that there was an exception.
- trace_exception(0);
- }
- break;
-
- case TRACE_DEV_REG_UNMAP_START:
- unmap_start = value;
- break;
- case TRACE_DEV_REG_UNMAP_END:
- trace_munmap(unmap_start, value);
- break;
-
- default:
- cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset);
- break;
- }
-}
-
-/* I/O read */
-static uint32_t trace_dev_read(void *opaque, target_phys_addr_t offset)
-{
- trace_dev_state *s = (trace_dev_state *)opaque;
-
- offset -= s->base;
- switch (offset >> 2) {
- case TRACE_DEV_REG_ENABLE: // tracing enable
- return tracing;
- default:
- cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset);
- return 0;
- }
- return 0;
-}
-
-static CPUReadMemoryFunc *trace_dev_readfn[] = {
- trace_dev_read,
- trace_dev_read,
- trace_dev_read
-};
-
-static CPUWriteMemoryFunc *trace_dev_writefn[] = {
- trace_dev_write,
- trace_dev_write,
- trace_dev_write
-};
-
-/* initialize the trace device */
-void trace_dev_init(uint32_t base)
-{
- int iomemtype;
- trace_dev_state *s;
-
- s = (trace_dev_state *)qemu_mallocz(sizeof(trace_dev_state));
- iomemtype = cpu_register_io_memory(0, trace_dev_readfn, trace_dev_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->base = base;
-
- path[0] = arg[0] = '\0';
-}
diff --git a/hw/goldfish_trace.h b/hw/goldfish_trace.h
deleted file mode 100644
index 44190ee..0000000
--- a/hw/goldfish_trace.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _TRACE_DEV_H_
-#define _TRACE_DEV_H_
-
-#define CLIENT_PAGE_SIZE 4096
-
-/* trace device registers */
-#define TRACE_DEV_REG_SWITCH 0
-#define TRACE_DEV_REG_FORK 1
-#define TRACE_DEV_REG_EXECVE_PID 2
-#define TRACE_DEV_REG_EXECVE_VMSTART 3
-#define TRACE_DEV_REG_EXECVE_VMEND 4
-#define TRACE_DEV_REG_EXECVE_OFFSET 5
-#define TRACE_DEV_REG_EXECVE_EXEPATH 6
-#define TRACE_DEV_REG_EXIT 7
-#define TRACE_DEV_REG_CMDLINE 8
-#define TRACE_DEV_REG_CMDLINE_LEN 9
-#define TRACE_DEV_REG_MMAP_EXEPATH 10
-#define TRACE_DEV_REG_INIT_PID 11
-#define TRACE_DEV_REG_INIT_NAME 12
-#define TRACE_DEV_REG_CLONE 13
-#define TRACE_DEV_REG_UNMAP_START 14
-#define TRACE_DEV_REG_UNMAP_END 15
-#define TRACE_DEV_REG_NAME 16
-#define TRACE_DEV_REG_TGID 17
-#define TRACE_DEV_REG_DYN_SYM 50
-#define TRACE_DEV_REG_DYN_SYM_ADDR 51
-#define TRACE_DEV_REG_REMOVE_ADDR 52
-#define TRACE_DEV_REG_PRINT_STR 60
-#define TRACE_DEV_REG_PRINT_NUM_DEC 61
-#define TRACE_DEV_REG_PRINT_NUM_HEX 62
-#define TRACE_DEV_REG_STOP_EMU 90
-#define TRACE_DEV_REG_ENABLE 100
-
-/* the virtual trace device state */
-typedef struct {
- uint32_t base;
-} trace_dev_state;
-
-/*
- * interfaces for copy from virtual space
- * from target-arm/op_helper.c
- */
-extern target_phys_addr_t v2p(target_ulong ptr, int is_user);
-extern void vmemcpy(target_ulong ptr, char *buf, int size);
-extern void pmemcpy(target_ulong ptr, const char* buf, int size);
-extern void vstrcpy(target_ulong ptr, char *buf, int max);
-
-/*
- * interfaces to trace module to signal kernel events
- */
-extern void trace_switch(int pid);
-extern void trace_fork(int tgid, int pid);
-extern void trace_clone(int tgid, int pid);
-extern void trace_execve(const char *arg, int len);
-extern void trace_exit(int exitcode);
-extern void trace_mmap(unsigned long vstart, unsigned long vend,
- unsigned long offset, const char *path);
-extern void trace_munmap(unsigned long vstart, unsigned long vend);
-extern void trace_dynamic_symbol_add(unsigned long vaddr, const char *name);
-extern void trace_dynamic_symbol_remove(unsigned long vaddr);
-extern void trace_init_name(int tgid, int pid, const char *name);
-extern void trace_init_exec(unsigned long start, unsigned long end,
- unsigned long offset, const char *exe);
-extern void start_tracing(void);
-extern void stop_tracing(void);
-extern void trace_exception(uint32 target_pc);
-
-#endif
diff --git a/hw/goldfish_tty.c b/hw/goldfish_tty.c
deleted file mode 100644
index aa62d75..0000000
--- a/hw/goldfish_tty.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "qemu_file.h"
-#include "qemu-char.h"
-#include "goldfish_device.h"
-
-enum {
- TTY_PUT_CHAR = 0x00,
- TTY_BYTES_READY = 0x04,
- TTY_CMD = 0x08,
-
- TTY_DATA_PTR = 0x10,
- TTY_DATA_LEN = 0x14,
-
- TTY_CMD_INT_DISABLE = 0,
- TTY_CMD_INT_ENABLE = 1,
- TTY_CMD_WRITE_BUFFER = 2,
- TTY_CMD_READ_BUFFER = 3,
-};
-
-struct tty_state {
- struct goldfish_device dev;
- CharDriverState *cs;
- uint32_t ptr;
- uint32_t ptr_len;
- uint32_t ready;
- uint8_t data[128];
- uint32_t data_count;
-};
-
-#define GOLDFISH_TTY_SAVE_VERSION 1
-
-static void goldfish_tty_save(QEMUFile* f, void* opaque)
-{
- struct tty_state* s = opaque;
-
- qemu_put_be32( f, s->ptr );
- qemu_put_be32( f, s->ptr_len );
- qemu_put_byte( f, s->ready );
- qemu_put_byte( f, s->data_count );
- qemu_put_buffer( f, s->data, s->data_count );
-}
-
-static int goldfish_tty_load(QEMUFile* f, void* opaque, int version_id)
-{
- struct tty_state* s = opaque;
-
- if (version_id != GOLDFISH_TTY_SAVE_VERSION)
- return -1;
-
- s->ptr = qemu_get_be32(f);
- s->ptr_len = qemu_get_be32(f);
- s->ready = qemu_get_byte(f);
- s->data_count = qemu_get_byte(f);
- qemu_get_buffer(f, s->data, s->data_count);
-
- return 0;
-}
-
-static uint32_t goldfish_tty_read(void *opaque, target_phys_addr_t offset)
-{
- struct tty_state *s = (struct tty_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_tty_read %x %x\n", offset, size);
-
- switch (offset) {
- case TTY_BYTES_READY:
- return s->data_count;
- default:
- cpu_abort (cpu_single_env, "goldfish_tty_read: Bad offset %x\n", offset);
- return 0;
- }
-}
-
-static void goldfish_tty_write(void *opaque, target_phys_addr_t offset, uint32_t value)
-{
- struct tty_state *s = (struct tty_state *)opaque;
- offset -= s->dev.base;
-
- //printf("goldfish_tty_read %x %x %x\n", offset, value, size);
-
- switch(offset) {
- case TTY_PUT_CHAR: {
- uint8_t ch = value;
- if(s->cs)
- qemu_chr_write(s->cs, &ch, 1);
- } break;
-
- case TTY_CMD:
- switch(value) {
- case TTY_CMD_INT_DISABLE:
- if(s->ready) {
- if(s->data_count > 0)
- goldfish_device_set_irq(&s->dev, 0, 0);
- s->ready = 0;
- }
- break;
-
- case TTY_CMD_INT_ENABLE:
- if(!s->ready) {
- if(s->data_count > 0)
- goldfish_device_set_irq(&s->dev, 0, 1);
- s->ready = 1;
- }
- break;
-
- case TTY_CMD_WRITE_BUFFER:
- if(s->cs) {
- int len;
- target_ulong buf;
-
- buf = s->ptr;
- len = s->ptr_len;
-
- while(len) {
- int page_remain = TARGET_PAGE_SIZE - (buf & ~TARGET_PAGE_MASK);
- int to_write = len;
- uint8_t *phys = (uint8_t *)v2p(buf, 0);
- if(to_write > page_remain)
- to_write = page_remain;
- qemu_chr_write(s->cs, phys, to_write);
- buf += to_write;
- len -= to_write;
- }
- //printf("goldfish_tty_write: got %d bytes from %x\n", s->ptr_len, s->ptr);
- }
- break;
-
- case TTY_CMD_READ_BUFFER:
- if(s->ptr_len > s->data_count)
- cpu_abort (cpu_single_env, "goldfish_tty_write: reading more data than available %d %d\n", s->ptr_len, s->data_count);
- pmemcpy(s->ptr, s->data, s->ptr_len);
- //printf("goldfish_tty_write: read %d bytes to %x\n", s->ptr_len, s->ptr);
- if(s->data_count > s->ptr_len)
- memmove(s->data, s->data + s->ptr_len, s->data_count - s->ptr_len);
- s->data_count -= s->ptr_len;
- if(s->data_count == 0 && s->ready)
- goldfish_device_set_irq(&s->dev, 0, 0);
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_tty_write: Bad command %x\n", value);
- };
- break;
-
- case TTY_DATA_PTR:
- s->ptr = value;
- break;
-
- case TTY_DATA_LEN:
- s->ptr_len = value;
- break;
-
- default:
- cpu_abort (cpu_single_env, "goldfish_tty_write: Bad offset %x\n", offset);
- }
-}
-
-static int tty_can_receive(void *opaque)
-{
- struct tty_state *s = opaque;
-
- return (sizeof(s->data) - s->data_count);
-}
-
-static void tty_receive(void *opaque, const uint8_t *buf, int size)
-{
- struct tty_state *s = opaque;
-
- memcpy(s->data + s->data_count, buf, size);
- s->data_count += size;
- if(s->data_count > 0 && s->ready)
- goldfish_device_set_irq(&s->dev, 0, 1);
-}
-
-static CPUReadMemoryFunc *goldfish_tty_readfn[] = {
- goldfish_tty_read,
- goldfish_tty_read,
- goldfish_tty_read
-};
-
-static CPUWriteMemoryFunc *goldfish_tty_writefn[] = {
- goldfish_tty_write,
- goldfish_tty_write,
- goldfish_tty_write
-};
-
-int goldfish_tty_add(CharDriverState *cs, int id, uint32_t base, int irq)
-{
- int ret;
- struct tty_state *s;
- static int instance_id = 0;
-
- s = qemu_mallocz(sizeof(*s));
- s->dev.name = "goldfish_tty";
- s->dev.id = id;
- s->dev.base = base;
- s->dev.size = 0x1000;
- s->dev.irq = irq;
- s->dev.irq_count = 1;
- s->cs = cs;
-
- if(cs) {
- qemu_chr_add_handlers(cs, tty_can_receive, tty_receive, NULL, s);
- }
-
- ret = goldfish_device_add(&s->dev, goldfish_tty_readfn, goldfish_tty_writefn, s);
- if(ret) {
- qemu_free(s);
- } else {
- register_savevm( "goldfish_tty", instance_id++, GOLDFISH_TTY_SAVE_VERSION,
- goldfish_tty_save, goldfish_tty_load, s);
- }
- return ret;
-}
-
diff --git a/hw/hw.h b/hw/hw.h
deleted file mode 100644
index 06e24cb..0000000
--- a/hw/hw.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Declarations for use by hardware emulation. */
-#ifndef QEMU_HW_H
-#define QEMU_HW_H
-
-#include "qemu-common.h"
-#include "irq.h"
-#include "cpu.h"
-
-/* VM Load/Save */
-
-QEMUFile *qemu_fopen(const char *filename, const char *mode);
-void qemu_fflush(QEMUFile *f);
-void qemu_fclose(QEMUFile *f);
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
- qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
- qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
- qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
- qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
- *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
- *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
- *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
- *pv = qemu_get_byte(f);
-}
-
-#ifdef NEED_CPU_H
-#if TARGET_LONG_BITS == 64
-#define qemu_put_betl qemu_put_be64
-#define qemu_get_betl qemu_get_be64
-#define qemu_put_betls qemu_put_be64s
-#define qemu_get_betls qemu_get_be64s
-#else
-#define qemu_put_betl qemu_put_be32
-#define qemu_get_betl qemu_get_be32
-#define qemu_put_betls qemu_put_be32s
-#define qemu_get_betls qemu_get_be32s
-#endif
-#endif
-
-int64_t qemu_ftell(QEMUFile *f);
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
-
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque);
-
-typedef void QEMUResetHandler(void *opaque);
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque);
-
-/* handler to set the boot_device for a specific type of QEMUMachine */
-/* return 0 if success */
-typedef int QEMUBootSetHandler(const char *boot_device);
-extern QEMUBootSetHandler *qemu_boot_set_handler;
-void qemu_register_boot_set(QEMUBootSetHandler *func);
-
-/* These should really be in isa.h, but are here to make pc.h happy. */
-typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
-typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-
-
-/* ANDROID: copy memory from the QEMU buffer to simulated virtual space */
-extern void pmemcpy(target_ulong ptr, const char *buf, int size);
-
-#endif
diff --git a/hw/irq.c b/hw/irq.c
deleted file mode 100644
index eca707d..0000000
--- a/hw/irq.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * QEMU IRQ/GPIO common code.
- *
- * Copyright (c) 2007 CodeSourcery.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "irq.h"
-
-struct IRQState {
- qemu_irq_handler handler;
- void *opaque;
- int n;
-};
-
-void qemu_set_irq(qemu_irq irq, int level)
-{
- if (!irq)
- return;
-
- irq->handler(irq->opaque, irq->n, level);
-}
-
-qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
-{
- qemu_irq *s;
- struct IRQState *p;
- int i;
-
- s = (qemu_irq *)qemu_mallocz(sizeof(qemu_irq) * n);
- p = (struct IRQState *)qemu_mallocz(sizeof(struct IRQState) * n);
- for (i = 0; i < n; i++) {
- p->handler = handler;
- p->opaque = opaque;
- p->n = i;
- s[i] = p;
- p++;
- }
- return s;
-}
-
-static void qemu_notirq(void *opaque, int line, int level)
-{
- struct IRQState *irq = opaque;
-
- irq->handler(irq->opaque, irq->n, !level);
-}
-
-qemu_irq qemu_irq_invert(qemu_irq irq)
-{
- /* The default state for IRQs is low, so raise the output now. */
- qemu_irq_raise(irq);
- return qemu_allocate_irqs(qemu_notirq, irq, 1)[0];
-}
diff --git a/hw/irq.h b/hw/irq.h
deleted file mode 100644
index 0880ad2..0000000
--- a/hw/irq.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef QEMU_IRQ_H
-#define QEMU_IRQ_H
-
-/* Generic IRQ/GPIO pin infrastructure. */
-
-/* FIXME: Rmove one of these. */
-typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
-typedef void SetIRQFunc(void *opaque, int irq_num, int level);
-
-void qemu_set_irq(qemu_irq irq, int level);
-
-static inline void qemu_irq_raise(qemu_irq irq)
-{
- qemu_set_irq(irq, 1);
-}
-
-static inline void qemu_irq_lower(qemu_irq irq)
-{
- qemu_set_irq(irq, 0);
-}
-
-static inline void qemu_irq_pulse(qemu_irq irq)
-{
- qemu_set_irq(irq, 1);
- qemu_set_irq(irq, 0);
-}
-
-/* Returns an array of N IRQs. */
-qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
-
-/* Returns a new IRQ with opposite polarity. */
-qemu_irq qemu_irq_invert(qemu_irq irq);
-
-#endif
diff --git a/hw/isa.h b/hw/isa.h
deleted file mode 100644
index 222e4f3..0000000
--- a/hw/isa.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef HW_ISA_H
-#define HW_ISA_H
-/* ISA bus */
-
-extern target_phys_addr_t isa_mem_base;
-
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque);
-void isa_unassign_ioport(int start, int length);
-
-void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
-
-/* dma.c */
-int DMA_get_channel_mode (int nchan);
-int DMA_read_memory (int nchan, void *buf, int pos, int size);
-int DMA_write_memory (int nchan, void *buf, int pos, int size);
-void DMA_hold_DREQ (int nchan);
-void DMA_release_DREQ (int nchan);
-void DMA_schedule(int nchan);
-void DMA_run (void);
-void DMA_init (int high_page_enable);
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque);
-#endif
diff --git a/hw/mmc.h b/hw/mmc.h
deleted file mode 100644
index 3ae3ea9..0000000
--- a/hw/mmc.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Header for MultiMediaCard (MMC)
- *
- * Copyright 2002 Hewlett-Packard Company
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Many thanks to Alessandro Rubini and Jonathan Corbet!
- *
- * Based strongly on code by:
- *
- * Author: Yong-iL Joh <tolkien@mizi.com>
- * Date : $Date: 2002/06/18 12:37:30 $
- *
- * Author: Andrew Christian
- * 15 May 2002
- */
-
-#ifndef MMC_MMC_H
-#define MMC_MMC_H
-
-/* Standard MMC commands (4.1) type argument response */
- /* class 1 */
-#define MMC_GO_IDLE_STATE 0 /* bc */
-#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
-#define MMC_ALL_SEND_CID 2 /* bcr R2 */
-#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
-#define MMC_SET_DSR 4 /* bc [31:16] RCA */
-#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
-#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
-#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
-#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
-#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
-#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
-#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
-#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
-#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
-
- /* class 2 */
-#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
-#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
-#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
-
- /* class 3 */
-#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
-
- /* class 4 */
-#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
-#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
-#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
-#define MMC_PROGRAM_CID 26 /* adtc R1 */
-#define MMC_PROGRAM_CSD 27 /* adtc R1 */
-
- /* class 6 */
-#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
-#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
-#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
-
- /* class 5 */
-#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
-#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
-#define MMC_ERASE 38 /* ac R1b */
-
- /* class 9 */
-#define MMC_FAST_IO 39 /* ac <Complex> R4 */
-#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
-
- /* class 7 */
-#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
-
- /* class 8 */
-#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
-#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
-
-/*
- * MMC_SWITCH argument format:
- *
- * [31:26] Always 0
- * [25:24] Access Mode
- * [23:16] Location of target Byte in EXT_CSD
- * [15:08] Value Byte
- * [07:03] Always 0
- * [02:00] Command Set
- */
-
-/*
- MMC status in R1
- Type
- e : error bit
- s : status bit
- r : detected and set for the actual command response
- x : detected and set during command execution. the host must poll
- the card by sending status command in order to read these bits.
- Clear condition
- a : according to the card state
- b : always related to the previous command. Reception of
- a valid command will clear it (with a delay of one command)
- c : clear by read
- */
-
-#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
-#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
-#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
-#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
-#define R1_ERASE_PARAM (1 << 27) /* ex, c */
-#define R1_WP_VIOLATION (1 << 26) /* erx, c */
-#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
-#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
-#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
-#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
-#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
-#define R1_CC_ERROR (1 << 20) /* erx, c */
-#define R1_ERROR (1 << 19) /* erx, c */
-#define R1_UNDERRUN (1 << 18) /* ex, c */
-#define R1_OVERRUN (1 << 17) /* ex, c */
-#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
-#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
-#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
-#define R1_ERASE_RESET (1 << 13) /* sr, c */
-#define R1_STATUS(x) (x & 0xFFFFE000)
-#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
-#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
-#define R1_APP_CMD (1 << 5) /* sr, c */
-
-
-/*
- * OCR bits are mostly in host.h
- */
-#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
-
-/*
- * Card Command Classes (CCC)
- */
-#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
- /* (CMD0,1,2,3,4,7,9,10,12,13,15) */
-#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
- /* (CMD11) */
-#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
- /* (CMD16,17,18) */
-#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
- /* (CMD20) */
-#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
- /* (CMD16,24,25,26,27) */
-#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
- /* (CMD32,33,34,35,36,37,38,39) */
-#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
- /* (CMD28,29,30) */
-#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
- /* (CMD16,CMD42) */
-#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
- /* (CMD55,56,57,ACMD*) */
-#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
- /* (CMD5,39,40,52,53) */
-#define CCC_SWITCH (1<<10) /* (10) High speed switch */
- /* (CMD6,34,35,36,37,50) */
- /* (11) Reserved */
- /* (CMD?) */
-
-/*
- * CSD field definitions
- */
-
-#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
-#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
-#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
-#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
-
-#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
-#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
-#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
-#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
-#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
-
-/*
- * EXT_CSD fields
- */
-
-#define EXT_CSD_BUS_WIDTH 183 /* R/W */
-#define EXT_CSD_HS_TIMING 185 /* R/W */
-#define EXT_CSD_CARD_TYPE 196 /* RO */
-#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
-
-/*
- * EXT_CSD field definitions
- */
-
-#define EXT_CSD_CMD_SET_NORMAL (1<<0)
-#define EXT_CSD_CMD_SET_SECURE (1<<1)
-#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
-
-#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
-#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
-
-#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
-#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
-#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
-
-/*
- * MMC_SWITCH access modes
- */
-
-#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
-#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
-#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
-#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
-
-#endif /* MMC_MMC_PROTOCOL_H */
-
diff --git a/hw/pc.h b/hw/pc.h
deleted file mode 100644
index 2862849..0000000
--- a/hw/pc.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef HW_PC_H
-#define HW_PC_H
-/* PC-style peripherals (also used by other machines). */
-
-/* serial.c */
-
-SerialState *serial_init(int base, qemu_irq irq, int baudbase,
- CharDriverState *chr);
-SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
- qemu_irq irq, int baudbase,
- CharDriverState *chr, int ioregister);
-uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr);
-void serial_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value);
-uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr);
-void serial_mm_writew (void *opaque, target_phys_addr_t addr, uint32_t value);
-uint32_t serial_mm_readl (void *opaque, target_phys_addr_t addr);
-void serial_mm_writel (void *opaque, target_phys_addr_t addr, uint32_t value);
-
-/* parallel.c */
-
-typedef struct ParallelState ParallelState;
-ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr);
-ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr);
-
-/* i8259.c */
-
-typedef struct PicState2 PicState2;
-extern PicState2 *isa_pic;
-void pic_set_irq(int irq, int level);
-void pic_set_irq_new(void *opaque, int irq, int level);
-qemu_irq *i8259_init(qemu_irq parent_irq);
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
- void *alt_irq_opaque);
-int pic_read_irq(PicState2 *s);
-void pic_update_irq(PicState2 *s);
-uint32_t pic_intack_read(PicState2 *s);
-void pic_info(void);
-void irq_info(void);
-
-/* APIC */
-typedef struct IOAPICState IOAPICState;
-
-int apic_init(CPUState *env);
-int apic_accept_pic_intr(CPUState *env);
-void apic_deliver_pic_intr(CPUState *env, int level);
-int apic_get_interrupt(CPUState *env);
-IOAPICState *ioapic_init(void);
-void ioapic_set_irq(void *opaque, int vector, int level);
-
-/* i8254.c */
-
-#define PIT_FREQ 1193182
-
-typedef struct PITState PITState;
-
-PITState *pit_init(int base, qemu_irq irq);
-void pit_set_gate(PITState *pit, int channel, int val);
-int pit_get_gate(PITState *pit, int channel);
-int pit_get_initial_count(PITState *pit, int channel);
-int pit_get_mode(PITState *pit, int channel);
-int pit_get_out(PITState *pit, int channel, int64_t current_time);
-
-/* vmport.c */
-void vmport_init(void);
-void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque);
-
-/* vmmouse.c */
-void *vmmouse_init(void *m);
-
-/* pckbd.c */
-
-void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
-void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
- target_phys_addr_t base, int it_shift);
-
-/* mc146818rtc.c */
-
-typedef struct RTCState RTCState;
-
-RTCState *rtc_init(int base, qemu_irq irq);
-RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq);
-void rtc_set_memory(RTCState *s, int addr, int val);
-void rtc_set_date(RTCState *s, const struct tm *tm);
-
-/* pc.c */
-extern int fd_bootchk;
-
-void ioport_set_a20(int enable);
-int ioport_get_a20(void);
-
-/* acpi.c */
-extern int acpi_enabled;
-i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
- qemu_irq sci_irq);
-void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
-void acpi_bios_init(void);
-
-/* pcspk.c */
-void pcspk_init(PITState *);
-int pcspk_audio_init(AudioState *, qemu_irq *pic);
-
-/* piix_pci.c */
-PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic);
-void i440fx_set_smm(PCIDevice *d, int val);
-int piix3_init(PCIBus *bus, int devfn);
-void i440fx_init_memory_mappings(PCIDevice *d);
-
-int piix4_init(PCIBus *bus, int devfn);
-
-/* vga.c */
-
-#ifndef TARGET_SPARC
-#define VGA_RAM_SIZE (8192 * 1024)
-#else
-#define VGA_RAM_SIZE (9 * 1024 * 1024)
-#endif
-
-int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- unsigned long vga_bios_offset, int vga_bios_size);
-int isa_vga_mm_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size,
- target_phys_addr_t vram_base, target_phys_addr_t ctrl_base,
- int it_shift);
-
-/* cirrus_vga.c */
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* ide.c */
-void isa_ide_init(int iobase, int iobase2, qemu_irq irq,
- BlockDriverState *hd0, BlockDriverState *hd1);
-void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
- int secondary_ide_enabled);
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
- qemu_irq *pic);
-void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
- qemu_irq *pic);
-
-/* ne2000.c */
-
-void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
-
-#endif
diff --git a/hw/pci.c b/hw/pci.c
deleted file mode 100644
index 5f7004a..0000000
--- a/hw/pci.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * QEMU PCI bus manager
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "pci.h"
-#include "console.h"
-#include "net.h"
-
-//#define DEBUG_PCI
-
-struct PCIBus {
- int bus_num;
- int devfn_min;
- pci_set_irq_fn set_irq;
- pci_map_irq_fn map_irq;
- uint32_t config_reg; /* XXX: suppress */
- /* low level pic */
- SetIRQFunc *low_set_irq;
- qemu_irq *irq_opaque;
- PCIDevice *devices[256];
- PCIDevice *parent_dev;
- PCIBus *next;
- /* The bus IRQ state is the logical OR of the connected devices.
- Keep a count of the number of devices with raised IRQs. */
- int nirq;
- int irq_count[];
-};
-
-static void pci_update_mappings(PCIDevice *d);
-static void pci_set_irq(void *opaque, int irq_num, int level);
-
-target_phys_addr_t pci_mem_base;
-static int pci_irq_index;
-static PCIBus *first_bus;
-
-static void pcibus_save(QEMUFile *f, void *opaque)
-{
- PCIBus *bus = (PCIBus *)opaque;
- int i;
-
- qemu_put_be32(f, bus->nirq);
- for (i = 0; i < bus->nirq; i++)
- qemu_put_be32(f, bus->irq_count[i]);
-}
-
-static int pcibus_load(QEMUFile *f, void *opaque, int version_id)
-{
- PCIBus *bus = (PCIBus *)opaque;
- int i, nirq;
-
- if (version_id != 1)
- return -EINVAL;
-
- nirq = qemu_get_be32(f);
- if (bus->nirq != nirq) {
- fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n",
- nirq, bus->nirq);
- return -EINVAL;
- }
-
- for (i = 0; i < nirq; i++)
- bus->irq_count[i] = qemu_get_be32(f);
-
- return 0;
-}
-
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- qemu_irq *pic, int devfn_min, int nirq)
-{
- PCIBus *bus;
- static int nbus = 0;
-
- bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
- bus->set_irq = set_irq;
- bus->map_irq = map_irq;
- bus->irq_opaque = pic;
- bus->devfn_min = devfn_min;
- bus->nirq = nirq;
- first_bus = bus;
- register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
- return bus;
-}
-
-static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq)
-{
- PCIBus *bus;
- bus = qemu_mallocz(sizeof(PCIBus));
- bus->map_irq = map_irq;
- bus->parent_dev = dev;
- bus->next = dev->bus->next;
- dev->bus->next = bus;
- return bus;
-}
-
-int pci_bus_num(PCIBus *s)
-{
- return s->bus_num;
-}
-
-void pci_device_save(PCIDevice *s, QEMUFile *f)
-{
- int i;
-
- qemu_put_be32(f, 2); /* PCI device version */
- qemu_put_buffer(f, s->config, 256);
- for (i = 0; i < 4; i++)
- qemu_put_be32(f, s->irq_state[i]);
-}
-
-int pci_device_load(PCIDevice *s, QEMUFile *f)
-{
- uint32_t version_id;
- int i;
-
- version_id = qemu_get_be32(f);
- if (version_id > 2)
- return -EINVAL;
- qemu_get_buffer(f, s->config, 256);
- pci_update_mappings(s);
-
- if (version_id >= 2)
- for (i = 0; i < 4; i ++)
- s->irq_state[i] = qemu_get_be32(f);
-
- return 0;
-}
-
-/* -1 for devfn means auto assign */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write)
-{
- PCIDevice *pci_dev;
-
- if (pci_irq_index >= PCI_DEVICES_MAX)
- return NULL;
-
- if (devfn < 0) {
- for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
- if (!bus->devices[devfn])
- goto found;
- }
- return NULL;
- found: ;
- }
- pci_dev = qemu_mallocz(instance_size);
- if (!pci_dev)
- return NULL;
- pci_dev->bus = bus;
- pci_dev->devfn = devfn;
- pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
- memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
-
- if (!config_read)
- config_read = pci_default_read_config;
- if (!config_write)
- config_write = pci_default_write_config;
- pci_dev->config_read = config_read;
- pci_dev->config_write = config_write;
- pci_dev->irq_index = pci_irq_index++;
- bus->devices[devfn] = pci_dev;
- pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
- return pci_dev;
-}
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func)
-{
- PCIIORegion *r;
- uint32_t addr;
-
- if ((unsigned int)region_num >= PCI_NUM_REGIONS)
- return;
- r = &pci_dev->io_regions[region_num];
- r->addr = -1;
- r->size = size;
- r->type = type;
- r->map_func = map_func;
- if (region_num == PCI_ROM_SLOT) {
- addr = 0x30;
- } else {
- addr = 0x10 + region_num * 4;
- }
- *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
-}
-
-static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr)
-{
- return addr + pci_mem_base;
-}
-
-static void pci_update_mappings(PCIDevice *d)
-{
- PCIIORegion *r;
- int cmd, i;
- uint32_t last_addr, new_addr, config_ofs;
-
- cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
- for(i = 0; i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (i == PCI_ROM_SLOT) {
- config_ofs = 0x30;
- } else {
- config_ofs = 0x10 + i * 4;
- }
- if (r->size != 0) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we have only 64K ioports on PC */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr >= 0x10000) {
- new_addr = -1;
- }
- } else {
- new_addr = -1;
- }
- } else {
- if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- /* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & 1))
- goto no_mem_map;
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we do not support wrapping */
- /* XXX: as we cannot support really dynamic
- mappings, we handle specific values as invalid
- mappings. */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr == -1) {
- new_addr = -1;
- }
- } else {
- no_mem_map:
- new_addr = -1;
- }
- }
- /* now do the real mapping */
- if (new_addr != r->addr) {
- if (r->addr != -1) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- int class;
- /* NOTE: specific hack for IDE in PC case:
- only one byte must be mapped. */
- class = d->config[0x0a] | (d->config[0x0b] << 8);
- if (class == 0x0101 && r->size == 4) {
- isa_unassign_ioport(r->addr + 2, 1);
- } else {
- isa_unassign_ioport(r->addr, r->size);
- }
- } else {
- cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
- r->size,
- IO_MEM_UNASSIGNED);
- }
- }
- r->addr = new_addr;
- if (r->addr != -1) {
- r->map_func(d, i, r->addr, r->size, r->type);
- }
- }
- }
- }
-}
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len)
-{
- uint32_t val;
-
- switch(len) {
- default:
- case 4:
- if (address <= 0xfc) {
- val = le32_to_cpu(*(uint32_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 2:
- if (address <= 0xfe) {
- val = le16_to_cpu(*(uint16_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 1:
- val = d->config[address];
- break;
- }
- return val;
-}
-
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- int can_write, i;
- uint32_t end, addr;
-
- if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
- (address >= 0x30 && address < 0x34))) {
- PCIIORegion *r;
- int reg;
-
- if ( address >= 0x30 ) {
- reg = PCI_ROM_SLOT;
- }else{
- reg = (address - 0x10) >> 2;
- }
- r = &d->io_regions[reg];
- if (r->size == 0)
- goto default_config;
- /* compute the stored value */
- if (reg == PCI_ROM_SLOT) {
- /* keep ROM enable bit */
- val &= (~(r->size - 1)) | 1;
- } else {
- val &= ~(r->size - 1);
- val |= r->type;
- }
- *(uint32_t *)(d->config + address) = cpu_to_le32(val);
- pci_update_mappings(d);
- return;
- }
- default_config:
- /* not efficient, but simple */
- addr = address;
- for(i = 0; i < len; i++) {
- /* default read/write accesses */
- switch(d->config[0x0e]) {
- case 0x00:
- case 0x80:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x10 ... 0x27: /* base */
- case 0x30 ... 0x33: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- default:
- case 0x01:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x38 ... 0x3b: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- }
- if (can_write) {
- d->config[addr] = val;
- }
- if (++addr > 0xff)
- break;
- val >>= 8;
- }
-
- end = address + len;
- if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
- /* if the command register is modified, we must modify the mappings */
- pci_update_mappings(d);
- }
-}
-
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
-
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_write: addr=%08x val=%08x len=%d\n",
- addr, val, len);
-#endif
- bus_num = (addr >> 16) & 0xff;
- while (s && s->bus_num != bus_num)
- s = s->next;
- if (!s)
- return;
- pci_dev = s->devices[(addr >> 8) & 0xff];
- if (!pci_dev)
- return;
- config_addr = addr & 0xff;
-#if defined(DEBUG_PCI)
- printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- pci_dev->config_write(pci_dev, config_addr, val, len);
-}
-
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
- uint32_t val;
-
- bus_num = (addr >> 16) & 0xff;
- while (s && s->bus_num != bus_num)
- s= s->next;
- if (!s)
- goto fail;
- pci_dev = s->devices[(addr >> 8) & 0xff];
- if (!pci_dev) {
- fail:
- switch(len) {
- case 1:
- val = 0xff;
- break;
- case 2:
- val = 0xffff;
- break;
- default:
- case 4:
- val = 0xffffffff;
- break;
- }
- goto the_end;
- }
- config_addr = addr & 0xff;
- val = pci_dev->config_read(pci_dev, config_addr, len);
-#if defined(DEBUG_PCI)
- printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- the_end:
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_read: addr=%08x val=%08x len=%d\n",
- addr, val, len);
-#endif
- return val;
-}
-
-/***********************************************************/
-/* generic PCI irq support */
-
-/* 0 <= irq_num <= 3. level must be 0 or 1 */
-static void pci_set_irq(void *opaque, int irq_num, int level)
-{
- PCIDevice *pci_dev = (PCIDevice *)opaque;
- PCIBus *bus;
- int change;
-
- change = level - pci_dev->irq_state[irq_num];
- if (!change)
- return;
-
- pci_dev->irq_state[irq_num] = level;
- for (;;) {
- bus = pci_dev->bus;
- irq_num = bus->map_irq(pci_dev, irq_num);
- if (bus->set_irq)
- break;
- pci_dev = bus->parent_dev;
- }
- bus->irq_count[irq_num] += change;
- bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
-}
-
-/***********************************************************/
-/* monitor info on PCI */
-
-typedef struct {
- uint16_t class;
- const char *desc;
-} pci_class_desc;
-
-static pci_class_desc pci_class_descriptions[] =
-{
- { 0x0100, "SCSI controller"},
- { 0x0101, "IDE controller"},
- { 0x0102, "Floppy controller"},
- { 0x0103, "IPI controller"},
- { 0x0104, "RAID controller"},
- { 0x0106, "SATA controller"},
- { 0x0107, "SAS controller"},
- { 0x0180, "Storage controller"},
- { 0x0200, "Ethernet controller"},
- { 0x0201, "Token Ring controller"},
- { 0x0202, "FDDI controller"},
- { 0x0203, "ATM controller"},
- { 0x0280, "Network controller"},
- { 0x0300, "VGA controller"},
- { 0x0301, "XGA controller"},
- { 0x0302, "3D controller"},
- { 0x0380, "Display controller"},
- { 0x0400, "Video controller"},
- { 0x0401, "Audio controller"},
- { 0x0402, "Phone"},
- { 0x0480, "Multimedia controller"},
- { 0x0500, "RAM controller"},
- { 0x0501, "Flash controller"},
- { 0x0580, "Memory controller"},
- { 0x0600, "Host bridge"},
- { 0x0601, "ISA bridge"},
- { 0x0602, "EISA bridge"},
- { 0x0603, "MC bridge"},
- { 0x0604, "PCI bridge"},
- { 0x0605, "PCMCIA bridge"},
- { 0x0606, "NUBUS bridge"},
- { 0x0607, "CARDBUS bridge"},
- { 0x0608, "RACEWAY bridge"},
- { 0x0680, "Bridge"},
- { 0x0c03, "USB controller"},
- { 0, NULL}
-};
-
-static void pci_info_device(PCIDevice *d)
-{
- int i, class;
- PCIIORegion *r;
- pci_class_desc *desc;
-
- term_printf(" Bus %2d, device %3d, function %d:\n",
- d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
- class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
- term_printf(" ");
- desc = pci_class_descriptions;
- while (desc->desc && class != desc->class)
- desc++;
- if (desc->desc) {
- term_printf("%s", desc->desc);
- } else {
- term_printf("Class %04x", class);
- }
- term_printf(": PCI device %04x:%04x\n",
- le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
- le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
-
- if (d->config[PCI_INTERRUPT_PIN] != 0) {
- term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
- }
- if (class == 0x0604) {
- term_printf(" BUS %d.\n", d->config[0x19]);
- }
- for(i = 0;i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (r->size != 0) {
- term_printf(" BAR%d: ", i);
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- term_printf("I/O at 0x%04x [0x%04x].\n",
- r->addr, r->addr + r->size - 1);
- } else {
- term_printf("32 bit memory at 0x%08x [0x%08x].\n",
- r->addr, r->addr + r->size - 1);
- }
- }
- }
- if (class == 0x0604 && d->config[0x19] != 0) {
- pci_for_each_device(d->config[0x19], pci_info_device);
- }
-}
-
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d))
-{
- PCIBus *bus = first_bus;
- PCIDevice *d;
- int devfn;
-
- while (bus && bus->bus_num != bus_num)
- bus = bus->next;
- if (bus) {
- for(devfn = 0; devfn < 256; devfn++) {
- d = bus->devices[devfn];
- if (d)
- fn(d);
- }
- }
-}
-
-void pci_info(void)
-{
- pci_for_each_device(0, pci_info_device);
-}
-
-/* Initialize a PCI NIC. */
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn)
-{
-#if 0
- if (strcmp(nd->model, "ne2k_pci") == 0) {
- pci_ne2000_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "i82551") == 0) {
- pci_i82551_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "i82557b") == 0) {
- pci_i82557b_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "i82559er") == 0) {
- pci_i82559er_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "rtl8139") == 0) {
- pci_rtl8139_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "e1000") == 0) {
- pci_e1000_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "pcnet") == 0) {
- pci_pcnet_init(bus, nd, devfn);
- } else if (strcmp(nd->model, "?") == 0) {
- fprintf(stderr, "qemu: Supported PCI NICs: i82551 i82557b i82559er"
- " ne2k_pci pcnet rtl8139 e1000\n");
- exit (1);
- } else {
- fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
- exit (1);
- }
-#endif
-}
-
-typedef struct {
- PCIDevice dev;
- PCIBus *bus;
-} PCIBridge;
-
-static void pci_bridge_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- PCIBridge *s = (PCIBridge *)d;
-
- if (address == 0x19 || (address == 0x18 && len > 1)) {
- if (address == 0x19)
- s->bus->bus_num = val & 0xff;
- else
- s->bus->bus_num = (val >> 8) & 0xff;
-#if defined(DEBUG_PCI)
- printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num);
-#endif
- }
- pci_default_write_config(d, address, val, len);
-}
-
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name)
-{
- PCIBridge *s;
- s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
- devfn, NULL, pci_bridge_write_config);
- s->dev.config[0x00] = id >> 16;
- s->dev.config[0x01] = id >> 24;
- s->dev.config[0x02] = id; // device_id
- s->dev.config[0x03] = id >> 8;
- s->dev.config[0x04] = 0x06; // command = bus master, pci mem
- s->dev.config[0x05] = 0x00;
- s->dev.config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- s->dev.config[0x07] = 0x00; // status = fast devsel
- s->dev.config[0x08] = 0x00; // revision
- s->dev.config[0x09] = 0x00; // programming i/f
- s->dev.config[0x0A] = 0x04; // class_sub = PCI to PCI bridge
- s->dev.config[0x0B] = 0x06; // class_base = PCI_bridge
- s->dev.config[0x0D] = 0x10; // latency_timer
- s->dev.config[0x0E] = 0x81; // header_type
- s->dev.config[0x1E] = 0xa0; // secondary status
-
- s->bus = pci_register_secondary_bus(&s->dev, map_irq);
- return s->bus;
-}
diff --git a/hw/pci.h b/hw/pci.h
deleted file mode 100644
index e870987..0000000
--- a/hw/pci.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef QEMU_PCI_H
-#define QEMU_PCI_H
-
-/* PCI includes legacy ISA access. */
-#include "isa.h"
-
-/* PCI bus */
-
-extern target_phys_addr_t pci_mem_base;
-
-typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
- uint32_t address, uint32_t data, int len);
-typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
- uint32_t address, int len);
-typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type);
-
-#define PCI_ADDRESS_SPACE_MEM 0x00
-#define PCI_ADDRESS_SPACE_IO 0x01
-#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
-
-typedef struct PCIIORegion {
- uint32_t addr; /* current PCI mapping address. -1 means not mapped */
- uint32_t size;
- uint8_t type;
- PCIMapIORegionFunc *map_func;
-} PCIIORegion;
-
-#define PCI_ROM_SLOT 6
-#define PCI_NUM_REGIONS 7
-
-#define PCI_DEVICES_MAX 64
-
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-struct PCIDevice {
- /* PCI config space */
- uint8_t config[256];
-
- /* the following fields are read only */
- PCIBus *bus;
- int devfn;
- char name[64];
- PCIIORegion io_regions[PCI_NUM_REGIONS];
-
- /* do not access the following fields */
- PCIConfigReadFunc *config_read;
- PCIConfigWriteFunc *config_write;
- /* ??? This is a PC-specific hack, and should be removed. */
- int irq_index;
-
- /* IRQ objects for the INTA-INTD pins. */
- qemu_irq *irq;
-
- /* Current IRQ levels. Used internally by the generic PCI code. */
- int irq_state[4];
-};
-
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write);
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func);
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len);
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len);
-void pci_device_save(PCIDevice *s, QEMUFile *f);
-int pci_device_load(PCIDevice *s, QEMUFile *f);
-
-typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
-typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- qemu_irq *pic, int devfn_min, int nirq);
-
-void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
-uint32_t pci_data_read(void *opaque, uint32_t addr, int len);
-int pci_bus_num(PCIBus *s);
-void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
-
-void pci_info(void);
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
- pci_map_irq_fn map_irq, const char *name);
-
-/* lsi53c895a.c */
-#define LSI_MAX_DEVS 7
-void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
-void *lsi_scsi_init(PCIBus *bus, int devfn);
-
-/* vmware_vga.c */
-void pci_vmsvga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* usb-uhci.c */
-void usb_uhci_piix3_init(PCIBus *bus, int devfn);
-void usb_uhci_piix4_init(PCIBus *bus, int devfn);
-
-/* usb-ohci.c */
-void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn);
-
-/* eepro100.c */
-
-void pci_i82551_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82557b_init(PCIBus *bus, NICInfo *nd, int devfn);
-void pci_i82559er_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* ne2000.c */
-
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* rtl8139.c */
-
-void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* e1000.c */
-void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* pcnet.c */
-void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn);
-
-/* prep_pci.c */
-PCIBus *pci_prep_init(qemu_irq *pic);
-
-/* apb_pci.c */
-PCIBus *pci_apb_init(target_phys_addr_t special_base, target_phys_addr_t mem_base,
- qemu_irq *pic);
-
-#endif
diff --git a/hw/pci_host.h b/hw/pci_host.h
deleted file mode 100644
index 49a0c59..0000000
--- a/hw/pci_host.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * QEMU Common PCI Host bridge configuration data space access routines.
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Worker routines for a PCI host controller that uses an {address,data}
- register pair to access PCI configuration space. */
-
-typedef struct {
- uint32_t config_reg;
- PCIBus *bus;
-} PCIHostState;
-
-static void pci_host_data_writeb(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1);
-}
-
-static void pci_host_data_writew(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2);
-}
-
-static void pci_host_data_writel(void* opaque, pci_addr_t addr, uint32_t val)
-{
- PCIHostState *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- if (s->config_reg & (1u << 31))
- pci_data_write(s->bus, s->config_reg, val, 4);
-}
-
-static uint32_t pci_host_data_readb(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- if (!(s->config_reg & (1 << 31)))
- return 0xff;
- return pci_data_read(s->bus, s->config_reg | (addr & 3), 1);
-}
-
-static uint32_t pci_host_data_readw(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- uint32_t val;
- if (!(s->config_reg & (1 << 31)))
- return 0xffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t pci_host_data_readl(void* opaque, pci_addr_t addr)
-{
- PCIHostState *s = opaque;
- uint32_t val;
- if (!(s->config_reg & (1 << 31)))
- return 0xffffffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
diff --git a/hw/pcmcia.h b/hw/pcmcia.h
deleted file mode 100644
index bfa23ba..0000000
--- a/hw/pcmcia.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* PCMCIA/Cardbus */
-
-struct pcmcia_socket_s {
- qemu_irq irq;
- int attached;
- const char *slot_string;
- const char *card_string;
-};
-
-void pcmcia_socket_register(struct pcmcia_socket_s *socket);
-void pcmcia_socket_unregister(struct pcmcia_socket_s *socket);
-void pcmcia_info(void);
-
-struct pcmcia_card_s {
- void *state;
- struct pcmcia_socket_s *slot;
- int (*attach)(void *state);
- int (*detach)(void *state);
- const uint8_t *cis;
- int cis_len;
-
- /* Only valid if attached */
- uint8_t (*attr_read)(void *state, uint32_t address);
- void (*attr_write)(void *state, uint32_t address, uint8_t value);
- uint16_t (*common_read)(void *state, uint32_t address);
- void (*common_write)(void *state, uint32_t address, uint16_t value);
- uint16_t (*io_read)(void *state, uint32_t address);
- void (*io_write)(void *state, uint32_t address, uint16_t value);
-};
-
-#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */
-#define CISTPL_NO_LINK 0x14 /* No Link Tuple */
-#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */
-#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */
-#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */
-#define CISTPL_CONFIG 0x1a /* Configuration Tuple */
-#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */
-#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */
-#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */
-#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */
-#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */
-#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */
-#define CISTPL_FUNCID 0x21 /* Function ID Tuple */
-#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */
-#define CISTPL_END 0xff /* Tuple End */
-#define CISTPL_ENDMARK 0xff
-
-/* dscm1xxxx.c */
-struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv);
-
diff --git a/hw/power_supply.h b/hw/power_supply.h
deleted file mode 100644
index b85edc7..0000000
--- a/hw/power_supply.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Universal power supply monitor class
- *
- * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
- * Copyright © 2004 Szabolcs Gyurko
- * Copyright © 2003 Ian Molton <spyro@f2s.com>
- *
- * Modified: 2004, Oct Szabolcs Gyurko
- *
- * You may use this code as per GPL version 2
- */
-
-#ifndef __LINUX_POWER_SUPPLY_H__
-#define __LINUX_POWER_SUPPLY_H__
-
-/*
- * All voltages, currents, charges, energies, time and temperatures in uV,
- * µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
- * stated. It's driver's job to convert its raw values to units in which
- * this class operates.
- */
-
-/*
- * For systems where the charger determines the maximum battery capacity
- * the min and max fields should be used to present these values to user
- * space. Unused/unknown fields will not appear in sysfs.
- */
-
-enum {
- POWER_SUPPLY_STATUS_UNKNOWN = 0,
- POWER_SUPPLY_STATUS_CHARGING,
- POWER_SUPPLY_STATUS_DISCHARGING,
- POWER_SUPPLY_STATUS_NOT_CHARGING,
- POWER_SUPPLY_STATUS_FULL,
-};
-
-enum {
- POWER_SUPPLY_HEALTH_UNKNOWN = 0,
- POWER_SUPPLY_HEALTH_GOOD,
- POWER_SUPPLY_HEALTH_OVERHEAT,
- POWER_SUPPLY_HEALTH_DEAD,
- POWER_SUPPLY_HEALTH_OVERVOLTAGE,
- POWER_SUPPLY_HEALTH_UNSPEC_FAILURE,
-};
-
-enum {
- POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0,
- POWER_SUPPLY_TECHNOLOGY_NiMH,
- POWER_SUPPLY_TECHNOLOGY_LION,
- POWER_SUPPLY_TECHNOLOGY_LIPO,
- POWER_SUPPLY_TECHNOLOGY_LiFe,
- POWER_SUPPLY_TECHNOLOGY_NiCd,
-};
-
-enum {
- POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0,
- POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL,
- POWER_SUPPLY_CAPACITY_LEVEL_LOW,
- POWER_SUPPLY_CAPACITY_LEVEL_NORMAL,
- POWER_SUPPLY_CAPACITY_LEVEL_HIGH,
- POWER_SUPPLY_CAPACITY_LEVEL_FULL,
-};
-
-enum power_supply_property {
- /* Properties of type `int' */
- POWER_SUPPLY_PROP_STATUS = 0,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_VOLTAGE_AVG,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CURRENT_AVG,
- POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_FULL,
- POWER_SUPPLY_PROP_CHARGE_EMPTY,
- POWER_SUPPLY_PROP_CHARGE_NOW,
- POWER_SUPPLY_PROP_CHARGE_AVG,
- POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_FULL,
- POWER_SUPPLY_PROP_ENERGY_EMPTY,
- POWER_SUPPLY_PROP_ENERGY_NOW,
- POWER_SUPPLY_PROP_ENERGY_AVG,
- POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
- POWER_SUPPLY_PROP_CAPACITY_LEVEL,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_TEMP_AMBIENT,
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
- POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
- POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
- /* Properties of type `const char *' */
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
-enum power_supply_type {
- POWER_SUPPLY_TYPE_BATTERY = 0,
- POWER_SUPPLY_TYPE_UPS,
- POWER_SUPPLY_TYPE_MAINS,
- POWER_SUPPLY_TYPE_USB,
-};
-
-#endif /* __LINUX_POWER_SUPPLY_H__ */
diff --git a/hw/pxa.h b/hw/pxa.h
deleted file mode 100644
index 16a68d9..0000000
--- a/hw/pxa.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Intel XScale PXA255/270 processor support.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licenced under the GNU GPL v2.
- */
-#ifndef PXA_H
-# define PXA_H "pxa.h"
-
-/* Interrupt numbers */
-# define PXA2XX_PIC_SSP3 0
-# define PXA2XX_PIC_USBH2 2
-# define PXA2XX_PIC_USBH1 3
-# define PXA2XX_PIC_KEYPAD 4
-# define PXA2XX_PIC_PWRI2C 6
-# define PXA25X_PIC_HWUART 7
-# define PXA27X_PIC_OST_4_11 7
-# define PXA2XX_PIC_GPIO_0 8
-# define PXA2XX_PIC_GPIO_1 9
-# define PXA2XX_PIC_GPIO_X 10
-# define PXA2XX_PIC_I2S 13
-# define PXA26X_PIC_ASSP 15
-# define PXA25X_PIC_NSSP 16
-# define PXA27X_PIC_SSP2 16
-# define PXA2XX_PIC_LCD 17
-# define PXA2XX_PIC_I2C 18
-# define PXA2XX_PIC_ICP 19
-# define PXA2XX_PIC_STUART 20
-# define PXA2XX_PIC_BTUART 21
-# define PXA2XX_PIC_FFUART 22
-# define PXA2XX_PIC_MMC 23
-# define PXA2XX_PIC_SSP 24
-# define PXA2XX_PIC_DMA 25
-# define PXA2XX_PIC_OST_0 26
-# define PXA2XX_PIC_RTC1HZ 30
-# define PXA2XX_PIC_RTCALARM 31
-
-/* DMA requests */
-# define PXA2XX_RX_RQ_I2S 2
-# define PXA2XX_TX_RQ_I2S 3
-# define PXA2XX_RX_RQ_BTUART 4
-# define PXA2XX_TX_RQ_BTUART 5
-# define PXA2XX_RX_RQ_FFUART 6
-# define PXA2XX_TX_RQ_FFUART 7
-# define PXA2XX_RX_RQ_SSP1 13
-# define PXA2XX_TX_RQ_SSP1 14
-# define PXA2XX_RX_RQ_SSP2 15
-# define PXA2XX_TX_RQ_SSP2 16
-# define PXA2XX_RX_RQ_ICP 17
-# define PXA2XX_TX_RQ_ICP 18
-# define PXA2XX_RX_RQ_STUART 19
-# define PXA2XX_TX_RQ_STUART 20
-# define PXA2XX_RX_RQ_MMCI 21
-# define PXA2XX_TX_RQ_MMCI 22
-# define PXA2XX_USB_RQ(x) ((x) + 24)
-# define PXA2XX_RX_RQ_SSP3 66
-# define PXA2XX_TX_RQ_SSP3 67
-
-# define PXA2XX_SDRAM_BASE 0xa0000000
-# define PXA2XX_INTERNAL_BASE 0x5c000000
-# define PXA2XX_INTERNAL_SIZE 0x40000
-
-/* pxa2xx_pic.c */
-qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env);
-
-/* pxa2xx_timer.c */
-void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs);
-void pxa27x_timer_init(target_phys_addr_t base, qemu_irq *irqs, qemu_irq irq4);
-
-/* pxa2xx_gpio.c */
-struct pxa2xx_gpio_info_s;
-struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base,
- CPUState *env, qemu_irq *pic, int lines);
-qemu_irq *pxa2xx_gpio_in_get(struct pxa2xx_gpio_info_s *s);
-void pxa2xx_gpio_out_set(struct pxa2xx_gpio_info_s *s,
- int line, qemu_irq handler);
-void pxa2xx_gpio_read_notifier(struct pxa2xx_gpio_info_s *s, qemu_irq handler);
-
-/* pxa2xx_dma.c */
-struct pxa2xx_dma_state_s;
-struct pxa2xx_dma_state_s *pxa255_dma_init(target_phys_addr_t base,
- qemu_irq irq);
-struct pxa2xx_dma_state_s *pxa27x_dma_init(target_phys_addr_t base,
- qemu_irq irq);
-void pxa2xx_dma_request(struct pxa2xx_dma_state_s *s, int req_num, int on);
-
-/* pxa2xx_lcd.c */
-struct pxa2xx_lcdc_s;
-struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base,
- qemu_irq irq, DisplayState *ds);
-void pxa2xx_lcd_vsync_notifier(struct pxa2xx_lcdc_s *s, qemu_irq handler);
-void pxa2xx_lcdc_oritentation(void *opaque, int angle);
-
-/* pxa2xx_mmci.c */
-struct pxa2xx_mmci_s;
-struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base,
- BlockDriverState *bd, qemu_irq irq, void *dma);
-void pxa2xx_mmci_handlers(struct pxa2xx_mmci_s *s, qemu_irq readonly,
- qemu_irq coverswitch);
-
-/* pxa2xx_pcmcia.c */
-struct pxa2xx_pcmcia_s;
-struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base);
-int pxa2xx_pcmcia_attach(void *opaque, struct pcmcia_card_s *card);
-int pxa2xx_pcmcia_dettach(void *opaque);
-void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
-
-/* pxa2xx_keypad.c */
-struct keymap {
- int column;
- int row;
-};
-struct pxa2xx_keypad_s;
-struct pxa2xx_keypad_s *pxa27x_keypad_init(target_phys_addr_t base,
- qemu_irq irq);
-void pxa27x_register_keypad(struct pxa2xx_keypad_s *kp, struct keymap *map,
- int size);
-
-/* pxa2xx.c */
-struct pxa2xx_ssp_s;
-void pxa2xx_ssp_attach(struct pxa2xx_ssp_s *port,
- uint32_t (*readfn)(void *opaque),
- void (*writefn)(void *opaque, uint32_t value), void *opaque);
-
-struct pxa2xx_i2c_s;
-struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
- qemu_irq irq, uint32_t page_size);
-i2c_bus *pxa2xx_i2c_bus(struct pxa2xx_i2c_s *s);
-
-struct pxa2xx_i2s_s;
-struct pxa2xx_fir_s;
-
-struct pxa2xx_state_s {
- CPUState *env;
- qemu_irq *pic;
- qemu_irq reset;
- struct pxa2xx_dma_state_s *dma;
- struct pxa2xx_gpio_info_s *gpio;
- struct pxa2xx_lcdc_s *lcd;
- struct pxa2xx_ssp_s **ssp;
- struct pxa2xx_i2c_s *i2c[2];
- struct pxa2xx_mmci_s *mmc;
- struct pxa2xx_pcmcia_s *pcmcia[2];
- struct pxa2xx_i2s_s *i2s;
- struct pxa2xx_fir_s *fir;
- struct pxa2xx_keypad_s *kp;
-
- /* Power management */
- target_phys_addr_t pm_base;
- uint32_t pm_regs[0x40];
-
- /* Clock management */
- target_phys_addr_t cm_base;
- uint32_t cm_regs[4];
- uint32_t clkcfg;
-
- /* Memory management */
- target_phys_addr_t mm_base;
- uint32_t mm_regs[0x1a];
-
- /* Performance monitoring */
- uint32_t pmnc;
-
- /* Real-Time clock */
- target_phys_addr_t rtc_base;
- uint32_t rttr;
- uint32_t rtsr;
- uint32_t rtar;
- uint32_t rdar1;
- uint32_t rdar2;
- uint32_t ryar1;
- uint32_t ryar2;
- uint32_t swar1;
- uint32_t swar2;
- uint32_t piar;
- uint32_t last_rcnr;
- uint32_t last_rdcr;
- uint32_t last_rycr;
- uint32_t last_swcr;
- uint32_t last_rtcpicr;
- int64_t last_hz;
- int64_t last_sw;
- int64_t last_pi;
- QEMUTimer *rtc_hz;
- QEMUTimer *rtc_rdal1;
- QEMUTimer *rtc_rdal2;
- QEMUTimer *rtc_swal1;
- QEMUTimer *rtc_swal2;
- QEMUTimer *rtc_pi;
-};
-
-struct pxa2xx_i2s_s {
- target_phys_addr_t base;
- qemu_irq irq;
- struct pxa2xx_dma_state_s *dma;
- void (*data_req)(void *, int, int);
-
- uint32_t control[2];
- uint32_t status;
- uint32_t mask;
- uint32_t clk;
-
- int enable;
- int rx_len;
- int tx_len;
- void (*codec_out)(void *, uint32_t);
- uint32_t (*codec_in)(void *);
- void *opaque;
-
- int fifo_len;
- uint32_t fifo[16];
-};
-
-# define PA_FMT "0x%08lx"
-# define REG_FMT "0x" TARGET_FMT_plx
-
-struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, DisplayState *ds,
- const char *revision);
-struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, DisplayState *ds);
-
-/* usb-ohci.c */
-void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
- qemu_irq irq);
-
-#endif /* PXA_H */
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
deleted file mode 100644
index 16b3215..0000000
--- a/hw/scsi-disk.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * SCSI Device emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Based on code by Fabrice Bellard
- *
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- *
- * Note that this file only handles the SCSI architecture model and device
- * commands. Emulation of interface/link layer protocols is handled by
- * the host adapter emulator.
- */
-
-//#define DEBUG_SCSI
-
-#ifdef DEBUG_SCSI
-#define DPRINTF(fmt, args...) \
-do { printf("scsi-disk: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-#define BADF(fmt, args...) \
-do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
-
-#include "qemu-common.h"
-#include "block.h"
-#include "scsi-disk.h"
-
-#define SENSE_NO_SENSE 0
-#define SENSE_NOT_READY 2
-#define SENSE_HARDWARE_ERROR 4
-#define SENSE_ILLEGAL_REQUEST 5
-
-#define SCSI_DMA_BUF_SIZE 65536
-
-typedef struct SCSIRequest {
- SCSIDeviceState *dev;
- uint32_t tag;
- /* ??? We should probably keep track of whether the data trasfer is
- a read or a write. Currently we rely on the host getting it right. */
- /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
- int sector;
- int sector_count;
- /* The amounnt of data in the buffer. */
- int buf_len;
- uint8_t *dma_buf;
- BlockDriverAIOCB *aiocb;
- struct SCSIRequest *next;
-} SCSIRequest;
-
-struct SCSIDeviceState
-{
- BlockDriverState *bdrv;
- SCSIRequest *requests;
- /* The qemu block layer uses a fixed 512 byte sector size.
- This is the number of 512 byte blocks in a single scsi sector. */
- int cluster_size;
- int sense;
- int tcq;
- /* Completion functions may be called from either scsi_{read,write}_data
- or from the AIO completion routines. */
- scsi_completionfn completion;
- void *opaque;
-};
-
-/* Global pool of SCSIRequest structures. */
-static SCSIRequest *free_requests = NULL;
-
-static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- if (free_requests) {
- r = free_requests;
- free_requests = r->next;
- } else {
- r = qemu_malloc(sizeof(SCSIRequest));
- r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
- }
- r->dev = s;
- r->tag = tag;
- r->sector_count = 0;
- r->buf_len = 0;
- r->aiocb = NULL;
-
- r->next = s->requests;
- s->requests = r;
- return r;
-}
-
-static void scsi_remove_request(SCSIRequest *r)
-{
- SCSIRequest *last;
- SCSIDeviceState *s = r->dev;
-
- if (s->requests == r) {
- s->requests = r->next;
- } else {
- last = s->requests;
- while (last && last->next != r)
- last = last->next;
- if (last) {
- last->next = r->next;
- } else {
- BADF("Orphaned request\n");
- }
- }
- r->next = free_requests;
- free_requests = r;
-}
-
-static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
-{
- SCSIRequest *r;
-
- r = s->requests;
- while (r && r->tag != tag)
- r = r->next;
-
- return r;
-}
-
-/* Helper function for command completion. */
-static void scsi_command_complete(SCSIRequest *r, int sense)
-{
- SCSIDeviceState *s = r->dev;
- uint32_t tag;
- DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
- s->sense = sense;
- tag = r->tag;
- scsi_remove_request(r);
- s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
-}
-
-/* Cancel a pending data transfer. */
-static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
- DPRINTF("Cancel tag=0x%x\n", tag);
- r = scsi_find_request(s, tag);
- if (r) {
- if (r->aiocb)
- bdrv_aio_cancel(r->aiocb);
- r->aiocb = NULL;
- scsi_remove_request(r);
- }
-}
-
-static void scsi_read_complete(void * opaque, int ret)
-{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDeviceState *s = r->dev;
-
- if (ret) {
- DPRINTF("IO error\n");
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return;
- }
- DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
-
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
-}
-
-/* Read more data from scsi device into buffer. */
-static void scsi_read_data(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
- uint32_t n;
-
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad read tag 0x%x\n", tag);
- /* ??? This is the wrong error. */
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return;
- }
- if (r->sector_count == (uint32_t)-1) {
- DPRINTF("Read buf_len=%d\n", r->buf_len);
- r->sector_count = 0;
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
- return;
- }
- DPRINTF("Read sector_count=%d\n", r->sector_count);
- if (r->sector_count == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- return;
- }
-
- n = r->sector_count;
- if (n > SCSI_DMA_BUF_SIZE / 512)
- n = SCSI_DMA_BUF_SIZE / 512;
-
- r->buf_len = n * 512;
- r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
- scsi_read_complete, r);
- if (r->aiocb == NULL)
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- r->sector += n;
- r->sector_count -= n;
-}
-
-static void scsi_write_complete(void * opaque, int ret)
-{
- SCSIRequest *r = (SCSIRequest *)opaque;
- SCSIDeviceState *s = r->dev;
- uint32_t len;
-
- if (ret) {
- fprintf(stderr, "scsi-disc: IO write error\n");
- exit(1);
- }
-
- r->aiocb = NULL;
- if (r->sector_count == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- } else {
- len = r->sector_count * 512;
- if (len > SCSI_DMA_BUF_SIZE) {
- len = SCSI_DMA_BUF_SIZE;
- }
- r->buf_len = len;
- DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
- s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
- }
-}
-
-/* Write data to a scsi device. Returns nonzero on failure.
- The transfer may complete asynchronously. */
-static int scsi_write_data(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
- uint32_t n;
-
- DPRINTF("Write data tag=0x%x\n", tag);
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad write tag 0x%x\n", tag);
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- return 1;
- }
- if (r->aiocb)
- BADF("Data transfer already in progress\n");
- n = r->buf_len / 512;
- if (n) {
- r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
- scsi_write_complete, r);
- if (r->aiocb == NULL)
- scsi_command_complete(r, SENSE_HARDWARE_ERROR);
- r->sector += n;
- r->sector_count -= n;
- } else {
- /* Invoke completion routine to fetch data from host. */
- scsi_write_complete(r, 0);
- }
-
- return 0;
-}
-
-/* Return a pointer to the data buffer. */
-static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
-{
- SCSIDeviceState *s = d->state;
- SCSIRequest *r;
-
- r = scsi_find_request(s, tag);
- if (!r) {
- BADF("Bad buffer tag 0x%x\n", tag);
- return NULL;
- }
- return r->dma_buf;
-}
-
-/* Execute a scsi command. Returns the length of the data expected by the
- command. This will be Positive for data transfers from the device
- (eg. disk reads), negative for transfers to the device (eg. disk writes),
- and zero if the command does not transfer any data. */
-
-static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
- uint8_t *buf, int lun)
-{
- SCSIDeviceState *s = d->state;
- uint64_t nb_sectors;
- uint32_t lba;
- uint32_t len;
- int cmdlen;
- int is_write;
- uint8_t command;
- uint8_t *outbuf;
- SCSIRequest *r;
-
- command = buf[0];
- r = scsi_find_request(s, tag);
- if (r) {
- BADF("Tag 0x%x already in use\n", tag);
- scsi_cancel_io(d, tag);
- }
- /* ??? Tags are not unique for different luns. We only implement a
- single lun, so this should not matter. */
- r = scsi_new_request(s, tag);
- outbuf = r->dma_buf;
- is_write = 0;
- DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
- switch (command >> 5) {
- case 0:
- lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
- len = buf[4];
- cmdlen = 6;
- break;
- case 1:
- case 2:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[8] | (buf[7] << 8);
- cmdlen = 10;
- break;
- case 4:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
- cmdlen = 16;
- break;
- case 5:
- lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
- len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
- cmdlen = 12;
- break;
- default:
- BADF("Unsupported command length, command %x\n", command);
- goto fail;
- }
-#ifdef DEBUG_SCSI
- {
- int i;
- for (i = 1; i < cmdlen; i++) {
- printf(" 0x%02x", buf[i]);
- }
- printf("\n");
- }
-#endif
- if (lun || buf[1] >> 5) {
- /* Only LUN 0 supported. */
- DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
- goto fail;
- }
- switch (command) {
- case 0x0:
- DPRINTF("Test Unit Ready\n");
- break;
- case 0x03:
- DPRINTF("Request Sense (len %d)\n", len);
- if (len < 4)
- goto fail;
- memset(outbuf, 0, 4);
- outbuf[0] = 0xf0;
- outbuf[1] = 0;
- outbuf[2] = s->sense;
- r->buf_len = 4;
- break;
- case 0x12:
- DPRINTF("Inquiry (len %d)\n", len);
- if (buf[1] & 0x2) {
- /* Command support data - optional, not implemented */
- BADF("optional INQUIRY command support request not implemented\n");
- goto fail;
- }
- else if (buf[1] & 0x1) {
- /* Vital product data */
- uint8_t page_code = buf[2];
- if (len < 4) {
- BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
- "less than 4\n", page_code, len);
- goto fail;
- }
-
- switch (page_code) {
- case 0x00:
- {
- /* Supported page codes, mandatory */
- DPRINTF("Inquiry EVPD[Supported pages] "
- "buffer size %d\n", len);
-
- r->buf_len = 0;
-
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[r->buf_len++] = 5;
- } else {
- outbuf[r->buf_len++] = 0;
- }
-
- outbuf[r->buf_len++] = 0x00; // this page
- outbuf[r->buf_len++] = 0x00;
- outbuf[r->buf_len++] = 3; // number of pages
- outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
- outbuf[r->buf_len++] = 0x80; // unit serial number
- outbuf[r->buf_len++] = 0x83; // device identification
- }
- break;
- case 0x80:
- {
- /* Device serial number, optional */
- if (len < 4) {
- BADF("Error: EVPD[Serial number] Inquiry buffer "
- "size %d too small, %d needed\n", len, 4);
- goto fail;
- }
-
- DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
-
- r->buf_len = 0;
-
- /* Supported page codes */
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[r->buf_len++] = 5;
- } else {
- outbuf[r->buf_len++] = 0;
- }
-
- outbuf[r->buf_len++] = 0x80; // this page
- outbuf[r->buf_len++] = 0x00;
- outbuf[r->buf_len++] = 0x01; // 1 byte data follow
-
- outbuf[r->buf_len++] = '0'; // 1 byte data follow
- }
-
- break;
- case 0x83:
- {
- /* Device identification page, mandatory */
- int max_len = 255 - 8;
- int id_len = strlen(bdrv_get_device_name(s->bdrv));
- if (id_len > max_len)
- id_len = max_len;
-
- DPRINTF("Inquiry EVPD[Device identification] "
- "buffer size %d\n", len);
- r->buf_len = 0;
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[r->buf_len++] = 5;
- } else {
- outbuf[r->buf_len++] = 0;
- }
-
- outbuf[r->buf_len++] = 0x83; // this page
- outbuf[r->buf_len++] = 0x00;
- outbuf[r->buf_len++] = 3 + id_len;
-
- outbuf[r->buf_len++] = 0x2; // ASCII
- outbuf[r->buf_len++] = 0; // not officially assigned
- outbuf[r->buf_len++] = 0; // reserved
- outbuf[r->buf_len++] = id_len; // length of data following
-
- memcpy(&outbuf[r->buf_len],
- bdrv_get_device_name(s->bdrv), id_len);
- r->buf_len += id_len;
- }
- break;
- default:
- BADF("Error: unsupported Inquiry (EVPD[%02X]) "
- "buffer size %d\n", page_code, len);
- goto fail;
- }
- /* done with EVPD */
- break;
- }
- else {
- /* Standard INQUIRY data */
- if (buf[2] != 0) {
- BADF("Error: Inquiry (STANDARD) page or code "
- "is non-zero [%02X]\n", buf[2]);
- goto fail;
- }
-
- /* PAGE CODE == 0 */
- if (len < 5) {
- BADF("Error: Inquiry (STANDARD) buffer size %d "
- "is less than 5\n", len);
- goto fail;
- }
-
- if (len < 36) {
- BADF("Error: Inquiry (STANDARD) buffer size %d "
- "is less than 36 (TODO: only 5 required)\n", len);
- }
- }
- memset(outbuf, 0, 36);
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[0] = 5;
- outbuf[1] = 0x80;
- memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
- } else {
- outbuf[0] = 0;
- memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
- }
- memcpy(&outbuf[8], "QEMU ", 8);
- memcpy(&outbuf[32], QEMU_VERSION, 4);
- /* Identify device as SCSI-3 rev 1.
- Some later commands are also implemented. */
- outbuf[2] = 3;
- outbuf[3] = 2; /* Format 2 */
- outbuf[4] = 31;
- /* Sync data transfer and TCQ. */
- outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
- r->buf_len = 36;
- break;
- case 0x16:
- DPRINTF("Reserve(6)\n");
- if (buf[1] & 1)
- goto fail;
- break;
- case 0x17:
- DPRINTF("Release(6)\n");
- if (buf[1] & 1)
- goto fail;
- break;
- case 0x1a:
- case 0x5a:
- {
- uint8_t *p;
- int page;
-
- page = buf[2] & 0x3f;
- DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
- p = outbuf;
- memset(p, 0, 4);
- outbuf[1] = 0; /* Default media type. */
- outbuf[3] = 0; /* Block descriptor length. */
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- outbuf[2] = 0x80; /* Readonly. */
- }
- p += 4;
- if (page == 4) {
- int cylinders, heads, secs;
-
- /* Rigid disk device geometry page. */
- p[0] = 4;
- p[1] = 0x16;
- /* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
- p[2] = (cylinders >> 16) & 0xff;
- p[3] = (cylinders >> 8) & 0xff;
- p[4] = cylinders & 0xff;
- p[5] = heads & 0xff;
- /* Write precomp start cylinder, disabled */
- p[6] = (cylinders >> 16) & 0xff;
- p[7] = (cylinders >> 8) & 0xff;
- p[8] = cylinders & 0xff;
- /* Reduced current start cylinder, disabled */
- p[9] = (cylinders >> 16) & 0xff;
- p[10] = (cylinders >> 8) & 0xff;
- p[11] = cylinders & 0xff;
- /* Device step rate [ns], 200ns */
- p[12] = 0;
- p[13] = 200;
- /* Landing zone cylinder */
- p[14] = 0xff;
- p[15] = 0xff;
- p[16] = 0xff;
- /* Medium rotation rate [rpm], 5400 rpm */
- p[20] = (5400 >> 8) & 0xff;
- p[21] = 5400 & 0xff;
- p += 0x16;
- } else if (page == 5) {
- int cylinders, heads, secs;
-
- /* Flexible disk device geometry page. */
- p[0] = 5;
- p[1] = 0x1e;
- /* Transfer rate [kbit/s], 5Mbit/s */
- p[2] = 5000 >> 8;
- p[3] = 5000 & 0xff;
- /* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
- p[4] = heads & 0xff;
- p[5] = secs & 0xff;
- p[6] = s->cluster_size * 2;
- p[8] = (cylinders >> 8) & 0xff;
- p[9] = cylinders & 0xff;
- /* Write precomp start cylinder, disabled */
- p[10] = (cylinders >> 8) & 0xff;
- p[11] = cylinders & 0xff;
- /* Reduced current start cylinder, disabled */
- p[12] = (cylinders >> 8) & 0xff;
- p[13] = cylinders & 0xff;
- /* Device step rate [100us], 100us */
- p[14] = 0;
- p[15] = 1;
- /* Device step pulse width [us], 1us */
- p[16] = 1;
- /* Device head settle delay [100us], 100us */
- p[17] = 0;
- p[18] = 1;
- /* Motor on delay [0.1s], 0.1s */
- p[19] = 1;
- /* Motor off delay [0.1s], 0.1s */
- p[20] = 1;
- /* Medium rotation rate [rpm], 5400 rpm */
- p[28] = (5400 >> 8) & 0xff;
- p[29] = 5400 & 0xff;
- p += 0x1e;
- } else if ((page == 8 || page == 0x3f)) {
- /* Caching page. */
- memset(p,0,20);
- p[0] = 8;
- p[1] = 0x12;
- p[2] = 4; /* WCE */
- p += 20;
- }
- if ((page == 0x3f || page == 0x2a)
- && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
- /* CD Capabilities and Mechanical Status page. */
- p[0] = 0x2a;
- p[1] = 0x14;
- p[2] = 3; // CD-R & CD-RW read
- p[3] = 0; // Writing not supported
- p[4] = 0x7f; /* Audio, composite, digital out,
- mode 2 form 1&2, multi session */
- p[5] = 0xff; /* CD DA, DA accurate, RW supported,
- RW corrected, C2 errors, ISRC,
- UPC, Bar code */
- p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
- /* Locking supported, jumper present, eject, tray */
- p[7] = 0; /* no volume & mute control, no
- changer */
- p[8] = (50 * 176) >> 8; // 50x read speed
- p[9] = (50 * 176) & 0xff;
- p[10] = 0 >> 8; // No volume
- p[11] = 0 & 0xff;
- p[12] = 2048 >> 8; // 2M buffer
- p[13] = 2048 & 0xff;
- p[14] = (16 * 176) >> 8; // 16x read speed current
- p[15] = (16 * 176) & 0xff;
- p[18] = (16 * 176) >> 8; // 16x write speed
- p[19] = (16 * 176) & 0xff;
- p[20] = (16 * 176) >> 8; // 16x write speed current
- p[21] = (16 * 176) & 0xff;
- p += 22;
- }
- r->buf_len = p - outbuf;
- outbuf[0] = r->buf_len - 4;
- if (r->buf_len > len)
- r->buf_len = len;
- }
- break;
- case 0x1b:
- DPRINTF("Start Stop Unit\n");
- break;
- case 0x1e:
- DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
- bdrv_set_locked(s->bdrv, buf[4] & 1);
- break;
- case 0x25:
- DPRINTF("Read Capacity\n");
- /* The normal LEN field for this command is zero. */
- memset(outbuf, 0, 8);
- bdrv_get_geometry(s->bdrv, &nb_sectors);
- /* Returned value is the address of the last sector. */
- if (nb_sectors) {
- nb_sectors--;
- outbuf[0] = (nb_sectors >> 24) & 0xff;
- outbuf[1] = (nb_sectors >> 16) & 0xff;
- outbuf[2] = (nb_sectors >> 8) & 0xff;
- outbuf[3] = nb_sectors & 0xff;
- outbuf[4] = 0;
- outbuf[5] = 0;
- outbuf[6] = s->cluster_size * 2;
- outbuf[7] = 0;
- r->buf_len = 8;
- } else {
- scsi_command_complete(r, SENSE_NOT_READY);
- return 0;
- }
- break;
- case 0x08:
- case 0x28:
- DPRINTF("Read (sector %d, count %d)\n", lba, len);
- r->sector = lba * s->cluster_size;
- r->sector_count = len * s->cluster_size;
- break;
- case 0x0a:
- case 0x2a:
- DPRINTF("Write (sector %d, count %d)\n", lba, len);
- r->sector = lba * s->cluster_size;
- r->sector_count = len * s->cluster_size;
- is_write = 1;
- break;
- case 0x35:
- DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
- bdrv_flush(s->bdrv);
- break;
- case 0x43:
- {
- int start_track, format, msf, toclen;
-
- msf = buf[1] & 2;
- format = buf[2] & 0xf;
- start_track = buf[6];
- bdrv_get_geometry(s->bdrv, &nb_sectors);
- DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
- switch(format) {
- case 0:
- toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
- break;
- case 1:
- /* multi session : only a single session defined */
- toclen = 12;
- memset(outbuf, 0, 12);
- outbuf[1] = 0x0a;
- outbuf[2] = 0x01;
- outbuf[3] = 0x01;
- break;
- case 2:
- toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
- break;
- default:
- goto error_cmd;
- }
- if (toclen > 0) {
- if (len > toclen)
- len = toclen;
- r->buf_len = len;
- break;
- }
- error_cmd:
- DPRINTF("Read TOC error\n");
- goto fail;
- }
- case 0x46:
- DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
- memset(outbuf, 0, 8);
- /* ??? This should probably return much more information. For now
- just return the basic header indicating the CD-ROM profile. */
- outbuf[7] = 8; // CD-ROM
- r->buf_len = 8;
- break;
- case 0x56:
- DPRINTF("Reserve(10)\n");
- if (buf[1] & 3)
- goto fail;
- break;
- case 0x57:
- DPRINTF("Release(10)\n");
- if (buf[1] & 3)
- goto fail;
- break;
- case 0xa0:
- DPRINTF("Report LUNs (len %d)\n", len);
- if (len < 16)
- goto fail;
- memset(outbuf, 0, 16);
- outbuf[3] = 8;
- r->buf_len = 16;
- break;
- default:
- DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
- fail:
- scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
- return 0;
- }
- if (r->sector_count == 0 && r->buf_len == 0) {
- scsi_command_complete(r, SENSE_NO_SENSE);
- }
- len = r->sector_count * 512 + r->buf_len;
- if (is_write) {
- return -len;
- } else {
- if (!r->sector_count)
- r->sector_count = -1;
- return len;
- }
-}
-
-static void scsi_destroy(SCSIDevice *d)
-{
- qemu_free(d->state);
- qemu_free(d);
-}
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
- scsi_completionfn completion, void *opaque)
-{
- SCSIDevice *d;
- SCSIDeviceState *s;
-
- s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
- s->bdrv = bdrv;
- s->tcq = tcq;
- s->completion = completion;
- s->opaque = opaque;
- if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
- s->cluster_size = 4;
- } else {
- s->cluster_size = 1;
- }
-
- d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
- d->state = s;
- d->destroy = scsi_destroy;
- d->send_command = scsi_send_command;
- d->read_data = scsi_read_data;
- d->write_data = scsi_write_data;
- d->cancel_io = scsi_cancel_io;
- d->get_buf = scsi_get_buf;
-
- return d;
-}
diff --git a/hw/scsi-disk.h b/hw/scsi-disk.h
deleted file mode 100644
index f42212b..0000000
--- a/hw/scsi-disk.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef SCSI_DISK_H
-#define SCSI_DISK_H
-
-/* scsi-disk.c */
-enum scsi_reason {
- SCSI_REASON_DONE, /* Command complete. */
- SCSI_REASON_DATA /* Transfer complete, more data required. */
-};
-
-typedef struct SCSIDeviceState SCSIDeviceState;
-typedef struct SCSIDevice SCSIDevice;
-typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
- uint32_t arg);
-
-struct SCSIDevice
-{
- SCSIDeviceState *state;
- void (*destroy)(SCSIDevice *s);
- int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf,
- int lun);
- void (*read_data)(SCSIDevice *s, uint32_t tag);
- int (*write_data)(SCSIDevice *s, uint32_t tag);
- void (*cancel_io)(SCSIDevice *s, uint32_t tag);
- uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag);
-};
-
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
- scsi_completionfn completion, void *opaque);
-SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
- scsi_completionfn completion, void *opaque);
-
-/* cdrom.c */
-int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
-int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
-
-#endif
diff --git a/hw/sd.h b/hw/sd.h
deleted file mode 100644
index f310062..0000000
--- a/hw/sd.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * include/linux/mmc/sd.h
- *
- * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- */
-
-#ifndef MMC_SD_H
-#define MMC_SD_H
-
-/* SD commands type argument response */
- /* class 0 */
-/* This is basically the same command as for MMC with some quirks. */
-#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
-#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
-
- /* class 10 */
-#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
-
- /* Application commands */
-#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
-#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
-#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
-#define SD_APP_SEND_SCR 51 /* adtc R1 */
-
-/*
- * SD_SWITCH argument format:
- *
- * [31] Check (0) or switch (1)
- * [30:24] Reserved (0)
- * [23:20] Function group 6
- * [19:16] Function group 5
- * [15:12] Function group 4
- * [11:8] Function group 3
- * [7:4] Function group 2
- * [3:0] Function group 1
- */
-
-/*
- * SD_SEND_IF_COND argument format:
- *
- * [31:12] Reserved (0)
- * [11:8] Host Voltage Supply Flags
- * [7:0] Check Pattern (0xAA)
- */
-
-/*
- * SCR field definitions
- */
-
-#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
-#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
-#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */
-
-/*
- * SD bus widths
- */
-#define SD_BUS_WIDTH_1 0
-#define SD_BUS_WIDTH_4 2
-
-/*
- * SD_SWITCH mode
- */
-#define SD_SWITCH_CHECK 0
-#define SD_SWITCH_SET 1
-
-/*
- * SD_SWITCH function groups
- */
-#define SD_SWITCH_GRP_ACCESS 0
-
-/*
- * SD_SWITCH access modes
- */
-#define SD_SWITCH_ACCESS_DEF 0
-#define SD_SWITCH_ACCESS_HS 1
-
-#endif
-
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
deleted file mode 100644
index 410051d..0000000
--- a/hw/smc91c111.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * SMSC 91C111 Ethernet interface emulation
- *
- * Copyright (c) 2005 CodeSourcery, LLC.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL
- */
-
-#include "hw.h"
-#include "net.h"
-#include "devices.h"
-/* For crc32 */
-#include <zlib.h>
-
-/* Number of 2k memory pages available. */
-#define NUM_PACKETS 4
-
-typedef struct {
- uint32_t base;
- VLANClientState *vc;
- uint16_t tcr;
- uint16_t rcr;
- uint16_t cr;
- uint16_t ctr;
- uint16_t gpr;
- uint16_t ptr;
- uint16_t ercv;
- qemu_irq irq;
- int bank;
- int packet_num;
- int tx_alloc;
- /* Bitmask of allocated packets. */
- int allocated;
- int tx_fifo_len;
- int tx_fifo[NUM_PACKETS];
- int rx_fifo_len;
- int rx_fifo[NUM_PACKETS];
- int tx_fifo_done_len;
- int tx_fifo_done[NUM_PACKETS];
- /* Packet buffer memory. */
- uint8_t data[NUM_PACKETS][2048];
- uint8_t int_level;
- uint8_t int_mask;
- uint8_t macaddr[6];
-} smc91c111_state;
-
-#define RCR_SOFT_RST 0x8000
-#define RCR_STRIP_CRC 0x0200
-#define RCR_RXEN 0x0100
-
-#define TCR_EPH_LOOP 0x2000
-#define TCR_NOCRC 0x0100
-#define TCR_PAD_EN 0x0080
-#define TCR_FORCOL 0x0004
-#define TCR_LOOP 0x0002
-#define TCR_TXEN 0x0001
-
-#define INT_MD 0x80
-#define INT_ERCV 0x40
-#define INT_EPH 0x20
-#define INT_RX_OVRN 0x10
-#define INT_ALLOC 0x08
-#define INT_TX_EMPTY 0x04
-#define INT_TX 0x02
-#define INT_RCV 0x01
-
-#define CTR_AUTO_RELEASE 0x0800
-#define CTR_RELOAD 0x0002
-#define CTR_STORE 0x0001
-
-#define RS_ALGNERR 0x8000
-#define RS_BRODCAST 0x4000
-#define RS_BADCRC 0x2000
-#define RS_ODDFRAME 0x1000
-#define RS_TOOLONG 0x0800
-#define RS_TOOSHORT 0x0400
-#define RS_MULTICAST 0x0001
-
-/* Update interrupt status. */
-static void smc91c111_update(smc91c111_state *s)
-{
- int level;
-
- if (s->tx_fifo_len == 0)
- s->int_level |= INT_TX_EMPTY;
- if (s->tx_fifo_done_len != 0)
- s->int_level |= INT_TX;
- level = (s->int_level & s->int_mask) != 0;
- qemu_set_irq(s->irq, level);
-}
-
-/* Try to allocate a packet. Returns 0x80 on failure. */
-static int smc91c111_allocate_packet(smc91c111_state *s)
-{
- int i;
- if (s->allocated == (1 << NUM_PACKETS) - 1) {
- return 0x80;
- }
-
- for (i = 0; i < NUM_PACKETS; i++) {
- if ((s->allocated & (1 << i)) == 0)
- break;
- }
- s->allocated |= 1 << i;
- return i;
-}
-
-
-/* Process a pending TX allocate. */
-static void smc91c111_tx_alloc(smc91c111_state *s)
-{
- s->tx_alloc = smc91c111_allocate_packet(s);
- if (s->tx_alloc == 0x80)
- return;
- s->int_level |= INT_ALLOC;
- smc91c111_update(s);
-}
-
-/* Remove and item from the RX FIFO. */
-static void smc91c111_pop_rx_fifo(smc91c111_state *s)
-{
- int i;
-
- s->rx_fifo_len--;
- if (s->rx_fifo_len) {
- for (i = 0; i < s->rx_fifo_len; i++)
- s->rx_fifo[i] = s->rx_fifo[i + 1];
- s->int_level |= INT_RCV;
- } else {
- s->int_level &= ~INT_RCV;
- }
- smc91c111_update(s);
-}
-
-/* Remove an item from the TX completion FIFO. */
-static void smc91c111_pop_tx_fifo_done(smc91c111_state *s)
-{
- int i;
-
- if (s->tx_fifo_done_len == 0)
- return;
- s->tx_fifo_done_len--;
- for (i = 0; i < s->tx_fifo_done_len; i++)
- s->tx_fifo_done[i] = s->tx_fifo_done[i + 1];
-}
-
-/* Release the memory allocated to a packet. */
-static void smc91c111_release_packet(smc91c111_state *s, int packet)
-{
- s->allocated &= ~(1 << packet);
- if (s->tx_alloc == 0x80)
- smc91c111_tx_alloc(s);
-}
-
-/* Flush the TX FIFO. */
-static void smc91c111_do_tx(smc91c111_state *s)
-{
- int i;
- int len;
- int control;
- int add_crc;
- int packetnum;
- uint8_t *p;
-
- if ((s->tcr & TCR_TXEN) == 0)
- return;
- if (s->tx_fifo_len == 0)
- return;
- for (i = 0; i < s->tx_fifo_len; i++) {
- packetnum = s->tx_fifo[i];
- p = &s->data[packetnum][0];
- /* Set status word. */
- *(p++) = 0x01;
- *(p++) = 0x40;
- len = *(p++);
- len |= ((int)*(p++)) << 8;
- len -= 6;
- control = p[len + 1];
- if (control & 0x20)
- len++;
- /* ??? This overwrites the data following the buffer.
- Don't know what real hardware does. */
- if (len < 64 && (s->tcr & TCR_PAD_EN)) {
- memset(p + len, 0, 64 - len);
- len = 64;
- }
-#if 0
- /* The card is supposed to append the CRC to the frame. However
- none of the other network traffic has the CRC appended.
- Suspect this is low level ethernet detail we don't need to worry
- about. */
- add_crc = (control & 0x10) || (s->tcr & TCR_NOCRC) == 0;
- if (add_crc) {
- uint32_t crc;
-
- crc = crc32(~0, p, len);
- memcpy(p + len, &crc, 4);
- len += 4;
- }
-#else
- add_crc = 0;
-#endif
- if (s->ctr & CTR_AUTO_RELEASE)
- /* Race? */
- smc91c111_release_packet(s, packetnum);
- else if (s->tx_fifo_done_len < NUM_PACKETS)
- s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
- qemu_send_packet(s->vc, p, len);
- }
- s->tx_fifo_len = 0;
- smc91c111_update(s);
-}
-
-/* Add a packet to the TX FIFO. */
-static void smc91c111_queue_tx(smc91c111_state *s, int packet)
-{
- if (s->tx_fifo_len == NUM_PACKETS)
- return;
- s->tx_fifo[s->tx_fifo_len++] = packet;
- smc91c111_do_tx(s);
-}
-
-static void smc91c111_reset(smc91c111_state *s)
-{
- s->bank = 0;
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- s->rx_fifo_len = 0;
- s->allocated = 0;
- s->packet_num = 0;
- s->tx_alloc = 0;
- s->tcr = 0;
- s->rcr = 0;
- s->cr = 0xa0b1;
- s->ctr = 0x1210;
- s->ptr = 0;
- s->ercv = 0x1f;
- s->int_level = INT_TX_EMPTY;
- s->int_mask = 0;
- smc91c111_update(s);
-}
-
-#define SET_LOW(name, val) s->name = (s->name & 0xff00) | val
-#define SET_HIGH(name, val) s->name = (s->name & 0xff) | (val << 8)
-
-static void smc91c111_writeb(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- offset -= s->base;
- if (offset == 14) {
- s->bank = value;
- return;
- }
- if (offset == 15)
- return;
- switch (s->bank) {
- case 0:
- switch (offset) {
- case 0: /* TCR */
- SET_LOW(tcr, value);
- return;
- case 1:
- SET_HIGH(tcr, value);
- return;
- case 4: /* RCR */
- SET_LOW(rcr, value);
- return;
- case 5:
- SET_HIGH(rcr, value);
- if (s->rcr & RCR_SOFT_RST)
- smc91c111_reset(s);
- return;
- case 10: case 11: /* RPCR */
- /* Ignored */
- return;
- }
- break;
-
- case 1:
- switch (offset) {
- case 0: /* CONFIG */
- SET_LOW(cr, value);
- return;
- case 1:
- SET_HIGH(cr,value);
- return;
- case 2: case 3: /* BASE */
- case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
- /* Not implemented. */
- return;
- case 10: /* Genral Purpose */
- SET_LOW(gpr, value);
- return;
- case 11:
- SET_HIGH(gpr, value);
- return;
- case 12: /* Control */
- if (value & 1)
- fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
- if (value & 2)
- fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
- value &= ~3;
- SET_LOW(ctr, value);
- return;
- case 13:
- SET_HIGH(ctr, value);
- return;
- }
- break;
-
- case 2:
- switch (offset) {
- case 0: /* MMU Command */
- switch (value >> 5) {
- case 0: /* no-op */
- break;
- case 1: /* Allocate for TX. */
- s->tx_alloc = 0x80;
- s->int_level &= ~INT_ALLOC;
- smc91c111_update(s);
- smc91c111_tx_alloc(s);
- break;
- case 2: /* Reset MMU. */
- s->allocated = 0;
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- s->rx_fifo_len = 0;
- s->tx_alloc = 0;
- break;
- case 3: /* Remove from RX FIFO. */
- smc91c111_pop_rx_fifo(s);
- break;
- case 4: /* Remove from RX FIFO and release. */
- if (s->rx_fifo_len > 0) {
- smc91c111_release_packet(s, s->rx_fifo[0]);
- }
- smc91c111_pop_rx_fifo(s);
- break;
- case 5: /* Release. */
- smc91c111_release_packet(s, s->packet_num);
- break;
- case 6: /* Add to TX FIFO. */
- smc91c111_queue_tx(s, s->packet_num);
- break;
- case 7: /* Reset TX FIFO. */
- s->tx_fifo_len = 0;
- s->tx_fifo_done_len = 0;
- break;
- }
- return;
- case 1:
- /* Ignore. */
- return;
- case 2: /* Packet Number Register */
- s->packet_num = value;
- return;
- case 3: case 4: case 5:
- /* Should be readonly, but linux writes to them anyway. Ignore. */
- return;
- case 6: /* Pointer */
- SET_LOW(ptr, value);
- return;
- case 7:
- SET_HIGH(ptr, value);
- return;
- case 8: case 9: case 10: case 11: /* Data */
- {
- int p;
- int n;
-
- if (s->ptr & 0x8000)
- n = s->rx_fifo[0];
- else
- n = s->packet_num;
- p = s->ptr & 0x07ff;
- if (s->ptr & 0x4000) {
- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x7ff);
- } else {
- p += (offset & 3);
- }
- s->data[n][p] = value;
- }
- return;
- case 12: /* Interrupt ACK. */
- s->int_level &= ~(value & 0xd6);
- if (value & INT_TX)
- smc91c111_pop_tx_fifo_done(s);
- smc91c111_update(s);
- return;
- case 13: /* Interrupt mask. */
- s->int_mask = value;
- smc91c111_update(s);
- return;
- }
- break;;
-
- case 3:
- switch (offset) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* Multicast table. */
- /* Not implemented. */
- return;
- case 8: case 9: /* Management Interface. */
- /* Not implemented. */
- return;
- case 12: /* Early receive. */
- s->ercv = value & 0x1f;
- case 13:
- /* Ignore. */
- return;
- }
- break;
- }
- cpu_abort (cpu_single_env, "smc91c111_write: Bad reg %d:%x\n",
- s->bank, (int)offset);
-}
-
-static uint32_t smc91c111_readb(void *opaque, target_phys_addr_t offset)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- offset -= s->base;
- if (offset == 14) {
- return s->bank;
- }
- if (offset == 15)
- return 0x33;
- switch (s->bank) {
- case 0:
- switch (offset) {
- case 0: /* TCR */
- return s->tcr & 0xff;
- case 1:
- return s->tcr >> 8;
- case 2: /* EPH Status */
- return 0;
- case 3:
- return 0x40;
- case 4: /* RCR */
- return s->rcr & 0xff;
- case 5:
- return s->rcr >> 8;
- case 6: /* Counter */
- case 7:
- /* Not implemented. */
- return 0;
- case 8: /* Memory size. */
- return NUM_PACKETS;
- case 9: /* Free memory available. */
- {
- int i;
- int n;
- n = 0;
- for (i = 0; i < NUM_PACKETS; i++) {
- if (s->allocated & (1 << i))
- n++;
- }
- return n;
- }
- case 10: case 11: /* RPCR */
- /* Not implemented. */
- return 0;
- }
- break;
-
- case 1:
- switch (offset) {
- case 0: /* CONFIG */
- return s->cr & 0xff;
- case 1:
- return s->cr >> 8;
- case 2: case 3: /* BASE */
- /* Not implemented. */
- return 0;
- case 4: case 5: case 6: case 7: case 8: case 9: /* IA */
- return s->macaddr[offset - 4];
- case 10: /* General Purpose */
- return s->gpr & 0xff;
- case 11:
- return s->gpr >> 8;
- case 12: /* Control */
- return s->ctr & 0xff;
- case 13:
- return s->ctr >> 8;
- }
- break;
-
- case 2:
- switch (offset) {
- case 0: case 1: /* MMUCR Busy bit. */
- return 0;
- case 2: /* Packet Number. */
- return s->packet_num;
- case 3: /* Allocation Result. */
- return s->tx_alloc;
- case 4: /* TX FIFO */
- if (s->tx_fifo_done_len == 0)
- return 0x80;
- else
- return s->tx_fifo_done[0];
- case 5: /* RX FIFO */
- if (s->rx_fifo_len == 0)
- return 0x80;
- else
- return s->rx_fifo[0];
- case 6: /* Pointer */
- return s->ptr & 0xff;
- case 7:
- return (s->ptr >> 8) & 0xf7;
- case 8: case 9: case 10: case 11: /* Data */
- {
- int p;
- int n;
-
- if (s->ptr & 0x8000)
- n = s->rx_fifo[0];
- else
- n = s->packet_num;
- p = s->ptr & 0x07ff;
- if (s->ptr & 0x4000) {
- s->ptr = (s->ptr & 0xf800) | ((s->ptr + 1) & 0x07ff);
- } else {
- p += (offset & 3);
- }
- return s->data[n][p];
- }
- case 12: /* Interrupt status. */
- return s->int_level;
- case 13: /* Interrupt mask. */
- return s->int_mask;
- }
- break;
-
- case 3:
- switch (offset) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* Multicast table. */
- /* Not implemented. */
- return 0;
- case 8: /* Management Interface. */
- /* Not implemented. */
- return 0x30;
- case 9:
- return 0x33;
- case 10: /* Revision. */
- return 0x91;
- case 11:
- return 0x33;
- case 12:
- return s->ercv;
- case 13:
- return 0;
- }
- break;
- }
- cpu_abort (cpu_single_env, "smc91c111_read: Bad reg %d:%x\n",
- s->bank, (int)offset);
- return 0;
-}
-
-static void smc91c111_writew(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_writeb(opaque, offset, value & 0xff);
- smc91c111_writeb(opaque, offset + 1, value >> 8);
-}
-
-static void smc91c111_writel(void *opaque, target_phys_addr_t offset,
- uint32_t value)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
- /* 32-bit writes to offset 0xc only actually write to the bank select
- register (offset 0xe) */
- if (offset != s->base + 0xc)
- smc91c111_writew(opaque, offset, value & 0xffff);
- smc91c111_writew(opaque, offset + 2, value >> 16);
-}
-
-static uint32_t smc91c111_readw(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = smc91c111_readb(opaque, offset);
- val |= smc91c111_readb(opaque, offset + 1) << 8;
- return val;
-}
-
-static uint32_t smc91c111_readl(void *opaque, target_phys_addr_t offset)
-{
- uint32_t val;
- val = smc91c111_readw(opaque, offset);
- val |= smc91c111_readw(opaque, offset + 2) << 16;
- return val;
-}
-
-static int smc91c111_can_receive(void *opaque)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
-
- if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
- return 1;
- if (s->allocated == (1 << NUM_PACKETS) - 1)
- return 0;
- return 1;
-}
-
-static void smc91c111_receive(void *opaque, const uint8_t *buf, int size)
-{
- smc91c111_state *s = (smc91c111_state *)opaque;
- int status;
- int packetsize;
- uint32_t crc;
- int packetnum;
- uint8_t *p;
-
- if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
- return;
- /* Short packets are padded with zeros. Receiving a packet
- < 64 bytes long is considered an error condition. */
- if (size < 64)
- packetsize = 64;
- else
- packetsize = (size & ~1);
- packetsize += 6;
- crc = (s->rcr & RCR_STRIP_CRC) == 0;
- if (crc)
- packetsize += 4;
- /* TODO: Flag overrun and receive errors. */
- if (packetsize > 2048)
- return;
- packetnum = smc91c111_allocate_packet(s);
- if (packetnum == 0x80)
- return;
- s->rx_fifo[s->rx_fifo_len++] = packetnum;
-
- p = &s->data[packetnum][0];
- /* ??? Multicast packets? */
- status = 0;
- if (size > 1518)
- status |= RS_TOOLONG;
- if (size & 1)
- status |= RS_ODDFRAME;
- *(p++) = status & 0xff;
- *(p++) = status >> 8;
- *(p++) = packetsize & 0xff;
- *(p++) = packetsize >> 8;
- memcpy(p, buf, size & ~1);
- p += (size & ~1);
- /* Pad short packets. */
- if (size < 64) {
- int pad;
-
- if (size & 1)
- *(p++) = buf[size - 1];
- pad = 64 - size;
- memset(p, 0, pad);
- p += pad;
- size = 64;
- }
- /* It's not clear if the CRC should go before or after the last byte in
- odd sized packets. Linux disables the CRC, so that's no help.
- The pictures in the documentation show the CRC aligned on a 16-bit
- boundary before the last odd byte, so that's what we do. */
- if (crc) {
- crc = crc32(~0, buf, size);
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- *(p++) = crc & 0xff; crc >>= 8;
- }
- if (size & 1) {
- *(p++) = buf[size - 1];
- *(p++) = 0x60;
- } else {
- *(p++) = 0;
- *(p++) = 0x40;
- }
- /* TODO: Raise early RX interrupt? */
- s->int_level |= INT_RCV;
- smc91c111_update(s);
-}
-
-static CPUReadMemoryFunc *smc91c111_readfn[] = {
- smc91c111_readb,
- smc91c111_readw,
- smc91c111_readl
-};
-
-static CPUWriteMemoryFunc *smc91c111_writefn[] = {
- smc91c111_writeb,
- smc91c111_writew,
- smc91c111_writel
-};
-
-void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
-{
- smc91c111_state *s;
- int iomemtype;
-
- s = (smc91c111_state *)qemu_mallocz(sizeof(smc91c111_state));
- iomemtype = cpu_register_io_memory(0, smc91c111_readfn,
- smc91c111_writefn, s);
- cpu_register_physical_memory(base, 16, iomemtype);
- s->base = base;
- s->irq = irq;
- memcpy(s->macaddr, nd->macaddr, 6);
-
- smc91c111_reset(s);
-
- s->vc = qemu_new_vlan_client(nd->vlan, smc91c111_receive,
- smc91c111_can_receive, s);
- /* ??? Save/restore. */
-}
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
deleted file mode 100644
index 406c9ab..0000000
--- a/hw/usb-hid.c
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * QEMU USB HID devices
- *
- * Copyright (c) 2005 Fabrice Bellard
- * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw.h"
-#include "console.h"
-#include "usb.h"
-
-/* HID interface requests */
-#define GET_REPORT 0xa101
-#define GET_IDLE 0xa102
-#define GET_PROTOCOL 0xa103
-#define SET_REPORT 0x2109
-#define SET_IDLE 0x210a
-#define SET_PROTOCOL 0x210b
-
-/* HID descriptor types */
-#define USB_DT_HID 0x21
-#define USB_DT_REPORT 0x22
-#define USB_DT_PHY 0x23
-
-#define USB_MOUSE 1
-#define USB_TABLET 2
-#define USB_KEYBOARD 3
-
-typedef struct USBMouseState {
- int dx, dy, dz, buttons_state;
- int x, y;
- int mouse_grabbed;
- QEMUPutMouseEntry *eh_entry;
-} USBMouseState;
-
-typedef struct USBKeyboardState {
- uint16_t modifiers;
- uint8_t leds;
- uint8_t key[16];
- int keys;
-} USBKeyboardState;
-
-typedef struct USBHIDState {
- USBDevice dev;
- union {
- USBMouseState ptr;
- USBKeyboardState kbd;
- };
- int kind;
- int protocol;
- int idle;
- int changed;
-} USBHIDState;
-
-/* mostly the same values as the Bochs USB Mouse device */
-static const uint8_t qemu_mouse_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x00, 0x01, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x27, 0x06, /* u16 idVendor; */
- 0x01, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_mouse_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x07, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 52, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x04, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_tablet_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x05, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x07, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 74, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_keyboard_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- USB_DT_CONFIG, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x06, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x32, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- USB_DT_INTERFACE, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; HID */
- 0x01, /* u8 if_bInterfaceSubClass; Boot */
- 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
- 0x07, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- USB_DT_HID, /* u8 bDescriptorType; */
- 0x11, 0x01, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- USB_DT_REPORT, /* u8 type; Report */
- 0x3f, 0x00, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; Endpoint */
- USB_DIR_IN | 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_mouse_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x02, /* Usage (Mouse) */
- 0xa1, 0x01, /* Collection (Application) */
- 0x09, 0x01, /* Usage (Pointer) */
- 0xa1, 0x00, /* Collection (Physical) */
- 0x05, 0x09, /* Usage Page (Button) */
- 0x19, 0x01, /* Usage Minimum (1) */
- 0x29, 0x03, /* Usage Maximum (3) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x95, 0x03, /* Report Count (3) */
- 0x75, 0x01, /* Report Size (1) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x05, /* Report Size (5) */
- 0x81, 0x01, /* Input (Constant) */
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x30, /* Usage (X) */
- 0x09, 0x31, /* Usage (Y) */
- 0x09, 0x38, /* Usage (Wheel) */
- 0x15, 0x81, /* Logical Minimum (-0x7f) */
- 0x25, 0x7f, /* Logical Maximum (0x7f) */
- 0x75, 0x08, /* Report Size (8) */
- 0x95, 0x03, /* Report Count (3) */
- 0x81, 0x06, /* Input (Data, Variable, Relative) */
- 0xc0, /* End Collection */
- 0xc0, /* End Collection */
-};
-
-static const uint8_t qemu_tablet_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x01, /* Usage (Pointer) */
- 0xa1, 0x01, /* Collection (Application) */
- 0x09, 0x01, /* Usage (Pointer) */
- 0xa1, 0x00, /* Collection (Physical) */
- 0x05, 0x09, /* Usage Page (Button) */
- 0x19, 0x01, /* Usage Minimum (1) */
- 0x29, 0x03, /* Usage Maximum (3) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x95, 0x03, /* Report Count (3) */
- 0x75, 0x01, /* Report Size (1) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x05, /* Report Size (5) */
- 0x81, 0x01, /* Input (Constant) */
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x30, /* Usage (X) */
- 0x09, 0x31, /* Usage (Y) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
- 0x35, 0x00, /* Physical Minimum (0) */
- 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
- 0x75, 0x10, /* Report Size (16) */
- 0x95, 0x02, /* Report Count (2) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x38, /* Usage (Wheel) */
- 0x15, 0x81, /* Logical Minimum (-0x7f) */
- 0x25, 0x7f, /* Logical Maximum (0x7f) */
- 0x35, 0x00, /* Physical Minimum (same as logical) */
- 0x45, 0x00, /* Physical Maximum (same as logical) */
- 0x75, 0x08, /* Report Size (8) */
- 0x95, 0x01, /* Report Count (1) */
- 0x81, 0x06, /* Input (Data, Variable, Relative) */
- 0xc0, /* End Collection */
- 0xc0, /* End Collection */
-};
-
-static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page (Generic Desktop) */
- 0x09, 0x06, /* Usage (Keyboard) */
- 0xa1, 0x01, /* Collection (Application) */
- 0x75, 0x01, /* Report Size (1) */
- 0x95, 0x08, /* Report Count (8) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0xe0, /* Usage Minimum (224) */
- 0x29, 0xe7, /* Usage Maximum (231) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0x01, /* Logical Maximum (1) */
- 0x81, 0x02, /* Input (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x08, /* Report Size (8) */
- 0x81, 0x01, /* Input (Constant) */
- 0x95, 0x05, /* Report Count (5) */
- 0x75, 0x01, /* Report Size (1) */
- 0x05, 0x08, /* Usage Page (LEDs) */
- 0x19, 0x01, /* Usage Minimum (1) */
- 0x29, 0x05, /* Usage Maximum (5) */
- 0x91, 0x02, /* Output (Data, Variable, Absolute) */
- 0x95, 0x01, /* Report Count (1) */
- 0x75, 0x03, /* Report Size (3) */
- 0x91, 0x01, /* Output (Constant) */
- 0x95, 0x06, /* Report Count (6) */
- 0x75, 0x08, /* Report Size (8) */
- 0x15, 0x00, /* Logical Minimum (0) */
- 0x25, 0xff, /* Logical Maximum (255) */
- 0x05, 0x07, /* Usage Page (Key Codes) */
- 0x19, 0x00, /* Usage Minimum (0) */
- 0x29, 0xff, /* Usage Maximum (255) */
- 0x81, 0x00, /* Input (Data, Array) */
- 0xc0, /* End Collection */
-};
-
-#define USB_HID_USAGE_ERROR_ROLLOVER 0x01
-#define USB_HID_USAGE_POSTFAIL 0x02
-#define USB_HID_USAGE_ERROR_UNDEFINED 0x03
-
-/* Indices are QEMU keycodes, values are from HID Usage Table. Indices
- * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
-static const uint8_t usb_hid_usage_keys[0x100] = {
- 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
- 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
- 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
- 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
- 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
- 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
- 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
- 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
- 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
- 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
- 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
- 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
- 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
- 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
- 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static void usb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- USBHIDState *hs = opaque;
- USBMouseState *s = &hs->ptr;
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
- hs->changed = 1;
-}
-
-static void usb_tablet_event(void *opaque,
- int x, int y, int dz, int buttons_state)
-{
- USBHIDState *hs = opaque;
- USBMouseState *s = &hs->ptr;
-
- s->x = x;
- s->y = y;
- s->dz += dz;
- s->buttons_state = buttons_state;
- hs->changed = 1;
-}
-
-static void usb_keyboard_event(void *opaque, int keycode)
-{
- USBHIDState *hs = opaque;
- USBKeyboardState *s = &hs->kbd;
- uint8_t hid_code, key;
- int i;
-
- key = keycode & 0x7f;
- hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
- s->modifiers &= ~(1 << 8);
-
- hs->changed = 1;
-
- switch (hid_code) {
- case 0x00:
- return;
-
- case 0xe0:
- if (s->modifiers & (1 << 9)) {
- s->modifiers ^= 3 << 8;
- return;
- }
- case 0xe1 ... 0xe7:
- if (keycode & (1 << 7)) {
- s->modifiers &= ~(1 << (hid_code & 0x0f));
- return;
- }
- case 0xe8 ... 0xef:
- s->modifiers |= 1 << (hid_code & 0x0f);
- return;
- }
-
- if (keycode & (1 << 7)) {
- for (i = s->keys - 1; i >= 0; i --)
- if (s->key[i] == hid_code) {
- s->key[i] = s->key[-- s->keys];
- s->key[s->keys] = 0x00;
- return;
- }
- } else {
- for (i = s->keys - 1; i >= 0; i --)
- if (s->key[i] == hid_code)
- return;
- if (s->keys < sizeof(s->key))
- s->key[s->keys ++] = hid_code;
- }
-}
-
-static inline int int_clamp(int val, int vmin, int vmax)
-{
- if (val < vmin)
- return vmin;
- else if (val > vmax)
- return vmax;
- else
- return val;
-}
-
-static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
-{
- int dx, dy, dz, b, l;
- USBMouseState *s = &hs->ptr;
-
- if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
- 0, "QEMU USB Mouse");
- s->mouse_grabbed = 1;
- }
-
- dx = int_clamp(s->dx, -127, 127);
- dy = int_clamp(s->dy, -127, 127);
- dz = int_clamp(s->dz, -127, 127);
-
- s->dx -= dx;
- s->dy -= dy;
- s->dz -= dz;
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
-
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- l = 0;
- if (len > l)
- buf[l ++] = b;
- if (len > l)
- buf[l ++] = dx;
- if (len > l)
- buf[l ++] = dy;
- if (len > l)
- buf[l ++] = dz;
- return l;
-}
-
-static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
-{
- int dz, b, l;
- USBMouseState *s = &hs->ptr;
-
- if (!s->mouse_grabbed) {
- s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
- 1, "QEMU USB Tablet");
- s->mouse_grabbed = 1;
- }
-
- dz = int_clamp(s->dz, -127, 127);
- s->dz -= dz;
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- buf[0] = b;
- buf[1] = s->x & 0xff;
- buf[2] = s->x >> 8;
- buf[3] = s->y & 0xff;
- buf[4] = s->y >> 8;
- buf[5] = dz;
- l = 6;
-
- return l;
-}
-
-static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
-{
- if (len < 2)
- return 0;
-
- buf[0] = s->modifiers & 0xff;
- buf[1] = 0;
- if (s->keys > 6)
- memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
- else
- memcpy(buf + 2, s->key, MIN(8, len) - 2);
-
- return MIN(8, len);
-}
-
-static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
-{
- if (len > 0) {
- /* 0x01: Num Lock LED
- * 0x02: Caps Lock LED
- * 0x04: Scroll Lock LED
- * 0x08: Compose LED
- * 0x10: Kana LED */
- s->leds = buf[0];
- }
- return 0;
-}
-
-static void usb_mouse_handle_reset(USBDevice *dev)
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- s->ptr.dx = 0;
- s->ptr.dy = 0;
- s->ptr.dz = 0;
- s->ptr.x = 0;
- s->ptr.y = 0;
- s->ptr.buttons_state = 0;
- s->protocol = 1;
-}
-
-static void usb_keyboard_handle_reset(USBDevice *dev)
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
- s->protocol = 1;
-}
-
-static int usb_hid_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBHIDState *s = (USBHIDState *)dev;
- int ret = 0;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_mouse_dev_descriptor,
- sizeof(qemu_mouse_dev_descriptor));
- ret = sizeof(qemu_mouse_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_config_descriptor,
- sizeof(qemu_mouse_config_descriptor));
- ret = sizeof(qemu_mouse_config_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_config_descriptor,
- sizeof(qemu_tablet_config_descriptor));
- ret = sizeof(qemu_tablet_config_descriptor);
- } else if (s->kind == USB_KEYBOARD) {
- memcpy(data, qemu_keyboard_config_descriptor,
- sizeof(qemu_keyboard_config_descriptor));
- ret = sizeof(qemu_keyboard_config_descriptor);
- }
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, s->dev.devname);
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 4:
- ret = set_usb_string(data, "HID Mouse");
- break;
- case 5:
- ret = set_usb_string(data, "HID Tablet");
- break;
- case 6:
- ret = set_usb_string(data, "HID Keyboard");
- break;
- case 7:
- ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* hid specific requests */
- case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case 0x22:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_hid_report_descriptor,
- sizeof(qemu_mouse_hid_report_descriptor));
- ret = sizeof(qemu_mouse_hid_report_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_hid_report_descriptor,
- sizeof(qemu_tablet_hid_report_descriptor));
- ret = sizeof(qemu_tablet_hid_report_descriptor);
- } else if (s->kind == USB_KEYBOARD) {
- memcpy(data, qemu_keyboard_hid_report_descriptor,
- sizeof(qemu_keyboard_hid_report_descriptor));
- ret = sizeof(qemu_keyboard_hid_report_descriptor);
- }
- break;
- default:
- goto fail;
- }
- break;
- case GET_REPORT:
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, data, length);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, data, length);
- else if (s->kind == USB_KEYBOARD)
- ret = usb_keyboard_poll(&s->kbd, data, length);
- break;
- case SET_REPORT:
- if (s->kind == USB_KEYBOARD)
- ret = usb_keyboard_write(&s->kbd, data, length);
- else
- goto fail;
- break;
- case GET_PROTOCOL:
- if (s->kind != USB_KEYBOARD)
- goto fail;
- ret = 1;
- data[0] = s->protocol;
- break;
- case SET_PROTOCOL:
- if (s->kind != USB_KEYBOARD)
- goto fail;
- ret = 0;
- s->protocol = value;
- break;
- case GET_IDLE:
- ret = 1;
- data[0] = s->idle;
- break;
- case SET_IDLE:
- s->idle = value;
- ret = 0;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBHIDState *s = (USBHIDState *)dev;
- int ret = 0;
-
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
- /* TODO: Implement finite idle delays. */
- if (!(s->changed || s->idle))
- return USB_RET_NAK;
- s->changed = 0;
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, p->data, p->len);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, p->data, p->len);
- else if (s->kind == USB_KEYBOARD)
- ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static void usb_hid_handle_destroy(USBDevice *dev)
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- if (s->kind != USB_KEYBOARD)
- qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
- qemu_free(s);
-}
-
-USBDevice *usb_tablet_init(void)
-{
- USBHIDState *s;
-
- s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_hid_handle_control;
- s->dev.handle_data = usb_hid_handle_data;
- s->dev.handle_destroy = usb_hid_handle_destroy;
- s->kind = USB_TABLET;
- /* Force poll routine to be run and grab input the first time. */
- s->changed = 1;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
-
- return (USBDevice *)s;
-}
-
-USBDevice *usb_mouse_init(void)
-{
- USBHIDState *s;
-
- s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_hid_handle_control;
- s->dev.handle_data = usb_hid_handle_data;
- s->dev.handle_destroy = usb_hid_handle_destroy;
- s->kind = USB_MOUSE;
- /* Force poll routine to be run and grab input the first time. */
- s->changed = 1;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
-
- return (USBDevice *)s;
-}
-
-USBDevice *usb_keyboard_init(void)
-{
- USBHIDState *s;
-
- s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_keyboard_handle_reset;
- s->dev.handle_control = usb_hid_handle_control;
- s->dev.handle_data = usb_hid_handle_data;
- s->dev.handle_destroy = usb_hid_handle_destroy;
- s->kind = USB_KEYBOARD;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
-
- return (USBDevice *) s;
-}
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
deleted file mode 100644
index 97c3d05..0000000
--- a/hw/usb-hub.c
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * QEMU USB HUB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "usb.h"
-
-//#define DEBUG
-
-#define MAX_PORTS 8
-
-typedef struct USBHubPort {
- USBPort port;
- uint16_t wPortStatus;
- uint16_t wPortChange;
-} USBHubPort;
-
-typedef struct USBHubState {
- USBDevice dev;
- int nb_ports;
- USBHubPort ports[MAX_PORTS];
-} USBHubState;
-
-#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
-#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
-#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
-#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
-#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
-#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
-#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
-
-#define PORT_STAT_CONNECTION 0x0001
-#define PORT_STAT_ENABLE 0x0002
-#define PORT_STAT_SUSPEND 0x0004
-#define PORT_STAT_OVERCURRENT 0x0008
-#define PORT_STAT_RESET 0x0010
-#define PORT_STAT_POWER 0x0100
-#define PORT_STAT_LOW_SPEED 0x0200
-#define PORT_STAT_HIGH_SPEED 0x0400
-#define PORT_STAT_TEST 0x0800
-#define PORT_STAT_INDICATOR 0x1000
-
-#define PORT_STAT_C_CONNECTION 0x0001
-#define PORT_STAT_C_ENABLE 0x0002
-#define PORT_STAT_C_SUSPEND 0x0004
-#define PORT_STAT_C_OVERCURRENT 0x0008
-#define PORT_STAT_C_RESET 0x0010
-
-#define PORT_CONNECTION 0
-#define PORT_ENABLE 1
-#define PORT_SUSPEND 2
-#define PORT_OVERCURRENT 3
-#define PORT_RESET 4
-#define PORT_POWER 8
-#define PORT_LOWSPEED 9
-#define PORT_HIGHSPEED 10
-#define PORT_C_CONNECTION 16
-#define PORT_C_ENABLE 17
-#define PORT_C_SUSPEND 18
-#define PORT_C_OVERCURRENT 19
-#define PORT_C_RESET 20
-#define PORT_TEST 21
-#define PORT_INDICATOR 22
-
-/* same as Linux kernel root hubs */
-
-static const uint8_t qemu_hub_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x01, /* u16 bcdUSB; v1.1 */
-
- 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x01, 0x01, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-/* XXX: patch interrupt size */
-static const uint8_t qemu_hub_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
- 0x00, /* u8 if_bInterfaceSubClass; */
- 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x00, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
- 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_hub_hub_descriptor[] =
-{
- 0x00, /* u8 bLength; patched in later */
- 0x29, /* u8 bDescriptorType; Hub-descriptor */
- 0x00, /* u8 bNbrPorts; (patched later) */
- 0x0a, /* u16 wHubCharacteristics; */
- 0x00, /* (per-port OC, no power switching) */
- 0x01, /* u8 bPwrOn2pwrGood; 2ms */
- 0x00 /* u8 bHubContrCurrent; 0 mA */
-
- /* DeviceRemovable and PortPwrCtrlMask patched in later */
-};
-
-static void usb_hub_attach(USBPort *port1, USBDevice *dev)
-{
- USBHubState *s = port1->opaque;
- USBHubPort *port = &s->ports[port1->index];
-
- if (dev) {
- if (port->port.dev)
- usb_attach(port1, NULL);
-
- port->wPortStatus |= PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (dev->speed == USB_SPEED_LOW)
- port->wPortStatus |= PORT_STAT_LOW_SPEED;
- else
- port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
- port->port.dev = dev;
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- } else {
- dev = port->port.dev;
- if (dev) {
- port->wPortStatus &= ~PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (port->wPortStatus & PORT_STAT_ENABLE) {
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- port->wPortChange |= PORT_STAT_C_ENABLE;
- }
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- port->port.dev = NULL;
- }
- }
-}
-
-static void usb_hub_handle_reset(USBDevice *dev)
-{
- /* XXX: do it */
-}
-
-static int usb_hub_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_hub_dev_descriptor,
- sizeof(qemu_hub_dev_descriptor));
- ret = sizeof(qemu_hub_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_hub_config_descriptor,
- sizeof(qemu_hub_config_descriptor));
-
- /* status change endpoint size based on number
- * of ports */
- data[22] = (s->nb_ports + 1 + 7) / 8;
-
- ret = sizeof(qemu_hub_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "314159");
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB Hub");
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* usb specific requests */
- case GetHubStatus:
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
- ret = 4;
- break;
- case GetPortStatus:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- data[0] = port->wPortStatus;
- data[1] = port->wPortStatus >> 8;
- data[2] = port->wPortChange;
- data[3] = port->wPortChange >> 8;
- ret = 4;
- }
- break;
- case SetHubFeature:
- case ClearHubFeature:
- if (value == 0 || value == 1) {
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case SetPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_SUSPEND:
- port->wPortStatus |= PORT_STAT_SUSPEND;
- break;
- case PORT_RESET:
- if (dev) {
- usb_send_msg(dev, USB_MSG_RESET);
- port->wPortChange |= PORT_STAT_C_RESET;
- /* set enable bit */
- port->wPortStatus |= PORT_STAT_ENABLE;
- }
- break;
- case PORT_POWER:
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case ClearPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_ENABLE:
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- break;
- case PORT_C_ENABLE:
- port->wPortChange &= ~PORT_STAT_C_ENABLE;
- break;
- case PORT_SUSPEND:
- port->wPortStatus &= ~PORT_STAT_SUSPEND;
- break;
- case PORT_C_SUSPEND:
- port->wPortChange &= ~PORT_STAT_C_SUSPEND;
- break;
- case PORT_C_CONNECTION:
- port->wPortChange &= ~PORT_STAT_C_CONNECTION;
- break;
- case PORT_C_OVERCURRENT:
- port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
- break;
- case PORT_C_RESET:
- port->wPortChange &= ~PORT_STAT_C_RESET;
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case GetHubDescriptor:
- {
- unsigned int n, limit, var_hub_size = 0;
- memcpy(data, qemu_hub_hub_descriptor,
- sizeof(qemu_hub_hub_descriptor));
- data[2] = s->nb_ports;
-
- /* fill DeviceRemovable bits */
- limit = ((s->nb_ports + 1 + 7) / 8) + 7;
- for (n = 7; n < limit; n++) {
- data[n] = 0x00;
- var_hub_size++;
- }
-
- /* fill PortPwrCtrlMask bits */
- limit = limit + ((s->nb_ports + 7) / 8);
- for (;n < limit; n++) {
- data[n] = 0xff;
- var_hub_size++;
- }
-
- ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
- data[0] = ret;
- break;
- }
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(p->pid) {
- case USB_TOKEN_IN:
- if (p->devep == 1) {
- USBHubPort *port;
- unsigned int status;
- int i, n;
- n = (s->nb_ports + 1 + 7) / 8;
- if (p->len == 1) { /* FreeBSD workaround */
- n = 1;
- } else if (n > p->len) {
- return USB_RET_BABBLE;
- }
- status = 0;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- if (port->wPortChange)
- status |= (1 << (i + 1));
- }
- if (status != 0) {
- for(i = 0; i < n; i++) {
- p->data[i] = status >> (8 * i);
- }
- ret = n;
- } else {
- ret = USB_RET_NAK; /* usb11 11.13.1 */
- }
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p)
-{
- USBHubPort *port;
- USBDevice *dev;
- int i, ret;
-
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
- ret = dev->handle_packet(dev, p);
- if (ret != USB_RET_NODEV) {
- return ret;
- }
- }
- }
- return USB_RET_NODEV;
-}
-
-static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p)
-{
- USBHubState *s = (USBHubState *)dev;
-
-#if defined(DEBUG) && 0
- printf("usb_hub: pid=0x%x\n", pid);
-#endif
- if (dev->state == USB_STATE_DEFAULT &&
- dev->addr != 0 &&
- p->devaddr != dev->addr &&
- (p->pid == USB_TOKEN_SETUP ||
- p->pid == USB_TOKEN_OUT ||
- p->pid == USB_TOKEN_IN)) {
- /* broadcast the packet to the devices */
- return usb_hub_broadcast_packet(s, p);
- }
- return usb_generic_handle_packet(dev, p);
-}
-
-static void usb_hub_handle_destroy(USBDevice *dev)
-{
- USBHubState *s = (USBHubState *)dev;
-
- qemu_free(s);
-}
-
-USBDevice *usb_hub_init(int nb_ports)
-{
- USBHubState *s;
- USBHubPort *port;
- int i;
-
- if (nb_ports > MAX_PORTS)
- return NULL;
- s = qemu_mallocz(sizeof(USBHubState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_hub_handle_packet;
-
- /* generic USB device init */
- s->dev.handle_reset = usb_hub_handle_reset;
- s->dev.handle_control = usb_hub_handle_control;
- s->dev.handle_data = usb_hub_handle_data;
- s->dev.handle_destroy = usb_hub_handle_destroy;
-
- pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Hub");
-
- s->nb_ports = nb_ports;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- qemu_register_usb_port(&port->port, s, i, usb_hub_attach);
- port->wPortStatus = PORT_STAT_POWER;
- port->wPortChange = 0;
- }
- return (USBDevice *)s;
-}
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
deleted file mode 100644
index f7ad25e..0000000
--- a/hw/usb-msd.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * USB Mass Storage Device emulation
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the LGPL.
- */
-
-#include "qemu-common.h"
-#include "usb.h"
-#include "block.h"
-#include "scsi-disk.h"
-
-//#define DEBUG_MSD
-
-#ifdef DEBUG_MSD
-#define DPRINTF(fmt, args...) \
-do { printf("usb-msd: " fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do {} while(0)
-#endif
-
-/* USB requests. */
-#define MassStorageReset 0xff
-#define GetMaxLun 0xfe
-
-enum USBMSDMode {
- USB_MSDM_CBW, /* Command Block. */
- USB_MSDM_DATAOUT, /* Tranfer data to device. */
- USB_MSDM_DATAIN, /* Transfer data from device. */
- USB_MSDM_CSW /* Command Status. */
-};
-
-typedef struct {
- USBDevice dev;
- enum USBMSDMode mode;
- uint32_t scsi_len;
- uint8_t *scsi_buf;
- uint32_t usb_len;
- uint8_t *usb_buf;
- uint32_t data_len;
- uint32_t residue;
- uint32_t tag;
- BlockDriverState *bs;
- SCSIDevice *scsi_dev;
- int result;
- /* For async completion. */
- USBPacket *packet;
-} MSDState;
-
-struct usb_msd_cbw {
- uint32_t sig;
- uint32_t tag;
- uint32_t data_len;
- uint8_t flags;
- uint8_t lun;
- uint8_t cmd_len;
- uint8_t cmd[16];
-};
-
-struct usb_msd_csw {
- uint32_t sig;
- uint32_t tag;
- uint32_t residue;
- uint8_t status;
-};
-
-static const uint8_t qemu_msd_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x00, 0x01, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- /* Vendor and product id are arbitrary. */
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x01, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x03, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_msd_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x20, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x02, /* u8 if_bNumEndpoints; */
- 0x08, /* u8 if_bInterfaceClass; MASS STORAGE */
- 0x06, /* u8 if_bInterfaceSubClass; SCSI */
- 0x50, /* u8 if_bInterfaceProtocol; Bulk Only */
- 0x00, /* u8 if_iInterface; */
-
- /* Bulk-In endpoint */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x02, /* u8 ep_bmAttributes; Bulk */
- 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x00, /* u8 ep_bInterval; */
-
- /* Bulk-Out endpoint */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x02, /* u8 ep_bEndpointAddress; OUT Endpoint 2 */
- 0x02, /* u8 ep_bmAttributes; Bulk */
- 0x40, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x00 /* u8 ep_bInterval; */
-};
-
-static void usb_msd_copy_data(MSDState *s)
-{
- uint32_t len;
- len = s->usb_len;
- if (len > s->scsi_len)
- len = s->scsi_len;
- if (s->mode == USB_MSDM_DATAIN) {
- memcpy(s->usb_buf, s->scsi_buf, len);
- } else {
- memcpy(s->scsi_buf, s->usb_buf, len);
- }
- s->usb_len -= len;
- s->scsi_len -= len;
- s->usb_buf += len;
- s->scsi_buf += len;
- s->data_len -= len;
- if (s->scsi_len == 0) {
- if (s->mode == USB_MSDM_DATAIN) {
- s->scsi_dev->read_data(s->scsi_dev, s->tag);
- } else if (s->mode == USB_MSDM_DATAOUT) {
- s->scsi_dev->write_data(s->scsi_dev, s->tag);
- }
- }
-}
-
-static void usb_msd_send_status(MSDState *s)
-{
- struct usb_msd_csw csw;
-
- csw.sig = cpu_to_le32(0x53425355);
- csw.tag = cpu_to_le32(s->tag);
- csw.residue = s->residue;
- csw.status = s->result;
- memcpy(s->usb_buf, &csw, 13);
-}
-
-static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
- uint32_t arg)
-{
- MSDState *s = (MSDState *)opaque;
- USBPacket *p = s->packet;
-
- if (tag != s->tag) {
- fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag);
- }
- if (reason == SCSI_REASON_DONE) {
- DPRINTF("Command complete %d\n", arg);
- s->residue = s->data_len;
- s->result = arg != 0;
- if (s->packet) {
- if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
- /* A deferred packet with no write data remaining must be
- the status read packet. */
- usb_msd_send_status(s);
- s->mode = USB_MSDM_CBW;
- } else {
- if (s->data_len) {
- s->data_len -= s->usb_len;
- if (s->mode == USB_MSDM_DATAIN)
- memset(s->usb_buf, 0, s->usb_len);
- s->usb_len = 0;
- }
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- }
- s->packet = NULL;
- usb_packet_complete(p);
- } else if (s->data_len == 0) {
- s->mode = USB_MSDM_CSW;
- }
- return;
- }
- s->scsi_len = arg;
- s->scsi_buf = s->scsi_dev->get_buf(s->scsi_dev, tag);
- if (p) {
- usb_msd_copy_data(s);
- if (s->usb_len == 0) {
- /* Set s->packet to NULL before calling usb_packet_complete
- because annother request may be issued before
- usb_packet_complete returns. */
- DPRINTF("Packet complete %p\n", p);
- s->packet = NULL;
- usb_packet_complete(p);
- }
- }
-}
-
-static void usb_msd_handle_reset(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- DPRINTF("Reset\n");
- s->mode = USB_MSDM_CBW;
-}
-
-static int usb_msd_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- MSDState *s = (MSDState *)dev;
- int ret = 0;
-
- switch (request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_msd_dev_descriptor,
- sizeof(qemu_msd_dev_descriptor));
- ret = sizeof(qemu_msd_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_msd_config_descriptor,
- sizeof(qemu_msd_config_descriptor));
- ret = sizeof(qemu_msd_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB HARDDRIVE");
- break;
- case 3:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- /* Class specific requests. */
- case MassStorageReset:
- /* Reset state ready for the next CBW. */
- s->mode = USB_MSDM_CBW;
- ret = 0;
- break;
- case GetMaxLun:
- data[0] = 0;
- ret = 1;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static void usb_msd_cancel_io(USBPacket *p, void *opaque)
-{
- MSDState *s = opaque;
- s->scsi_dev->cancel_io(s->scsi_dev, s->tag);
- s->packet = NULL;
- s->scsi_len = 0;
-}
-
-static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
-{
- MSDState *s = (MSDState *)dev;
- int ret = 0;
- struct usb_msd_cbw cbw;
- uint8_t devep = p->devep;
- uint8_t *data = p->data;
- int len = p->len;
-
- switch (p->pid) {
- case USB_TOKEN_OUT:
- if (devep != 2)
- goto fail;
-
- switch (s->mode) {
- case USB_MSDM_CBW:
- if (len != 31) {
- fprintf(stderr, "usb-msd: Bad CBW size");
- goto fail;
- }
- memcpy(&cbw, data, 31);
- if (le32_to_cpu(cbw.sig) != 0x43425355) {
- fprintf(stderr, "usb-msd: Bad signature %08x\n",
- le32_to_cpu(cbw.sig));
- goto fail;
- }
- DPRINTF("Command on LUN %d\n", cbw.lun);
- if (cbw.lun != 0) {
- fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
- goto fail;
- }
- s->tag = le32_to_cpu(cbw.tag);
- s->data_len = le32_to_cpu(cbw.data_len);
- if (s->data_len == 0) {
- s->mode = USB_MSDM_CSW;
- } else if (cbw.flags & 0x80) {
- s->mode = USB_MSDM_DATAIN;
- } else {
- s->mode = USB_MSDM_DATAOUT;
- }
- DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
- s->tag, cbw.flags, cbw.cmd_len, s->data_len);
- s->residue = 0;
- s->scsi_dev->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
- /* ??? Should check that USB and SCSI data transfer
- directions match. */
- if (s->residue == 0) {
- if (s->mode == USB_MSDM_DATAIN) {
- s->scsi_dev->read_data(s->scsi_dev, s->tag);
- } else if (s->mode == USB_MSDM_DATAOUT) {
- s->scsi_dev->write_data(s->scsi_dev, s->tag);
- }
- }
- ret = len;
- break;
-
- case USB_MSDM_DATAOUT:
- DPRINTF("Data out %d/%d\n", len, s->data_len);
- if (len > s->data_len)
- goto fail;
-
- s->usb_buf = data;
- s->usb_len = len;
- if (s->scsi_len) {
- usb_msd_copy_data(s);
- }
- if (s->residue && s->usb_len) {
- s->data_len -= s->usb_len;
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- s->usb_len = 0;
- }
- if (s->usb_len) {
- DPRINTF("Deferring packet %p\n", p);
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- } else {
- ret = len;
- }
- break;
-
- default:
- DPRINTF("Unexpected write (len %d)\n", len);
- goto fail;
- }
- break;
-
- case USB_TOKEN_IN:
- if (devep != 1)
- goto fail;
-
- switch (s->mode) {
- case USB_MSDM_DATAOUT:
- if (s->data_len != 0 || len < 13)
- goto fail;
- /* Waiting for SCSI write to complete. */
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- break;
-
- case USB_MSDM_CSW:
- DPRINTF("Command status %d tag 0x%x, len %d\n",
- s->result, s->tag, len);
- if (len < 13)
- goto fail;
-
- s->usb_len = len;
- s->usb_buf = data;
- usb_msd_send_status(s);
- s->mode = USB_MSDM_CBW;
- ret = 13;
- break;
-
- case USB_MSDM_DATAIN:
- DPRINTF("Data in %d/%d\n", len, s->data_len);
- if (len > s->data_len)
- len = s->data_len;
- s->usb_buf = data;
- s->usb_len = len;
- if (s->scsi_len) {
- usb_msd_copy_data(s);
- }
- if (s->residue && s->usb_len) {
- s->data_len -= s->usb_len;
- memset(s->usb_buf, 0, s->usb_len);
- if (s->data_len == 0)
- s->mode = USB_MSDM_CSW;
- s->usb_len = 0;
- }
- if (s->usb_len) {
- DPRINTF("Deferring packet %p\n", p);
- usb_defer_packet(p, usb_msd_cancel_io, s);
- s->packet = p;
- ret = USB_RET_ASYNC;
- } else {
- ret = len;
- }
- break;
-
- default:
- DPRINTF("Unexpected read (len %d)\n", len);
- goto fail;
- }
- break;
-
- default:
- DPRINTF("Bad token\n");
- fail:
- ret = USB_RET_STALL;
- break;
- }
-
- return ret;
-}
-
-static void usb_msd_handle_destroy(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- s->scsi_dev->destroy(s->scsi_dev);
- bdrv_delete(s->bs);
- qemu_free(s);
-}
-
-USBDevice *usb_msd_init(const char *filename)
-{
- MSDState *s;
- BlockDriverState *bdrv;
- BlockDriver *drv = NULL;
- const char *p1;
- char fmt[32];
-
- p1 = strchr(filename, ':');
- if (p1++) {
- const char *p2;
-
- if (strstart(filename, "format=", &p2)) {
- int len = MIN(p1 - p2, sizeof(fmt));
- pstrcpy(fmt, len, p2);
-
- drv = bdrv_find_format(fmt);
- if (!drv) {
- printf("invalid format %s\n", fmt);
- return NULL;
- }
- } else if (*filename != ':') {
- printf("unrecognized USB mass-storage option %s\n", filename);
- return NULL;
- }
-
- filename = p1;
- }
-
- if (!*filename) {
- printf("block device specification needed\n");
- return NULL;
- }
-
- s = qemu_mallocz(sizeof(MSDState));
- if (!s)
- return NULL;
-
- bdrv = bdrv_new("usb");
- if (bdrv_open2(bdrv, filename, 0, drv) < 0)
- goto fail;
- if (qemu_key_check(bdrv, filename))
- goto fail;
- s->bs = bdrv;
-
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_msd_handle_reset;
- s->dev.handle_control = usb_msd_handle_control;
- s->dev.handle_data = usb_msd_handle_data;
- s->dev.handle_destroy = usb_msd_handle_destroy;
-
- snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB MSD(%.16s)",
- filename);
-
- s->scsi_dev = scsi_disk_init(bdrv, 0, usb_msd_command_complete, s);
- usb_msd_handle_reset((USBDevice *)s);
- return (USBDevice *)s;
- fail:
- qemu_free(s);
- return NULL;
-}
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
deleted file mode 100644
index 55cb77b..0000000
--- a/hw/usb-ohci.c
+++ /dev/null
@@ -1,1684 +0,0 @@
-/*
- * QEMU USB OHCI Emulation
- * Copyright (c) 2004 Gianni Tedesco
- * Copyright (c) 2006 CodeSourcery
- * Copyright (c) 2006 Openedhand Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * TODO:
- * o Isochronous transfers
- * o Allocate bandwidth in frames properly
- * o Disable timers when nothing needs to be done, or remove timer usage
- * all together.
- * o Handle unrecoverable errors properly
- * o BIOS work to boot from USB storage
-*/
-
-#include "hw.h"
-#include "qemu-timer.h"
-#include "usb.h"
-#include "pci.h"
-#include "pxa.h"
-
-//#define DEBUG_OHCI
-/* Dump packet contents. */
-//#define DEBUG_PACKET
-//#define DEBUG_ISOCH
-/* This causes frames to occur 1000x slower */
-//#define OHCI_TIME_WARP 1
-
-#ifdef DEBUG_OHCI
-#define dprintf printf
-#else
-#define dprintf(...)
-#endif
-
-/* Number of Downstream Ports on the root hub. */
-
-#define OHCI_MAX_PORTS 15
-
-static int64_t usb_frame_time;
-static int64_t usb_bit_time;
-
-typedef struct OHCIPort {
- USBPort port;
- uint32_t ctrl;
-} OHCIPort;
-
-enum ohci_type {
- OHCI_TYPE_PCI,
- OHCI_TYPE_PXA
-};
-
-typedef struct {
- qemu_irq irq;
- enum ohci_type type;
- target_phys_addr_t mem_base;
- int mem;
- int num_ports;
- const char *name;
-
- QEMUTimer *eof_timer;
- int64_t sof_time;
-
- /* OHCI state */
- /* Control partition */
- uint32_t ctl, status;
- uint32_t intr_status;
- uint32_t intr;
-
- /* memory pointer partition */
- uint32_t hcca;
- uint32_t ctrl_head, ctrl_cur;
- uint32_t bulk_head, bulk_cur;
- uint32_t per_cur;
- uint32_t done;
- int done_count;
-
- /* Frame counter partition */
- uint32_t fsmps:15;
- uint32_t fit:1;
- uint32_t fi:14;
- uint32_t frt:1;
- uint16_t frame_number;
- uint16_t padding;
- uint32_t pstart;
- uint32_t lst;
-
- /* Root Hub partition */
- uint32_t rhdesc_a, rhdesc_b;
- uint32_t rhstatus;
- OHCIPort rhport[OHCI_MAX_PORTS];
-
- /* PXA27x Non-OHCI events */
- uint32_t hstatus;
- uint32_t hmask;
- uint32_t hreset;
- uint32_t htest;
-
- /* Active packets. */
- uint32_t old_ctl;
- USBPacket usb_packet;
- uint8_t usb_buf[8192];
- uint32_t async_td;
- int async_complete;
-
-} OHCIState;
-
-/* Host Controller Communications Area */
-struct ohci_hcca {
- uint32_t intr[32];
- uint16_t frame, pad;
- uint32_t done;
-};
-
-static void ohci_bus_stop(OHCIState *ohci);
-
-/* Bitfields for the first word of an Endpoint Desciptor. */
-#define OHCI_ED_FA_SHIFT 0
-#define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT)
-#define OHCI_ED_EN_SHIFT 7
-#define OHCI_ED_EN_MASK (0xf<<OHCI_ED_EN_SHIFT)
-#define OHCI_ED_D_SHIFT 11
-#define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT)
-#define OHCI_ED_S (1<<13)
-#define OHCI_ED_K (1<<14)
-#define OHCI_ED_F (1<<15)
-#define OHCI_ED_MPS_SHIFT 16
-#define OHCI_ED_MPS_MASK (0x7ff<<OHCI_ED_MPS_SHIFT)
-
-/* Flags in the head field of an Endpoint Desciptor. */
-#define OHCI_ED_H 1
-#define OHCI_ED_C 2
-
-/* Bitfields for the first word of a Transfer Desciptor. */
-#define OHCI_TD_R (1<<18)
-#define OHCI_TD_DP_SHIFT 19
-#define OHCI_TD_DP_MASK (3<<OHCI_TD_DP_SHIFT)
-#define OHCI_TD_DI_SHIFT 21
-#define OHCI_TD_DI_MASK (7<<OHCI_TD_DI_SHIFT)
-#define OHCI_TD_T0 (1<<24)
-#define OHCI_TD_T1 (1<<24)
-#define OHCI_TD_EC_SHIFT 26
-#define OHCI_TD_EC_MASK (3<<OHCI_TD_EC_SHIFT)
-#define OHCI_TD_CC_SHIFT 28
-#define OHCI_TD_CC_MASK (0xf<<OHCI_TD_CC_SHIFT)
-
-/* Bitfields for the first word of an Isochronous Transfer Desciptor. */
-/* CC & DI - same as in the General Transfer Desciptor */
-#define OHCI_TD_SF_SHIFT 0
-#define OHCI_TD_SF_MASK (0xffff<<OHCI_TD_SF_SHIFT)
-#define OHCI_TD_FC_SHIFT 24
-#define OHCI_TD_FC_MASK (7<<OHCI_TD_FC_SHIFT)
-
-/* Isochronous Transfer Desciptor - Offset / PacketStatusWord */
-#define OHCI_TD_PSW_CC_SHIFT 12
-#define OHCI_TD_PSW_CC_MASK (0xf<<OHCI_TD_PSW_CC_SHIFT)
-#define OHCI_TD_PSW_SIZE_SHIFT 0
-#define OHCI_TD_PSW_SIZE_MASK (0xfff<<OHCI_TD_PSW_SIZE_SHIFT)
-
-#define OHCI_PAGE_MASK 0xfffff000
-#define OHCI_OFFSET_MASK 0xfff
-
-#define OHCI_DPTR_MASK 0xfffffff0
-
-#define OHCI_BM(val, field) \
- (((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
-
-#define OHCI_SET_BM(val, field, newval) do { \
- val &= ~OHCI_##field##_MASK; \
- val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
- } while(0)
-
-/* endpoint descriptor */
-struct ohci_ed {
- uint32_t flags;
- uint32_t tail;
- uint32_t head;
- uint32_t next;
-};
-
-/* General transfer descriptor */
-struct ohci_td {
- uint32_t flags;
- uint32_t cbp;
- uint32_t next;
- uint32_t be;
-};
-
-/* Isochronous transfer descriptor */
-struct ohci_iso_td {
- uint32_t flags;
- uint32_t bp;
- uint32_t next;
- uint32_t be;
- uint16_t offset[8];
-};
-
-#define USB_HZ 12000000
-
-/* OHCI Local stuff */
-#define OHCI_CTL_CBSR ((1<<0)|(1<<1))
-#define OHCI_CTL_PLE (1<<2)
-#define OHCI_CTL_IE (1<<3)
-#define OHCI_CTL_CLE (1<<4)
-#define OHCI_CTL_BLE (1<<5)
-#define OHCI_CTL_HCFS ((1<<6)|(1<<7))
-#define OHCI_USB_RESET 0x00
-#define OHCI_USB_RESUME 0x40
-#define OHCI_USB_OPERATIONAL 0x80
-#define OHCI_USB_SUSPEND 0xc0
-#define OHCI_CTL_IR (1<<8)
-#define OHCI_CTL_RWC (1<<9)
-#define OHCI_CTL_RWE (1<<10)
-
-#define OHCI_STATUS_HCR (1<<0)
-#define OHCI_STATUS_CLF (1<<1)
-#define OHCI_STATUS_BLF (1<<2)
-#define OHCI_STATUS_OCR (1<<3)
-#define OHCI_STATUS_SOC ((1<<6)|(1<<7))
-
-#define OHCI_INTR_SO (1<<0) /* Scheduling overrun */
-#define OHCI_INTR_WD (1<<1) /* HcDoneHead writeback */
-#define OHCI_INTR_SF (1<<2) /* Start of frame */
-#define OHCI_INTR_RD (1<<3) /* Resume detect */
-#define OHCI_INTR_UE (1<<4) /* Unrecoverable error */
-#define OHCI_INTR_FNO (1<<5) /* Frame number overflow */
-#define OHCI_INTR_RHSC (1<<6) /* Root hub status change */
-#define OHCI_INTR_OC (1<<30) /* Ownership change */
-#define OHCI_INTR_MIE (1<<31) /* Master Interrupt Enable */
-
-#define OHCI_HCCA_SIZE 0x100
-#define OHCI_HCCA_MASK 0xffffff00
-
-#define OHCI_EDPTR_MASK 0xfffffff0
-
-#define OHCI_FMI_FI 0x00003fff
-#define OHCI_FMI_FSMPS 0xffff0000
-#define OHCI_FMI_FIT 0x80000000
-
-#define OHCI_FR_RT (1<<31)
-
-#define OHCI_LS_THRESH 0x628
-
-#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */
-#define OHCI_RHA_PSM (1<<8)
-#define OHCI_RHA_NPS (1<<9)
-#define OHCI_RHA_DT (1<<10)
-#define OHCI_RHA_OCPM (1<<11)
-#define OHCI_RHA_NOCP (1<<12)
-#define OHCI_RHA_POTPGT_MASK 0xff000000
-
-#define OHCI_RHS_LPS (1<<0)
-#define OHCI_RHS_OCI (1<<1)
-#define OHCI_RHS_DRWE (1<<15)
-#define OHCI_RHS_LPSC (1<<16)
-#define OHCI_RHS_OCIC (1<<17)
-#define OHCI_RHS_CRWE (1<<31)
-
-#define OHCI_PORT_CCS (1<<0)
-#define OHCI_PORT_PES (1<<1)
-#define OHCI_PORT_PSS (1<<2)
-#define OHCI_PORT_POCI (1<<3)
-#define OHCI_PORT_PRS (1<<4)
-#define OHCI_PORT_PPS (1<<8)
-#define OHCI_PORT_LSDA (1<<9)
-#define OHCI_PORT_CSC (1<<16)
-#define OHCI_PORT_PESC (1<<17)
-#define OHCI_PORT_PSSC (1<<18)
-#define OHCI_PORT_OCIC (1<<19)
-#define OHCI_PORT_PRSC (1<<20)
-#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
- |OHCI_PORT_OCIC|OHCI_PORT_PRSC)
-
-#define OHCI_TD_DIR_SETUP 0x0
-#define OHCI_TD_DIR_OUT 0x1
-#define OHCI_TD_DIR_IN 0x2
-#define OHCI_TD_DIR_RESERVED 0x3
-
-#define OHCI_CC_NOERROR 0x0
-#define OHCI_CC_CRC 0x1
-#define OHCI_CC_BITSTUFFING 0x2
-#define OHCI_CC_DATATOGGLEMISMATCH 0x3
-#define OHCI_CC_STALL 0x4
-#define OHCI_CC_DEVICENOTRESPONDING 0x5
-#define OHCI_CC_PIDCHECKFAILURE 0x6
-#define OHCI_CC_UNDEXPETEDPID 0x7
-#define OHCI_CC_DATAOVERRUN 0x8
-#define OHCI_CC_DATAUNDERRUN 0x9
-#define OHCI_CC_BUFFEROVERRUN 0xc
-#define OHCI_CC_BUFFERUNDERRUN 0xd
-
-#define OHCI_HRESET_FSBIR (1 << 0)
-
-/* Update IRQ levels */
-static inline void ohci_intr_update(OHCIState *ohci)
-{
- int level = 0;
-
- if ((ohci->intr & OHCI_INTR_MIE) &&
- (ohci->intr_status & ohci->intr))
- level = 1;
-
- qemu_set_irq(ohci->irq, level);
-}
-
-/* Set an interrupt */
-static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr)
-{
- ohci->intr_status |= intr;
- ohci_intr_update(ohci);
-}
-
-/* Attach or detach a device on a root hub port. */
-static void ohci_attach(USBPort *port1, USBDevice *dev)
-{
- OHCIState *s = port1->opaque;
- OHCIPort *port = &s->rhport[port1->index];
- uint32_t old_state = port->ctrl;
-
- if (dev) {
- if (port->port.dev) {
- usb_attach(port1, NULL);
- }
- /* set connect status */
- port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
-
- /* update speed */
- if (dev->speed == USB_SPEED_LOW)
- port->ctrl |= OHCI_PORT_LSDA;
- else
- port->ctrl &= ~OHCI_PORT_LSDA;
- port->port.dev = dev;
-
- /* notify of remote-wakeup */
- if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
- ohci_set_interrupt(s, OHCI_INTR_RD);
-
- /* send the attach message */
- usb_send_msg(dev, USB_MSG_ATTACH);
- dprintf("usb-ohci: Attached port %d\n", port1->index);
- } else {
- /* set connect status */
- if (port->ctrl & OHCI_PORT_CCS) {
- port->ctrl &= ~OHCI_PORT_CCS;
- port->ctrl |= OHCI_PORT_CSC;
- }
- /* disable port */
- if (port->ctrl & OHCI_PORT_PES) {
- port->ctrl &= ~OHCI_PORT_PES;
- port->ctrl |= OHCI_PORT_PESC;
- }
- dev = port->port.dev;
- if (dev) {
- /* send the detach message */
- usb_send_msg(dev, USB_MSG_DETACH);
- }
- port->port.dev = NULL;
- dprintf("usb-ohci: Detached port %d\n", port1->index);
- }
-
- if (old_state != port->ctrl)
- ohci_set_interrupt(s, OHCI_INTR_RHSC);
-}
-
-/* Reset the controller */
-static void ohci_reset(void *opaque)
-{
- OHCIState *ohci = opaque;
- OHCIPort *port;
- int i;
-
- ohci_bus_stop(ohci);
- ohci->ctl = 0;
- ohci->old_ctl = 0;
- ohci->status = 0;
- ohci->intr_status = 0;
- ohci->intr = OHCI_INTR_MIE;
-
- ohci->hcca = 0;
- ohci->ctrl_head = ohci->ctrl_cur = 0;
- ohci->bulk_head = ohci->bulk_cur = 0;
- ohci->per_cur = 0;
- ohci->done = 0;
- ohci->done_count = 7;
-
- /* FSMPS is marked TBD in OCHI 1.0, what gives ffs?
- * I took the value linux sets ...
- */
- ohci->fsmps = 0x2778;
- ohci->fi = 0x2edf;
- ohci->fit = 0;
- ohci->frt = 0;
- ohci->frame_number = 0;
- ohci->pstart = 0;
- ohci->lst = OHCI_LS_THRESH;
-
- ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports;
- ohci->rhdesc_b = 0x0; /* Impl. specific */
- ohci->rhstatus = 0;
-
- for (i = 0; i < ohci->num_ports; i++)
- {
- port = &ohci->rhport[i];
- port->ctrl = 0;
- if (port->port.dev)
- ohci_attach(&port->port, port->port.dev);
- }
- if (ohci->async_td) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- dprintf("usb-ohci: Reset %s\n", ohci->name);
-}
-
-/* Get an array of dwords from main memory */
-static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
- *buf = le32_to_cpu(*buf);
- }
-
- return 1;
-}
-
-/* Put an array of dwords in to main memory */
-static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- uint32_t tmp = cpu_to_le32(*buf);
- cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
- }
-
- return 1;
-}
-
-/* Get an array of words from main memory */
-static inline int get_words(uint32_t addr, uint16_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
- *buf = le16_to_cpu(*buf);
- }
-
- return 1;
-}
-
-/* Put an array of words in to main memory */
-static inline int put_words(uint32_t addr, uint16_t *buf, int num)
-{
- int i;
-
- for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- uint16_t tmp = cpu_to_le16(*buf);
- cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
- }
-
- return 1;
-}
-
-static inline int ohci_read_ed(uint32_t addr, struct ohci_ed *ed)
-{
- return get_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
-}
-
-static inline int ohci_read_td(uint32_t addr, struct ohci_td *td)
-{
- return get_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
-}
-
-static inline int ohci_read_iso_td(uint32_t addr, struct ohci_iso_td *td)
-{
- return (get_dwords(addr, (uint32_t *)td, 4) &&
- get_words(addr + 16, td->offset, 8));
-}
-
-static inline int ohci_put_ed(uint32_t addr, struct ohci_ed *ed)
-{
- return put_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
-}
-
-static inline int ohci_put_td(uint32_t addr, struct ohci_td *td)
-{
- return put_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
-}
-
-static inline int ohci_put_iso_td(uint32_t addr, struct ohci_iso_td *td)
-{
- return (put_dwords(addr, (uint32_t *)td, 4) &&
- put_words(addr + 16, td->offset, 8));
-}
-
-/* Read/Write the contents of a TD from/to main memory. */
-static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
-{
- uint32_t ptr;
- uint32_t n;
-
- ptr = td->cbp;
- n = 0x1000 - (ptr & 0xfff);
- if (n > len)
- n = len;
- cpu_physical_memory_rw(ptr, buf, n, write);
- if (n == len)
- return;
- ptr = td->be & ~0xfffu;
- buf += n;
- cpu_physical_memory_rw(ptr, buf, len - n, write);
-}
-
-/* Read/Write the contents of an ISO TD from/to main memory. */
-static void ohci_copy_iso_td(uint32_t start_addr, uint32_t end_addr,
- uint8_t *buf, int len, int write)
-{
- uint32_t ptr;
- uint32_t n;
-
- ptr = start_addr;
- n = 0x1000 - (ptr & 0xfff);
- if (n > len)
- n = len;
- cpu_physical_memory_rw(ptr, buf, n, write);
- if (n == len)
- return;
- ptr = end_addr & ~0xfffu;
- buf += n;
- cpu_physical_memory_rw(ptr, buf, len - n, write);
-}
-
-static void ohci_process_lists(OHCIState *ohci, int completion);
-
-static void ohci_async_complete_packet(USBPacket *packet, void *opaque)
-{
- OHCIState *ohci = opaque;
-#ifdef DEBUG_PACKET
- dprintf("Async packet complete\n");
-#endif
- ohci->async_complete = 1;
- ohci_process_lists(ohci, 1);
-}
-
-#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
-
-static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
- int completion)
-{
- int dir;
- size_t len = 0;
- const char *str = NULL;
- int pid;
- int ret;
- int i;
- USBDevice *dev;
- struct ohci_iso_td iso_td;
- uint32_t addr;
- uint16_t starting_frame;
- int16_t relative_frame_number;
- int frame_count;
- uint32_t start_offset, next_offset, end_offset = 0;
- uint32_t start_addr, end_addr;
-
- addr = ed->head & OHCI_DPTR_MASK;
-
- if (!ohci_read_iso_td(addr, &iso_td)) {
- printf("usb-ohci: ISO_TD read error at %x\n", addr);
- return 0;
- }
-
- starting_frame = OHCI_BM(iso_td.flags, TD_SF);
- frame_count = OHCI_BM(iso_td.flags, TD_FC);
- relative_frame_number = USUB(ohci->frame_number, starting_frame);
-
-#ifdef DEBUG_ISOCH
- printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n"
- "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
- "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
- "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n"
- "frame_number 0x%.8x starting_frame 0x%.8x\n"
- "frame_count 0x%.8x relative %d\n"
- "di 0x%.8x cc 0x%.8x\n",
- ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK,
- iso_td.flags, iso_td.bp, iso_td.next, iso_td.be,
- iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3],
- iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7],
- ohci->frame_number, starting_frame,
- frame_count, relative_frame_number,
- OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC));
-#endif
-
- if (relative_frame_number < 0) {
- dprintf("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number);
- return 1;
- } else if (relative_frame_number > frame_count) {
- /* ISO TD expired - retire the TD to the Done Queue and continue with
- the next ISO TD of the same ED */
- dprintf("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number,
- frame_count);
- OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= (iso_td.next & OHCI_DPTR_MASK);
- iso_td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(iso_td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- ohci_put_iso_td(addr, &iso_td);
- return 0;
- }
-
- dir = OHCI_BM(ed->flags, ED_D);
- switch (dir) {
- case OHCI_TD_DIR_IN:
- str = "in";
- pid = USB_TOKEN_IN;
- break;
- case OHCI_TD_DIR_OUT:
- str = "out";
- pid = USB_TOKEN_OUT;
- break;
- case OHCI_TD_DIR_SETUP:
- str = "setup";
- pid = USB_TOKEN_SETUP;
- break;
- default:
- printf("usb-ohci: Bad direction %d\n", dir);
- return 1;
- }
-
- if (!iso_td.bp || !iso_td.be) {
- printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be);
- return 1;
- }
-
- start_offset = iso_td.offset[relative_frame_number];
- next_offset = iso_td.offset[relative_frame_number + 1];
-
- if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) ||
- ((relative_frame_number < frame_count) &&
- !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
- printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n",
- start_offset, next_offset);
- return 1;
- }
-
- if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
- printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n",
- start_offset, next_offset);
- return 1;
- }
-
- if ((start_offset & 0x1000) == 0) {
- start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
- (start_offset & OHCI_OFFSET_MASK);
- } else {
- start_addr = (iso_td.be & OHCI_PAGE_MASK) |
- (start_offset & OHCI_OFFSET_MASK);
- }
-
- if (relative_frame_number < frame_count) {
- end_offset = next_offset - 1;
- if ((end_offset & 0x1000) == 0) {
- end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
- (end_offset & OHCI_OFFSET_MASK);
- } else {
- end_addr = (iso_td.be & OHCI_PAGE_MASK) |
- (end_offset & OHCI_OFFSET_MASK);
- }
- } else {
- /* Last packet in the ISO TD */
- end_addr = iso_td.be;
- }
-
- if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
- len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
- - (start_addr & OHCI_OFFSET_MASK);
- } else {
- len = end_addr - start_addr + 1;
- }
-
- if (len && dir != OHCI_TD_DIR_IN) {
- ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, len, 0);
- }
-
- if (completion) {
- ret = ohci->usb_packet.len;
- } else {
- ret = USB_RET_NODEV;
- for (i = 0; i < ohci->num_ports; i++) {
- dev = ohci->rhport[i].port.dev;
- if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
- continue;
- ohci->usb_packet.pid = pid;
- ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
- ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
- ohci->usb_packet.data = ohci->usb_buf;
- ohci->usb_packet.len = len;
- ohci->usb_packet.complete_cb = ohci_async_complete_packet;
- ohci->usb_packet.complete_opaque = ohci;
- ret = dev->handle_packet(dev, &ohci->usb_packet);
- if (ret != USB_RET_NODEV)
- break;
- }
-
- if (ret == USB_RET_ASYNC) {
- return 1;
- }
- }
-
-#ifdef DEBUG_ISOCH
- printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n",
- start_offset, end_offset, start_addr, end_addr, str, len, ret);
-#endif
-
- /* Writeback */
- if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
- /* IN transfer succeeded */
- ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, ret, 1);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_NOERROR);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
- } else if (dir == OHCI_TD_DIR_OUT && ret == len) {
- /* OUT transfer succeeded */
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_NOERROR);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
- } else {
- if (ret > (ssize_t) len) {
- printf("usb-ohci: DataOverrun %d > %zu\n", ret, len);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_DATAOVERRUN);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
- len);
- } else if (ret >= 0) {
- printf("usb-ohci: DataUnderrun %d\n", ret);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_DATAUNDERRUN);
- } else {
- switch (ret) {
- case USB_RET_NODEV:
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_DEVICENOTRESPONDING);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
- 0);
- break;
- case USB_RET_NAK:
- case USB_RET_STALL:
- printf("usb-ohci: got NAK/STALL %d\n", ret);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_STALL);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
- 0);
- break;
- default:
- printf("usb-ohci: Bad device response %d\n", ret);
- OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
- OHCI_CC_UNDEXPETEDPID);
- break;
- }
- }
- }
-
- if (relative_frame_number == frame_count) {
- /* Last data packet of ISO TD - retire the TD to the Done Queue */
- OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= (iso_td.next & OHCI_DPTR_MASK);
- iso_td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(iso_td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- }
- ohci_put_iso_td(addr, &iso_td);
- return 1;
-}
-
-/* Service a transport descriptor.
- Returns nonzero to terminate processing of this endpoint. */
-
-static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
-{
- int dir;
- size_t len = 0;
- const char *str = NULL;
- int pid;
- int ret;
- int i;
- USBDevice *dev;
- struct ohci_td td;
- uint32_t addr;
- int flag_r;
- int completion;
-
- addr = ed->head & OHCI_DPTR_MASK;
- /* See if this TD has already been submitted to the device. */
- completion = (addr == ohci->async_td);
- if (completion && !ohci->async_complete) {
-#ifdef DEBUG_PACKET
- dprintf("Skipping async TD\n");
-#endif
- return 1;
- }
- if (!ohci_read_td(addr, &td)) {
- fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
- return 0;
- }
-
- dir = OHCI_BM(ed->flags, ED_D);
- switch (dir) {
- case OHCI_TD_DIR_OUT:
- case OHCI_TD_DIR_IN:
- /* Same value. */
- break;
- default:
- dir = OHCI_BM(td.flags, TD_DP);
- break;
- }
-
- switch (dir) {
- case OHCI_TD_DIR_IN:
- str = "in";
- pid = USB_TOKEN_IN;
- break;
- case OHCI_TD_DIR_OUT:
- str = "out";
- pid = USB_TOKEN_OUT;
- break;
- case OHCI_TD_DIR_SETUP:
- str = "setup";
- pid = USB_TOKEN_SETUP;
- break;
- default:
- fprintf(stderr, "usb-ohci: Bad direction\n");
- return 1;
- }
- if (td.cbp && td.be) {
- if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
- len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
- } else {
- len = (td.be - td.cbp) + 1;
- }
-
- if (len && dir != OHCI_TD_DIR_IN && !completion) {
- ohci_copy_td(&td, ohci->usb_buf, len, 0);
- }
- }
-
- flag_r = (td.flags & OHCI_TD_R) != 0;
-#ifdef DEBUG_PACKET
- dprintf(" TD @ 0x%.8x %u bytes %s r=%d cbp=0x%.8x be=0x%.8x\n",
- addr, len, str, flag_r, td.cbp, td.be);
-
- if (len > 0 && dir != OHCI_TD_DIR_IN) {
- dprintf(" data:");
- for (i = 0; i < len; i++)
- printf(" %.2x", ohci->usb_buf[i]);
- dprintf("\n");
- }
-#endif
- if (completion) {
- ret = ohci->usb_packet.len;
- ohci->async_td = 0;
- ohci->async_complete = 0;
- } else {
- ret = USB_RET_NODEV;
- for (i = 0; i < ohci->num_ports; i++) {
- dev = ohci->rhport[i].port.dev;
- if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
- continue;
-
- if (ohci->async_td) {
- /* ??? The hardware should allow one active packet per
- endpoint. We only allow one active packet per controller.
- This should be sufficient as long as devices respond in a
- timely manner.
- */
-#ifdef DEBUG_PACKET
- dprintf("Too many pending packets\n");
-#endif
- return 1;
- }
- ohci->usb_packet.pid = pid;
- ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
- ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
- ohci->usb_packet.data = ohci->usb_buf;
- ohci->usb_packet.len = len;
- ohci->usb_packet.complete_cb = ohci_async_complete_packet;
- ohci->usb_packet.complete_opaque = ohci;
- ret = dev->handle_packet(dev, &ohci->usb_packet);
- if (ret != USB_RET_NODEV)
- break;
- }
-#ifdef DEBUG_PACKET
- dprintf("ret=%d\n", ret);
-#endif
- if (ret == USB_RET_ASYNC) {
- ohci->async_td = addr;
- return 1;
- }
- }
- if (ret >= 0) {
- if (dir == OHCI_TD_DIR_IN) {
- ohci_copy_td(&td, ohci->usb_buf, ret, 1);
-#ifdef DEBUG_PACKET
- dprintf(" data:");
- for (i = 0; i < ret; i++)
- printf(" %.2x", ohci->usb_buf[i]);
- dprintf("\n");
-#endif
- } else {
- ret = len;
- }
- }
-
- /* Writeback */
- if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
- /* Transmission succeeded. */
- if (ret == len) {
- td.cbp = 0;
- } else {
- td.cbp += ret;
- if ((td.cbp & 0xfff) + ret > 0xfff) {
- td.cbp &= 0xfff;
- td.cbp |= td.be & ~0xfff;
- }
- }
- td.flags |= OHCI_TD_T1;
- td.flags ^= OHCI_TD_T0;
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
- OHCI_SET_BM(td.flags, TD_EC, 0);
-
- ed->head &= ~OHCI_ED_C;
- if (td.flags & OHCI_TD_T0)
- ed->head |= OHCI_ED_C;
- } else {
- if (ret >= 0) {
- dprintf("usb-ohci: Underrun\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
- } else {
- switch (ret) {
- case USB_RET_NODEV:
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
- case USB_RET_NAK:
- dprintf("usb-ohci: got NAK\n");
- return 1;
- case USB_RET_STALL:
- dprintf("usb-ohci: got STALL\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL);
- break;
- case USB_RET_BABBLE:
- dprintf("usb-ohci: got BABBLE\n");
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN);
- break;
- default:
- fprintf(stderr, "usb-ohci: Bad device response %d\n", ret);
- OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
- OHCI_SET_BM(td.flags, TD_EC, 3);
- break;
- }
- }
- ed->head |= OHCI_ED_H;
- }
-
- /* Retire this TD */
- ed->head &= ~OHCI_DPTR_MASK;
- ed->head |= td.next & OHCI_DPTR_MASK;
- td.next = ohci->done;
- ohci->done = addr;
- i = OHCI_BM(td.flags, TD_DI);
- if (i < ohci->done_count)
- ohci->done_count = i;
- ohci_put_td(addr, &td);
- return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
-}
-
-/* Service an endpoint list. Returns nonzero if active TD were found. */
-static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
-{
- struct ohci_ed ed;
- uint32_t next_ed;
- uint32_t cur;
- int active;
-
- active = 0;
-
- if (head == 0)
- return 0;
-
- for (cur = head; cur; cur = next_ed) {
- if (!ohci_read_ed(cur, &ed)) {
- fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
- return 0;
- }
-
- next_ed = ed.next & OHCI_DPTR_MASK;
-
- if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
- uint32_t addr;
- /* Cancel pending packets for ED that have been paused. */
- addr = ed.head & OHCI_DPTR_MASK;
- if (ohci->async_td && addr == ohci->async_td) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- continue;
- }
-
- while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
-#ifdef DEBUG_PACKET
- dprintf("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
- "h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
- OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
- OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0,
- (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
- OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
- (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
- ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
-#endif
- active = 1;
-
- if ((ed.flags & OHCI_ED_F) == 0) {
- if (ohci_service_td(ohci, &ed))
- break;
- } else {
- /* Handle isochronous endpoints */
- if (ohci_service_iso_td(ohci, &ed, completion))
- break;
- }
- }
-
- ohci_put_ed(cur, &ed);
- }
-
- return active;
-}
-
-/* Generate a SOF event, and set a timer for EOF */
-static void ohci_sof(OHCIState *ohci)
-{
- ohci->sof_time = qemu_get_clock(vm_clock);
- qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
- ohci_set_interrupt(ohci, OHCI_INTR_SF);
-}
-
-/* Process Control and Bulk lists. */
-static void ohci_process_lists(OHCIState *ohci, int completion)
-{
- if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
- if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
- dprintf("usb-ohci: head %x, cur %x\n",
- ohci->ctrl_head, ohci->ctrl_cur);
- if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) {
- ohci->ctrl_cur = 0;
- ohci->status &= ~OHCI_STATUS_CLF;
- }
- }
-
- if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
- if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) {
- ohci->bulk_cur = 0;
- ohci->status &= ~OHCI_STATUS_BLF;
- }
- }
-}
-
-/* Do frame processing on frame boundary */
-static void ohci_frame_boundary(void *opaque)
-{
- OHCIState *ohci = opaque;
- struct ohci_hcca hcca;
-
- cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 0);
-
- /* Process all the lists at the end of the frame */
- if (ohci->ctl & OHCI_CTL_PLE) {
- int n;
-
- n = ohci->frame_number & 0x1f;
- ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
- }
-
- /* Cancel all pending packets if either of the lists has been disabled. */
- if (ohci->async_td &&
- ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
- usb_cancel_packet(&ohci->usb_packet);
- ohci->async_td = 0;
- }
- ohci->old_ctl = ohci->ctl;
- ohci_process_lists(ohci, 0);
-
- /* Frame boundary, so do EOF stuf here */
- ohci->frt = ohci->fit;
-
- /* XXX: endianness */
- ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
- hcca.frame = cpu_to_le32(ohci->frame_number);
-
- if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
- if (!ohci->done)
- abort();
- if (ohci->intr & ohci->intr_status)
- ohci->done |= 1;
- hcca.done = cpu_to_le32(ohci->done);
- ohci->done = 0;
- ohci->done_count = 7;
- ohci_set_interrupt(ohci, OHCI_INTR_WD);
- }
-
- if (ohci->done_count != 7 && ohci->done_count != 0)
- ohci->done_count--;
-
- /* Do SOF stuff here */
- ohci_sof(ohci);
-
- /* Writeback HCCA */
- cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 1);
-}
-
-/* Start sending SOF tokens across the USB bus, lists are processed in
- * next frame
- */
-static int ohci_bus_start(OHCIState *ohci)
-{
- ohci->eof_timer = qemu_new_timer(vm_clock,
- ohci_frame_boundary,
- ohci);
-
- if (ohci->eof_timer == NULL) {
- fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n", ohci->name);
- /* TODO: Signal unrecoverable error */
- return 0;
- }
-
- dprintf("usb-ohci: %s: USB Operational\n", ohci->name);
-
- ohci_sof(ohci);
-
- return 1;
-}
-
-/* Stop sending SOF tokens on the bus */
-static void ohci_bus_stop(OHCIState *ohci)
-{
- if (ohci->eof_timer)
- qemu_del_timer(ohci->eof_timer);
- ohci->eof_timer = NULL;
-}
-
-/* Sets a flag in a port status register but only set it if the port is
- * connected, if not set ConnectStatusChange flag. If flag is enabled
- * return 1.
- */
-static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
-{
- int ret = 1;
-
- /* writing a 0 has no effect */
- if (val == 0)
- return 0;
-
- /* If CurrentConnectStatus is cleared we set
- * ConnectStatusChange
- */
- if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
- ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
- if (ohci->rhstatus & OHCI_RHS_DRWE) {
- /* TODO: CSC is a wakeup event */
- }
- return 0;
- }
-
- if (ohci->rhport[i].ctrl & val)
- ret = 0;
-
- /* set the bit */
- ohci->rhport[i].ctrl |= val;
-
- return ret;
-}
-
-/* Set the frame interval - frame interval toggle is manipulated by the hcd only */
-static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
-{
- val &= OHCI_FMI_FI;
-
- if (val != ohci->fi) {
- dprintf("usb-ohci: %s: FrameInterval = 0x%x (%u)\n",
- ohci->name, ohci->fi, ohci->fi);
- }
-
- ohci->fi = val;
-}
-
-static void ohci_port_power(OHCIState *ohci, int i, int p)
-{
- if (p) {
- ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
- } else {
- ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS|
- OHCI_PORT_CCS|
- OHCI_PORT_PSS|
- OHCI_PORT_PRS);
- }
-}
-
-/* Set HcControlRegister */
-static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
-{
- uint32_t old_state;
- uint32_t new_state;
-
- old_state = ohci->ctl & OHCI_CTL_HCFS;
- ohci->ctl = val;
- new_state = ohci->ctl & OHCI_CTL_HCFS;
-
- /* no state change */
- if (old_state == new_state)
- return;
-
- switch (new_state) {
- case OHCI_USB_OPERATIONAL:
- ohci_bus_start(ohci);
- break;
- case OHCI_USB_SUSPEND:
- ohci_bus_stop(ohci);
- dprintf("usb-ohci: %s: USB Suspended\n", ohci->name);
- break;
- case OHCI_USB_RESUME:
- dprintf("usb-ohci: %s: USB Resume\n", ohci->name);
- break;
- case OHCI_USB_RESET:
- ohci_reset(ohci);
- dprintf("usb-ohci: %s: USB Reset\n", ohci->name);
- break;
- }
-}
-
-static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
-{
- uint16_t fr;
- int64_t tks;
-
- if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL)
- return (ohci->frt << 31);
-
- /* Being in USB operational state guarnatees sof_time was
- * set already.
- */
- tks = qemu_get_clock(vm_clock) - ohci->sof_time;
-
- /* avoid muldiv if possible */
- if (tks >= usb_frame_time)
- return (ohci->frt << 31);
-
- tks = muldiv64(1, tks, usb_bit_time);
- fr = (uint16_t)(ohci->fi - tks);
-
- return (ohci->frt << 31) | fr;
-}
-
-
-/* Set root hub status */
-static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
-{
- uint32_t old_state;
-
- old_state = ohci->rhstatus;
-
- /* write 1 to clear OCIC */
- if (val & OHCI_RHS_OCIC)
- ohci->rhstatus &= ~OHCI_RHS_OCIC;
-
- if (val & OHCI_RHS_LPS) {
- int i;
-
- for (i = 0; i < ohci->num_ports; i++)
- ohci_port_power(ohci, i, 0);
- dprintf("usb-ohci: powered down all ports\n");
- }
-
- if (val & OHCI_RHS_LPSC) {
- int i;
-
- for (i = 0; i < ohci->num_ports; i++)
- ohci_port_power(ohci, i, 1);
- dprintf("usb-ohci: powered up all ports\n");
- }
-
- if (val & OHCI_RHS_DRWE)
- ohci->rhstatus |= OHCI_RHS_DRWE;
-
- if (val & OHCI_RHS_CRWE)
- ohci->rhstatus &= ~OHCI_RHS_DRWE;
-
- if (old_state != ohci->rhstatus)
- ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
-}
-
-/* Set root hub port status */
-static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
-{
- uint32_t old_state;
- OHCIPort *port;
-
- port = &ohci->rhport[portnum];
- old_state = port->ctrl;
-
- /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */
- if (val & OHCI_PORT_WTC)
- port->ctrl &= ~(val & OHCI_PORT_WTC);
-
- if (val & OHCI_PORT_CCS)
- port->ctrl &= ~OHCI_PORT_PES;
-
- ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
-
- if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS))
- dprintf("usb-ohci: port %d: SUSPEND\n", portnum);
-
- if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
- dprintf("usb-ohci: port %d: RESET\n", portnum);
- usb_send_msg(port->port.dev, USB_MSG_RESET);
- port->ctrl &= ~OHCI_PORT_PRS;
- /* ??? Should this also set OHCI_PORT_PESC. */
- port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
- }
-
- /* Invert order here to ensure in ambiguous case, device is
- * powered up...
- */
- if (val & OHCI_PORT_LSDA)
- ohci_port_power(ohci, portnum, 0);
- if (val & OHCI_PORT_PPS)
- ohci_port_power(ohci, portnum, 1);
-
- if (old_state != port->ctrl)
- ohci_set_interrupt(ohci, OHCI_INTR_RHSC);
-
- return;
-}
-
-static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr)
-{
- OHCIState *ohci = ptr;
-
- addr -= ohci->mem_base;
-
- /* Only aligned reads are allowed on OHCI */
- if (addr & 3) {
- fprintf(stderr, "usb-ohci: Mis-aligned read\n");
- return 0xffffffff;
- }
-
- if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
- /* HcRhPortStatus */
- return ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
- }
-
- switch (addr >> 2) {
- case 0: /* HcRevision */
- return 0x10;
-
- case 1: /* HcControl */
- return ohci->ctl;
-
- case 2: /* HcCommandStatus */
- return ohci->status;
-
- case 3: /* HcInterruptStatus */
- return ohci->intr_status;
-
- case 4: /* HcInterruptEnable */
- case 5: /* HcInterruptDisable */
- return ohci->intr;
-
- case 6: /* HcHCCA */
- return ohci->hcca;
-
- case 7: /* HcPeriodCurrentED */
- return ohci->per_cur;
-
- case 8: /* HcControlHeadED */
- return ohci->ctrl_head;
-
- case 9: /* HcControlCurrentED */
- return ohci->ctrl_cur;
-
- case 10: /* HcBulkHeadED */
- return ohci->bulk_head;
-
- case 11: /* HcBulkCurrentED */
- return ohci->bulk_cur;
-
- case 12: /* HcDoneHead */
- return ohci->done;
-
- case 13: /* HcFmInterval */
- return (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi);
-
- case 14: /* HcFmRemaining */
- return ohci_get_frame_remaining(ohci);
-
- case 15: /* HcFmNumber */
- return ohci->frame_number;
-
- case 16: /* HcPeriodicStart */
- return ohci->pstart;
-
- case 17: /* HcLSThreshold */
- return ohci->lst;
-
- case 18: /* HcRhDescriptorA */
- return ohci->rhdesc_a;
-
- case 19: /* HcRhDescriptorB */
- return ohci->rhdesc_b;
-
- case 20: /* HcRhStatus */
- return ohci->rhstatus;
-
- /* PXA27x specific registers */
- case 24: /* HcStatus */
- return ohci->hstatus & ohci->hmask;
-
- case 25: /* HcHReset */
- return ohci->hreset;
-
- case 26: /* HcHInterruptEnable */
- return ohci->hmask;
-
- case 27: /* HcHInterruptTest */
- return ohci->htest;
-
- default:
- fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr);
- return 0xffffffff;
- }
-}
-
-static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val)
-{
- OHCIState *ohci = ptr;
-
- addr -= ohci->mem_base;
-
- /* Only aligned reads are allowed on OHCI */
- if (addr & 3) {
- fprintf(stderr, "usb-ohci: Mis-aligned write\n");
- return;
- }
-
- if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
- /* HcRhPortStatus */
- ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
- return;
- }
-
- switch (addr >> 2) {
- case 1: /* HcControl */
- ohci_set_ctl(ohci, val);
- break;
-
- case 2: /* HcCommandStatus */
- /* SOC is read-only */
- val = (val & ~OHCI_STATUS_SOC);
-
- /* Bits written as '0' remain unchanged in the register */
- ohci->status |= val;
-
- if (ohci->status & OHCI_STATUS_HCR)
- ohci_reset(ohci);
- break;
-
- case 3: /* HcInterruptStatus */
- ohci->intr_status &= ~val;
- ohci_intr_update(ohci);
- break;
-
- case 4: /* HcInterruptEnable */
- ohci->intr |= val;
- ohci_intr_update(ohci);
- break;
-
- case 5: /* HcInterruptDisable */
- ohci->intr &= ~val;
- ohci_intr_update(ohci);
- break;
-
- case 6: /* HcHCCA */
- ohci->hcca = val & OHCI_HCCA_MASK;
- break;
-
- case 8: /* HcControlHeadED */
- ohci->ctrl_head = val & OHCI_EDPTR_MASK;
- break;
-
- case 9: /* HcControlCurrentED */
- ohci->ctrl_cur = val & OHCI_EDPTR_MASK;
- break;
-
- case 10: /* HcBulkHeadED */
- ohci->bulk_head = val & OHCI_EDPTR_MASK;
- break;
-
- case 11: /* HcBulkCurrentED */
- ohci->bulk_cur = val & OHCI_EDPTR_MASK;
- break;
-
- case 13: /* HcFmInterval */
- ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16;
- ohci->fit = (val & OHCI_FMI_FIT) >> 31;
- ohci_set_frame_interval(ohci, val);
- break;
-
- case 15: /* HcFmNumber */
- break;
-
- case 16: /* HcPeriodicStart */
- ohci->pstart = val & 0xffff;
- break;
-
- case 17: /* HcLSThreshold */
- ohci->lst = val & 0xffff;
- break;
-
- case 18: /* HcRhDescriptorA */
- ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK;
- ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK;
- break;
-
- case 19: /* HcRhDescriptorB */
- break;
-
- case 20: /* HcRhStatus */
- ohci_set_hub_status(ohci, val);
- break;
-
- /* PXA27x specific registers */
- case 24: /* HcStatus */
- ohci->hstatus &= ~(val & ohci->hmask);
-
- case 25: /* HcHReset */
- ohci->hreset = val & ~OHCI_HRESET_FSBIR;
- if (val & OHCI_HRESET_FSBIR)
- ohci_reset(ohci);
- break;
-
- case 26: /* HcHInterruptEnable */
- ohci->hmask = val;
- break;
-
- case 27: /* HcHInterruptTest */
- ohci->htest = val;
- break;
-
- default:
- fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr);
- break;
- }
-}
-
-/* Only dword reads are defined on OHCI register space */
-static CPUReadMemoryFunc *ohci_readfn[3]={
- ohci_mem_read,
- ohci_mem_read,
- ohci_mem_read
-};
-
-/* Only dword writes are defined on OHCI register space */
-static CPUWriteMemoryFunc *ohci_writefn[3]={
- ohci_mem_write,
- ohci_mem_write,
- ohci_mem_write
-};
-
-static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
- qemu_irq irq, enum ohci_type type, const char *name)
-{
- int i;
-
- if (usb_frame_time == 0) {
-#ifdef OHCI_TIME_WARP
- usb_frame_time = ticks_per_sec;
- usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ/1000);
-#else
- usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
- if (ticks_per_sec >= USB_HZ) {
- usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
- } else {
- usb_bit_time = 1;
- }
-#endif
- dprintf("usb-ohci: usb_bit_time=%lli usb_frame_time=%lli\n",
- usb_frame_time, usb_bit_time);
- }
-
- ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
- ohci->name = name;
-
- ohci->irq = irq;
- ohci->type = type;
-
- ohci->num_ports = num_ports;
- for (i = 0; i < num_ports; i++) {
- qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
- }
-
- ohci->async_td = 0;
- qemu_register_reset(ohci_reset, ohci);
- ohci_reset(ohci);
-}
-
-typedef struct {
- PCIDevice pci_dev;
- OHCIState state;
-} OHCIPCIState;
-
-static void ohci_mapfunc(PCIDevice *pci_dev, int i,
- uint32_t addr, uint32_t size, int type)
-{
- OHCIPCIState *ohci = (OHCIPCIState *)pci_dev;
- ohci->state.mem_base = addr;
- cpu_register_physical_memory(addr, size, ohci->state.mem);
-}
-
-void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn)
-{
- OHCIPCIState *ohci;
- int vid = 0x106b;
- int did = 0x003f;
-
- ohci = (OHCIPCIState *)pci_register_device(bus, "OHCI USB", sizeof(*ohci),
- devfn, NULL, NULL);
- if (ohci == NULL) {
- fprintf(stderr, "usb-ohci: Failed to register PCI device\n");
- return;
- }
-
- ohci->pci_dev.config[0x00] = vid & 0xff;
- ohci->pci_dev.config[0x01] = (vid >> 8) & 0xff;
- ohci->pci_dev.config[0x02] = did & 0xff;
- ohci->pci_dev.config[0x03] = (did >> 8) & 0xff;
- ohci->pci_dev.config[0x09] = 0x10; /* OHCI */
- ohci->pci_dev.config[0x0a] = 0x3;
- ohci->pci_dev.config[0x0b] = 0xc;
- ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
-
- usb_ohci_init(&ohci->state, num_ports, devfn, ohci->pci_dev.irq[0],
- OHCI_TYPE_PCI, ohci->pci_dev.name);
-
- pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
- PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
-}
-
-void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
- qemu_irq irq)
-{
- OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
-
- usb_ohci_init(ohci, num_ports, devfn, irq,
- OHCI_TYPE_PXA, "OHCI USB");
- ohci->mem_base = base;
-
- cpu_register_physical_memory(ohci->mem_base, 0x1000, ohci->mem);
-}
diff --git a/hw/usb.c b/hw/usb.c
deleted file mode 100644
index c17266d..0000000
--- a/hw/usb.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * QEMU USB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * 2008 Generic packet handler rewrite by Max Krasnyansky
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "usb.h"
-
-void usb_attach(USBPort *port, USBDevice *dev)
-{
- port->attach(port, dev);
-}
-
-/**********************/
-
-/* generic USB device helpers (you are not forced to use them when
- writing your USB device driver, but they help handling the
- protocol)
-*/
-
-#define SETUP_STATE_IDLE 0
-#define SETUP_STATE_DATA 1
-#define SETUP_STATE_ACK 2
-
-static int do_token_setup(USBDevice *s, USBPacket *p)
-{
- int request, value, index;
- int ret = 0;
-
- if (p->len != 8)
- return USB_RET_STALL;
-
- memcpy(s->setup_buf, p->data, 8);
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
- s->setup_index = 0;
-
- request = (s->setup_buf[0] << 8) | s->setup_buf[1];
- value = (s->setup_buf[3] << 8) | s->setup_buf[2];
- index = (s->setup_buf[5] << 8) | s->setup_buf[4];
-
- if (s->setup_buf[0] & USB_DIR_IN) {
- ret = s->handle_control(s, request, value, index,
- s->setup_len, s->data_buf);
- if (ret < 0)
- return ret;
-
- if (ret < s->setup_len)
- s->setup_len = ret;
- s->setup_state = SETUP_STATE_DATA;
- } else {
- if (s->setup_len == 0)
- s->setup_state = SETUP_STATE_ACK;
- else
- s->setup_state = SETUP_STATE_DATA;
- }
-
- return ret;
-}
-
-static int do_token_in(USBDevice *s, USBPacket *p)
-{
- int request, value, index;
- int ret = 0;
-
- if (p->devep != 0)
- return s->handle_data(s, p);
-
- request = (s->setup_buf[0] << 8) | s->setup_buf[1];
- value = (s->setup_buf[3] << 8) | s->setup_buf[2];
- index = (s->setup_buf[5] << 8) | s->setup_buf[4];
-
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- s->setup_state = SETUP_STATE_IDLE;
- ret = s->handle_control(s, request, value, index,
- s->setup_len, s->data_buf);
- if (ret > 0)
- return 0;
- return ret;
- }
-
- /* return 0 byte */
- return 0;
-
- case SETUP_STATE_DATA:
- if (s->setup_buf[0] & USB_DIR_IN) {
- int len = s->setup_len - s->setup_index;
- if (len > p->len)
- len = p->len;
- memcpy(p->data, s->data_buf + s->setup_index, len);
- s->setup_index += len;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- return len;
- }
-
- s->setup_state = SETUP_STATE_IDLE;
- return USB_RET_STALL;
-
- default:
- return USB_RET_STALL;
- }
-}
-
-static int do_token_out(USBDevice *s, USBPacket *p)
-{
- if (p->devep != 0)
- return s->handle_data(s, p);
-
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (s->setup_buf[0] & USB_DIR_IN) {
- s->setup_state = SETUP_STATE_IDLE;
- /* transfer OK */
- } else {
- /* ignore additional output */
- }
- return 0;
-
- case SETUP_STATE_DATA:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- int len = s->setup_len - s->setup_index;
- if (len > p->len)
- len = p->len;
- memcpy(s->data_buf + s->setup_index, p->data, len);
- s->setup_index += len;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- return len;
- }
-
- s->setup_state = SETUP_STATE_IDLE;
- return USB_RET_STALL;
-
- default:
- return USB_RET_STALL;
- }
-}
-
-/*
- * Generic packet handler.
- * Called by the HC (host controller).
- *
- * Returns length of the transaction or one of the USB_RET_XXX codes.
- */
-int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
-{
- switch(p->pid) {
- case USB_MSG_ATTACH:
- s->state = USB_STATE_ATTACHED;
- return 0;
-
- case USB_MSG_DETACH:
- s->state = USB_STATE_NOTATTACHED;
- return 0;
-
- case USB_MSG_RESET:
- s->remote_wakeup = 0;
- s->addr = 0;
- s->state = USB_STATE_DEFAULT;
- s->handle_reset(s);
- return 0;
- }
-
- /* Rest of the PIDs must match our address */
- if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
- return USB_RET_NODEV;
-
- switch (p->pid) {
- case USB_TOKEN_SETUP:
- return do_token_setup(s, p);
-
- case USB_TOKEN_IN:
- return do_token_in(s, p);
-
- case USB_TOKEN_OUT:
- return do_token_out(s, p);
-
- default:
- return USB_RET_STALL;
- }
-}
-
-/* XXX: fix overflow */
-int set_usb_string(uint8_t *buf, const char *str)
-{
- int len, i;
- uint8_t *q;
-
- q = buf;
- len = strlen(str);
- *q++ = 2 * len + 2;
- *q++ = 3;
- for(i = 0; i < len; i++) {
- *q++ = str[i];
- *q++ = 0;
- }
- return q - buf;
-}
-
-/* Send an internal message to a USB device. */
-void usb_send_msg(USBDevice *dev, int msg)
-{
- USBPacket p;
- memset(&p, 0, sizeof(p));
- p.pid = msg;
- dev->handle_packet(dev, &p);
-
- /* This _must_ be synchronous */
-}
diff --git a/hw/usb.h b/hw/usb.h
deleted file mode 100644
index 1a353bb..0000000
--- a/hw/usb.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * QEMU USB API
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define USB_TOKEN_SETUP 0x2d
-#define USB_TOKEN_IN 0x69 /* device -> host */
-#define USB_TOKEN_OUT 0xe1 /* host -> device */
-
-/* specific usb messages, also sent in the 'pid' parameter */
-#define USB_MSG_ATTACH 0x100
-#define USB_MSG_DETACH 0x101
-#define USB_MSG_RESET 0x102
-
-#define USB_RET_NODEV (-1)
-#define USB_RET_NAK (-2)
-#define USB_RET_STALL (-3)
-#define USB_RET_BABBLE (-4)
-#define USB_RET_ASYNC (-5)
-
-#define USB_SPEED_LOW 0
-#define USB_SPEED_FULL 1
-#define USB_SPEED_HIGH 2
-
-#define USB_STATE_NOTATTACHED 0
-#define USB_STATE_ATTACHED 1
-//#define USB_STATE_POWERED 2
-#define USB_STATE_DEFAULT 3
-//#define USB_STATE_ADDRESS 4
-//#define USB_STATE_CONFIGURED 5
-#define USB_STATE_SUSPENDED 6
-
-#define USB_CLASS_AUDIO 1
-#define USB_CLASS_COMM 2
-#define USB_CLASS_HID 3
-#define USB_CLASS_PHYSICAL 5
-#define USB_CLASS_STILL_IMAGE 6
-#define USB_CLASS_PRINTER 7
-#define USB_CLASS_MASS_STORAGE 8
-#define USB_CLASS_HUB 9
-#define USB_CLASS_CDC_DATA 0x0a
-#define USB_CLASS_CSCID 0x0b
-#define USB_CLASS_CONTENT_SEC 0x0d
-#define USB_CLASS_APP_SPEC 0xfe
-#define USB_CLASS_VENDOR_SPEC 0xff
-
-#define USB_DIR_OUT 0
-#define USB_DIR_IN 0x80
-
-#define USB_TYPE_MASK (0x03 << 5)
-#define USB_TYPE_STANDARD (0x00 << 5)
-#define USB_TYPE_CLASS (0x01 << 5)
-#define USB_TYPE_VENDOR (0x02 << 5)
-#define USB_TYPE_RESERVED (0x03 << 5)
-
-#define USB_RECIP_MASK 0x1f
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
-
-#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define InterfaceRequest \
- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define InterfaceOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-#define EndpointOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-
-#define USB_REQ_GET_STATUS 0x00
-#define USB_REQ_CLEAR_FEATURE 0x01
-#define USB_REQ_SET_FEATURE 0x03
-#define USB_REQ_SET_ADDRESS 0x05
-#define USB_REQ_GET_DESCRIPTOR 0x06
-#define USB_REQ_SET_DESCRIPTOR 0x07
-#define USB_REQ_GET_CONFIGURATION 0x08
-#define USB_REQ_SET_CONFIGURATION 0x09
-#define USB_REQ_GET_INTERFACE 0x0A
-#define USB_REQ_SET_INTERFACE 0x0B
-#define USB_REQ_SYNCH_FRAME 0x0C
-
-#define USB_DEVICE_SELF_POWERED 0
-#define USB_DEVICE_REMOTE_WAKEUP 1
-
-#define USB_DT_DEVICE 0x01
-#define USB_DT_CONFIG 0x02
-#define USB_DT_STRING 0x03
-#define USB_DT_INTERFACE 0x04
-#define USB_DT_ENDPOINT 0x05
-
-#define USB_ENDPOINT_XFER_CONTROL 0
-#define USB_ENDPOINT_XFER_ISOC 1
-#define USB_ENDPOINT_XFER_BULK 2
-#define USB_ENDPOINT_XFER_INT 3
-
-typedef struct USBPort USBPort;
-typedef struct USBDevice USBDevice;
-typedef struct USBPacket USBPacket;
-
-/* definition of a USB device */
-struct USBDevice {
- void *opaque;
-
- /*
- * Process USB packet.
- * Called by the HC (Host Controller).
- *
- * Returns length of the transaction
- * or one of the USB_RET_XXX codes.
- */
- int (*handle_packet)(USBDevice *dev, USBPacket *p);
-
- /*
- * Called when device is destroyed.
- */
- void (*handle_destroy)(USBDevice *dev);
-
- int speed;
-
- /* The following fields are used by the generic USB device
- layer. They are here just to avoid creating a new structure
- for them. */
-
- /*
- * Reset the device
- */
- void (*handle_reset)(USBDevice *dev);
-
- /*
- * Process control request.
- * Called from handle_packet().
- *
- * Returns length or one of the USB_RET_ codes.
- */
- int (*handle_control)(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data);
-
- /*
- * Process data transfers (both BULK and ISOC).
- * Called from handle_packet().
- *
- * Returns length or one of the USB_RET_ codes.
- */
- int (*handle_data)(USBDevice *dev, USBPacket *p);
-
- uint8_t addr;
- char devname[32];
-
- int state;
- uint8_t setup_buf[8];
- uint8_t data_buf[1024];
- int remote_wakeup;
- int setup_state;
- int setup_len;
- int setup_index;
-};
-
-typedef void (*usb_attachfn)(USBPort *port, USBDevice *dev);
-
-/* USB port on which a device can be connected */
-struct USBPort {
- USBDevice *dev;
- usb_attachfn attach;
- void *opaque;
- int index; /* internal port index, may be used with the opaque */
- struct USBPort *next; /* Used internally by qemu. */
-};
-
-typedef void USBCallback(USBPacket * packet, void *opaque);
-
-/* Structure used to hold information about an active USB packet. */
-struct USBPacket {
- /* Data fields for use by the driver. */
- int pid;
- uint8_t devaddr;
- uint8_t devep;
- uint8_t *data;
- int len;
- /* Internal use by the USB layer. */
- USBCallback *complete_cb;
- void *complete_opaque;
- USBCallback *cancel_cb;
- void *cancel_opaque;
-};
-
-/* Defer completion of a USB packet. The hadle_packet routine should then
- return USB_RET_ASYNC. Packets that complete immediately (before
- handle_packet returns) should not call this method. */
-static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel,
- void * opaque)
-{
- p->cancel_cb = cancel;
- p->cancel_opaque = opaque;
-}
-
-/* Notify the controller that an async packet is complete. This should only
- be called for packets previously deferred with usb_defer_packet, and
- should never be called from within handle_packet. */
-static inline void usb_packet_complete(USBPacket *p)
-{
- p->complete_cb(p, p->complete_opaque);
-}
-
-/* Cancel an active packet. The packed must have been deferred with
- usb_defer_packet, and not yet completed. */
-static inline void usb_cancel_packet(USBPacket * p)
-{
- p->cancel_cb(p, p->cancel_opaque);
-}
-
-int usb_device_add_dev(USBDevice *dev);
-int usb_device_del_addr(int bus_num, int addr);
-void usb_attach(USBPort *port, USBDevice *dev);
-int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
-int set_usb_string(uint8_t *buf, const char *str);
-void usb_send_msg(USBDevice *dev, int msg);
-
-/* usb hub */
-USBDevice *usb_hub_init(int nb_ports);
-
-/* usb-linux.c */
-USBDevice *usb_host_device_open(const char *devname);
-int usb_host_device_close(const char *devname);
-void usb_host_info(void);
-
-/* usb-hid.c */
-USBDevice *usb_mouse_init(void);
-USBDevice *usb_tablet_init(void);
-USBDevice *usb_keyboard_init(void);
-
-/* usb-msd.c */
-USBDevice *usb_msd_init(const char *filename);
-
-/* usb-net.c */
-USBDevice *usb_net_init(NICInfo *nd);
-
-/* usb-wacom.c */
-USBDevice *usb_wacom_init(void);
-
-/* usb-serial.c */
-USBDevice *usb_serial_init(const char *filename);
-
-/* usb ports of the VM */
-
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach);
-
-#define VM_USB_HUB_SIZE 8
-
-/* usb-musb.c */
-enum musb_irq_source_e {
- musb_irq_suspend = 0,
- musb_irq_resume,
- musb_irq_rst_babble,
- musb_irq_sof,
- musb_irq_connect,
- musb_irq_disconnect,
- musb_irq_vbus_request,
- musb_irq_vbus_error,
- musb_irq_rx,
- musb_irq_tx,
- musb_set_vbus,
- musb_set_session,
- __musb_irq_max,
-};
-
-struct musb_s;
-struct musb_s *musb_init(qemu_irq *irqs);
-uint32_t musb_core_intr_get(struct musb_s *s);
-void musb_core_intr_clear(struct musb_s *s, uint32_t mask);
-void musb_set_size(struct musb_s *s, int epnum, int size, int is_tx);
diff --git a/i386-dis.c b/i386-dis.c
deleted file mode 100644
index 7b44179..0000000
--- a/i386-dis.c
+++ /dev/null
@@ -1,4120 +0,0 @@
-/* Print i386 instructions for GDB, the GNU debugger.
- Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2001
- Free Software Foundation, Inc.
-
-This file is part of GDB.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/*
- * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
- * July 1988
- * modified by John Hassey (hassey@dg-rtp.dg.com)
- * x86-64 support added by Jan Hubicka (jh@suse.cz)
- */
-
-/*
- * The main tables describing the instructions is essentially a copy
- * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
- * Programmers Manual. Usually, there is a capital letter, followed
- * by a small letter. The capital letter tell the addressing mode,
- * and the small letter tells about the operand size. Refer to
- * the Intel manual for details.
- */
-
-#include <stdlib.h>
-#include "dis-asm.h"
-#include "qemu-common.h"
-
-#define MAXLEN 20
-
-#include <setjmp.h>
-
-#ifndef UNIXWARE_COMPAT
-/* Set non-zero for broken, compatible instructions. Set to zero for
- non-broken opcodes. */
-#define UNIXWARE_COMPAT 1
-#endif
-
-static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
-static void ckprefix PARAMS ((void));
-static const char *prefix_name PARAMS ((int, int));
-static int print_insn PARAMS ((bfd_vma, disassemble_info *));
-static void dofloat PARAMS ((int));
-static void OP_ST PARAMS ((int, int));
-static void OP_STi PARAMS ((int, int));
-static int putop PARAMS ((const char *, int));
-static void oappend PARAMS ((const char *));
-static void append_seg PARAMS ((void));
-static void OP_indirE PARAMS ((int, int));
-static void print_operand_value (char *buf, size_t bufsize, int hex,
- bfd_vma disp);
-static void OP_E PARAMS ((int, int));
-static void OP_G PARAMS ((int, int));
-static bfd_vma get64 PARAMS ((void));
-static bfd_signed_vma get32 PARAMS ((void));
-static bfd_signed_vma get32s PARAMS ((void));
-static int get16 PARAMS ((void));
-static void set_op PARAMS ((bfd_vma, int));
-static void OP_REG PARAMS ((int, int));
-static void OP_IMREG PARAMS ((int, int));
-static void OP_I PARAMS ((int, int));
-static void OP_I64 PARAMS ((int, int));
-static void OP_sI PARAMS ((int, int));
-static void OP_J PARAMS ((int, int));
-static void OP_SEG PARAMS ((int, int));
-static void OP_DIR PARAMS ((int, int));
-static void OP_OFF PARAMS ((int, int));
-static void OP_OFF64 PARAMS ((int, int));
-static void ptr_reg PARAMS ((int, int));
-static void OP_ESreg PARAMS ((int, int));
-static void OP_DSreg PARAMS ((int, int));
-static void OP_C PARAMS ((int, int));
-static void OP_D PARAMS ((int, int));
-static void OP_T PARAMS ((int, int));
-static void OP_Rd PARAMS ((int, int));
-static void OP_MMX PARAMS ((int, int));
-static void OP_XMM PARAMS ((int, int));
-static void OP_EM PARAMS ((int, int));
-static void OP_EX PARAMS ((int, int));
-static void OP_MS PARAMS ((int, int));
-static void OP_XS PARAMS ((int, int));
-static void OP_3DNowSuffix PARAMS ((int, int));
-static void OP_SIMD_Suffix PARAMS ((int, int));
-static void SIMD_Fixup PARAMS ((int, int));
-static void BadOp PARAMS ((void));
-
-struct dis_private {
- /* Points to first byte not fetched. */
- bfd_byte *max_fetched;
- bfd_byte the_buffer[MAXLEN];
- bfd_vma insn_start;
- int orig_sizeflag;
- jmp_buf bailout;
-};
-
-/* The opcode for the fwait instruction, which we treat as a prefix
- when we can. */
-#define FWAIT_OPCODE (0x9b)
-
-/* Set to 1 for 64bit mode disassembly. */
-static int mode_64bit;
-
-/* Flags for the prefixes for the current instruction. See below. */
-static int prefixes;
-
-/* REX prefix the current instruction. See below. */
-static int rex;
-/* Bits of REX we've already used. */
-static int rex_used;
-#define REX_MODE64 8
-#define REX_EXTX 4
-#define REX_EXTY 2
-#define REX_EXTZ 1
-/* Mark parts used in the REX prefix. When we are testing for
- empty prefix (for 8bit register REX extension), just mask it
- out. Otherwise test for REX bit is excuse for existence of REX
- only in case value is nonzero. */
-#define USED_REX(value) \
- { \
- if (value) \
- rex_used |= (rex & value) ? (value) | 0x40 : 0; \
- else \
- rex_used |= 0x40; \
- }
-
-/* Flags for prefixes which we somehow handled when printing the
- current instruction. */
-static int used_prefixes;
-
-/* Flags stored in PREFIXES. */
-#define PREFIX_REPZ 1
-#define PREFIX_REPNZ 2
-#define PREFIX_LOCK 4
-#define PREFIX_CS 8
-#define PREFIX_SS 0x10
-#define PREFIX_DS 0x20
-#define PREFIX_ES 0x40
-#define PREFIX_FS 0x80
-#define PREFIX_GS 0x100
-#define PREFIX_DATA 0x200
-#define PREFIX_ADDR 0x400
-#define PREFIX_FWAIT 0x800
-
-/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
- to ADDR (exclusive) are valid. Returns 1 for success, longjmps
- on error. */
-#define FETCH_DATA(info, addr) \
- ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
- ? 1 : fetch_data ((info), (addr)))
-
-static int
-fetch_data (info, addr)
- struct disassemble_info *info;
- bfd_byte *addr;
-{
- int status;
- struct dis_private *priv = (struct dis_private *) info->private_data;
- bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
-
- status = (*info->read_memory_func) (start,
- priv->max_fetched,
- addr - priv->max_fetched,
- info);
- if (status != 0)
- {
- /* If we did manage to read at least one byte, then
- print_insn_i386 will do something sensible. Otherwise, print
- an error. We do that here because this is where we know
- STATUS. */
- if (priv->max_fetched == priv->the_buffer)
- (*info->memory_error_func) (status, start, info);
- longjmp (priv->bailout, 1);
- }
- else
- priv->max_fetched = addr;
- return 1;
-}
-
-#define XX NULL, 0
-
-#define Eb OP_E, b_mode
-#define Ev OP_E, v_mode
-#define Ed OP_E, d_mode
-#define indirEb OP_indirE, b_mode
-#define indirEv OP_indirE, v_mode
-#define Ew OP_E, w_mode
-#define Ma OP_E, v_mode
-#define M OP_E, 0 /* lea, lgdt, etc. */
-#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
-#define Gb OP_G, b_mode
-#define Gv OP_G, v_mode
-#define Gd OP_G, d_mode
-#define Gw OP_G, w_mode
-#define Rd OP_Rd, d_mode
-#define Rm OP_Rd, m_mode
-#define Ib OP_I, b_mode
-#define sIb OP_sI, b_mode /* sign extened byte */
-#define Iv OP_I, v_mode
-#define Iq OP_I, q_mode
-#define Iv64 OP_I64, v_mode
-#define Iw OP_I, w_mode
-#define Jb OP_J, b_mode
-#define Jv OP_J, v_mode
-#define Cm OP_C, m_mode
-#define Dm OP_D, m_mode
-#define Td OP_T, d_mode
-
-#define RMeAX OP_REG, eAX_reg
-#define RMeBX OP_REG, eBX_reg
-#define RMeCX OP_REG, eCX_reg
-#define RMeDX OP_REG, eDX_reg
-#define RMeSP OP_REG, eSP_reg
-#define RMeBP OP_REG, eBP_reg
-#define RMeSI OP_REG, eSI_reg
-#define RMeDI OP_REG, eDI_reg
-#define RMrAX OP_REG, rAX_reg
-#define RMrBX OP_REG, rBX_reg
-#define RMrCX OP_REG, rCX_reg
-#define RMrDX OP_REG, rDX_reg
-#define RMrSP OP_REG, rSP_reg
-#define RMrBP OP_REG, rBP_reg
-#define RMrSI OP_REG, rSI_reg
-#define RMrDI OP_REG, rDI_reg
-#define RMAL OP_REG, al_reg
-#define RMAL OP_REG, al_reg
-#define RMCL OP_REG, cl_reg
-#define RMDL OP_REG, dl_reg
-#define RMBL OP_REG, bl_reg
-#define RMAH OP_REG, ah_reg
-#define RMCH OP_REG, ch_reg
-#define RMDH OP_REG, dh_reg
-#define RMBH OP_REG, bh_reg
-#define RMAX OP_REG, ax_reg
-#define RMDX OP_REG, dx_reg
-
-#define eAX OP_IMREG, eAX_reg
-#define eBX OP_IMREG, eBX_reg
-#define eCX OP_IMREG, eCX_reg
-#define eDX OP_IMREG, eDX_reg
-#define eSP OP_IMREG, eSP_reg
-#define eBP OP_IMREG, eBP_reg
-#define eSI OP_IMREG, eSI_reg
-#define eDI OP_IMREG, eDI_reg
-#define AL OP_IMREG, al_reg
-#define AL OP_IMREG, al_reg
-#define CL OP_IMREG, cl_reg
-#define DL OP_IMREG, dl_reg
-#define BL OP_IMREG, bl_reg
-#define AH OP_IMREG, ah_reg
-#define CH OP_IMREG, ch_reg
-#define DH OP_IMREG, dh_reg
-#define BH OP_IMREG, bh_reg
-#define AX OP_IMREG, ax_reg
-#define DX OP_IMREG, dx_reg
-#define indirDX OP_IMREG, indir_dx_reg
-
-#define Sw OP_SEG, w_mode
-#define Ap OP_DIR, 0
-#define Ob OP_OFF, b_mode
-#define Ob64 OP_OFF64, b_mode
-#define Ov OP_OFF, v_mode
-#define Ov64 OP_OFF64, v_mode
-#define Xb OP_DSreg, eSI_reg
-#define Xv OP_DSreg, eSI_reg
-#define Yb OP_ESreg, eDI_reg
-#define Yv OP_ESreg, eDI_reg
-#define DSBX OP_DSreg, eBX_reg
-
-#define es OP_REG, es_reg
-#define ss OP_REG, ss_reg
-#define cs OP_REG, cs_reg
-#define ds OP_REG, ds_reg
-#define fs OP_REG, fs_reg
-#define gs OP_REG, gs_reg
-
-#define MX OP_MMX, 0
-#define XM OP_XMM, 0
-#define EM OP_EM, v_mode
-#define EX OP_EX, v_mode
-#define MS OP_MS, v_mode
-#define XS OP_XS, v_mode
-#define None OP_E, 0
-#define OPSUF OP_3DNowSuffix, 0
-#define OPSIMD OP_SIMD_Suffix, 0
-
-#define cond_jump_flag NULL, cond_jump_mode
-#define loop_jcxz_flag NULL, loop_jcxz_mode
-
-/* bits in sizeflag */
-#define SUFFIX_ALWAYS 4
-#define AFLAG 2
-#define DFLAG 1
-
-#define b_mode 1 /* byte operand */
-#define v_mode 2 /* operand size depends on prefixes */
-#define w_mode 3 /* word operand */
-#define d_mode 4 /* double word operand */
-#define q_mode 5 /* quad word operand */
-#define x_mode 6
-#define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
-#define cond_jump_mode 8
-#define loop_jcxz_mode 9
-
-#define es_reg 100
-#define cs_reg 101
-#define ss_reg 102
-#define ds_reg 103
-#define fs_reg 104
-#define gs_reg 105
-
-#define eAX_reg 108
-#define eCX_reg 109
-#define eDX_reg 110
-#define eBX_reg 111
-#define eSP_reg 112
-#define eBP_reg 113
-#define eSI_reg 114
-#define eDI_reg 115
-
-#define al_reg 116
-#define cl_reg 117
-#define dl_reg 118
-#define bl_reg 119
-#define ah_reg 120
-#define ch_reg 121
-#define dh_reg 122
-#define bh_reg 123
-
-#define ax_reg 124
-#define cx_reg 125
-#define dx_reg 126
-#define bx_reg 127
-#define sp_reg 128
-#define bp_reg 129
-#define si_reg 130
-#define di_reg 131
-
-#define rAX_reg 132
-#define rCX_reg 133
-#define rDX_reg 134
-#define rBX_reg 135
-#define rSP_reg 136
-#define rBP_reg 137
-#define rSI_reg 138
-#define rDI_reg 139
-
-#define indir_dx_reg 150
-
-#define FLOATCODE 1
-#define USE_GROUPS 2
-#define USE_PREFIX_USER_TABLE 3
-#define X86_64_SPECIAL 4
-
-#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
-
-#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
-#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
-#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
-#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
-#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
-#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
-#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
-#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
-#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
-#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
-#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
-#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
-#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
-#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
-#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
-#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
-#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
-#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
-#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
-#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
-#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
-#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
-#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
-
-#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
-#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
-#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
-#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
-#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
-#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
-#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
-#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
-#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
-#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
-#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
-#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
-#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
-#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
-#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
-#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
-#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
-#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
-#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
-#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
-#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
-#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
-#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
-#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
-#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
-#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
-#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
-
-#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
-
-typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
-
-struct dis386 {
- const char *name;
- op_rtn op1;
- int bytemode1;
- op_rtn op2;
- int bytemode2;
- op_rtn op3;
- int bytemode3;
-};
-
-/* Upper case letters in the instruction names here are macros.
- 'A' => print 'b' if no register operands or suffix_always is true
- 'B' => print 'b' if suffix_always is true
- 'E' => print 'e' if 32-bit form of jcxz
- 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
- 'H' => print ",pt" or ",pn" branch hint
- 'L' => print 'l' if suffix_always is true
- 'N' => print 'n' if instruction has no wait "prefix"
- 'O' => print 'd', or 'o'
- 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
- . or suffix_always is true. print 'q' if rex prefix is present.
- 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
- . is true
- 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
- 'S' => print 'w', 'l' or 'q' if suffix_always is true
- 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
- 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
- 'X' => print 's', 'd' depending on data16 prefix (for XMM)
- 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
- 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
-
- Many of the above letters print nothing in Intel mode. See "putop"
- for the details.
-
- Braces '{' and '}', and vertical bars '|', indicate alternative
- mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
- modes. In cases where there are only two alternatives, the X86_64
- instruction is reserved, and "(bad)" is printed.
-*/
-
-static const struct dis386 dis386[] = {
- /* 00 */
- { "addB", Eb, Gb, XX },
- { "addS", Ev, Gv, XX },
- { "addB", Gb, Eb, XX },
- { "addS", Gv, Ev, XX },
- { "addB", AL, Ib, XX },
- { "addS", eAX, Iv, XX },
- { "push{T|}", es, XX, XX },
- { "pop{T|}", es, XX, XX },
- /* 08 */
- { "orB", Eb, Gb, XX },
- { "orS", Ev, Gv, XX },
- { "orB", Gb, Eb, XX },
- { "orS", Gv, Ev, XX },
- { "orB", AL, Ib, XX },
- { "orS", eAX, Iv, XX },
- { "push{T|}", cs, XX, XX },
- { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
- /* 10 */
- { "adcB", Eb, Gb, XX },
- { "adcS", Ev, Gv, XX },
- { "adcB", Gb, Eb, XX },
- { "adcS", Gv, Ev, XX },
- { "adcB", AL, Ib, XX },
- { "adcS", eAX, Iv, XX },
- { "push{T|}", ss, XX, XX },
- { "popT|}", ss, XX, XX },
- /* 18 */
- { "sbbB", Eb, Gb, XX },
- { "sbbS", Ev, Gv, XX },
- { "sbbB", Gb, Eb, XX },
- { "sbbS", Gv, Ev, XX },
- { "sbbB", AL, Ib, XX },
- { "sbbS", eAX, Iv, XX },
- { "push{T|}", ds, XX, XX },
- { "pop{T|}", ds, XX, XX },
- /* 20 */
- { "andB", Eb, Gb, XX },
- { "andS", Ev, Gv, XX },
- { "andB", Gb, Eb, XX },
- { "andS", Gv, Ev, XX },
- { "andB", AL, Ib, XX },
- { "andS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG ES prefix */
- { "daa{|}", XX, XX, XX },
- /* 28 */
- { "subB", Eb, Gb, XX },
- { "subS", Ev, Gv, XX },
- { "subB", Gb, Eb, XX },
- { "subS", Gv, Ev, XX },
- { "subB", AL, Ib, XX },
- { "subS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG CS prefix */
- { "das{|}", XX, XX, XX },
- /* 30 */
- { "xorB", Eb, Gb, XX },
- { "xorS", Ev, Gv, XX },
- { "xorB", Gb, Eb, XX },
- { "xorS", Gv, Ev, XX },
- { "xorB", AL, Ib, XX },
- { "xorS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG SS prefix */
- { "aaa{|}", XX, XX, XX },
- /* 38 */
- { "cmpB", Eb, Gb, XX },
- { "cmpS", Ev, Gv, XX },
- { "cmpB", Gb, Eb, XX },
- { "cmpS", Gv, Ev, XX },
- { "cmpB", AL, Ib, XX },
- { "cmpS", eAX, Iv, XX },
- { "(bad)", XX, XX, XX }, /* SEG DS prefix */
- { "aas{|}", XX, XX, XX },
- /* 40 */
- { "inc{S|}", RMeAX, XX, XX },
- { "inc{S|}", RMeCX, XX, XX },
- { "inc{S|}", RMeDX, XX, XX },
- { "inc{S|}", RMeBX, XX, XX },
- { "inc{S|}", RMeSP, XX, XX },
- { "inc{S|}", RMeBP, XX, XX },
- { "inc{S|}", RMeSI, XX, XX },
- { "inc{S|}", RMeDI, XX, XX },
- /* 48 */
- { "dec{S|}", RMeAX, XX, XX },
- { "dec{S|}", RMeCX, XX, XX },
- { "dec{S|}", RMeDX, XX, XX },
- { "dec{S|}", RMeBX, XX, XX },
- { "dec{S|}", RMeSP, XX, XX },
- { "dec{S|}", RMeBP, XX, XX },
- { "dec{S|}", RMeSI, XX, XX },
- { "dec{S|}", RMeDI, XX, XX },
- /* 50 */
- { "pushS", RMrAX, XX, XX },
- { "pushS", RMrCX, XX, XX },
- { "pushS", RMrDX, XX, XX },
- { "pushS", RMrBX, XX, XX },
- { "pushS", RMrSP, XX, XX },
- { "pushS", RMrBP, XX, XX },
- { "pushS", RMrSI, XX, XX },
- { "pushS", RMrDI, XX, XX },
- /* 58 */
- { "popS", RMrAX, XX, XX },
- { "popS", RMrCX, XX, XX },
- { "popS", RMrDX, XX, XX },
- { "popS", RMrBX, XX, XX },
- { "popS", RMrSP, XX, XX },
- { "popS", RMrBP, XX, XX },
- { "popS", RMrSI, XX, XX },
- { "popS", RMrDI, XX, XX },
- /* 60 */
- { "pusha{P|}", XX, XX, XX },
- { "popa{P|}", XX, XX, XX },
- { "bound{S|}", Gv, Ma, XX },
- { X86_64_0 },
- { "(bad)", XX, XX, XX }, /* seg fs */
- { "(bad)", XX, XX, XX }, /* seg gs */
- { "(bad)", XX, XX, XX }, /* op size prefix */
- { "(bad)", XX, XX, XX }, /* adr size prefix */
- /* 68 */
- { "pushT", Iq, XX, XX },
- { "imulS", Gv, Ev, Iv },
- { "pushT", sIb, XX, XX },
- { "imulS", Gv, Ev, sIb },
- { "ins{b||b|}", Yb, indirDX, XX },
- { "ins{R||R|}", Yv, indirDX, XX },
- { "outs{b||b|}", indirDX, Xb, XX },
- { "outs{R||R|}", indirDX, Xv, XX },
- /* 70 */
- { "joH", Jb, XX, cond_jump_flag },
- { "jnoH", Jb, XX, cond_jump_flag },
- { "jbH", Jb, XX, cond_jump_flag },
- { "jaeH", Jb, XX, cond_jump_flag },
- { "jeH", Jb, XX, cond_jump_flag },
- { "jneH", Jb, XX, cond_jump_flag },
- { "jbeH", Jb, XX, cond_jump_flag },
- { "jaH", Jb, XX, cond_jump_flag },
- /* 78 */
- { "jsH", Jb, XX, cond_jump_flag },
- { "jnsH", Jb, XX, cond_jump_flag },
- { "jpH", Jb, XX, cond_jump_flag },
- { "jnpH", Jb, XX, cond_jump_flag },
- { "jlH", Jb, XX, cond_jump_flag },
- { "jgeH", Jb, XX, cond_jump_flag },
- { "jleH", Jb, XX, cond_jump_flag },
- { "jgH", Jb, XX, cond_jump_flag },
- /* 80 */
- { GRP1b },
- { GRP1S },
- { "(bad)", XX, XX, XX },
- { GRP1Ss },
- { "testB", Eb, Gb, XX },
- { "testS", Ev, Gv, XX },
- { "xchgB", Eb, Gb, XX },
- { "xchgS", Ev, Gv, XX },
- /* 88 */
- { "movB", Eb, Gb, XX },
- { "movS", Ev, Gv, XX },
- { "movB", Gb, Eb, XX },
- { "movS", Gv, Ev, XX },
- { "movQ", Ev, Sw, XX },
- { "leaS", Gv, M, XX },
- { "movQ", Sw, Ev, XX },
- { "popU", Ev, XX, XX },
- /* 90 */
- { "nop", XX, XX, XX },
- /* FIXME: NOP with REPz prefix is called PAUSE. */
- { "xchgS", RMeCX, eAX, XX },
- { "xchgS", RMeDX, eAX, XX },
- { "xchgS", RMeBX, eAX, XX },
- { "xchgS", RMeSP, eAX, XX },
- { "xchgS", RMeBP, eAX, XX },
- { "xchgS", RMeSI, eAX, XX },
- { "xchgS", RMeDI, eAX, XX },
- /* 98 */
- { "cW{tR||tR|}", XX, XX, XX },
- { "cR{tO||tO|}", XX, XX, XX },
- { "lcall{T|}", Ap, XX, XX },
- { "(bad)", XX, XX, XX }, /* fwait */
- { "pushfT", XX, XX, XX },
- { "popfT", XX, XX, XX },
- { "sahf{|}", XX, XX, XX },
- { "lahf{|}", XX, XX, XX },
- /* a0 */
- { "movB", AL, Ob64, XX },
- { "movS", eAX, Ov64, XX },
- { "movB", Ob64, AL, XX },
- { "movS", Ov64, eAX, XX },
- { "movs{b||b|}", Yb, Xb, XX },
- { "movs{R||R|}", Yv, Xv, XX },
- { "cmps{b||b|}", Xb, Yb, XX },
- { "cmps{R||R|}", Xv, Yv, XX },
- /* a8 */
- { "testB", AL, Ib, XX },
- { "testS", eAX, Iv, XX },
- { "stosB", Yb, AL, XX },
- { "stosS", Yv, eAX, XX },
- { "lodsB", AL, Xb, XX },
- { "lodsS", eAX, Xv, XX },
- { "scasB", AL, Yb, XX },
- { "scasS", eAX, Yv, XX },
- /* b0 */
- { "movB", RMAL, Ib, XX },
- { "movB", RMCL, Ib, XX },
- { "movB", RMDL, Ib, XX },
- { "movB", RMBL, Ib, XX },
- { "movB", RMAH, Ib, XX },
- { "movB", RMCH, Ib, XX },
- { "movB", RMDH, Ib, XX },
- { "movB", RMBH, Ib, XX },
- /* b8 */
- { "movS", RMeAX, Iv64, XX },
- { "movS", RMeCX, Iv64, XX },
- { "movS", RMeDX, Iv64, XX },
- { "movS", RMeBX, Iv64, XX },
- { "movS", RMeSP, Iv64, XX },
- { "movS", RMeBP, Iv64, XX },
- { "movS", RMeSI, Iv64, XX },
- { "movS", RMeDI, Iv64, XX },
- /* c0 */
- { GRP2b },
- { GRP2S },
- { "retT", Iw, XX, XX },
- { "retT", XX, XX, XX },
- { "les{S|}", Gv, Mp, XX },
- { "ldsS", Gv, Mp, XX },
- { "movA", Eb, Ib, XX },
- { "movQ", Ev, Iv, XX },
- /* c8 */
- { "enterT", Iw, Ib, XX },
- { "leaveT", XX, XX, XX },
- { "lretP", Iw, XX, XX },
- { "lretP", XX, XX, XX },
- { "int3", XX, XX, XX },
- { "int", Ib, XX, XX },
- { "into{|}", XX, XX, XX },
- { "iretP", XX, XX, XX },
- /* d0 */
- { GRP2b_one },
- { GRP2S_one },
- { GRP2b_cl },
- { GRP2S_cl },
- { "aam{|}", sIb, XX, XX },
- { "aad{|}", sIb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "xlat", DSBX, XX, XX },
- /* d8 */
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- { FLOAT },
- /* e0 */
- { "loopneFH", Jb, XX, loop_jcxz_flag },
- { "loopeFH", Jb, XX, loop_jcxz_flag },
- { "loopFH", Jb, XX, loop_jcxz_flag },
- { "jEcxzH", Jb, XX, loop_jcxz_flag },
- { "inB", AL, Ib, XX },
- { "inS", eAX, Ib, XX },
- { "outB", Ib, AL, XX },
- { "outS", Ib, eAX, XX },
- /* e8 */
- { "callT", Jv, XX, XX },
- { "jmpT", Jv, XX, XX },
- { "ljmp{T|}", Ap, XX, XX },
- { "jmp", Jb, XX, XX },
- { "inB", AL, indirDX, XX },
- { "inS", eAX, indirDX, XX },
- { "outB", indirDX, AL, XX },
- { "outS", indirDX, eAX, XX },
- /* f0 */
- { "(bad)", XX, XX, XX }, /* lock prefix */
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX }, /* repne */
- { "(bad)", XX, XX, XX }, /* repz */
- { "hlt", XX, XX, XX },
- { "cmc", XX, XX, XX },
- { GRP3b },
- { GRP3S },
- /* f8 */
- { "clc", XX, XX, XX },
- { "stc", XX, XX, XX },
- { "cli", XX, XX, XX },
- { "sti", XX, XX, XX },
- { "cld", XX, XX, XX },
- { "std", XX, XX, XX },
- { GRP4 },
- { GRP5 },
-};
-
-static const struct dis386 dis386_twobyte[] = {
- /* 00 */
- { GRP6 },
- { GRP7 },
- { "larS", Gv, Ew, XX },
- { "lslS", Gv, Ew, XX },
- { "(bad)", XX, XX, XX },
- { "syscall", XX, XX, XX },
- { "clts", XX, XX, XX },
- { "sysretP", XX, XX, XX },
- /* 08 */
- { "invd", XX, XX, XX },
- { "wbinvd", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "ud2a", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { GRPAMD },
- { "femms", XX, XX, XX },
- { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
- /* 10 */
- { PREGRP8 },
- { PREGRP9 },
- { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
- { "movlpX", EX, XM, SIMD_Fixup, 'h' },
- { "unpcklpX", XM, EX, XX },
- { "unpckhpX", XM, EX, XX },
- { "movhpX", XM, EX, SIMD_Fixup, 'l' },
- { "movhpX", EX, XM, SIMD_Fixup, 'l' },
- /* 18 */
- { GRP14 },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* 20 */
- { "movL", Rm, Cm, XX },
- { "movL", Rm, Dm, XX },
- { "movL", Cm, Rm, XX },
- { "movL", Dm, Rm, XX },
- { "movL", Rd, Td, XX },
- { "(bad)", XX, XX, XX },
- { "movL", Td, Rd, XX },
- { "(bad)", XX, XX, XX },
- /* 28 */
- { "movapX", XM, EX, XX },
- { "movapX", EX, XM, XX },
- { PREGRP2 },
- { "movntpX", Ev, XM, XX },
- { PREGRP4 },
- { PREGRP3 },
- { "ucomisX", XM,EX, XX },
- { "comisX", XM,EX, XX },
- /* 30 */
- { "wrmsr", XX, XX, XX },
- { "rdtsc", XX, XX, XX },
- { "rdmsr", XX, XX, XX },
- { "rdpmc", XX, XX, XX },
- { "sysenter", XX, XX, XX },
- { "sysexit", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* 38 */
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* 40 */
- { "cmovo", Gv, Ev, XX },
- { "cmovno", Gv, Ev, XX },
- { "cmovb", Gv, Ev, XX },
- { "cmovae", Gv, Ev, XX },
- { "cmove", Gv, Ev, XX },
- { "cmovne", Gv, Ev, XX },
- { "cmovbe", Gv, Ev, XX },
- { "cmova", Gv, Ev, XX },
- /* 48 */
- { "cmovs", Gv, Ev, XX },
- { "cmovns", Gv, Ev, XX },
- { "cmovp", Gv, Ev, XX },
- { "cmovnp", Gv, Ev, XX },
- { "cmovl", Gv, Ev, XX },
- { "cmovge", Gv, Ev, XX },
- { "cmovle", Gv, Ev, XX },
- { "cmovg", Gv, Ev, XX },
- /* 50 */
- { "movmskpX", Gd, XS, XX },
- { PREGRP13 },
- { PREGRP12 },
- { PREGRP11 },
- { "andpX", XM, EX, XX },
- { "andnpX", XM, EX, XX },
- { "orpX", XM, EX, XX },
- { "xorpX", XM, EX, XX },
- /* 58 */
- { PREGRP0 },
- { PREGRP10 },
- { PREGRP17 },
- { PREGRP16 },
- { PREGRP14 },
- { PREGRP7 },
- { PREGRP5 },
- { PREGRP6 },
- /* 60 */
- { "punpcklbw", MX, EM, XX },
- { "punpcklwd", MX, EM, XX },
- { "punpckldq", MX, EM, XX },
- { "packsswb", MX, EM, XX },
- { "pcmpgtb", MX, EM, XX },
- { "pcmpgtw", MX, EM, XX },
- { "pcmpgtd", MX, EM, XX },
- { "packuswb", MX, EM, XX },
- /* 68 */
- { "punpckhbw", MX, EM, XX },
- { "punpckhwd", MX, EM, XX },
- { "punpckhdq", MX, EM, XX },
- { "packssdw", MX, EM, XX },
- { PREGRP26 },
- { PREGRP24 },
- { "movd", MX, Ed, XX },
- { PREGRP19 },
- /* 70 */
- { PREGRP22 },
- { GRP10 },
- { GRP11 },
- { GRP12 },
- { "pcmpeqb", MX, EM, XX },
- { "pcmpeqw", MX, EM, XX },
- { "pcmpeqd", MX, EM, XX },
- { "emms", XX, XX, XX },
- /* 78 */
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { PREGRP23 },
- { PREGRP20 },
- /* 80 */
- { "joH", Jv, XX, cond_jump_flag },
- { "jnoH", Jv, XX, cond_jump_flag },
- { "jbH", Jv, XX, cond_jump_flag },
- { "jaeH", Jv, XX, cond_jump_flag },
- { "jeH", Jv, XX, cond_jump_flag },
- { "jneH", Jv, XX, cond_jump_flag },
- { "jbeH", Jv, XX, cond_jump_flag },
- { "jaH", Jv, XX, cond_jump_flag },
- /* 88 */
- { "jsH", Jv, XX, cond_jump_flag },
- { "jnsH", Jv, XX, cond_jump_flag },
- { "jpH", Jv, XX, cond_jump_flag },
- { "jnpH", Jv, XX, cond_jump_flag },
- { "jlH", Jv, XX, cond_jump_flag },
- { "jgeH", Jv, XX, cond_jump_flag },
- { "jleH", Jv, XX, cond_jump_flag },
- { "jgH", Jv, XX, cond_jump_flag },
- /* 90 */
- { "seto", Eb, XX, XX },
- { "setno", Eb, XX, XX },
- { "setb", Eb, XX, XX },
- { "setae", Eb, XX, XX },
- { "sete", Eb, XX, XX },
- { "setne", Eb, XX, XX },
- { "setbe", Eb, XX, XX },
- { "seta", Eb, XX, XX },
- /* 98 */
- { "sets", Eb, XX, XX },
- { "setns", Eb, XX, XX },
- { "setp", Eb, XX, XX },
- { "setnp", Eb, XX, XX },
- { "setl", Eb, XX, XX },
- { "setge", Eb, XX, XX },
- { "setle", Eb, XX, XX },
- { "setg", Eb, XX, XX },
- /* a0 */
- { "pushT", fs, XX, XX },
- { "popT", fs, XX, XX },
- { "cpuid", XX, XX, XX },
- { "btS", Ev, Gv, XX },
- { "shldS", Ev, Gv, Ib },
- { "shldS", Ev, Gv, CL },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- /* a8 */
- { "pushT", gs, XX, XX },
- { "popT", gs, XX, XX },
- { "rsm", XX, XX, XX },
- { "btsS", Ev, Gv, XX },
- { "shrdS", Ev, Gv, Ib },
- { "shrdS", Ev, Gv, CL },
- { GRP13 },
- { "imulS", Gv, Ev, XX },
- /* b0 */
- { "cmpxchgB", Eb, Gb, XX },
- { "cmpxchgS", Ev, Gv, XX },
- { "lssS", Gv, Mp, XX },
- { "btrS", Ev, Gv, XX },
- { "lfsS", Gv, Mp, XX },
- { "lgsS", Gv, Mp, XX },
- { "movz{bR|x|bR|x}", Gv, Eb, XX },
- { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
- /* b8 */
- { "(bad)", XX, XX, XX },
- { "ud2b", XX, XX, XX },
- { GRP8 },
- { "btcS", Ev, Gv, XX },
- { "bsfS", Gv, Ev, XX },
- { "bsrS", Gv, Ev, XX },
- { "movs{bR|x|bR|x}", Gv, Eb, XX },
- { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
- /* c0 */
- { "xaddB", Eb, Gb, XX },
- { "xaddS", Ev, Gv, XX },
- { PREGRP1 },
- { "movntiS", Ev, Gv, XX },
- { "pinsrw", MX, Ed, Ib },
- { "pextrw", Gd, MS, Ib },
- { "shufpX", XM, EX, Ib },
- { GRP9 },
- /* c8 */
- { "bswap", RMeAX, XX, XX },
- { "bswap", RMeCX, XX, XX },
- { "bswap", RMeDX, XX, XX },
- { "bswap", RMeBX, XX, XX },
- { "bswap", RMeSP, XX, XX },
- { "bswap", RMeBP, XX, XX },
- { "bswap", RMeSI, XX, XX },
- { "bswap", RMeDI, XX, XX },
- /* d0 */
- { "(bad)", XX, XX, XX },
- { "psrlw", MX, EM, XX },
- { "psrld", MX, EM, XX },
- { "psrlq", MX, EM, XX },
- { "paddq", MX, EM, XX },
- { "pmullw", MX, EM, XX },
- { PREGRP21 },
- { "pmovmskb", Gd, MS, XX },
- /* d8 */
- { "psubusb", MX, EM, XX },
- { "psubusw", MX, EM, XX },
- { "pminub", MX, EM, XX },
- { "pand", MX, EM, XX },
- { "paddusb", MX, EM, XX },
- { "paddusw", MX, EM, XX },
- { "pmaxub", MX, EM, XX },
- { "pandn", MX, EM, XX },
- /* e0 */
- { "pavgb", MX, EM, XX },
- { "psraw", MX, EM, XX },
- { "psrad", MX, EM, XX },
- { "pavgw", MX, EM, XX },
- { "pmulhuw", MX, EM, XX },
- { "pmulhw", MX, EM, XX },
- { PREGRP15 },
- { PREGRP25 },
- /* e8 */
- { "psubsb", MX, EM, XX },
- { "psubsw", MX, EM, XX },
- { "pminsw", MX, EM, XX },
- { "por", MX, EM, XX },
- { "paddsb", MX, EM, XX },
- { "paddsw", MX, EM, XX },
- { "pmaxsw", MX, EM, XX },
- { "pxor", MX, EM, XX },
- /* f0 */
- { "(bad)", XX, XX, XX },
- { "psllw", MX, EM, XX },
- { "pslld", MX, EM, XX },
- { "psllq", MX, EM, XX },
- { "pmuludq", MX, EM, XX },
- { "pmaddwd", MX, EM, XX },
- { "psadbw", MX, EM, XX },
- { PREGRP18 },
- /* f8 */
- { "psubb", MX, EM, XX },
- { "psubw", MX, EM, XX },
- { "psubd", MX, EM, XX },
- { "psubq", MX, EM, XX },
- { "paddb", MX, EM, XX },
- { "paddw", MX, EM, XX },
- { "paddd", MX, EM, XX },
- { "(bad)", XX, XX, XX }
-};
-
-static const unsigned char onebyte_has_modrm[256] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ------------------------------- */
- /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
- /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
- /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
- /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
- /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
- /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
- /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
- /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
- /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
- /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
- /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
- /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
- /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
- /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
- /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
- /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
- /* ------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-
-static const unsigned char twobyte_has_modrm[256] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ------------------------------- */
- /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
- /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
- /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
- /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
- /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
- /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
- /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
- /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
- /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
- /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
- /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
- /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
- /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
- /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
- /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
- /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
- /* ------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-
-static const unsigned char twobyte_uses_SSE_prefix[256] = {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
- /* ------------------------------- */
- /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
- /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
- /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
- /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
- /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
- /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
- /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
- /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
- /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
- /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
- /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
- /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
- /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
- /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
- /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
- /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
- /* ------------------------------- */
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-};
-
-static char obuf[100];
-static char *obufp;
-static char scratchbuf[100];
-static unsigned char *start_codep;
-static unsigned char *insn_codep;
-static unsigned char *codep;
-static disassemble_info *the_info;
-static int mod;
-static int rm;
-static int reg;
-static unsigned char need_modrm;
-
-/* If we are accessing mod/rm/reg without need_modrm set, then the
- values are stale. Hitting this abort likely indicates that you
- need to update onebyte_has_modrm or twobyte_has_modrm. */
-#define MODRM_CHECK if (!need_modrm) abort ()
-
-static const char **names64;
-static const char **names32;
-static const char **names16;
-static const char **names8;
-static const char **names8rex;
-static const char **names_seg;
-static const char **index16;
-
-static const char *intel_names64[] = {
- "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-};
-static const char *intel_names32[] = {
- "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
- "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
-};
-static const char *intel_names16[] = {
- "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
- "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
-};
-static const char *intel_names8[] = {
- "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
-};
-static const char *intel_names8rex[] = {
- "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
- "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
-};
-static const char *intel_names_seg[] = {
- "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
-};
-static const char *intel_index16[] = {
- "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
-};
-
-static const char *att_names64[] = {
- "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
- "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
-};
-static const char *att_names32[] = {
- "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
- "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
-};
-static const char *att_names16[] = {
- "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
- "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
-};
-static const char *att_names8[] = {
- "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
-};
-static const char *att_names8rex[] = {
- "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
- "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
-};
-static const char *att_names_seg[] = {
- "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
-};
-static const char *att_index16[] = {
- "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
-};
-
-static const struct dis386 grps[][8] = {
- /* GRP1b */
- {
- { "addA", Eb, Ib, XX },
- { "orA", Eb, Ib, XX },
- { "adcA", Eb, Ib, XX },
- { "sbbA", Eb, Ib, XX },
- { "andA", Eb, Ib, XX },
- { "subA", Eb, Ib, XX },
- { "xorA", Eb, Ib, XX },
- { "cmpA", Eb, Ib, XX }
- },
- /* GRP1S */
- {
- { "addQ", Ev, Iv, XX },
- { "orQ", Ev, Iv, XX },
- { "adcQ", Ev, Iv, XX },
- { "sbbQ", Ev, Iv, XX },
- { "andQ", Ev, Iv, XX },
- { "subQ", Ev, Iv, XX },
- { "xorQ", Ev, Iv, XX },
- { "cmpQ", Ev, Iv, XX }
- },
- /* GRP1Ss */
- {
- { "addQ", Ev, sIb, XX },
- { "orQ", Ev, sIb, XX },
- { "adcQ", Ev, sIb, XX },
- { "sbbQ", Ev, sIb, XX },
- { "andQ", Ev, sIb, XX },
- { "subQ", Ev, sIb, XX },
- { "xorQ", Ev, sIb, XX },
- { "cmpQ", Ev, sIb, XX }
- },
- /* GRP2b */
- {
- { "rolA", Eb, Ib, XX },
- { "rorA", Eb, Ib, XX },
- { "rclA", Eb, Ib, XX },
- { "rcrA", Eb, Ib, XX },
- { "shlA", Eb, Ib, XX },
- { "shrA", Eb, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "sarA", Eb, Ib, XX },
- },
- /* GRP2S */
- {
- { "rolQ", Ev, Ib, XX },
- { "rorQ", Ev, Ib, XX },
- { "rclQ", Ev, Ib, XX },
- { "rcrQ", Ev, Ib, XX },
- { "shlQ", Ev, Ib, XX },
- { "shrQ", Ev, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "sarQ", Ev, Ib, XX },
- },
- /* GRP2b_one */
- {
- { "rolA", Eb, XX, XX },
- { "rorA", Eb, XX, XX },
- { "rclA", Eb, XX, XX },
- { "rcrA", Eb, XX, XX },
- { "shlA", Eb, XX, XX },
- { "shrA", Eb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "sarA", Eb, XX, XX },
- },
- /* GRP2S_one */
- {
- { "rolQ", Ev, XX, XX },
- { "rorQ", Ev, XX, XX },
- { "rclQ", Ev, XX, XX },
- { "rcrQ", Ev, XX, XX },
- { "shlQ", Ev, XX, XX },
- { "shrQ", Ev, XX, XX },
- { "(bad)", XX, XX, XX},
- { "sarQ", Ev, XX, XX },
- },
- /* GRP2b_cl */
- {
- { "rolA", Eb, CL, XX },
- { "rorA", Eb, CL, XX },
- { "rclA", Eb, CL, XX },
- { "rcrA", Eb, CL, XX },
- { "shlA", Eb, CL, XX },
- { "shrA", Eb, CL, XX },
- { "(bad)", XX, XX, XX },
- { "sarA", Eb, CL, XX },
- },
- /* GRP2S_cl */
- {
- { "rolQ", Ev, CL, XX },
- { "rorQ", Ev, CL, XX },
- { "rclQ", Ev, CL, XX },
- { "rcrQ", Ev, CL, XX },
- { "shlQ", Ev, CL, XX },
- { "shrQ", Ev, CL, XX },
- { "(bad)", XX, XX, XX },
- { "sarQ", Ev, CL, XX }
- },
- /* GRP3b */
- {
- { "testA", Eb, Ib, XX },
- { "(bad)", Eb, XX, XX },
- { "notA", Eb, XX, XX },
- { "negA", Eb, XX, XX },
- { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
- { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
- { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
- { "idivA", Eb, XX, XX } /* and idiv for consistency. */
- },
- /* GRP3S */
- {
- { "testQ", Ev, Iv, XX },
- { "(bad)", XX, XX, XX },
- { "notQ", Ev, XX, XX },
- { "negQ", Ev, XX, XX },
- { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
- { "imulQ", Ev, XX, XX },
- { "divQ", Ev, XX, XX },
- { "idivQ", Ev, XX, XX },
- },
- /* GRP4 */
- {
- { "incA", Eb, XX, XX },
- { "decA", Eb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP5 */
- {
- { "incQ", Ev, XX, XX },
- { "decQ", Ev, XX, XX },
- { "callT", indirEv, XX, XX },
- { "lcallT", indirEv, XX, XX },
- { "jmpT", indirEv, XX, XX },
- { "ljmpT", indirEv, XX, XX },
- { "pushU", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP6 */
- {
- { "sldtQ", Ev, XX, XX },
- { "strQ", Ev, XX, XX },
- { "lldt", Ew, XX, XX },
- { "ltr", Ew, XX, XX },
- { "verr", Ew, XX, XX },
- { "verw", Ew, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX }
- },
- /* GRP7 */
- {
- { "sgdtQ", M, XX, XX },
- { "sidtQ", M, XX, XX },
- { "lgdtQ", M, XX, XX },
- { "lidtQ", M, XX, XX },
- { "smswQ", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "lmsw", Ew, XX, XX },
- { "invlpg", Ew, XX, XX },
- },
- /* GRP8 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "btQ", Ev, Ib, XX },
- { "btsQ", Ev, Ib, XX },
- { "btrQ", Ev, Ib, XX },
- { "btcQ", Ev, Ib, XX },
- },
- /* GRP9 */
- {
- { "(bad)", XX, XX, XX },
- { "cmpxchg8b", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP10 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psrlw", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "psraw", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "psllw", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP11 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psrld", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "psrad", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "pslld", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRP12 */
- {
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psrlq", MS, Ib, XX },
- { "psrldq", MS, Ib, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "psllq", MS, Ib, XX },
- { "pslldq", MS, Ib, XX },
- },
- /* GRP13 */
- {
- { "fxsave", Ev, XX, XX },
- { "fxrstor", Ev, XX, XX },
- { "ldmxcsr", Ev, XX, XX },
- { "stmxcsr", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "lfence", None, XX, XX },
- { "mfence", None, XX, XX },
- { "sfence", None, XX, XX },
- /* FIXME: the sfence with memory operand is clflush! */
- },
- /* GRP14 */
- {
- { "prefetchnta", Ev, XX, XX },
- { "prefetcht0", Ev, XX, XX },
- { "prefetcht1", Ev, XX, XX },
- { "prefetcht2", Ev, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* GRPAMD */
- {
- { "prefetch", Eb, XX, XX },
- { "prefetchw", Eb, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- }
-};
-
-static const struct dis386 prefix_user_table[][4] = {
- /* PREGRP0 */
- {
- { "addps", XM, EX, XX },
- { "addss", XM, EX, XX },
- { "addpd", XM, EX, XX },
- { "addsd", XM, EX, XX },
- },
- /* PREGRP1 */
- {
- { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
- { "", XM, EX, OPSIMD },
- { "", XM, EX, OPSIMD },
- { "", XM, EX, OPSIMD },
- },
- /* PREGRP2 */
- {
- { "cvtpi2ps", XM, EM, XX },
- { "cvtsi2ssY", XM, Ev, XX },
- { "cvtpi2pd", XM, EM, XX },
- { "cvtsi2sdY", XM, Ev, XX },
- },
- /* PREGRP3 */
- {
- { "cvtps2pi", MX, EX, XX },
- { "cvtss2siY", Gv, EX, XX },
- { "cvtpd2pi", MX, EX, XX },
- { "cvtsd2siY", Gv, EX, XX },
- },
- /* PREGRP4 */
- {
- { "cvttps2pi", MX, EX, XX },
- { "cvttss2siY", Gv, EX, XX },
- { "cvttpd2pi", MX, EX, XX },
- { "cvttsd2siY", Gv, EX, XX },
- },
- /* PREGRP5 */
- {
- { "divps", XM, EX, XX },
- { "divss", XM, EX, XX },
- { "divpd", XM, EX, XX },
- { "divsd", XM, EX, XX },
- },
- /* PREGRP6 */
- {
- { "maxps", XM, EX, XX },
- { "maxss", XM, EX, XX },
- { "maxpd", XM, EX, XX },
- { "maxsd", XM, EX, XX },
- },
- /* PREGRP7 */
- {
- { "minps", XM, EX, XX },
- { "minss", XM, EX, XX },
- { "minpd", XM, EX, XX },
- { "minsd", XM, EX, XX },
- },
- /* PREGRP8 */
- {
- { "movups", XM, EX, XX },
- { "movss", XM, EX, XX },
- { "movupd", XM, EX, XX },
- { "movsd", XM, EX, XX },
- },
- /* PREGRP9 */
- {
- { "movups", EX, XM, XX },
- { "movss", EX, XM, XX },
- { "movupd", EX, XM, XX },
- { "movsd", EX, XM, XX },
- },
- /* PREGRP10 */
- {
- { "mulps", XM, EX, XX },
- { "mulss", XM, EX, XX },
- { "mulpd", XM, EX, XX },
- { "mulsd", XM, EX, XX },
- },
- /* PREGRP11 */
- {
- { "rcpps", XM, EX, XX },
- { "rcpss", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP12 */
- {
- { "rsqrtps", XM, EX, XX },
- { "rsqrtss", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP13 */
- {
- { "sqrtps", XM, EX, XX },
- { "sqrtss", XM, EX, XX },
- { "sqrtpd", XM, EX, XX },
- { "sqrtsd", XM, EX, XX },
- },
- /* PREGRP14 */
- {
- { "subps", XM, EX, XX },
- { "subss", XM, EX, XX },
- { "subpd", XM, EX, XX },
- { "subsd", XM, EX, XX },
- },
- /* PREGRP15 */
- {
- { "(bad)", XM, EX, XX },
- { "cvtdq2pd", XM, EX, XX },
- { "cvttpd2dq", XM, EX, XX },
- { "cvtpd2dq", XM, EX, XX },
- },
- /* PREGRP16 */
- {
- { "cvtdq2ps", XM, EX, XX },
- { "cvttps2dq",XM, EX, XX },
- { "cvtps2dq",XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP17 */
- {
- { "cvtps2pd", XM, EX, XX },
- { "cvtss2sd", XM, EX, XX },
- { "cvtpd2ps", XM, EX, XX },
- { "cvtsd2ss", XM, EX, XX },
- },
- /* PREGRP18 */
- {
- { "maskmovq", MX, MS, XX },
- { "(bad)", XM, EX, XX },
- { "maskmovdqu", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP19 */
- {
- { "movq", MX, EM, XX },
- { "movdqu", XM, EX, XX },
- { "movdqa", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP20 */
- {
- { "movq", EM, MX, XX },
- { "movdqu", EX, XM, XX },
- { "movdqa", EX, XM, XX },
- { "(bad)", EX, XM, XX },
- },
- /* PREGRP21 */
- {
- { "(bad)", EX, XM, XX },
- { "movq2dq", XM, MS, XX },
- { "movq", EX, XM, XX },
- { "movdq2q", MX, XS, XX },
- },
- /* PREGRP22 */
- {
- { "pshufw", MX, EM, Ib },
- { "pshufhw", XM, EX, Ib },
- { "pshufd", XM, EX, Ib },
- { "pshuflw", XM, EX, Ib },
- },
- /* PREGRP23 */
- {
- { "movd", Ed, MX, XX },
- { "movq", XM, EX, XX },
- { "movd", Ed, XM, XX },
- { "(bad)", Ed, XM, XX },
- },
- /* PREGRP24 */
- {
- { "(bad)", MX, EX, XX },
- { "(bad)", XM, EX, XX },
- { "punpckhqdq", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
- /* PREGRP25 */
- {
- { "movntq", Ev, MX, XX },
- { "(bad)", Ev, XM, XX },
- { "movntdq", Ev, XM, XX },
- { "(bad)", Ev, XM, XX },
- },
- /* PREGRP26 */
- {
- { "(bad)", MX, EX, XX },
- { "(bad)", XM, EX, XX },
- { "punpcklqdq", XM, EX, XX },
- { "(bad)", XM, EX, XX },
- },
-};
-
-static const struct dis386 x86_64_table[][2] = {
- {
- { "arpl", Ew, Gw, XX },
- { "movs{||lq|xd}", Gv, Ed, XX },
- },
-};
-
-#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
-
-static void
-ckprefix ()
-{
- int newrex;
- rex = 0;
- prefixes = 0;
- used_prefixes = 0;
- rex_used = 0;
- while (1)
- {
- FETCH_DATA (the_info, codep + 1);
- newrex = 0;
- switch (*codep)
- {
- /* REX prefixes family. */
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x45:
- case 0x46:
- case 0x47:
- case 0x48:
- case 0x49:
- case 0x4a:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- case 0x4e:
- case 0x4f:
- if (mode_64bit)
- newrex = *codep;
- else
- return;
- break;
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- break;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- break;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- break;
- case 0x2e:
- prefixes |= PREFIX_CS;
- break;
- case 0x36:
- prefixes |= PREFIX_SS;
- break;
- case 0x3e:
- prefixes |= PREFIX_DS;
- break;
- case 0x26:
- prefixes |= PREFIX_ES;
- break;
- case 0x64:
- prefixes |= PREFIX_FS;
- break;
- case 0x65:
- prefixes |= PREFIX_GS;
- break;
- case 0x66:
- prefixes |= PREFIX_DATA;
- break;
- case 0x67:
- prefixes |= PREFIX_ADDR;
- break;
- case FWAIT_OPCODE:
- /* fwait is really an instruction. If there are prefixes
- before the fwait, they belong to the fwait, *not* to the
- following instruction. */
- if (prefixes)
- {
- prefixes |= PREFIX_FWAIT;
- codep++;
- return;
- }
- prefixes = PREFIX_FWAIT;
- break;
- default:
- return;
- }
- /* Rex is ignored when followed by another prefix. */
- if (rex)
- {
- oappend (prefix_name (rex, 0));
- oappend (" ");
- }
- rex = newrex;
- codep++;
- }
-}
-
-/* Return the name of the prefix byte PREF, or NULL if PREF is not a
- prefix byte. */
-
-static const char *
-prefix_name (pref, sizeflag)
- int pref;
- int sizeflag;
-{
- switch (pref)
- {
- /* REX prefixes family. */
- case 0x40:
- return "rex";
- case 0x41:
- return "rexZ";
- case 0x42:
- return "rexY";
- case 0x43:
- return "rexYZ";
- case 0x44:
- return "rexX";
- case 0x45:
- return "rexXZ";
- case 0x46:
- return "rexXY";
- case 0x47:
- return "rexXYZ";
- case 0x48:
- return "rex64";
- case 0x49:
- return "rex64Z";
- case 0x4a:
- return "rex64Y";
- case 0x4b:
- return "rex64YZ";
- case 0x4c:
- return "rex64X";
- case 0x4d:
- return "rex64XZ";
- case 0x4e:
- return "rex64XY";
- case 0x4f:
- return "rex64XYZ";
- case 0xf3:
- return "repz";
- case 0xf2:
- return "repnz";
- case 0xf0:
- return "lock";
- case 0x2e:
- return "cs";
- case 0x36:
- return "ss";
- case 0x3e:
- return "ds";
- case 0x26:
- return "es";
- case 0x64:
- return "fs";
- case 0x65:
- return "gs";
- case 0x66:
- return (sizeflag & DFLAG) ? "data16" : "data32";
- case 0x67:
- if (mode_64bit)
- return (sizeflag & AFLAG) ? "addr32" : "addr64";
- else
- return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
- case FWAIT_OPCODE:
- return "fwait";
- default:
- return NULL;
- }
-}
-
-static char op1out[100], op2out[100], op3out[100];
-static int op_ad, op_index[3];
-static bfd_vma op_address[3];
-static bfd_vma op_riprel[3];
-static bfd_vma start_pc;
-
-/*
- * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
- * (see topic "Redundant prefixes" in the "Differences from 8086"
- * section of the "Virtual 8086 Mode" chapter.)
- * 'pc' should be the address of this instruction, it will
- * be used to print the target address if this is a relative jump or call
- * The function returns the length of this instruction in bytes.
- */
-
-static int8_t intel_syntax;
-static char open_char;
-static char close_char;
-static char separator_char;
-static char scale_char;
-
-int
-print_insn_i386 (pc, info)
- bfd_vma pc;
- disassemble_info *info;
-{
- intel_syntax = -1;
-
- return print_insn (pc, info);
-}
-
-static int
-print_insn (pc, info)
- bfd_vma pc;
- disassemble_info *info;
-{
- const struct dis386 *dp;
- int i;
- int two_source_ops;
- char *first, *second, *third;
- int needcomma;
- unsigned char uses_SSE_prefix;
- int sizeflag;
- const char *p;
- struct dis_private priv;
-
- mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
- || info->mach == bfd_mach_x86_64);
-
- if (intel_syntax == -1)
- intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
- || info->mach == bfd_mach_x86_64_intel_syntax);
-
- if (info->mach == bfd_mach_i386_i386
- || info->mach == bfd_mach_x86_64
- || info->mach == bfd_mach_i386_i386_intel_syntax
- || info->mach == bfd_mach_x86_64_intel_syntax)
- priv.orig_sizeflag = AFLAG | DFLAG;
- else if (info->mach == bfd_mach_i386_i8086)
- priv.orig_sizeflag = 0;
- else
- abort ();
-
- for (p = info->disassembler_options; p != NULL; )
- {
- if (strncmp (p, "x86-64", 6) == 0)
- {
- mode_64bit = 1;
- priv.orig_sizeflag = AFLAG | DFLAG;
- }
- else if (strncmp (p, "i386", 4) == 0)
- {
- mode_64bit = 0;
- priv.orig_sizeflag = AFLAG | DFLAG;
- }
- else if (strncmp (p, "i8086", 5) == 0)
- {
- mode_64bit = 0;
- priv.orig_sizeflag = 0;
- }
- else if (strncmp (p, "intel", 5) == 0)
- {
- intel_syntax = 1;
- }
- else if (strncmp (p, "att", 3) == 0)
- {
- intel_syntax = 0;
- }
- else if (strncmp (p, "addr", 4) == 0)
- {
- if (p[4] == '1' && p[5] == '6')
- priv.orig_sizeflag &= ~AFLAG;
- else if (p[4] == '3' && p[5] == '2')
- priv.orig_sizeflag |= AFLAG;
- }
- else if (strncmp (p, "data", 4) == 0)
- {
- if (p[4] == '1' && p[5] == '6')
- priv.orig_sizeflag &= ~DFLAG;
- else if (p[4] == '3' && p[5] == '2')
- priv.orig_sizeflag |= DFLAG;
- }
- else if (strncmp (p, "suffix", 6) == 0)
- priv.orig_sizeflag |= SUFFIX_ALWAYS;
-
- p = strchr (p, ',');
- if (p != NULL)
- p++;
- }
-
- if (intel_syntax)
- {
- names64 = intel_names64;
- names32 = intel_names32;
- names16 = intel_names16;
- names8 = intel_names8;
- names8rex = intel_names8rex;
- names_seg = intel_names_seg;
- index16 = intel_index16;
- open_char = '[';
- close_char = ']';
- separator_char = '+';
- scale_char = '*';
- }
- else
- {
- names64 = att_names64;
- names32 = att_names32;
- names16 = att_names16;
- names8 = att_names8;
- names8rex = att_names8rex;
- names_seg = att_names_seg;
- index16 = att_index16;
- open_char = '(';
- close_char = ')';
- separator_char = ',';
- scale_char = ',';
- }
-
- /* The output looks better if we put 7 bytes on a line, since that
- puts most long word instructions on a single line. */
- info->bytes_per_line = 7;
-
- info->private_data = (PTR) &priv;
- priv.max_fetched = priv.the_buffer;
- priv.insn_start = pc;
-
- obuf[0] = 0;
- op1out[0] = 0;
- op2out[0] = 0;
- op3out[0] = 0;
-
- op_index[0] = op_index[1] = op_index[2] = -1;
-
- the_info = info;
- start_pc = pc;
- start_codep = priv.the_buffer;
- codep = priv.the_buffer;
-
- if (setjmp (priv.bailout) != 0)
- {
- const char *name;
-
- /* Getting here means we tried for data but didn't get it. That
- means we have an incomplete instruction of some sort. Just
- print the first byte as a prefix or a .byte pseudo-op. */
- if (codep > priv.the_buffer)
- {
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
- if (name != NULL)
- (*info->fprintf_func) (info->stream, "%s", name);
- else
- {
- /* Just print the first byte as a .byte instruction. */
- (*info->fprintf_func) (info->stream, ".byte 0x%x",
- (unsigned int) priv.the_buffer[0]);
- }
-
- return 1;
- }
-
- return -1;
- }
-
- obufp = obuf;
- ckprefix ();
-
- insn_codep = codep;
- sizeflag = priv.orig_sizeflag;
-
- FETCH_DATA (info, codep + 1);
- two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
-
- if ((prefixes & PREFIX_FWAIT)
- && ((*codep < 0xd8) || (*codep > 0xdf)))
- {
- const char *name;
-
- /* fwait not followed by floating point instruction. Print the
- first prefix, which is probably fwait itself. */
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s", name);
- return 1;
- }
-
- if (*codep == 0x0f)
- {
- FETCH_DATA (info, codep + 2);
- dp = &dis386_twobyte[*++codep];
- need_modrm = twobyte_has_modrm[*codep];
- uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
- }
- else
- {
- dp = &dis386[*codep];
- need_modrm = onebyte_has_modrm[*codep];
- uses_SSE_prefix = 0;
- }
- codep++;
-
- if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
- {
- oappend ("repz ");
- used_prefixes |= PREFIX_REPZ;
- }
- if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
- {
- oappend ("repnz ");
- used_prefixes |= PREFIX_REPNZ;
- }
- if (prefixes & PREFIX_LOCK)
- {
- oappend ("lock ");
- used_prefixes |= PREFIX_LOCK;
- }
-
- if (prefixes & PREFIX_ADDR)
- {
- sizeflag ^= AFLAG;
- if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
- {
- if ((sizeflag & AFLAG) || mode_64bit)
- oappend ("addr32 ");
- else
- oappend ("addr16 ");
- used_prefixes |= PREFIX_ADDR;
- }
- }
-
- if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
- {
- sizeflag ^= DFLAG;
- if (dp->bytemode3 == cond_jump_mode
- && dp->bytemode1 == v_mode
- && !intel_syntax)
- {
- if (sizeflag & DFLAG)
- oappend ("data32 ");
- else
- oappend ("data16 ");
- used_prefixes |= PREFIX_DATA;
- }
- }
-
- if (need_modrm)
- {
- FETCH_DATA (info, codep + 1);
- mod = (*codep >> 6) & 3;
- reg = (*codep >> 3) & 7;
- rm = *codep & 7;
- }
-
- if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
- {
- dofloat (sizeflag);
- }
- else
- {
- int index;
- if (dp->name == NULL)
- {
- switch (dp->bytemode1)
- {
- case USE_GROUPS:
- dp = &grps[dp->bytemode2][reg];
- break;
-
- case USE_PREFIX_USER_TABLE:
- index = 0;
- used_prefixes |= (prefixes & PREFIX_REPZ);
- if (prefixes & PREFIX_REPZ)
- index = 1;
- else
- {
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- index = 2;
- else
- {
- used_prefixes |= (prefixes & PREFIX_REPNZ);
- if (prefixes & PREFIX_REPNZ)
- index = 3;
- }
- }
- dp = &prefix_user_table[dp->bytemode2][index];
- break;
-
- case X86_64_SPECIAL:
- dp = &x86_64_table[dp->bytemode2][mode_64bit];
- break;
-
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
- }
- }
-
- if (putop (dp->name, sizeflag) == 0)
- {
- obufp = op1out;
- op_ad = 2;
- if (dp->op1)
- (*dp->op1) (dp->bytemode1, sizeflag);
-
- obufp = op2out;
- op_ad = 1;
- if (dp->op2)
- (*dp->op2) (dp->bytemode2, sizeflag);
-
- obufp = op3out;
- op_ad = 0;
- if (dp->op3)
- (*dp->op3) (dp->bytemode3, sizeflag);
- }
- }
-
- /* See if any prefixes were not used. If so, print the first one
- separately. If we don't do this, we'll wind up printing an
- instruction stream which does not precisely correspond to the
- bytes we are disassembling. */
- if ((prefixes & ~used_prefixes) != 0)
- {
- const char *name;
-
- name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s", name);
- return 1;
- }
- if (rex & ~rex_used)
- {
- const char *name;
- name = prefix_name (rex | 0x40, priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
- (*info->fprintf_func) (info->stream, "%s ", name);
- }
-
- obufp = obuf + strlen (obuf);
- for (i = strlen (obuf); i < 6; i++)
- oappend (" ");
- oappend (" ");
- (*info->fprintf_func) (info->stream, "%s", obuf);
-
- /* The enter and bound instructions are printed with operands in the same
- order as the intel book; everything else is printed in reverse order. */
- if (intel_syntax || two_source_ops)
- {
- first = op1out;
- second = op2out;
- third = op3out;
- op_ad = op_index[0];
- op_index[0] = op_index[2];
- op_index[2] = op_ad;
- }
- else
- {
- first = op3out;
- second = op2out;
- third = op1out;
- }
- needcomma = 0;
- if (*first)
- {
- if (op_index[0] != -1 && !op_riprel[0])
- (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
- else
- (*info->fprintf_func) (info->stream, "%s", first);
- needcomma = 1;
- }
- if (*second)
- {
- if (needcomma)
- (*info->fprintf_func) (info->stream, ",");
- if (op_index[1] != -1 && !op_riprel[1])
- (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
- else
- (*info->fprintf_func) (info->stream, "%s", second);
- needcomma = 1;
- }
- if (*third)
- {
- if (needcomma)
- (*info->fprintf_func) (info->stream, ",");
- if (op_index[2] != -1 && !op_riprel[2])
- (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
- else
- (*info->fprintf_func) (info->stream, "%s", third);
- }
- for (i = 0; i < 3; i++)
- if (op_index[i] != -1 && op_riprel[i])
- {
- (*info->fprintf_func) (info->stream, " # ");
- (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
- + op_address[op_index[i]]), info);
- }
- return codep - priv.the_buffer;
-}
-
-static const char *float_mem[] = {
- /* d8 */
- "fadd{s||s|}",
- "fmul{s||s|}",
- "fcom{s||s|}",
- "fcomp{s||s|}",
- "fsub{s||s|}",
- "fsubr{s||s|}",
- "fdiv{s||s|}",
- "fdivr{s||s|}",
- /* d9 */
- "fld{s||s|}",
- "(bad)",
- "fst{s||s|}",
- "fstp{s||s|}",
- "fldenv",
- "fldcw",
- "fNstenv",
- "fNstcw",
- /* da */
- "fiadd{l||l|}",
- "fimul{l||l|}",
- "ficom{l||l|}",
- "ficomp{l||l|}",
- "fisub{l||l|}",
- "fisubr{l||l|}",
- "fidiv{l||l|}",
- "fidivr{l||l|}",
- /* db */
- "fild{l||l|}",
- "(bad)",
- "fist{l||l|}",
- "fistp{l||l|}",
- "(bad)",
- "fld{t||t|}",
- "(bad)",
- "fstp{t||t|}",
- /* dc */
- "fadd{l||l|}",
- "fmul{l||l|}",
- "fcom{l||l|}",
- "fcomp{l||l|}",
- "fsub{l||l|}",
- "fsubr{l||l|}",
- "fdiv{l||l|}",
- "fdivr{l||l|}",
- /* dd */
- "fld{l||l|}",
- "(bad)",
- "fst{l||l|}",
- "fstp{l||l|}",
- "frstor",
- "(bad)",
- "fNsave",
- "fNstsw",
- /* de */
- "fiadd",
- "fimul",
- "ficom",
- "ficomp",
- "fisub",
- "fisubr",
- "fidiv",
- "fidivr",
- /* df */
- "fild",
- "(bad)",
- "fist",
- "fistp",
- "fbld",
- "fild{ll||ll|}",
- "fbstp",
- "fistpll",
-};
-
-#define ST OP_ST, 0
-#define STi OP_STi, 0
-
-#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
-#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
-#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
-#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
-#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
-#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
-#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
-#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
-#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
-
-static const struct dis386 float_reg[][8] = {
- /* d8 */
- {
- { "fadd", ST, STi, XX },
- { "fmul", ST, STi, XX },
- { "fcom", STi, XX, XX },
- { "fcomp", STi, XX, XX },
- { "fsub", ST, STi, XX },
- { "fsubr", ST, STi, XX },
- { "fdiv", ST, STi, XX },
- { "fdivr", ST, STi, XX },
- },
- /* d9 */
- {
- { "fld", STi, XX, XX },
- { "fxch", STi, XX, XX },
- { FGRPd9_2 },
- { "(bad)", XX, XX, XX },
- { FGRPd9_4 },
- { FGRPd9_5 },
- { FGRPd9_6 },
- { FGRPd9_7 },
- },
- /* da */
- {
- { "fcmovb", ST, STi, XX },
- { "fcmove", ST, STi, XX },
- { "fcmovbe",ST, STi, XX },
- { "fcmovu", ST, STi, XX },
- { "(bad)", XX, XX, XX },
- { FGRPda_5 },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* db */
- {
- { "fcmovnb",ST, STi, XX },
- { "fcmovne",ST, STi, XX },
- { "fcmovnbe",ST, STi, XX },
- { "fcmovnu",ST, STi, XX },
- { FGRPdb_4 },
- { "fucomi", ST, STi, XX },
- { "fcomi", ST, STi, XX },
- { "(bad)", XX, XX, XX },
- },
- /* dc */
- {
- { "fadd", STi, ST, XX },
- { "fmul", STi, ST, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
-#if UNIXWARE_COMPAT
- { "fsub", STi, ST, XX },
- { "fsubr", STi, ST, XX },
- { "fdiv", STi, ST, XX },
- { "fdivr", STi, ST, XX },
-#else
- { "fsubr", STi, ST, XX },
- { "fsub", STi, ST, XX },
- { "fdivr", STi, ST, XX },
- { "fdiv", STi, ST, XX },
-#endif
- },
- /* dd */
- {
- { "ffree", STi, XX, XX },
- { "(bad)", XX, XX, XX },
- { "fst", STi, XX, XX },
- { "fstp", STi, XX, XX },
- { "fucom", STi, XX, XX },
- { "fucomp", STi, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- },
- /* de */
- {
- { "faddp", STi, ST, XX },
- { "fmulp", STi, ST, XX },
- { "(bad)", XX, XX, XX },
- { FGRPde_3 },
-#if UNIXWARE_COMPAT
- { "fsubp", STi, ST, XX },
- { "fsubrp", STi, ST, XX },
- { "fdivp", STi, ST, XX },
- { "fdivrp", STi, ST, XX },
-#else
- { "fsubrp", STi, ST, XX },
- { "fsubp", STi, ST, XX },
- { "fdivrp", STi, ST, XX },
- { "fdivp", STi, ST, XX },
-#endif
- },
- /* df */
- {
- { "ffreep", STi, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { FGRPdf_4 },
- { "fucomip",ST, STi, XX },
- { "fcomip", ST, STi, XX },
- { "(bad)", XX, XX, XX },
- },
-};
-
-static const char *fgrps[][8] = {
- /* d9_2 0 */
- {
- "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-
- /* d9_4 1 */
- {
- "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
- },
-
- /* d9_5 2 */
- {
- "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
- },
-
- /* d9_6 3 */
- {
- "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
- },
-
- /* d9_7 4 */
- {
- "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
- },
-
- /* da_5 5 */
- {
- "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-
- /* db_4 6 */
- {
- "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
- "fNsetpm(287 only)","(bad)","(bad)","(bad)",
- },
-
- /* de_3 7 */
- {
- "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-
- /* df_4 8 */
- {
- "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
- },
-};
-
-static void
-dofloat (sizeflag)
- int sizeflag;
-{
- const struct dis386 *dp;
- unsigned char floatop;
-
- floatop = codep[-1];
-
- if (mod != 3)
- {
- putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
- obufp = op1out;
- if (floatop == 0xdb)
- OP_E (x_mode, sizeflag);
- else if (floatop == 0xdd)
- OP_E (d_mode, sizeflag);
- else
- OP_E (v_mode, sizeflag);
- return;
- }
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
-
- dp = &float_reg[floatop - 0xd8][reg];
- if (dp->name == NULL)
- {
- putop (fgrps[dp->bytemode1][rm], sizeflag);
-
- /* Instruction fnstsw is only one with strange arg. */
- if (floatop == 0xdf && codep[-1] == 0xe0)
- pstrcpy (op1out, sizeof(op1out), names16[0]);
- }
- else
- {
- putop (dp->name, sizeflag);
-
- obufp = op1out;
- if (dp->op1)
- (*dp->op1) (dp->bytemode1, sizeflag);
- obufp = op2out;
- if (dp->op2)
- (*dp->op2) (dp->bytemode2, sizeflag);
- }
-}
-
-static void
-OP_ST (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- oappend ("%st");
-}
-
-static void
-OP_STi (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- snprintf (scratchbuf, sizeof(scratchbuf), "%%st(%d)", rm);
- oappend (scratchbuf + intel_syntax);
-}
-
-/* Capital letters in template are macros. */
-static int
-putop (template, sizeflag)
- const char *template;
- int sizeflag;
-{
- const char *p;
- int alt;
-
- for (p = template; *p; p++)
- {
- switch (*p)
- {
- default:
- *obufp++ = *p;
- break;
- case '{':
- alt = 0;
- if (intel_syntax)
- alt += 1;
- if (mode_64bit)
- alt += 2;
- while (alt != 0)
- {
- while (*++p != '|')
- {
- if (*p == '}')
- {
- /* Alternative not valid. */
- pstrcpy (obuf, sizeof(obuf), "(bad)");
- obufp = obuf + 5;
- return 1;
- }
- else if (*p == '\0')
- abort ();
- }
- alt--;
- }
- break;
- case '|':
- while (*++p != '}')
- {
- if (*p == '\0')
- abort ();
- }
- break;
- case '}':
- break;
- case 'A':
- if (intel_syntax)
- break;
- if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
- *obufp++ = 'b';
- break;
- case 'B':
- if (intel_syntax)
- break;
- if (sizeflag & SUFFIX_ALWAYS)
- *obufp++ = 'b';
- break;
- case 'E': /* For jcxz/jecxz */
- if (mode_64bit)
- {
- if (sizeflag & AFLAG)
- *obufp++ = 'r';
- else
- *obufp++ = 'e';
- }
- else
- if (sizeflag & AFLAG)
- *obufp++ = 'e';
- used_prefixes |= (prefixes & PREFIX_ADDR);
- break;
- case 'F':
- if (intel_syntax)
- break;
- if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
- {
- if (sizeflag & AFLAG)
- *obufp++ = mode_64bit ? 'q' : 'l';
- else
- *obufp++ = mode_64bit ? 'l' : 'w';
- used_prefixes |= (prefixes & PREFIX_ADDR);
- }
- break;
- case 'H':
- if (intel_syntax)
- break;
- if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
- || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
- {
- used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
- *obufp++ = ',';
- *obufp++ = 'p';
- if (prefixes & PREFIX_DS)
- *obufp++ = 't';
- else
- *obufp++ = 'n';
- }
- break;
- case 'L':
- if (intel_syntax)
- break;
- if (sizeflag & SUFFIX_ALWAYS)
- *obufp++ = 'l';
- break;
- case 'N':
- if ((prefixes & PREFIX_FWAIT) == 0)
- *obufp++ = 'n';
- else
- used_prefixes |= PREFIX_FWAIT;
- break;
- case 'O':
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- *obufp++ = 'o';
- else
- *obufp++ = 'd';
- break;
- case 'T':
- if (intel_syntax)
- break;
- if (mode_64bit)
- {
- *obufp++ = 'q';
- break;
- }
- /* Fall through. */
- case 'P':
- if (intel_syntax)
- break;
- if ((prefixes & PREFIX_DATA)
- || (rex & REX_MODE64)
- || (sizeflag & SUFFIX_ALWAYS))
- {
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- }
- break;
- case 'U':
- if (intel_syntax)
- break;
- if (mode_64bit)
- {
- *obufp++ = 'q';
- break;
- }
- /* Fall through. */
- case 'Q':
- if (intel_syntax)
- break;
- USED_REX (REX_MODE64);
- if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
- {
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- }
- break;
- case 'R':
- USED_REX (REX_MODE64);
- if (intel_syntax)
- {
- if (rex & REX_MODE64)
- {
- *obufp++ = 'q';
- *obufp++ = 't';
- }
- else if (sizeflag & DFLAG)
- {
- *obufp++ = 'd';
- *obufp++ = 'q';
- }
- else
- {
- *obufp++ = 'w';
- *obufp++ = 'd';
- }
- }
- else
- {
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- }
- if (!(rex & REX_MODE64))
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case 'S':
- if (intel_syntax)
- break;
- if (sizeflag & SUFFIX_ALWAYS)
- {
- if (rex & REX_MODE64)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- }
- break;
- case 'X':
- if (prefixes & PREFIX_DATA)
- *obufp++ = 'd';
- else
- *obufp++ = 's';
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case 'Y':
- if (intel_syntax)
- break;
- if (rex & REX_MODE64)
- {
- USED_REX (REX_MODE64);
- *obufp++ = 'q';
- }
- break;
- /* implicit operand size 'l' for i386 or 'q' for x86-64 */
- case 'W':
- /* operand size flag for cwtl, cbtw */
- USED_REX (0);
- if (rex)
- *obufp++ = 'l';
- else if (sizeflag & DFLAG)
- *obufp++ = 'w';
- else
- *obufp++ = 'b';
- if (intel_syntax)
- {
- if (rex)
- {
- *obufp++ = 'q';
- *obufp++ = 'e';
- }
- if (sizeflag & DFLAG)
- {
- *obufp++ = 'd';
- *obufp++ = 'e';
- }
- else
- {
- *obufp++ = 'w';
- }
- }
- if (!rex)
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- }
- }
- *obufp = 0;
- return 0;
-}
-
-static void
-oappend (s)
- const char *s;
-{
- strcpy (obufp, s);
- obufp += strlen (s);
-}
-
-static void
-append_seg ()
-{
- if (prefixes & PREFIX_CS)
- {
- used_prefixes |= PREFIX_CS;
- oappend ("%cs:" + intel_syntax);
- }
- if (prefixes & PREFIX_DS)
- {
- used_prefixes |= PREFIX_DS;
- oappend ("%ds:" + intel_syntax);
- }
- if (prefixes & PREFIX_SS)
- {
- used_prefixes |= PREFIX_SS;
- oappend ("%ss:" + intel_syntax);
- }
- if (prefixes & PREFIX_ES)
- {
- used_prefixes |= PREFIX_ES;
- oappend ("%es:" + intel_syntax);
- }
- if (prefixes & PREFIX_FS)
- {
- used_prefixes |= PREFIX_FS;
- oappend ("%fs:" + intel_syntax);
- }
- if (prefixes & PREFIX_GS)
- {
- used_prefixes |= PREFIX_GS;
- oappend ("%gs:" + intel_syntax);
- }
-}
-
-static void
-OP_indirE (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (!intel_syntax)
- oappend ("*");
- OP_E (bytemode, sizeflag);
-}
-
-static void
-print_operand_value (char *buf, size_t bufsize, int hex, bfd_vma disp)
-{
- if (mode_64bit)
- {
- if (hex)
- {
- char tmp[30];
- int i;
- buf[0] = '0';
- buf[1] = 'x';
- snprintf_vma (tmp, sizeof(tmp), disp);
- for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
- pstrcpy (buf + 2, bufsize - 2, tmp + i);
- }
- else
- {
- bfd_signed_vma v = disp;
- char tmp[30];
- int i;
- if (v < 0)
- {
- *(buf++) = '-';
- v = -disp;
- /* Check for possible overflow on 0x8000000000000000. */
- if (v < 0)
- {
- pstrcpy (buf, bufsize, "9223372036854775808");
- return;
- }
- }
- if (!v)
- {
- pstrcpy (buf, bufsize, "0");
- return;
- }
-
- i = 0;
- tmp[29] = 0;
- while (v)
- {
- tmp[28 - i] = (v % 10) + '0';
- v /= 10;
- i++;
- }
- pstrcpy (buf, bufsize, tmp + 29 - i);
- }
- }
- else
- {
- if (hex)
- snprintf (buf, bufsize, "0x%x", (unsigned int) disp);
- else
- snprintf (buf, bufsize, "%d", (int) disp);
- }
-}
-
-static void
-OP_E (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma disp;
- int add = 0;
- int riprel = 0;
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add += 8;
-
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
-
- if (mod == 3)
- {
- switch (bytemode)
- {
- case b_mode:
- USED_REX (0);
- if (rex)
- oappend (names8rex[rm + add]);
- else
- oappend (names8[rm + add]);
- break;
- case w_mode:
- oappend (names16[rm + add]);
- break;
- case d_mode:
- oappend (names32[rm + add]);
- break;
- case q_mode:
- oappend (names64[rm + add]);
- break;
- case m_mode:
- if (mode_64bit)
- oappend (names64[rm + add]);
- else
- oappend (names32[rm + add]);
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- oappend (names64[rm + add]);
- else if (sizeflag & DFLAG)
- oappend (names32[rm + add]);
- else
- oappend (names16[rm + add]);
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case 0:
- if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
- && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
- && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
- BadOp (); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
- }
- return;
- }
-
- disp = 0;
- append_seg ();
-
- if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
- {
- int havesib;
- int havebase;
- int base;
- int index = 0;
- int scale = 0;
-
- havesib = 0;
- havebase = 1;
- base = rm;
-
- if (base == 4)
- {
- havesib = 1;
- FETCH_DATA (the_info, codep + 1);
- scale = (*codep >> 6) & 3;
- index = (*codep >> 3) & 7;
- base = *codep & 7;
- USED_REX (REX_EXTY);
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTY)
- index += 8;
- if (rex & REX_EXTZ)
- base += 8;
- codep++;
- }
-
- switch (mod)
- {
- case 0:
- if ((base & 7) == 5)
- {
- havebase = 0;
- if (mode_64bit && !havesib && (sizeflag & AFLAG))
- riprel = 1;
- disp = get32s ();
- }
- break;
- case 1:
- FETCH_DATA (the_info, codep + 1);
- disp = *codep++;
- if ((disp & 0x80) != 0)
- disp -= 0x100;
- break;
- case 2:
- disp = get32s ();
- break;
- }
-
- if (!intel_syntax)
- if (mod != 0 || (base & 7) == 5)
- {
- print_operand_value (scratchbuf, sizeof(scratchbuf), !riprel, disp);
- oappend (scratchbuf);
- if (riprel)
- {
- set_op (disp, 1);
- oappend ("(%rip)");
- }
- }
-
- if (havebase || (havesib && (index != 4 || scale != 0)))
- {
- if (intel_syntax)
- {
- switch (bytemode)
- {
- case b_mode:
- oappend ("BYTE PTR ");
- break;
- case w_mode:
- oappend ("WORD PTR ");
- break;
- case v_mode:
- oappend ("DWORD PTR ");
- break;
- case d_mode:
- oappend ("QWORD PTR ");
- break;
- case m_mode:
- if (mode_64bit)
- oappend ("DWORD PTR ");
- else
- oappend ("QWORD PTR ");
- break;
- case x_mode:
- oappend ("XWORD PTR ");
- break;
- default:
- break;
- }
- }
- *obufp++ = open_char;
- if (intel_syntax && riprel)
- oappend ("rip + ");
- *obufp = '\0';
- USED_REX (REX_EXTZ);
- if (!havesib && (rex & REX_EXTZ))
- base += 8;
- if (havebase)
- oappend (mode_64bit && (sizeflag & AFLAG)
- ? names64[base] : names32[base]);
- if (havesib)
- {
- if (index != 4)
- {
- if (intel_syntax)
- {
- if (havebase)
- {
- *obufp++ = separator_char;
- *obufp = '\0';
- }
- snprintf (scratchbuf, sizeof(scratchbuf), "%s",
- mode_64bit && (sizeflag & AFLAG)
- ? names64[index] : names32[index]);
- }
- else
- snprintf (scratchbuf, sizeof(scratchbuf), ",%s",
- mode_64bit && (sizeflag & AFLAG)
- ? names64[index] : names32[index]);
- oappend (scratchbuf);
- }
- if (!intel_syntax
- || (intel_syntax
- && bytemode != b_mode
- && bytemode != w_mode
- && bytemode != v_mode))
- {
- *obufp++ = scale_char;
- *obufp = '\0';
- snprintf (scratchbuf, sizeof(scratchbuf), "%d", 1 << scale);
- oappend (scratchbuf);
- }
- }
- if (intel_syntax)
- if (mod != 0 || (base & 7) == 5)
- {
- /* Don't print zero displacements. */
- if (disp != 0)
- {
- if ((bfd_signed_vma) disp > 0)
- {
- *obufp++ = '+';
- *obufp = '\0';
- }
-
- print_operand_value (scratchbuf, sizeof(scratchbuf), 0,
- disp);
- oappend (scratchbuf);
- }
- }
-
- *obufp++ = close_char;
- *obufp = '\0';
- }
- else if (intel_syntax)
- {
- if (mod != 0 || (base & 7) == 5)
- {
- if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS))
- ;
- else
- {
- oappend (names_seg[ds_reg - es_reg]);
- oappend (":");
- }
- print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
- oappend (scratchbuf);
- }
- }
- }
- else
- { /* 16 bit address mode */
- switch (mod)
- {
- case 0:
- if ((rm & 7) == 6)
- {
- disp = get16 ();
- if ((disp & 0x8000) != 0)
- disp -= 0x10000;
- }
- break;
- case 1:
- FETCH_DATA (the_info, codep + 1);
- disp = *codep++;
- if ((disp & 0x80) != 0)
- disp -= 0x100;
- break;
- case 2:
- disp = get16 ();
- if ((disp & 0x8000) != 0)
- disp -= 0x10000;
- break;
- }
-
- if (!intel_syntax)
- if (mod != 0 || (rm & 7) == 6)
- {
- print_operand_value (scratchbuf, sizeof(scratchbuf), 0, disp);
- oappend (scratchbuf);
- }
-
- if (mod != 0 || (rm & 7) != 6)
- {
- *obufp++ = open_char;
- *obufp = '\0';
- oappend (index16[rm + add]);
- *obufp++ = close_char;
- *obufp = '\0';
- }
- }
-}
-
-static void
-OP_G (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add += 8;
- switch (bytemode)
- {
- case b_mode:
- USED_REX (0);
- if (rex)
- oappend (names8rex[reg + add]);
- else
- oappend (names8[reg + add]);
- break;
- case w_mode:
- oappend (names16[reg + add]);
- break;
- case d_mode:
- oappend (names32[reg + add]);
- break;
- case q_mode:
- oappend (names64[reg + add]);
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- oappend (names64[reg + add]);
- else if (sizeflag & DFLAG)
- oappend (names32[reg + add]);
- else
- oappend (names16[reg + add]);
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
- }
-}
-
-static bfd_vma
-get64 ()
-{
- bfd_vma x;
-#ifdef BFD64
- unsigned int a;
- unsigned int b;
-
- FETCH_DATA (the_info, codep + 8);
- a = *codep++ & 0xff;
- a |= (*codep++ & 0xff) << 8;
- a |= (*codep++ & 0xff) << 16;
- a |= (*codep++ & 0xff) << 24;
- b = *codep++ & 0xff;
- b |= (*codep++ & 0xff) << 8;
- b |= (*codep++ & 0xff) << 16;
- b |= (*codep++ & 0xff) << 24;
- x = a + ((bfd_vma) b << 32);
-#else
- abort ();
- x = 0;
-#endif
- return x;
-}
-
-static bfd_signed_vma
-get32 ()
-{
- bfd_signed_vma x = 0;
-
- FETCH_DATA (the_info, codep + 4);
- x = *codep++ & (bfd_signed_vma) 0xff;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
- return x;
-}
-
-static bfd_signed_vma
-get32s ()
-{
- bfd_signed_vma x = 0;
-
- FETCH_DATA (the_info, codep + 4);
- x = *codep++ & (bfd_signed_vma) 0xff;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
- x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
-
- x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
-
- return x;
-}
-
-static int
-get16 ()
-{
- int x = 0;
-
- FETCH_DATA (the_info, codep + 2);
- x = *codep++ & 0xff;
- x |= (*codep++ & 0xff) << 8;
- return x;
-}
-
-static void
-set_op (op, riprel)
- bfd_vma op;
- int riprel;
-{
- op_index[op_ad] = op_ad;
- if (mode_64bit)
- {
- op_address[op_ad] = op;
- op_riprel[op_ad] = riprel;
- }
- else
- {
- /* Mask to get a 32-bit address. */
- op_address[op_ad] = op & 0xffffffff;
- op_riprel[op_ad] = riprel & 0xffffffff;
- }
-}
-
-static void
-OP_REG (code, sizeflag)
- int code;
- int sizeflag;
-{
- const char *s;
- int add = 0;
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add = 8;
-
- switch (code)
- {
- case indir_dx_reg:
- if (intel_syntax)
- s = "[dx]";
- else
- s = "(%dx)";
- break;
- case ax_reg: case cx_reg: case dx_reg: case bx_reg:
- case sp_reg: case bp_reg: case si_reg: case di_reg:
- s = names16[code - ax_reg + add];
- break;
- case es_reg: case ss_reg: case cs_reg:
- case ds_reg: case fs_reg: case gs_reg:
- s = names_seg[code - es_reg + add];
- break;
- case al_reg: case ah_reg: case cl_reg: case ch_reg:
- case dl_reg: case dh_reg: case bl_reg: case bh_reg:
- USED_REX (0);
- if (rex)
- s = names8rex[code - al_reg + add];
- else
- s = names8[code - al_reg];
- break;
- case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
- case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
- if (mode_64bit)
- {
- s = names64[code - rAX_reg + add];
- break;
- }
- code += eAX_reg - rAX_reg;
- /* Fall through. */
- case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
- case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- s = names64[code - eAX_reg + add];
- else if (sizeflag & DFLAG)
- s = names32[code - eAX_reg + add];
- else
- s = names16[code - eAX_reg + add];
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- default:
- s = INTERNAL_DISASSEMBLER_ERROR;
- break;
- }
- oappend (s);
-}
-
-static void
-OP_IMREG (code, sizeflag)
- int code;
- int sizeflag;
-{
- const char *s;
-
- switch (code)
- {
- case indir_dx_reg:
- if (intel_syntax)
- s = "[dx]";
- else
- s = "(%dx)";
- break;
- case ax_reg: case cx_reg: case dx_reg: case bx_reg:
- case sp_reg: case bp_reg: case si_reg: case di_reg:
- s = names16[code - ax_reg];
- break;
- case es_reg: case ss_reg: case cs_reg:
- case ds_reg: case fs_reg: case gs_reg:
- s = names_seg[code - es_reg];
- break;
- case al_reg: case ah_reg: case cl_reg: case ch_reg:
- case dl_reg: case dh_reg: case bl_reg: case bh_reg:
- USED_REX (0);
- if (rex)
- s = names8rex[code - al_reg];
- else
- s = names8[code - al_reg];
- break;
- case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
- case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- s = names64[code - eAX_reg];
- else if (sizeflag & DFLAG)
- s = names32[code - eAX_reg];
- else
- s = names16[code - eAX_reg];
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- default:
- s = INTERNAL_DISASSEMBLER_ERROR;
- break;
- }
- oappend (s);
-}
-
-static void
-OP_I (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_signed_vma op;
- bfd_signed_vma mask = -1;
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- op = *codep++;
- mask = 0xff;
- break;
- case q_mode:
- if (mode_64bit)
- {
- op = get32s ();
- break;
- }
- /* Fall through. */
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- op = get32s ();
- else if (sizeflag & DFLAG)
- {
- op = get32 ();
- mask = 0xffffffff;
- }
- else
- {
- op = get16 ();
- mask = 0xfffff;
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case w_mode:
- mask = 0xfffff;
- op = get16 ();
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
-
- op &= mask;
- scratchbuf[0] = '$';
- print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
- oappend (scratchbuf + intel_syntax);
- scratchbuf[0] = '\0';
-}
-
-static void
-OP_I64 (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_signed_vma op;
- bfd_signed_vma mask = -1;
-
- if (!mode_64bit)
- {
- OP_I (bytemode, sizeflag);
- return;
- }
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- op = *codep++;
- mask = 0xff;
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- op = get64 ();
- else if (sizeflag & DFLAG)
- {
- op = get32 ();
- mask = 0xffffffff;
- }
- else
- {
- op = get16 ();
- mask = 0xfffff;
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case w_mode:
- mask = 0xfffff;
- op = get16 ();
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
-
- op &= mask;
- scratchbuf[0] = '$';
- print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
- oappend (scratchbuf + intel_syntax);
- scratchbuf[0] = '\0';
-}
-
-static void
-OP_sI (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_signed_vma op;
- bfd_signed_vma mask = -1;
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- op = *codep++;
- if ((op & 0x80) != 0)
- op -= 0x100;
- mask = 0xffffffff;
- break;
- case v_mode:
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- op = get32s ();
- else if (sizeflag & DFLAG)
- {
- op = get32s ();
- mask = 0xffffffff;
- }
- else
- {
- mask = 0xffffffff;
- op = get16 ();
- if ((op & 0x8000) != 0)
- op -= 0x10000;
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- break;
- case w_mode:
- op = get16 ();
- mask = 0xffffffff;
- if ((op & 0x8000) != 0)
- op -= 0x10000;
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
-
- scratchbuf[0] = '$';
- print_operand_value (scratchbuf + 1, sizeof(scratchbuf) - 1, 1, op);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_J (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma disp;
- bfd_vma mask = -1;
-
- switch (bytemode)
- {
- case b_mode:
- FETCH_DATA (the_info, codep + 1);
- disp = *codep++;
- if ((disp & 0x80) != 0)
- disp -= 0x100;
- break;
- case v_mode:
- if (sizeflag & DFLAG)
- disp = get32s ();
- else
- {
- disp = get16 ();
- /* For some reason, a data16 prefix on a jump instruction
- means that the pc is masked to 16 bits after the
- displacement is added! */
- mask = 0xffff;
- }
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- return;
- }
- disp = (start_pc + codep - start_codep + disp) & mask;
- set_op (disp, 0);
- print_operand_value (scratchbuf, sizeof(scratchbuf), 1, disp);
- oappend (scratchbuf);
-}
-
-static void
-OP_SEG (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- oappend (names_seg[reg]);
-}
-
-static void
-OP_DIR (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- int seg, offset;
-
- if (sizeflag & DFLAG)
- {
- offset = get32 ();
- seg = get16 ();
- }
- else
- {
- offset = get16 ();
- seg = get16 ();
- }
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (intel_syntax)
- snprintf (scratchbuf, sizeof(scratchbuf), "0x%x,0x%x", seg, offset);
- else
- snprintf (scratchbuf, sizeof(scratchbuf), "$0x%x,$0x%x", seg, offset);
- oappend (scratchbuf);
-}
-
-static void
-OP_OFF (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma off;
-
- append_seg ();
-
- if ((sizeflag & AFLAG) || mode_64bit)
- off = get32 ();
- else
- off = get16 ();
-
- if (intel_syntax)
- {
- if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
- {
- oappend (names_seg[ds_reg - es_reg]);
- oappend (":");
- }
- }
- print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
- oappend (scratchbuf);
-}
-
-static void
-OP_OFF64 (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- bfd_vma off;
-
- if (!mode_64bit)
- {
- OP_OFF (bytemode, sizeflag);
- return;
- }
-
- append_seg ();
-
- off = get64 ();
-
- if (intel_syntax)
- {
- if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
- | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
- {
- oappend (names_seg[ds_reg - es_reg]);
- oappend (":");
- }
- }
- print_operand_value (scratchbuf, sizeof(scratchbuf), 1, off);
- oappend (scratchbuf);
-}
-
-static void
-ptr_reg (code, sizeflag)
- int code;
- int sizeflag;
-{
- const char *s;
- if (intel_syntax)
- oappend ("[");
- else
- oappend ("(");
-
- USED_REX (REX_MODE64);
- if (rex & REX_MODE64)
- {
- if (!(sizeflag & AFLAG))
- s = names32[code - eAX_reg];
- else
- s = names64[code - eAX_reg];
- }
- else if (sizeflag & AFLAG)
- s = names32[code - eAX_reg];
- else
- s = names16[code - eAX_reg];
- oappend (s);
- if (intel_syntax)
- oappend ("]");
- else
- oappend (")");
-}
-
-static void
-OP_ESreg (code, sizeflag)
- int code;
- int sizeflag;
-{
- oappend ("%es:" + intel_syntax);
- ptr_reg (code, sizeflag);
-}
-
-static void
-OP_DSreg (code, sizeflag)
- int code;
- int sizeflag;
-{
- if ((prefixes
- & (PREFIX_CS
- | PREFIX_DS
- | PREFIX_SS
- | PREFIX_ES
- | PREFIX_FS
- | PREFIX_GS)) == 0)
- prefixes |= PREFIX_DS;
- append_seg ();
- ptr_reg (code, sizeflag);
-}
-
-static void
-OP_C (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- snprintf (scratchbuf, sizeof(scratchbuf), "%%cr%d", reg + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_D (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- if (intel_syntax)
- snprintf (scratchbuf, sizeof(scratchbuf), "db%d", reg + add);
- else
- snprintf (scratchbuf, sizeof(scratchbuf), "%%db%d", reg + add);
- oappend (scratchbuf);
-}
-
-static void
-OP_T (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- snprintf (scratchbuf, sizeof(scratchbuf), "%%tr%d", reg);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_Rd (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (mod == 3)
- OP_E (bytemode, sizeflag);
- else
- BadOp ();
-}
-
-static void
-OP_MMX (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", reg + add);
- else
- snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", reg + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_XMM (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- USED_REX (REX_EXTX);
- if (rex & REX_EXTX)
- add = 8;
- snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", reg + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EM (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- if (mod != 3)
- {
- OP_E (bytemode, sizeflag);
- return;
- }
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add = 8;
-
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", rm + add);
- else
- snprintf (scratchbuf, sizeof(scratchbuf), "%%mm%d", rm + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_EX (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- int add = 0;
- if (mod != 3)
- {
- OP_E (bytemode, sizeflag);
- return;
- }
- USED_REX (REX_EXTZ);
- if (rex & REX_EXTZ)
- add = 8;
-
- /* Skip mod/rm byte. */
- MODRM_CHECK;
- codep++;
- snprintf (scratchbuf, sizeof(scratchbuf), "%%xmm%d", rm + add);
- oappend (scratchbuf + intel_syntax);
-}
-
-static void
-OP_MS (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (mod == 3)
- OP_EM (bytemode, sizeflag);
- else
- BadOp ();
-}
-
-static void
-OP_XS (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- if (mod == 3)
- OP_EX (bytemode, sizeflag);
- else
- BadOp ();
-}
-
-static const char *Suffix3DNow[] = {
-/* 00 */ NULL, NULL, NULL, NULL,
-/* 04 */ NULL, NULL, NULL, NULL,
-/* 08 */ NULL, NULL, NULL, NULL,
-/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
-/* 10 */ NULL, NULL, NULL, NULL,
-/* 14 */ NULL, NULL, NULL, NULL,
-/* 18 */ NULL, NULL, NULL, NULL,
-/* 1C */ "pf2iw", "pf2id", NULL, NULL,
-/* 20 */ NULL, NULL, NULL, NULL,
-/* 24 */ NULL, NULL, NULL, NULL,
-/* 28 */ NULL, NULL, NULL, NULL,
-/* 2C */ NULL, NULL, NULL, NULL,
-/* 30 */ NULL, NULL, NULL, NULL,
-/* 34 */ NULL, NULL, NULL, NULL,
-/* 38 */ NULL, NULL, NULL, NULL,
-/* 3C */ NULL, NULL, NULL, NULL,
-/* 40 */ NULL, NULL, NULL, NULL,
-/* 44 */ NULL, NULL, NULL, NULL,
-/* 48 */ NULL, NULL, NULL, NULL,
-/* 4C */ NULL, NULL, NULL, NULL,
-/* 50 */ NULL, NULL, NULL, NULL,
-/* 54 */ NULL, NULL, NULL, NULL,
-/* 58 */ NULL, NULL, NULL, NULL,
-/* 5C */ NULL, NULL, NULL, NULL,
-/* 60 */ NULL, NULL, NULL, NULL,
-/* 64 */ NULL, NULL, NULL, NULL,
-/* 68 */ NULL, NULL, NULL, NULL,
-/* 6C */ NULL, NULL, NULL, NULL,
-/* 70 */ NULL, NULL, NULL, NULL,
-/* 74 */ NULL, NULL, NULL, NULL,
-/* 78 */ NULL, NULL, NULL, NULL,
-/* 7C */ NULL, NULL, NULL, NULL,
-/* 80 */ NULL, NULL, NULL, NULL,
-/* 84 */ NULL, NULL, NULL, NULL,
-/* 88 */ NULL, NULL, "pfnacc", NULL,
-/* 8C */ NULL, NULL, "pfpnacc", NULL,
-/* 90 */ "pfcmpge", NULL, NULL, NULL,
-/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
-/* 98 */ NULL, NULL, "pfsub", NULL,
-/* 9C */ NULL, NULL, "pfadd", NULL,
-/* A0 */ "pfcmpgt", NULL, NULL, NULL,
-/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
-/* A8 */ NULL, NULL, "pfsubr", NULL,
-/* AC */ NULL, NULL, "pfacc", NULL,
-/* B0 */ "pfcmpeq", NULL, NULL, NULL,
-/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
-/* B8 */ NULL, NULL, NULL, "pswapd",
-/* BC */ NULL, NULL, NULL, "pavgusb",
-/* C0 */ NULL, NULL, NULL, NULL,
-/* C4 */ NULL, NULL, NULL, NULL,
-/* C8 */ NULL, NULL, NULL, NULL,
-/* CC */ NULL, NULL, NULL, NULL,
-/* D0 */ NULL, NULL, NULL, NULL,
-/* D4 */ NULL, NULL, NULL, NULL,
-/* D8 */ NULL, NULL, NULL, NULL,
-/* DC */ NULL, NULL, NULL, NULL,
-/* E0 */ NULL, NULL, NULL, NULL,
-/* E4 */ NULL, NULL, NULL, NULL,
-/* E8 */ NULL, NULL, NULL, NULL,
-/* EC */ NULL, NULL, NULL, NULL,
-/* F0 */ NULL, NULL, NULL, NULL,
-/* F4 */ NULL, NULL, NULL, NULL,
-/* F8 */ NULL, NULL, NULL, NULL,
-/* FC */ NULL, NULL, NULL, NULL,
-};
-
-static void
-OP_3DNowSuffix (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- const char *mnemonic;
-
- FETCH_DATA (the_info, codep + 1);
- /* AMD 3DNow! instructions are specified by an opcode suffix in the
- place where an 8-bit immediate would normally go. ie. the last
- byte of the instruction. */
- obufp = obuf + strlen (obuf);
- mnemonic = Suffix3DNow[*codep++ & 0xff];
- if (mnemonic)
- oappend (mnemonic);
- else
- {
- /* Since a variable sized modrm/sib chunk is between the start
- of the opcode (0x0f0f) and the opcode suffix, we need to do
- all the modrm processing first, and don't know until now that
- we have a bad opcode. This necessitates some cleaning up. */
- op1out[0] = '\0';
- op2out[0] = '\0';
- BadOp ();
- }
-}
-
-static const char *simd_cmp_op[] = {
- "eq",
- "lt",
- "le",
- "unord",
- "neq",
- "nlt",
- "nle",
- "ord"
-};
-
-static void
-OP_SIMD_Suffix (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
-{
- unsigned int cmp_type;
-
- FETCH_DATA (the_info, codep + 1);
- obufp = obuf + strlen (obuf);
- cmp_type = *codep++ & 0xff;
- if (cmp_type < 8)
- {
- char suffix1 = 'p', suffix2 = 's';
- used_prefixes |= (prefixes & PREFIX_REPZ);
- if (prefixes & PREFIX_REPZ)
- suffix1 = 's';
- else
- {
- used_prefixes |= (prefixes & PREFIX_DATA);
- if (prefixes & PREFIX_DATA)
- suffix2 = 'd';
- else
- {
- used_prefixes |= (prefixes & PREFIX_REPNZ);
- if (prefixes & PREFIX_REPNZ)
- suffix1 = 's', suffix2 = 'd';
- }
- }
- snprintf (scratchbuf, sizeof(scratchbuf), "cmp%s%c%c",
- simd_cmp_op[cmp_type], suffix1, suffix2);
- used_prefixes |= (prefixes & PREFIX_REPZ);
- oappend (scratchbuf);
- }
- else
- {
- /* We have a bad extension byte. Clean up. */
- op1out[0] = '\0';
- op2out[0] = '\0';
- BadOp ();
- }
-}
-
-static void
-SIMD_Fixup (extrachar, sizeflag)
- int extrachar;
- int sizeflag;
-{
- /* Change movlps/movhps to movhlps/movlhps for 2 register operand
- forms of these instructions. */
- if (mod == 3)
- {
- char *p = obuf + strlen (obuf);
- *(p + 1) = '\0';
- *p = *(p - 1);
- *(p - 1) = *(p - 2);
- *(p - 2) = *(p - 3);
- *(p - 3) = extrachar;
- }
-}
-
-static void
-BadOp (void)
-{
- /* Throw away prefixes and 1st. opcode byte. */
- codep = insn_codep + 1;
- oappend ("(bad)");
-}
diff --git a/i386-vl.ld b/i386-vl.ld
deleted file mode 100644
index 428fe83..0000000
--- a/i386-vl.ld
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0xa8000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- __preinit_array_start = .;
- .preinit_array : { *(.preinit_array) }
- __preinit_array_end = .;
- __init_array_start = .;
- .init_array : { *(.init_array) }
- __init_array_end = .;
- __fini_array_start = .;
- .fini_array : { *(.fini_array) }
- __fini_array_end = .;
-
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
diff --git a/i386.ld b/i386.ld
deleted file mode 100644
index 9f4cb5b..0000000
--- a/i386.ld
+++ /dev/null
@@ -1,142 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
diff --git a/ia64.ld b/ia64.ld
deleted file mode 100644
index 8d2ede2..0000000
--- a/ia64.ld
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Default linker script, for normal executables */
-OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little",
- "elf64-ia64-little")
-OUTPUT_ARCH(ia64)
-ENTRY(_start)
-SEARCH_DIR("/usr/ia64-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }
- .init :
- {
- KEEP (*(.init))
- } =0x00300000010070000002000001000400
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x00300000010070000002000001000400
- .fini :
- {
- KEEP (*(.fini))
- } =0x00300000010070000002000001000400
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
- .opd : { *(.opd) }
- .IA_64.unwind_info : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) }
- .IA_64.unwind : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x10000) + (. & (0x10000 - 1));
- /* Ensure the __preinit_array_start label is properly aligned. We
- could instead move the label definition inside the section, but
- the linker would then create the section even if it turns out to
- be empty, which isn't pretty. */
- . = ALIGN(64 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : { KEEP (*(.eh_frame)) }
- .gcc_except_table : { *(.gcc_except_table) }
- .dynamic : { *(.dynamic) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin*.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin*.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- /* Ensure __gp is outside the range of any normal data. We need to
- do this to avoid the linker optimizing the code in op.o and getting
- it out of sync with the relocs that we read when processing that
- file. A better solution might be to ensure that the dynamically
- generated code and static qemu code share a single gp-value. */
- __gp = . + 0x200000;
- .got : { *(.got.plt) *(.got) }
- .IA_64.pltoff : { *(.IA_64.pltoff) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata :
- {
- *(.sdata .sdata.* .gnu.linkonce.s.*)
- }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss :
- {
- PROVIDE (__sbss_start = .);
- PROVIDE (___sbss_start = .);
- *(.dynsbss)
- *(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
- PROVIDE (__sbss_end = .);
- PROVIDE (___sbss_end = .);
- }
- .bss :
- {
- . += 0x400000; /* ensure .bss stuff is out of reach of gp */
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
- . = ALIGN(64 / 8);
- }
- . = ALIGN(64 / 8);
- _end = .;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/images/android_icon.ico b/images/android_icon.ico
deleted file mode 100644
index bd25179..0000000
--- a/images/android_icon.ico
+++ /dev/null
Binary files differ
diff --git a/images/android_icon.rc b/images/android_icon.rc
deleted file mode 100644
index df468ac..0000000
--- a/images/android_icon.rc
+++ /dev/null
@@ -1,3 +0,0 @@
-1 ICON "../images/android_icon.ico"
-
-
diff --git a/images/android_icon_16.png b/images/android_icon_16.png
deleted file mode 100644
index 0b0744b..0000000
--- a/images/android_icon_16.png
+++ /dev/null
Binary files differ
diff --git a/images/android_icon_256.png b/images/android_icon_256.png
deleted file mode 100644
index 2d1dc05..0000000
--- a/images/android_icon_256.png
+++ /dev/null
Binary files differ
diff --git a/images/android_icon_32.png b/images/android_icon_32.png
deleted file mode 100644
index 72aa861..0000000
--- a/images/android_icon_32.png
+++ /dev/null
Binary files differ
diff --git a/keymaps.c b/keymaps.c
deleted file mode 100644
index 15c40fa..0000000
--- a/keymaps.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * QEMU keysym to keycode conversion using rdesktop keymaps
- *
- * Copyright (c) 2004 Johannes Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static int get_keysym(const char *name)
-{
- name2keysym_t *p;
- for(p = name2keysym; p->name != NULL; p++) {
- if (!strcmp(p->name, name))
- return p->keysym;
- }
- return 0;
-}
-
-struct key_range {
- int start;
- int end;
- struct key_range *next;
-};
-
-#define MAX_NORMAL_KEYCODE 512
-#define MAX_EXTRA_COUNT 256
-typedef struct {
- uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
- struct {
- int keysym;
- uint16_t keycode;
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
- int extra_count;
- struct key_range *keypad_range;
- struct key_range *numlock_range;
-} kbd_layout_t;
-
-static void add_to_key_range(struct key_range **krp, int code) {
- struct key_range *kr;
- for (kr = *krp; kr; kr = kr->next) {
- if (code >= kr->start && code <= kr->end)
- break;
- if (code == kr->start - 1) {
- kr->start--;
- break;
- }
- if (code == kr->end + 1) {
- kr->end++;
- break;
- }
- }
- if (kr == NULL) {
- kr = qemu_mallocz(sizeof(*kr));
- if (kr) {
- kr->start = kr->end = code;
- kr->next = *krp;
- *krp = kr;
- }
- }
-}
-
-static kbd_layout_t *parse_keyboard_layout(const char *language,
- kbd_layout_t * k)
-{
- FILE *f;
- char file_name[1024];
- char line[1024];
- int len;
-
- snprintf(file_name, sizeof(file_name),
- "%s/keymaps/%s", bios_dir, language);
-
- if (!k)
- k = qemu_mallocz(sizeof(kbd_layout_t));
- if (!k)
- return 0;
- if (!(f = fopen(file_name, "r"))) {
- fprintf(stderr,
- "Could not read keymap file: '%s'\n", file_name);
- return 0;
- }
- for(;;) {
- if (fgets(line, 1024, f) == NULL)
- break;
- len = strlen(line);
- if (len > 0 && line[len - 1] == '\n')
- line[len - 1] = '\0';
- if (line[0] == '#')
- continue;
- if (!strncmp(line, "map ", 4))
- continue;
- if (!strncmp(line, "include ", 8)) {
- parse_keyboard_layout(line + 8, k);
- } else {
- char *end_of_keysym = line;
- while (*end_of_keysym != 0 && *end_of_keysym != ' ')
- end_of_keysym++;
- if (*end_of_keysym) {
- int keysym;
- *end_of_keysym = 0;
- keysym = get_keysym(line);
- if (keysym == 0) {
- // fprintf(stderr, "Warning: unknown keysym %s\n", line);
- } else {
- const char *rest = end_of_keysym + 1;
- char *rest2;
- int keycode = strtol(rest, &rest2, 0);
-
- if (rest && strstr(rest, "numlock")) {
- add_to_key_range(&k->keypad_range, keycode);
- add_to_key_range(&k->numlock_range, keysym);
- //fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
- }
-
- /* if(keycode&0x80)
- keycode=(keycode<<8)^0x80e0; */
- if (keysym < MAX_NORMAL_KEYCODE) {
- //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
- k->keysym2keycode[keysym] = keycode;
- } else {
- if (k->extra_count >= MAX_EXTRA_COUNT) {
- fprintf(stderr,
- "Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",
- line, keysym);
- } else {
-#if 0
- fprintf(stderr, "Setting %d: %d,%d\n",
- k->extra_count, keysym, keycode);
-#endif
- k->keysym2keycode_extra[k->extra_count].
- keysym = keysym;
- k->keysym2keycode_extra[k->extra_count].
- keycode = keycode;
- k->extra_count++;
- }
- }
- }
- }
- }
- }
- fclose(f);
- return k;
-}
-
-static void *init_keyboard_layout(const char *language)
-{
- return parse_keyboard_layout(language, 0);
-}
-
-static int keysym2scancode(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- if (keysym < MAX_NORMAL_KEYCODE) {
- if (k->keysym2keycode[keysym] == 0)
- fprintf(stderr, "Warning: no scancode found for keysym %d\n",
- keysym);
- return k->keysym2keycode[keysym];
- } else {
- int i;
-#ifdef XK_ISO_Left_Tab
- if (keysym == XK_ISO_Left_Tab)
- keysym = XK_Tab;
-#endif
- for (i = 0; i < k->extra_count; i++)
- if (k->keysym2keycode_extra[i].keysym == keysym)
- return k->keysym2keycode_extra[i].keycode;
- }
- return 0;
-}
-
-static inline int keycode_is_keypad(void *kbd_layout, int keycode)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->keypad_range; kr; kr = kr->next)
- if (keycode >= kr->start && keycode <= kr->end)
- return 1;
- return 0;
-}
-
-static inline int keysym_is_numlock(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->numlock_range; kr; kr = kr->next)
- if (keysym >= kr->start && keysym <= kr->end)
- return 1;
- return 0;
-}
diff --git a/kqemu.c b/kqemu.c
deleted file mode 100644
index 4783aa2..0000000
--- a/kqemu.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * KQEMU support
- *
- * Copyright (c) 2005-2008 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winioctl.h>
-#else
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#endif
-#ifdef HOST_SOLARIS
-#include <sys/ioccom.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "qemu-common.h"
-
-#ifdef USE_KQEMU
-
-#define DEBUG
-//#define PROFILE
-
-#include <unistd.h>
-#include <fcntl.h>
-#include "kqemu.h"
-
-#ifdef _WIN32
-#define KQEMU_DEVICE "\\\\.\\kqemu"
-#else
-#define KQEMU_DEVICE "/dev/kqemu"
-#endif
-
-static void qpi_init(void);
-
-#ifdef _WIN32
-#define KQEMU_INVALID_FD INVALID_HANDLE_VALUE
-HANDLE kqemu_fd = KQEMU_INVALID_FD;
-#define kqemu_closefd(x) CloseHandle(x)
-#else
-#define KQEMU_INVALID_FD -1
-int kqemu_fd = KQEMU_INVALID_FD;
-#define kqemu_closefd(x) close(x)
-#endif
-
-/* 0 = not allowed
- 1 = user kqemu
- 2 = kernel kqemu
-*/
-int kqemu_allowed = 1;
-uint64_t *pages_to_flush;
-unsigned int nb_pages_to_flush;
-uint64_t *ram_pages_to_update;
-unsigned int nb_ram_pages_to_update;
-uint64_t *modified_ram_pages;
-unsigned int nb_modified_ram_pages;
-uint8_t *modified_ram_pages_table;
-int qpi_io_memory;
-uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
-
-#define cpuid(index, eax, ebx, ecx, edx) \
- asm volatile ("cpuid" \
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
- : "0" (index))
-
-#ifdef __x86_64__
-static int is_cpuid_supported(void)
-{
- return 1;
-}
-#else
-static int is_cpuid_supported(void)
-{
- int v0, v1;
- asm volatile ("pushf\n"
- "popl %0\n"
- "movl %0, %1\n"
- "xorl $0x00200000, %0\n"
- "pushl %0\n"
- "popf\n"
- "pushf\n"
- "popl %0\n"
- : "=a" (v0), "=d" (v1)
- :
- : "cc");
- return (v0 != v1);
-}
-#endif
-
-static void kqemu_update_cpuid(CPUState *env)
-{
- int critical_features_mask, features, ext_features, ext_features_mask;
- uint32_t eax, ebx, ecx, edx;
-
- /* the following features are kept identical on the host and
- target cpus because they are important for user code. Strictly
- speaking, only SSE really matters because the OS must support
- it if the user code uses it. */
- critical_features_mask =
- CPUID_CMOV | CPUID_CX8 |
- CPUID_FXSR | CPUID_MMX | CPUID_SSE |
- CPUID_SSE2 | CPUID_SEP;
- ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;
- if (!is_cpuid_supported()) {
- features = 0;
- ext_features = 0;
- } else {
- cpuid(1, eax, ebx, ecx, edx);
- features = edx;
- ext_features = ecx;
- }
-#ifdef __x86_64__
- /* NOTE: on x86_64 CPUs, SYSENTER is not supported in
- compatibility mode, so in order to have the best performances
- it is better not to use it */
- features &= ~CPUID_SEP;
-#endif
- env->cpuid_features = (env->cpuid_features & ~critical_features_mask) |
- (features & critical_features_mask);
- env->cpuid_ext_features = (env->cpuid_ext_features & ~ext_features_mask) |
- (ext_features & ext_features_mask);
- /* XXX: we could update more of the target CPUID state so that the
- non accelerated code sees exactly the same CPU features as the
- accelerated code */
-}
-
-int kqemu_init(CPUState *env)
-{
- struct kqemu_init kinit;
- int ret, version;
-#ifdef _WIN32
- DWORD temp;
-#endif
-
- if (!kqemu_allowed)
- return -1;
-
-#ifdef _WIN32
- kqemu_fd = CreateFile(KQEMU_DEVICE, GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (kqemu_fd == KQEMU_INVALID_FD) {
- fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n",
- KQEMU_DEVICE, GetLastError());
- return -1;
- }
-#else
- kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
- if (kqemu_fd == KQEMU_INVALID_FD) {
- fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
- KQEMU_DEVICE, strerror(errno));
- return -1;
- }
-#endif
- version = 0;
-#ifdef _WIN32
- DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0,
- &version, sizeof(version), &temp, NULL);
-#else
- ioctl(kqemu_fd, KQEMU_GET_VERSION, &version);
-#endif
- if (version != KQEMU_VERSION) {
- fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n",
- version, KQEMU_VERSION);
- goto fail;
- }
-
- pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
- sizeof(uint64_t));
- if (!pages_to_flush)
- goto fail;
-
- ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *
- sizeof(uint64_t));
- if (!ram_pages_to_update)
- goto fail;
-
- modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *
- sizeof(uint64_t));
- if (!modified_ram_pages)
- goto fail;
- modified_ram_pages_table = qemu_mallocz(phys_ram_size >> TARGET_PAGE_BITS);
- if (!modified_ram_pages_table)
- goto fail;
-
- memset(&kinit, 0, sizeof(kinit)); /* set the paddings to zero */
- kinit.ram_base = phys_ram_base;
- kinit.ram_size = phys_ram_size;
- kinit.ram_dirty = phys_ram_dirty;
- kinit.pages_to_flush = pages_to_flush;
- kinit.ram_pages_to_update = ram_pages_to_update;
- kinit.modified_ram_pages = modified_ram_pages;
-#ifdef _WIN32
- ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &kinit, sizeof(kinit),
- NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
-#else
- ret = ioctl(kqemu_fd, KQEMU_INIT, &kinit);
-#endif
- if (ret < 0) {
- fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);
- fail:
- kqemu_closefd(kqemu_fd);
- kqemu_fd = KQEMU_INVALID_FD;
- return -1;
- }
- kqemu_update_cpuid(env);
- env->kqemu_enabled = kqemu_allowed;
- nb_pages_to_flush = 0;
- nb_ram_pages_to_update = 0;
-
- qpi_init();
- return 0;
-}
-
-void kqemu_flush_page(CPUState *env, target_ulong addr)
-{
-#if defined(DEBUG)
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);
- }
-#endif
- if (nb_pages_to_flush >= KQEMU_MAX_PAGES_TO_FLUSH)
- nb_pages_to_flush = KQEMU_FLUSH_ALL;
- else
- pages_to_flush[nb_pages_to_flush++] = addr;
-}
-
-void kqemu_flush(CPUState *env, int global)
-{
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu_flush:\n");
- }
-#endif
- nb_pages_to_flush = KQEMU_FLUSH_ALL;
-}
-
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
-{
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu_set_notdirty: addr=%08lx\n",
- (unsigned long)ram_addr);
- }
-#endif
- /* we only track transitions to dirty state */
- if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)
- return;
- if (nb_ram_pages_to_update >= KQEMU_MAX_RAM_PAGES_TO_UPDATE)
- nb_ram_pages_to_update = KQEMU_RAM_PAGES_UPDATE_ALL;
- else
- ram_pages_to_update[nb_ram_pages_to_update++] = ram_addr;
-}
-
-static void kqemu_reset_modified_ram_pages(void)
-{
- int i;
- unsigned long page_index;
-
- for(i = 0; i < nb_modified_ram_pages; i++) {
- page_index = modified_ram_pages[i] >> TARGET_PAGE_BITS;
- modified_ram_pages_table[page_index] = 0;
- }
- nb_modified_ram_pages = 0;
-}
-
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
-{
- unsigned long page_index;
- int ret;
-#ifdef _WIN32
- DWORD temp;
-#endif
-
- page_index = ram_addr >> TARGET_PAGE_BITS;
- if (!modified_ram_pages_table[page_index]) {
-#if 0
- printf("%d: modify_page=%08lx\n", nb_modified_ram_pages, ram_addr);
-#endif
- modified_ram_pages_table[page_index] = 1;
- modified_ram_pages[nb_modified_ram_pages++] = ram_addr;
- if (nb_modified_ram_pages >= KQEMU_MAX_MODIFIED_RAM_PAGES) {
- /* flush */
-#ifdef _WIN32
- ret = DeviceIoControl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
- &nb_modified_ram_pages,
- sizeof(nb_modified_ram_pages),
- NULL, 0, &temp, NULL);
-#else
- ret = ioctl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
- &nb_modified_ram_pages);
-#endif
- kqemu_reset_modified_ram_pages();
- }
- }
-}
-
-void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size,
- ram_addr_t phys_offset)
-{
- struct kqemu_phys_mem kphys_mem1, *kphys_mem = &kphys_mem1;
- uint64_t end;
- int ret, io_index;
-
- end = (start_addr + size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
- start_addr &= TARGET_PAGE_MASK;
- kphys_mem->phys_addr = start_addr;
- kphys_mem->size = end - start_addr;
- kphys_mem->ram_addr = phys_offset & TARGET_PAGE_MASK;
- io_index = phys_offset & ~TARGET_PAGE_MASK;
- switch(io_index) {
- case IO_MEM_RAM:
- kphys_mem->io_index = KQEMU_IO_MEM_RAM;
- break;
- case IO_MEM_ROM:
- kphys_mem->io_index = KQEMU_IO_MEM_ROM;
- break;
- default:
- if (qpi_io_memory == io_index) {
- kphys_mem->io_index = KQEMU_IO_MEM_COMM;
- } else {
- kphys_mem->io_index = KQEMU_IO_MEM_UNASSIGNED;
- }
- break;
- }
-#ifdef _WIN32
- {
- DWORD temp;
- ret = DeviceIoControl(kqemu_fd, KQEMU_SET_PHYS_MEM,
- kphys_mem, sizeof(*kphys_mem),
- NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
- }
-#else
- ret = ioctl(kqemu_fd, KQEMU_SET_PHYS_MEM, kphys_mem);
-#endif
- if (ret < 0) {
- fprintf(stderr, "kqemu: KQEMU_SET_PHYS_PAGE error=%d: start_addr=0x%016" PRIx64 " size=0x%08lx phys_offset=0x%08lx\n",
- ret, start_addr,
- (unsigned long)size, (unsigned long)phys_offset);
- }
-}
-
-struct fpstate {
- uint16_t fpuc;
- uint16_t dummy1;
- uint16_t fpus;
- uint16_t dummy2;
- uint16_t fptag;
- uint16_t dummy3;
-
- uint32_t fpip;
- uint32_t fpcs;
- uint32_t fpoo;
- uint32_t fpos;
- uint8_t fpregs1[8 * 10];
-};
-
-struct fpxstate {
- uint16_t fpuc;
- uint16_t fpus;
- uint16_t fptag;
- uint16_t fop;
- uint32_t fpuip;
- uint16_t cs_sel;
- uint16_t dummy0;
- uint32_t fpudp;
- uint16_t ds_sel;
- uint16_t dummy1;
- uint32_t mxcsr;
- uint32_t mxcsr_mask;
- uint8_t fpregs1[8 * 16];
- uint8_t xmm_regs[16 * 16];
- uint8_t dummy2[96];
-};
-
-static struct fpxstate fpx1 __attribute__((aligned(16)));
-
-static void restore_native_fp_frstor(CPUState *env)
-{
- int fptag, i, j;
- struct fpstate fp1, *fp = &fp1;
-
- fp->fpuc = env->fpuc;
- fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for (i=7; i>=0; i--) {
- fptag <<= 2;
- if (env->fptags[i]) {
- fptag |= 3;
- } else {
- /* the FPU automatically computes it */
- }
- }
- fp->fptag = fptag;
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&fp->fpregs1[i * 10], &env->fpregs[j].d, 10);
- j = (j + 1) & 7;
- }
- asm volatile ("frstor %0" : "=m" (*fp));
-}
-
-static void save_native_fp_fsave(CPUState *env)
-{
- int fptag, i, j;
- uint16_t fpuc;
- struct fpstate fp1, *fp = &fp1;
-
- asm volatile ("fsave %0" : : "m" (*fp));
- env->fpuc = fp->fpuc;
- env->fpstt = (fp->fpus >> 11) & 7;
- env->fpus = fp->fpus & ~0x3800;
- fptag = fp->fptag;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = ((fptag & 3) == 3);
- fptag >>= 2;
- }
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 10], 10);
- j = (j + 1) & 7;
- }
- /* we must restore the default rounding state */
- fpuc = 0x037f | (env->fpuc & (3 << 10));
- asm volatile("fldcw %0" : : "m" (fpuc));
-}
-
-static void restore_native_fp_fxrstor(CPUState *env)
-{
- struct fpxstate *fp = &fpx1;
- int i, j, fptag;
-
- fp->fpuc = env->fpuc;
- fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- fptag = 0;
- for(i = 0; i < 8; i++)
- fptag |= (env->fptags[i] << i);
- fp->fptag = fptag ^ 0xff;
-
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&fp->fpregs1[i * 16], &env->fpregs[j].d, 10);
- j = (j + 1) & 7;
- }
- if (env->cpuid_features & CPUID_SSE) {
- fp->mxcsr = env->mxcsr;
- /* XXX: check if DAZ is not available */
- fp->mxcsr_mask = 0xffff;
- memcpy(fp->xmm_regs, env->xmm_regs, CPU_NB_REGS * 16);
- }
- asm volatile ("fxrstor %0" : "=m" (*fp));
-}
-
-static void save_native_fp_fxsave(CPUState *env)
-{
- struct fpxstate *fp = &fpx1;
- int fptag, i, j;
- uint16_t fpuc;
-
- asm volatile ("fxsave %0" : : "m" (*fp));
- env->fpuc = fp->fpuc;
- env->fpstt = (fp->fpus >> 11) & 7;
- env->fpus = fp->fpus & ~0x3800;
- fptag = fp->fptag ^ 0xff;
- for(i = 0;i < 8; i++) {
- env->fptags[i] = (fptag >> i) & 1;
- }
- j = env->fpstt;
- for(i = 0;i < 8; i++) {
- memcpy(&env->fpregs[j].d, &fp->fpregs1[i * 16], 10);
- j = (j + 1) & 7;
- }
- if (env->cpuid_features & CPUID_SSE) {
- env->mxcsr = fp->mxcsr;
- memcpy(env->xmm_regs, fp->xmm_regs, CPU_NB_REGS * 16);
- }
-
- /* we must restore the default rounding state */
- asm volatile ("fninit");
- fpuc = 0x037f | (env->fpuc & (3 << 10));
- asm volatile("fldcw %0" : : "m" (fpuc));
-}
-
-static int do_syscall(CPUState *env,
- struct kqemu_cpu_state *kenv)
-{
- int selector;
-
- selector = (env->star >> 32) & 0xffff;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- int code64;
-
- env->regs[R_ECX] = kenv->next_eip;
- env->regs[11] = env->eflags;
-
- code64 = env->hflags & HF_CS64_MASK;
-
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~env->fmask;
- if (code64)
- env->eip = env->lstar;
- else
- env->eip = env->cstar;
- } else
-#endif
- {
- env->regs[R_ECX] = (uint32_t)kenv->next_eip;
-
- cpu_x86_set_cpl(env, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
- env->eip = (uint32_t)env->star;
- }
- return 2;
-}
-
-#ifdef CONFIG_PROFILER
-
-#define PC_REC_SIZE 1
-#define PC_REC_HASH_BITS 16
-#define PC_REC_HASH_SIZE (1 << PC_REC_HASH_BITS)
-
-typedef struct PCRecord {
- unsigned long pc;
- int64_t count;
- struct PCRecord *next;
-} PCRecord;
-
-static PCRecord *pc_rec_hash[PC_REC_HASH_SIZE];
-static int nb_pc_records;
-
-static void kqemu_record_pc(unsigned long pc)
-{
- unsigned long h;
- PCRecord **pr, *r;
-
- h = pc / PC_REC_SIZE;
- h = h ^ (h >> PC_REC_HASH_BITS);
- h &= (PC_REC_HASH_SIZE - 1);
- pr = &pc_rec_hash[h];
- for(;;) {
- r = *pr;
- if (r == NULL)
- break;
- if (r->pc == pc) {
- r->count++;
- return;
- }
- pr = &r->next;
- }
- r = malloc(sizeof(PCRecord));
- r->count = 1;
- r->pc = pc;
- r->next = NULL;
- *pr = r;
- nb_pc_records++;
-}
-
-static int pc_rec_cmp(const void *p1, const void *p2)
-{
- PCRecord *r1 = *(PCRecord **)p1;
- PCRecord *r2 = *(PCRecord **)p2;
- if (r1->count < r2->count)
- return 1;
- else if (r1->count == r2->count)
- return 0;
- else
- return -1;
-}
-
-static void kqemu_record_flush(void)
-{
- PCRecord *r, *r_next;
- int h;
-
- for(h = 0; h < PC_REC_HASH_SIZE; h++) {
- for(r = pc_rec_hash[h]; r != NULL; r = r_next) {
- r_next = r->next;
- free(r);
- }
- pc_rec_hash[h] = NULL;
- }
- nb_pc_records = 0;
-}
-
-void kqemu_record_dump(void)
-{
- PCRecord **pr, *r;
- int i, h;
- FILE *f;
- int64_t total, sum;
-
- pr = malloc(sizeof(PCRecord *) * nb_pc_records);
- i = 0;
- total = 0;
- for(h = 0; h < PC_REC_HASH_SIZE; h++) {
- for(r = pc_rec_hash[h]; r != NULL; r = r->next) {
- pr[i++] = r;
- total += r->count;
- }
- }
- qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);
-
- f = fopen("/tmp/kqemu.stats", "w");
- if (!f) {
- perror("/tmp/kqemu.stats");
- exit(1);
- }
- fprintf(f, "total: %" PRId64 "\n", total);
- sum = 0;
- for(i = 0; i < nb_pc_records; i++) {
- r = pr[i];
- sum += r->count;
- fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",
- r->pc,
- r->count,
- (double)r->count / (double)total * 100.0,
- (double)sum / (double)total * 100.0);
- }
- fclose(f);
- free(pr);
-
- kqemu_record_flush();
-}
-#endif
-
-static inline void kqemu_load_seg(struct kqemu_segment_cache *ksc,
- const SegmentCache *sc)
-{
- ksc->selector = sc->selector;
- ksc->flags = sc->flags;
- ksc->limit = sc->limit;
- ksc->base = sc->base;
-}
-
-static inline void kqemu_save_seg(SegmentCache *sc,
- const struct kqemu_segment_cache *ksc)
-{
- sc->selector = ksc->selector;
- sc->flags = ksc->flags;
- sc->limit = ksc->limit;
- sc->base = ksc->base;
-}
-
-int kqemu_cpu_exec(CPUState *env)
-{
- struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
- int ret, cpl, i;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
-#ifdef _WIN32
- DWORD temp;
-#endif
-
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: cpu_exec: enter\n");
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- for(i = 0; i < CPU_NB_REGS; i++)
- kenv->regs[i] = env->regs[i];
- kenv->eip = env->eip;
- kenv->eflags = env->eflags;
- for(i = 0; i < 6; i++)
- kqemu_load_seg(&kenv->segs[i], &env->segs[i]);
- kqemu_load_seg(&kenv->ldt, &env->ldt);
- kqemu_load_seg(&kenv->tr, &env->tr);
- kqemu_load_seg(&kenv->gdt, &env->gdt);
- kqemu_load_seg(&kenv->idt, &env->idt);
- kenv->cr0 = env->cr[0];
- kenv->cr2 = env->cr[2];
- kenv->cr3 = env->cr[3];
- kenv->cr4 = env->cr[4];
- kenv->a20_mask = env->a20_mask;
- kenv->efer = env->efer;
- kenv->tsc_offset = 0;
- kenv->star = env->star;
- kenv->sysenter_cs = env->sysenter_cs;
- kenv->sysenter_esp = env->sysenter_esp;
- kenv->sysenter_eip = env->sysenter_eip;
-#ifdef TARGET_X86_64
- kenv->lstar = env->lstar;
- kenv->cstar = env->cstar;
- kenv->fmask = env->fmask;
- kenv->kernelgsbase = env->kernelgsbase;
-#endif
- if (env->dr[7] & 0xff) {
- kenv->dr7 = env->dr[7];
- kenv->dr0 = env->dr[0];
- kenv->dr1 = env->dr[1];
- kenv->dr2 = env->dr[2];
- kenv->dr3 = env->dr[3];
- } else {
- kenv->dr7 = 0;
- }
- kenv->dr6 = env->dr[6];
- cpl = (env->hflags & HF_CPL_MASK);
- kenv->cpl = cpl;
- kenv->nb_pages_to_flush = nb_pages_to_flush;
- kenv->user_only = (env->kqemu_enabled == 1);
- kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
- nb_ram_pages_to_update = 0;
- kenv->nb_modified_ram_pages = nb_modified_ram_pages;
-
- kqemu_reset_modified_ram_pages();
-
- if (env->cpuid_features & CPUID_FXSR)
- restore_native_fp_fxrstor(env);
- else
- restore_native_fp_frstor(env);
-
-#ifdef _WIN32
- if (DeviceIoControl(kqemu_fd, KQEMU_EXEC,
- kenv, sizeof(struct kqemu_cpu_state),
- kenv, sizeof(struct kqemu_cpu_state),
- &temp, NULL)) {
- ret = kenv->retval;
- } else {
- ret = -1;
- }
-#else
- ioctl(kqemu_fd, KQEMU_EXEC, kenv);
- ret = kenv->retval;
-#endif
- if (env->cpuid_features & CPUID_FXSR)
- save_native_fp_fxsave(env);
- else
- save_native_fp_fsave(env);
-
- for(i = 0; i < CPU_NB_REGS; i++)
- env->regs[i] = kenv->regs[i];
- env->eip = kenv->eip;
- env->eflags = kenv->eflags;
- for(i = 0; i < 6; i++)
- kqemu_save_seg(&env->segs[i], &kenv->segs[i]);
- cpu_x86_set_cpl(env, kenv->cpl);
- kqemu_save_seg(&env->ldt, &kenv->ldt);
- env->cr[0] = kenv->cr0;
- env->cr[4] = kenv->cr4;
- env->cr[3] = kenv->cr3;
- env->cr[2] = kenv->cr2;
- env->dr[6] = kenv->dr6;
-#ifdef TARGET_X86_64
- env->kernelgsbase = kenv->kernelgsbase;
-#endif
-
- /* flush pages as indicated by kqemu */
- if (kenv->nb_pages_to_flush >= KQEMU_FLUSH_ALL) {
- tlb_flush(env, 1);
- } else {
- for(i = 0; i < kenv->nb_pages_to_flush; i++) {
- tlb_flush_page(env, pages_to_flush[i]);
- }
- }
- nb_pages_to_flush = 0;
-
-#ifdef CONFIG_PROFILER
- kqemu_time += profile_getclock() - ti;
- kqemu_exec_count++;
-#endif
-
- if (kenv->nb_ram_pages_to_update > 0) {
- cpu_tlb_update_dirty(env);
- }
-
- if (kenv->nb_modified_ram_pages > 0) {
- for(i = 0; i < kenv->nb_modified_ram_pages; i++) {
- unsigned long addr;
- addr = modified_ram_pages[i];
- tb_invalidate_phys_page_range(addr, addr + TARGET_PAGE_SIZE, 0);
- }
- }
-
- /* restore the hidden flags */
- {
- unsigned int new_hflags;
-#ifdef TARGET_X86_64
- if ((env->hflags & HF_LMA_MASK) &&
- (env->segs[R_CS].flags & DESC_L_MASK)) {
- /* long mode */
- new_hflags = HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
- } else
-#endif
- {
- /* legacy / compatibility case */
- new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
- >> (DESC_B_SHIFT - HF_CS32_SHIFT);
- new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
- >> (DESC_B_SHIFT - HF_SS32_SHIFT);
- if (!(env->cr[0] & CR0_PE_MASK) ||
- (env->eflags & VM_MASK) ||
- !(env->hflags & HF_CS32_MASK)) {
- /* XXX: try to avoid this test. The problem comes from the
- fact that is real mode or vm86 mode we only modify the
- 'base' and 'selector' fields of the segment cache to go
- faster. A solution may be to force addseg to one in
- translate-i386.c. */
- new_hflags |= HF_ADDSEG_MASK;
- } else {
- new_hflags |= ((env->segs[R_DS].base |
- env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) <<
- HF_ADDSEG_SHIFT;
- }
- }
- env->hflags = (env->hflags &
- ~(HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)) |
- new_hflags;
- }
- /* update FPU flags */
- env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
- ((env->cr[0] << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
- if (env->cr[4] & CR4_OSFXSR_MASK)
- env->hflags |= HF_OSFXSR_MASK;
- else
- env->hflags &= ~HF_OSFXSR_MASK;
-
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
- }
-#endif
- if (ret == KQEMU_RET_SYSCALL) {
- /* syscall instruction */
- return do_syscall(env, kenv);
- } else
- if ((ret & 0xff00) == KQEMU_RET_INT) {
- env->exception_index = ret & 0xff;
- env->error_code = 0;
- env->exception_is_int = 1;
- env->exception_next_eip = kenv->next_eip;
-#ifdef CONFIG_PROFILER
- kqemu_ret_int_count++;
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: interrupt v=%02x:\n",
- env->exception_index);
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 1;
- } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
- env->exception_index = ret & 0xff;
- env->error_code = kenv->error_code;
- env->exception_is_int = 0;
- env->exception_next_eip = 0;
-#ifdef CONFIG_PROFILER
- kqemu_ret_excp_count++;
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- fprintf(logfile, "kqemu: exception v=%02x e=%04x:\n",
- env->exception_index, env->error_code);
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 1;
- } else if (ret == KQEMU_RET_INTR) {
-#ifdef CONFIG_PROFILER
- kqemu_ret_intr_count++;
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 0;
- } else if (ret == KQEMU_RET_SOFTMMU) {
-#ifdef CONFIG_PROFILER
- {
- unsigned long pc = env->eip + env->segs[R_CS].base;
- kqemu_record_pc(pc);
- }
-#endif
-#ifdef DEBUG
- if (loglevel & CPU_LOG_INT) {
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
- return 2;
- } else {
- cpu_dump_state(env, stderr, fprintf, 0);
- fprintf(stderr, "Unsupported return value: 0x%x\n", ret);
- exit(1);
- }
- return 0;
-}
-
-void kqemu_cpu_interrupt(CPUState *env)
-{
-#if defined(_WIN32)
- /* cancelling the I/O request causes KQEMU to finish executing the
- current block and successfully returning. */
- CancelIo(kqemu_fd);
-#endif
-}
-
-/*
- QEMU paravirtualization interface. The current interface only
- allows to modify the IF and IOPL flags when running in
- kqemu.
-
- At this point it is not very satisfactory. I leave it for reference
- as it adds little complexity.
-*/
-
-#define QPI_COMM_PAGE_PHYS_ADDR 0xff000000
-
-static uint32_t qpi_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static uint32_t qpi_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static void qpi_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-}
-
-static void qpi_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-}
-
-static uint32_t qpi_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- CPUState *env;
-
- env = cpu_single_env;
- if (!env)
- return 0;
- return env->eflags & (IF_MASK | IOPL_MASK);
-}
-
-/* Note: after writing to this address, the guest code must make sure
- it is exiting the current TB. pushf/popf can be used for that
- purpose. */
-static void qpi_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- CPUState *env;
-
- env = cpu_single_env;
- if (!env)
- return;
- env->eflags = (env->eflags & ~(IF_MASK | IOPL_MASK)) |
- (val & (IF_MASK | IOPL_MASK));
-}
-
-static CPUReadMemoryFunc *qpi_mem_read[3] = {
- qpi_mem_readb,
- qpi_mem_readw,
- qpi_mem_readl,
-};
-
-static CPUWriteMemoryFunc *qpi_mem_write[3] = {
- qpi_mem_writeb,
- qpi_mem_writew,
- qpi_mem_writel,
-};
-
-static void qpi_init(void)
-{
- kqemu_comm_base = 0xff000000 | 1;
- qpi_io_memory = cpu_register_io_memory(0,
- qpi_mem_read,
- qpi_mem_write, NULL);
- cpu_register_physical_memory(kqemu_comm_base & ~0xfff,
- 0x1000, qpi_io_memory);
-}
-#endif
diff --git a/kqemu.h b/kqemu.h
deleted file mode 100644
index ed25c75..0000000
--- a/kqemu.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * KQEMU header
- *
- * Copyright (c) 2004-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef KQEMU_H
-#define KQEMU_H
-
-#if defined(__i386__)
-#define KQEMU_PAD32(x) x
-#else
-#define KQEMU_PAD32(x)
-#endif
-
-#define KQEMU_VERSION 0x010400
-
-struct kqemu_segment_cache {
- uint16_t selector;
- uint16_t padding1;
- uint32_t flags;
- uint64_t base;
- uint32_t limit;
- uint32_t padding2;
-};
-
-struct kqemu_cpu_state {
- uint64_t regs[16];
- uint64_t eip;
- uint64_t eflags;
-
- struct kqemu_segment_cache segs[6]; /* selector values */
- struct kqemu_segment_cache ldt;
- struct kqemu_segment_cache tr;
- struct kqemu_segment_cache gdt; /* only base and limit are used */
- struct kqemu_segment_cache idt; /* only base and limit are used */
-
- uint64_t cr0;
- uint64_t cr2;
- uint64_t cr3;
- uint64_t cr4;
- uint64_t a20_mask;
-
- /* sysenter registers */
- uint64_t sysenter_cs;
- uint64_t sysenter_esp;
- uint64_t sysenter_eip;
- uint64_t efer;
- uint64_t star;
-
- uint64_t lstar;
- uint64_t cstar;
- uint64_t fmask;
- uint64_t kernelgsbase;
-
- uint64_t tsc_offset;
-
- uint64_t dr0;
- uint64_t dr1;
- uint64_t dr2;
- uint64_t dr3;
- uint64_t dr6;
- uint64_t dr7;
-
- uint8_t cpl;
- uint8_t user_only;
- uint16_t padding1;
-
- uint32_t error_code; /* error_code when exiting with an exception */
- uint64_t next_eip; /* next eip value when exiting with an interrupt */
- uint32_t nb_pages_to_flush; /* number of pages to flush,
- KQEMU_FLUSH_ALL means full flush */
-#define KQEMU_MAX_PAGES_TO_FLUSH 512
-#define KQEMU_FLUSH_ALL (KQEMU_MAX_PAGES_TO_FLUSH + 1)
-
- int32_t retval;
-
- /* number of ram_dirty entries to update */
- uint32_t nb_ram_pages_to_update;
-#define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512
-#define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)
-
-#define KQEMU_MAX_MODIFIED_RAM_PAGES 512
- uint32_t nb_modified_ram_pages;
-};
-
-struct kqemu_init {
- uint8_t *ram_base; /* must be page aligned */
- KQEMU_PAD32(uint32_t padding1;)
- uint64_t ram_size; /* must be multiple of 4 KB */
- uint8_t *ram_dirty; /* must be page aligned */
- KQEMU_PAD32(uint32_t padding2;)
- uint64_t *pages_to_flush; /* must be page aligned */
- KQEMU_PAD32(uint32_t padding4;)
- uint64_t *ram_pages_to_update; /* must be page aligned */
- KQEMU_PAD32(uint32_t padding5;)
- uint64_t *modified_ram_pages; /* must be page aligned */
- KQEMU_PAD32(uint32_t padding6;)
-};
-
-#define KQEMU_IO_MEM_RAM 0
-#define KQEMU_IO_MEM_ROM 1
-#define KQEMU_IO_MEM_COMM 2 /* kqemu communication page */
-#define KQEMU_IO_MEM_UNASSIGNED 3 /* any device: return to application */
-
-struct kqemu_phys_mem {
- uint64_t phys_addr; /* physical address range: phys_addr,
- phys_addr + size */
- uint64_t size;
- uint64_t ram_addr; /* corresponding ram address */
- uint32_t io_index; /* memory type: see KQEMU_IO_MEM_xxx */
- uint32_t padding1;
-};
-
-#define KQEMU_RET_ABORT (-1)
-#define KQEMU_RET_EXCEPTION 0x0000 /* 8 low order bit are the exception */
-#define KQEMU_RET_INT 0x0100 /* 8 low order bit are the interrupt */
-#define KQEMU_RET_SOFTMMU 0x0200 /* emulation needed (I/O or
- unsupported INSN) */
-#define KQEMU_RET_INTR 0x0201 /* interrupted by a signal */
-#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */
-
-#ifdef _WIN32
-#define KQEMU_EXEC CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
-#define KQEMU_INIT CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define KQEMU_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define KQEMU_MODIFY_RAM_PAGES CTL_CODE(FILE_DEVICE_UNKNOWN, 4, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define KQEMU_SET_PHYS_MEM CTL_CODE(FILE_DEVICE_UNKNOWN, 5, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#else
-#define KQEMU_EXEC _IOWR('q', 1, struct kqemu_cpu_state)
-#define KQEMU_INIT _IOW('q', 2, struct kqemu_init)
-#define KQEMU_GET_VERSION _IOR('q', 3, int)
-#define KQEMU_MODIFY_RAM_PAGES _IOW('q', 4, int)
-#define KQEMU_SET_PHYS_MEM _IOW('q', 5, struct kqemu_phys_mem)
-#endif
-
-#endif /* KQEMU_H */
diff --git a/linux_keycodes.h b/linux_keycodes.h
deleted file mode 100644
index 3875028..0000000
--- a/linux_keycodes.h
+++ /dev/null
@@ -1,452 +0,0 @@
-#ifndef _INPUT_H
-#define _INPUT_H
-
-/*
- * Copyright (c) 1999-2002 Vojtech Pavlik
- *
- * 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.
- */
-
-/*
- * Keys and buttons
- */
-
-#define KEY_RESERVED 0
-#define KEY_ESC 1
-#define KEY_1 2
-#define KEY_2 3
-#define KEY_3 4
-#define KEY_4 5
-#define KEY_5 6
-#define KEY_6 7
-#define KEY_7 8
-#define KEY_8 9
-#define KEY_9 10
-#define KEY_0 11
-#define KEY_MINUS 12
-#define KEY_EQUAL 13
-#define KEY_BACKSPACE 14
-#define KEY_TAB 15
-#define KEY_Q 16
-#define KEY_W 17
-#define KEY_E 18
-#define KEY_R 19
-#define KEY_T 20
-#define KEY_Y 21
-#define KEY_U 22
-#define KEY_I 23
-#define KEY_O 24
-#define KEY_P 25
-#define KEY_LEFTBRACE 26
-#define KEY_RIGHTBRACE 27
-#define KEY_ENTER 28
-#define KEY_LEFTCTRL 29
-#define KEY_A 30
-#define KEY_S 31
-#define KEY_D 32
-#define KEY_F 33
-#define KEY_G 34
-#define KEY_H 35
-#define KEY_J 36
-#define KEY_K 37
-#define KEY_L 38
-#define KEY_SEMICOLON 39
-#define KEY_APOSTROPHE 40
-#define KEY_GRAVE 41
-#define KEY_LEFTSHIFT 42
-#define KEY_BACKSLASH 43
-#define KEY_Z 44
-#define KEY_X 45
-#define KEY_C 46
-#define KEY_V 47
-#define KEY_B 48
-#define KEY_N 49
-#define KEY_M 50
-#define KEY_COMMA 51
-#define KEY_DOT 52
-#define KEY_SLASH 53
-#define KEY_RIGHTSHIFT 54
-#define KEY_KPASTERISK 55
-#define KEY_LEFTALT 56
-#define KEY_SPACE 57
-#define KEY_CAPSLOCK 58
-#define KEY_F1 59
-#define KEY_F2 60
-#define KEY_F3 61
-#define KEY_F4 62
-#define KEY_F5 63
-#define KEY_F6 64
-#define KEY_F7 65
-#define KEY_F8 66
-#define KEY_F9 67
-#define KEY_F10 68
-#define KEY_NUMLOCK 69
-#define KEY_SCROLLLOCK 70
-#define KEY_KP7 71
-#define KEY_KP8 72
-#define KEY_KP9 73
-#define KEY_KPMINUS 74
-#define KEY_KP4 75
-#define KEY_KP5 76
-#define KEY_KP6 77
-#define KEY_KPPLUS 78
-#define KEY_KP1 79
-#define KEY_KP2 80
-#define KEY_KP3 81
-#define KEY_KP0 82
-#define KEY_KPDOT 83
-
-#define KEY_ZENKAKUHANKAKU 85
-#define KEY_102ND 86
-#define KEY_F11 87
-#define KEY_F12 88
-#define KEY_RO 89
-#define KEY_KATAKANA 90
-#define KEY_HIRAGANA 91
-#define KEY_HENKAN 92
-#define KEY_KATAKANAHIRAGANA 93
-#define KEY_MUHENKAN 94
-#define KEY_KPJPCOMMA 95
-#define KEY_KPENTER 96
-#define KEY_RIGHTCTRL 97
-#define KEY_KPSLASH 98
-#define KEY_SYSRQ 99
-#define KEY_RIGHTALT 100
-#define KEY_LINEFEED 101
-#define KEY_HOME 102
-#define KEY_UP 103
-#define KEY_PAGEUP 104
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_END 107
-#define KEY_DOWN 108
-#define KEY_PAGEDOWN 109
-#define KEY_INSERT 110
-#define KEY_DELETE 111
-#define KEY_MACRO 112
-#define KEY_MUTE 113
-#define KEY_VOLUMEDOWN 114
-#define KEY_VOLUMEUP 115
-#define KEY_POWER 116
-#define KEY_KPEQUAL 117
-#define KEY_KPPLUSMINUS 118
-#define KEY_PAUSE 119
-
-#define KEY_KPCOMMA 121
-#define KEY_HANGEUL 122
-#define KEY_HANGUEL KEY_HANGEUL
-#define KEY_HANJA 123
-#define KEY_YEN 124
-#define KEY_LEFTMETA 125
-#define KEY_RIGHTMETA 126
-#define KEY_COMPOSE 127
-
-#define KEY_STOP 128
-#define KEY_AGAIN 129
-#define KEY_PROPS 130
-#define KEY_UNDO 131
-#define KEY_FRONT 132
-#define KEY_COPY 133
-#define KEY_OPEN 134
-#define KEY_PASTE 135
-#define KEY_FIND 136
-#define KEY_CUT 137
-#define KEY_HELP 138
-#define KEY_MENU 139
-#define KEY_CALC 140
-#define KEY_SETUP 141
-#define KEY_SLEEP 142
-#define KEY_WAKEUP 143
-#define KEY_FILE 144
-#define KEY_SENDFILE 145
-#define KEY_DELETEFILE 146
-#define KEY_XFER 147
-#define KEY_PROG1 148
-#define KEY_PROG2 149
-#define KEY_WWW 150
-#define KEY_MSDOS 151
-#define KEY_COFFEE 152
-#define KEY_DIRECTION 153
-#define KEY_CYCLEWINDOWS 154
-#define KEY_MAIL 155
-#define KEY_BOOKMARKS 156
-#define KEY_COMPUTER 157
-#define KEY_BACK 158
-#define KEY_FORWARD 159
-#define KEY_CLOSECD 160
-#define KEY_EJECTCD 161
-#define KEY_EJECTCLOSECD 162
-#define KEY_NEXTSONG 163
-#define KEY_PLAYPAUSE 164
-#define KEY_PREVIOUSSONG 165
-#define KEY_STOPCD 166
-#define KEY_RECORD 167
-#define KEY_REWIND 168
-#define KEY_PHONE 169
-#define KEY_ISO 170
-#define KEY_CONFIG 171
-#define KEY_HOMEPAGE 172
-#define KEY_REFRESH 173
-#define KEY_EXIT 174
-#define KEY_MOVE 175
-#define KEY_EDIT 176
-#define KEY_SCROLLUP 177
-#define KEY_SCROLLDOWN 178
-#define KEY_KPLEFTPAREN 179
-#define KEY_KPRIGHTPAREN 180
-#define KEY_NEW 181
-#define KEY_REDO 182
-
-#define KEY_F13 183
-#define KEY_F14 184
-#define KEY_F15 185
-#define KEY_F16 186
-#define KEY_F17 187
-#define KEY_F18 188
-#define KEY_F19 189
-#define KEY_F20 190
-#define KEY_F21 191
-#define KEY_F22 192
-#define KEY_F23 193
-#define KEY_F24 194
-
-#define KEY_PLAYCD 200
-#define KEY_PAUSECD 201
-#define KEY_PROG3 202
-#define KEY_PROG4 203
-#define KEY_SUSPEND 205
-#define KEY_CLOSE 206
-#define KEY_PLAY 207
-#define KEY_FASTFORWARD 208
-#define KEY_BASSBOOST 209
-#define KEY_PRINT 210
-#define KEY_HP 211
-#define KEY_CAMERA 212
-#define KEY_SOUND 213
-#define KEY_QUESTION 214
-#define KEY_EMAIL 215
-#define KEY_CHAT 216
-#define KEY_SEARCH 217
-#define KEY_CONNECT 218
-#define KEY_FINANCE 219
-#define KEY_SPORT 220
-#define KEY_SHOP 221
-#define KEY_ALTERASE 222
-#define KEY_CANCEL 223
-#define KEY_BRIGHTNESSDOWN 224
-#define KEY_BRIGHTNESSUP 225
-#define KEY_MEDIA 226
-
-
-/*Zeus: these keys are defined for OMAP730 Perseus2*/
-#define KEY_STAR 227
-#define KEY_SHARP 228
-#define KEY_SOFT1 229
-#define KEY_SOFT2 230
-#define KEY_SEND 231
-#define KEY_CENTER 232
-#define KEY_HEADSETHOOK 233
-#define KEY_0_5 234
-#define KEY_2_5 235
-
-#define KEY_SWITCHVIDEOMODE 236
-#define KEY_KBDILLUMTOGGLE 237
-#define KEY_KBDILLUMDOWN 238
-#define KEY_KBDILLUMUP 239
-
-#define KEY_SEND 231
-#define KEY_REPLY 232
-#define KEY_FORWARDMAIL 233
-#define KEY_SAVE 234
-#define KEY_DOCUMENTS 235
-
-#define KEY_BATTERY 236
-
-#define KEY_UNKNOWN 240
-
-#define KEY_NUM 241
-#define KEY_FOCUS 242
-#define KEY_PLUS 243
-#define KEY_NOTIFICATION 244
-
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-#define BTN_TASK 0x117
-
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-
-#define BTN_GAMEPAD 0x130
-#define BTN_A 0x130
-#define BTN_B 0x131
-#define BTN_C 0x132
-#define BTN_X 0x133
-#define BTN_Y 0x134
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-
-#define BTN_DIGI 0x140
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-
-#define BTN_WHEEL 0x150
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-
-#define KEY_OK 0x160
-#define KEY_SELECT 0x161
-#define KEY_GOTO 0x162
-#define KEY_CLEAR 0x163
-#define KEY_POWER2 0x164
-#define KEY_OPTION 0x165
-#define KEY_INFO 0x166
-#define KEY_TIME 0x167
-#define KEY_VENDOR 0x168
-#define KEY_ARCHIVE 0x169
-#define KEY_PROGRAM 0x16a
-#define KEY_CHANNEL 0x16b
-#define KEY_FAVORITES 0x16c
-#define KEY_EPG 0x16d
-#define KEY_PVR 0x16e
-#define KEY_MHP 0x16f
-#define KEY_LANGUAGE 0x170
-#define KEY_TITLE 0x171
-#define KEY_SUBTITLE 0x172
-#define KEY_ANGLE 0x173
-#define KEY_ZOOM 0x174
-#define KEY_MODE 0x175
-#define KEY_KEYBOARD 0x176
-#define KEY_SCREEN 0x177
-#define KEY_PC 0x178
-#define KEY_TV 0x179
-#define KEY_TV2 0x17a
-#define KEY_VCR 0x17b
-#define KEY_VCR2 0x17c
-#define KEY_SAT 0x17d
-#define KEY_SAT2 0x17e
-#define KEY_CD 0x17f
-#define KEY_TAPE 0x180
-#define KEY_RADIO 0x181
-#define KEY_TUNER 0x182
-#define KEY_PLAYER 0x183
-#define KEY_TEXT 0x184
-#define KEY_DVD 0x185
-#define KEY_AUX 0x186
-#define KEY_MP3 0x187
-#define KEY_AUDIO 0x188
-#define KEY_VIDEO 0x189
-#define KEY_DIRECTORY 0x18a
-#define KEY_LIST 0x18b
-#define KEY_MEMO 0x18c
-#define KEY_CALENDAR 0x18d
-#define KEY_RED 0x18e
-#define KEY_GREEN 0x18f
-#define KEY_YELLOW 0x190
-#define KEY_BLUE 0x191
-#define KEY_CHANNELUP 0x192
-#define KEY_CHANNELDOWN 0x193
-#define KEY_FIRST 0x194
-#define KEY_LAST 0x195
-#define KEY_AB 0x196
-#define KEY_NEXT 0x197
-#define KEY_RESTART 0x198
-#define KEY_SLOW 0x199
-#define KEY_SHUFFLE 0x19a
-#define KEY_BREAK 0x19b
-#define KEY_PREVIOUS 0x19c
-#define KEY_DIGITS 0x19d
-#define KEY_TEEN 0x19e
-#define KEY_TWEN 0x19f
-
-#define KEY_DEL_EOL 0x1c0
-#define KEY_DEL_EOS 0x1c1
-#define KEY_INS_LINE 0x1c2
-#define KEY_DEL_LINE 0x1c3
-
-#define KEY_FN 0x1d0
-#define KEY_FN_ESC 0x1d1
-#define KEY_FN_F1 0x1d2
-#define KEY_FN_F2 0x1d3
-#define KEY_FN_F3 0x1d4
-#define KEY_FN_F4 0x1d5
-#define KEY_FN_F5 0x1d6
-#define KEY_FN_F6 0x1d7
-#define KEY_FN_F7 0x1d8
-#define KEY_FN_F8 0x1d9
-#define KEY_FN_F9 0x1da
-#define KEY_FN_F10 0x1db
-#define KEY_FN_F11 0x1dc
-#define KEY_FN_F12 0x1dd
-#define KEY_FN_1 0x1de
-#define KEY_FN_2 0x1df
-#define KEY_FN_D 0x1e0
-#define KEY_FN_E 0x1e1
-#define KEY_FN_F 0x1e2
-#define KEY_FN_S 0x1e3
-#define KEY_FN_B 0x1e4
-
-#define KEY_BRL_DOT1 0x1f1
-#define KEY_BRL_DOT2 0x1f2
-#define KEY_BRL_DOT3 0x1f3
-#define KEY_BRL_DOT4 0x1f4
-#define KEY_BRL_DOT5 0x1f5
-#define KEY_BRL_DOT6 0x1f6
-#define KEY_BRL_DOT7 0x1f7
-#define KEY_BRL_DOT8 0x1f8
-
-/* We avoid low common keys in module aliases so they don't get huge. */
-#define KEY_MIN_INTERESTING KEY_MUTE
-#define KEY_MAX 0x1ff
-
-#endif
diff --git a/loader.c b/loader.c
deleted file mode 100644
index 84ed123..0000000
--- a/loader.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * QEMU Executable loader
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "cpu.h"
-#include "disas.h"
-#include "sysemu.h"
-#include "uboot_image.h"
-
-/* return the size or -1 if error */
-int get_image_size(const char *filename)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- close(fd);
- return size;
-}
-
-/* return the size or -1 if error */
-/* deprecated, because caller does not specify buffer size! */
-int load_image(const char *filename, uint8_t *addr)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
- if (read(fd, addr, size) != size) {
- close(fd);
- return -1;
- }
- close(fd);
- return size;
-}
-
-/* return the amount read, just like fread. 0 may mean error or eof */
-int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
-{
- uint8_t buf[4096];
- target_phys_addr_t dst_begin = dst_addr;
- size_t want, did;
-
- while (nbytes) {
- want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
- did = fread(buf, 1, want, f);
- if (did != want) break;
-
- cpu_physical_memory_write_rom(dst_addr, buf, did);
- dst_addr += did;
- nbytes -= did;
- }
- return dst_addr - dst_begin;
-}
-
-/* returns 0 on error, 1 if ok */
-int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
-{
- return fread_targphys(dst_addr, nbytes, f) == nbytes;
-}
-
-/* read()-like version */
-int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes)
-{
- uint8_t buf[4096];
- target_phys_addr_t dst_begin = dst_addr;
- size_t want, did;
-
- while (nbytes) {
- want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
- did = read(fd, buf, want);
- if (did != want) break;
-
- cpu_physical_memory_write_rom(dst_addr, buf, did);
- dst_addr += did;
- nbytes -= did;
- }
- return dst_addr - dst_begin;
-}
-
-/* return the size or -1 if error */
-int load_image_targphys(const char *filename,
- target_phys_addr_t addr, int max_sz)
-{
- FILE *f;
- size_t got;
-
- f = fopen(filename, "rb");
- if (!f) return -1;
-
- got = fread_targphys(addr, max_sz, f);
- if (ferror(f)) { fclose(f); return -1; }
- fclose(f);
-
- return got;
-}
-
-void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
- const char *source)
-{
- static const uint8_t nul_byte = 0;
- const char *nulp;
-
- if (buf_size <= 0) return;
- nulp = memchr(source, 0, buf_size);
- if (nulp) {
- cpu_physical_memory_write_rom(dest, (uint8_t *)source,
- (nulp - source) + 1);
- } else {
- cpu_physical_memory_write_rom(dest, (uint8_t *)source, buf_size - 1);
- cpu_physical_memory_write_rom(dest, &nul_byte, 1);
- }
-}
-
-/* A.OUT loader */
-
-struct exec
-{
- uint32_t a_info; /* Use macros N_MAGIC, etc for access */
- uint32_t a_text; /* length of text, in bytes */
- uint32_t a_data; /* length of data, in bytes */
- uint32_t a_bss; /* length of uninitialized data area, in bytes */
- uint32_t a_syms; /* length of symbol table data in file, in bytes */
- uint32_t a_entry; /* start address */
- uint32_t a_trsize; /* length of relocation info for text, in bytes */
- uint32_t a_drsize; /* length of relocation info for data, in bytes */
-};
-
-#ifdef BSWAP_NEEDED
-static void bswap_ahdr(struct exec *e)
-{
- bswap32s(&e->a_info);
- bswap32s(&e->a_text);
- bswap32s(&e->a_data);
- bswap32s(&e->a_bss);
- bswap32s(&e->a_syms);
- bswap32s(&e->a_entry);
- bswap32s(&e->a_trsize);
- bswap32s(&e->a_drsize);
-}
-#else
-#define bswap_ahdr(x) do { } while (0)
-#endif
-
-#define N_MAGIC(exec) ((exec).a_info & 0xffff)
-#define OMAGIC 0407
-#define NMAGIC 0410
-#define ZMAGIC 0413
-#define QMAGIC 0314
-#define _N_HDROFF(x) (1024 - sizeof (struct exec))
-#define N_TXTOFF(x) \
- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
- (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
-#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
-#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
-#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
-
-#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
-
-#define N_DATADDR(x) \
- (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
- : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
-
-
-int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
-{
- int fd, size, ret;
- struct exec e;
- uint32_t magic;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
-
- size = read(fd, &e, sizeof(e));
- if (size < 0)
- goto fail;
-
- bswap_ahdr(&e);
-
- magic = N_MAGIC(e);
- switch (magic) {
- case ZMAGIC:
- case QMAGIC:
- case OMAGIC:
- if (e.a_text + e.a_data > max_sz)
- goto fail;
- lseek(fd, N_TXTOFF(e), SEEK_SET);
- size = read_targphys(fd, addr, e.a_text + e.a_data);
- if (size < 0)
- goto fail;
- break;
- case NMAGIC:
- if (N_DATADDR(e) + e.a_data > max_sz)
- goto fail;
- lseek(fd, N_TXTOFF(e), SEEK_SET);
- size = read_targphys(fd, addr, e.a_text);
- if (size < 0)
- goto fail;
- ret = read_targphys(fd, addr + N_DATADDR(e), e.a_data);
- if (ret < 0)
- goto fail;
- size += ret;
- break;
- default:
- goto fail;
- }
- close(fd);
- return size;
- fail:
- close(fd);
- return -1;
-}
-
-/* ELF loader */
-
-static void *load_at(int fd, int offset, int size)
-{
- void *ptr;
- if (lseek(fd, offset, SEEK_SET) < 0)
- return NULL;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- if (read(fd, ptr, size) != size) {
- qemu_free(ptr);
- return NULL;
- }
- return ptr;
-}
-
-
-#define ELF_CLASS ELFCLASS32
-#include "elf.h"
-
-#define SZ 32
-#define elf_word uint32_t
-#define elf_sword int32_t
-#define bswapSZs bswap32s
-#include "elf_ops.h"
-
-#undef elfhdr
-#undef elf_phdr
-#undef elf_shdr
-#undef elf_sym
-#undef elf_note
-#undef elf_word
-#undef elf_sword
-#undef bswapSZs
-#undef SZ
-#define elfhdr elf64_hdr
-#define elf_phdr elf64_phdr
-#define elf_note elf64_note
-#define elf_shdr elf64_shdr
-#define elf_sym elf64_sym
-#define elf_word uint64_t
-#define elf_sword int64_t
-#define bswapSZs bswap64s
-#define SZ 64
-#include "elf_ops.h"
-
-/* return < 0 if error, otherwise the number of bytes loaded in memory */
-int load_elf(const char *filename, int64_t virt_to_phys_addend,
- uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
-{
- int fd, data_order, host_data_order, must_swab, ret;
- uint8_t e_ident[EI_NIDENT];
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0) {
- perror(filename);
- return -1;
- }
- if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
- goto fail;
- if (e_ident[0] != ELFMAG0 ||
- e_ident[1] != ELFMAG1 ||
- e_ident[2] != ELFMAG2 ||
- e_ident[3] != ELFMAG3)
- goto fail;
-#ifdef WORDS_BIGENDIAN
- data_order = ELFDATA2MSB;
-#else
- data_order = ELFDATA2LSB;
-#endif
- must_swab = data_order != e_ident[EI_DATA];
-
-#ifdef TARGET_WORDS_BIGENDIAN
- host_data_order = ELFDATA2MSB;
-#else
- host_data_order = ELFDATA2LSB;
-#endif
- if (host_data_order != e_ident[EI_DATA])
- return -1;
-
- lseek(fd, 0, SEEK_SET);
- if (e_ident[EI_CLASS] == ELFCLASS64) {
- ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry,
- lowaddr, highaddr);
- } else {
- ret = load_elf32(fd, virt_to_phys_addend, must_swab, pentry,
- lowaddr, highaddr);
- }
-
- close(fd);
- return ret;
-
- fail:
- close(fd);
- return -1;
-}
-
-static void bswap_uboot_header(uboot_image_header_t *hdr)
-{
-#ifndef WORDS_BIGENDIAN
- bswap32s(&hdr->ih_magic);
- bswap32s(&hdr->ih_hcrc);
- bswap32s(&hdr->ih_time);
- bswap32s(&hdr->ih_size);
- bswap32s(&hdr->ih_load);
- bswap32s(&hdr->ih_ep);
- bswap32s(&hdr->ih_dcrc);
-#endif
-}
-
-/* Load a U-Boot image. */
-int load_uboot(const char *filename, target_ulong *ep, int *is_linux)
-{
-
- int fd;
- int size;
- uboot_image_header_t h;
- uboot_image_header_t *hdr = &h;
- uint8_t *data = NULL;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
-
- size = read(fd, hdr, sizeof(uboot_image_header_t));
- if (size < 0)
- goto fail;
-
- bswap_uboot_header(hdr);
-
- if (hdr->ih_magic != IH_MAGIC)
- goto fail;
-
- /* TODO: Implement Multi-File images. */
- if (hdr->ih_type == IH_TYPE_MULTI) {
- fprintf(stderr, "Unable to load multi-file u-boot images\n");
- goto fail;
- }
-
- /* TODO: Implement compressed images. */
- if (hdr->ih_comp != IH_COMP_NONE) {
- fprintf(stderr, "Unable to load compressed u-boot images\n");
- goto fail;
- }
-
- /* TODO: Check CPU type. */
- if (is_linux) {
- if (hdr->ih_type == IH_TYPE_KERNEL && hdr->ih_os == IH_OS_LINUX)
- *is_linux = 1;
- else
- *is_linux = 0;
- }
-
- *ep = hdr->ih_ep;
- data = qemu_malloc(hdr->ih_size);
- if (!data)
- goto fail;
-
- if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
- fprintf(stderr, "Error reading file\n");
- goto fail;
- }
-
- cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size);
-
- return hdr->ih_size;
-
-fail:
- if (data)
- qemu_free(data);
- close(fd);
- return -1;
-}
-
diff --git a/loadpng.c b/loadpng.c
deleted file mode 100644
index 218ae20..0000000
--- a/loadpng.c
+++ /dev/null
@@ -1,275 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <png.h>
-
-#if 0
-#define LOG(x...) fprintf(stderr,"error: " x)
-#else
-#define LOG(x...) do {} while (0)
-#endif
-
-void *loadpng(const char *fn, unsigned *_width, unsigned *_height)
-{
- FILE *fp = 0;
- unsigned char header[8];
- unsigned char *data = 0;
- unsigned char **rowptrs = 0;
- png_structp p = 0;
- png_infop pi = 0;
-
- png_uint_32 width, height;
- int bitdepth, colortype, imethod, cmethod, fmethod, i;
-
- p = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
- if(p == 0) {
- LOG("%s: failed to allocate png read struct\n", fn);
- return 0;
- }
-
- pi = png_create_info_struct(p);
- if(pi == 0) {
- LOG("%s: failed to allocate png info struct\n", fn);
- goto oops;
- }
-
- fp = fopen(fn, "rb");
- if(fp == 0) {
- LOG("%s: failed to open file\n", fn);
- return 0;
- }
-
- if(fread(header, 8, 1, fp) != 1) {
- LOG("%s: failed to read header\n", fn);
- goto oops;
- }
-
- if(png_sig_cmp(header, 0, 8)) {
- LOG("%s: header is not a PNG header\n", fn);
- goto oops;
- }
-
- if(setjmp(png_jmpbuf(p))) {
- LOG("%s: png library error\n", fn);
- oops:
- png_destroy_read_struct(&p, &pi, 0);
- if(fp != 0) fclose(fp);
- if(data != 0) free(data);
- if(rowptrs != 0) free(rowptrs);
- return 0;
- }
-
- png_init_io(p, fp);
- png_set_sig_bytes(p, 8);
-
- png_read_info(p, pi);
-
- png_get_IHDR(p, pi, &width, &height, &bitdepth, &colortype,
- &imethod, &cmethod, &fmethod);
-// printf("PNG: %d x %d (d=%d, c=%d)\n",
-// width, height, bitdepth, colortype);
-
- switch(colortype){
- case PNG_COLOR_TYPE_PALETTE:
- png_set_palette_to_rgb(p);
- break;
-
- case PNG_COLOR_TYPE_RGB:
- if(png_get_valid(p, pi, PNG_INFO_tRNS)) {
- png_set_tRNS_to_alpha(p);
- } else {
- png_set_filler(p, 0xff, PNG_FILLER_AFTER);
- }
- break;
-
- case PNG_COLOR_TYPE_RGB_ALPHA:
- break;
-
- case PNG_COLOR_TYPE_GRAY:
- if(bitdepth < 8) {
- png_set_gray_1_2_4_to_8(p);
- }
-
- default:
- LOG("%s: unsupported (grayscale?) color type\n");
- goto oops;
- }
-
- if(bitdepth == 16) {
- png_set_strip_16(p);
- }
-
- data = (unsigned char*) malloc((width * 4) * height);
- rowptrs = (unsigned char **) malloc(sizeof(unsigned char*) * height);
-
- if((data == 0) || (rowptrs == 0)){
- LOG("could not allocate data buffer\n");
- goto oops;
- }
-
- for(i = 0; i < height; i++) {
- rowptrs[i] = data + ((width * 4) * i);
- }
-
- png_read_image(p, rowptrs);
-
- png_destroy_read_struct(&p, &pi, 0);
- fclose(fp);
- if(rowptrs != 0) free(rowptrs);
-
- *_width = width;
- *_height = height;
-
- return (void*) data;
-}
-
-
-typedef struct
-{
- const unsigned char* base;
- const unsigned char* end;
- const unsigned char* cursor;
-
-} PngReader;
-
-static void
-png_reader_read_data( png_structp png_ptr,
- png_bytep data,
- png_size_t length )
-{
- PngReader* reader = png_get_io_ptr(png_ptr);
- png_size_t avail = (png_size_t)(reader->end - reader->cursor);
-
- if (avail > length)
- avail = length;
-
- memcpy( data, reader->cursor, avail );
- reader->cursor += avail;
-}
-
-
-void *readpng(const unsigned char *base, size_t size, unsigned *_width, unsigned *_height)
-{
- PngReader reader;
- unsigned char *data = 0;
- unsigned char **rowptrs = 0;
- png_structp p = 0;
- png_infop pi = 0;
-
- png_uint_32 width, height;
- int bitdepth, colortype, imethod, cmethod, fmethod, i;
-
- p = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
- if(p == 0) {
- LOG("%s: failed to allocate png read struct\n", fn);
- return 0;
- }
-
- pi = png_create_info_struct(p);
- if(pi == 0) {
- LOG("%s: failed to allocate png info struct\n", fn);
- goto oops;
- }
-
- reader.base = base;
- reader.end = base + size;
- reader.cursor = base;
-
- if(size < 8 || png_sig_cmp((unsigned char*)base, 0, 8)) {
- LOG("%s: header is not a PNG header\n", fn);
- goto oops;
- }
-
- reader.cursor += 8;
-
- if(setjmp(png_jmpbuf(p))) {
- LOG("%s: png library error\n", fn);
- oops:
- png_destroy_read_struct(&p, &pi, 0);
- if(data != 0) free(data);
- if(rowptrs != 0) free(rowptrs);
- return 0;
- }
-
- png_set_read_fn (p, &reader, png_reader_read_data);
- png_set_sig_bytes(p, 8);
-
- png_read_info(p, pi);
-
- png_get_IHDR(p, pi, &width, &height, &bitdepth, &colortype,
- &imethod, &cmethod, &fmethod);
-// printf("PNG: %d x %d (d=%d, c=%d)\n",
-// width, height, bitdepth, colortype);
-
- switch(colortype){
- case PNG_COLOR_TYPE_PALETTE:
- png_set_palette_to_rgb(p);
- break;
-
- case PNG_COLOR_TYPE_RGB:
- if(png_get_valid(p, pi, PNG_INFO_tRNS)) {
- png_set_tRNS_to_alpha(p);
- } else {
- png_set_filler(p, 0xff, PNG_FILLER_AFTER);
- }
- break;
-
- case PNG_COLOR_TYPE_RGB_ALPHA:
- break;
-
- case PNG_COLOR_TYPE_GRAY:
- if(bitdepth < 8) {
- png_set_gray_1_2_4_to_8(p);
- }
-
- default:
- LOG("%s: unsupported (grayscale?) color type\n");
- goto oops;
- }
-
- if(bitdepth == 16) {
- png_set_strip_16(p);
- }
-
- data = (unsigned char*) malloc((width * 4) * height);
- rowptrs = (unsigned char **) malloc(sizeof(unsigned char*) * height);
-
- if((data == 0) || (rowptrs == 0)){
- LOG("could not allocate data buffer\n");
- goto oops;
- }
-
- for(i = 0; i < height; i++) {
- rowptrs[i] = data + ((width * 4) * i);
- }
-
- png_read_image(p, rowptrs);
-
- png_destroy_read_struct(&p, &pi, 0);
- if(rowptrs != 0) free(rowptrs);
-
- *_width = width;
- *_height = height;
-
- return (void*) data;
-}
-
-
-#if 0
-int main(int argc, char **argv)
-{
- unsigned w,h;
- unsigned char *data;
-
- if(argc < 2) return 0;
-
-
- data = loadpng(argv[1], &w, &h);
-
- if(data != 0) {
- printf("w: %d h: %d\n", w, h);
- }
-
- return 0;
-}
-#endif
diff --git a/m68k.ld b/m68k.ld
deleted file mode 100644
index 28da902..0000000
--- a/m68k.ld
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Script for -z combreloc: combine and sort reloc sections */
-OUTPUT_FORMAT("elf32-m68k", "elf32-m68k",
- "elf32-m68k")
-OUTPUT_ARCH(m68k)
-ENTRY(_start)
-SEARCH_DIR("/usr/local/m68k-linux/lib");
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.dyn :
- {
- *(.rel.init)
- *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
- *(.rel.fini)
- *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
- *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
- *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
- *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
- *(.rel.ctors)
- *(.rel.dtors)
- *(.rel.got)
- *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
- }
- .rela.dyn :
- {
- *(.rela.init)
- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
- *(.rela.fini)
- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
- *(.rela.ctors)
- *(.rela.dtors)
- *(.rela.got)
- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
- }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0x4e754e75
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x4e754e75
- .fini :
- {
- KEEP (*(.fini))
- } =0x4e754e75
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x2000) + (. & (0x2000 - 1));
- /* Ensure the __preinit_array_start label is properly aligned. We
- could instead move the label definition inside the section, but
- the linker would then create the section even if it turns out to
- be empty, which isn't pretty. */
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : { KEEP (*(.eh_frame)) }
- .gcc_except_table : { *(.gcc_except_table) }
- .dynamic : { *(.dynamic) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .got : { *(.got.plt) *(.got) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
- . = ALIGN(32 / 8);
- }
- . = ALIGN(32 / 8);
- _end = .;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-}
diff --git a/monitor.c b/monitor.c
deleted file mode 100644
index f0f38a7..0000000
--- a/monitor.c
+++ /dev/null
@@ -1,2736 +0,0 @@
-/*
- * QEMU monitor
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "hw/hw.h"
-#include "hw/usb.h"
-
-#include "hw/pc.h"
-#include "hw/pci.h"
-#include "gdbstub.h"
-#include "net.h"
-#include "qemu-char.h"
-#include "sysemu.h"
-#include "console.h"
-#include "block.h"
-#include "audio/audio.h"
-#include "disas.h"
-#include "cpu-defs.h"
-#include <dirent.h>
-#include "qemu-timer.h"
-
-//#define DEBUG
-//#define DEBUG_COMPLETION
-
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-/*
- * Supported types:
- *
- * 'F' filename
- * 'B' block device name
- * 's' string (accept optional quote)
- * 'i' 32 bit integer
- * 'l' target long (32 or 64 bit)
- * '/' optional gdb-like print format (like "/10x")
- *
- * '?' optional type (for 'F', 's' and 'i')
- *
- */
-
-typedef struct term_cmd_t {
- const char *name;
- const char *args_type;
- void *handler;
- const char *params;
- const char *help;
-} term_cmd_t;
-
-#define MAX_MON 4
-static CharDriverState *monitor_hd[MAX_MON];
-static int hide_banner;
-
-static term_cmd_t term_cmds[];
-static term_cmd_t info_cmds[];
-
-static uint8_t term_outbuf[1024];
-static int term_outbuf_index;
-
-static void monitor_start_input(void);
-
-CPUState *mon_cpu = NULL;
-
-void term_flush(void)
-{
- int i;
- if (term_outbuf_index > 0) {
- for (i = 0; i < MAX_MON; i++)
- if (monitor_hd[i] && monitor_hd[i]->focus == 0)
- qemu_chr_write(monitor_hd[i], term_outbuf, term_outbuf_index);
- term_outbuf_index = 0;
- }
-}
-
-/* flush at every end of line or if the buffer is full */
-void term_puts(const char *str)
-{
- char c;
- for(;;) {
- c = *str++;
- if (c == '\0')
- break;
- if (c == '\n')
- term_outbuf[term_outbuf_index++] = '\r';
- term_outbuf[term_outbuf_index++] = c;
- if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||
- c == '\n')
- term_flush();
- }
-}
-
-void term_vprintf(const char *fmt, va_list ap)
-{
- char buf[4096];
- vsnprintf(buf, sizeof(buf), fmt, ap);
- term_puts(buf);
-}
-
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
-}
-
-void term_print_filename(const char *filename)
-{
- int i;
-
- for (i = 0; filename[i]; i++) {
- switch (filename[i]) {
- case ' ':
- case '"':
- case '\\':
- term_printf("\\%c", filename[i]);
- break;
- case '\t':
- term_printf("\\t");
- break;
- case '\r':
- term_printf("\\r");
- break;
- case '\n':
- term_printf("\\n");
- break;
- default:
- term_printf("%c", filename[i]);
- break;
- }
- }
-}
-
-static int monitor_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
- return 0;
-}
-
-static int compare_cmd(const char *name, const char *list)
-{
- const char *p, *pstart;
- int len;
- len = strlen(name);
- p = list;
- for(;;) {
- pstart = p;
- p = strchr(p, '|');
- if (!p)
- p = pstart + strlen(pstart);
- if ((p - pstart) == len && !memcmp(pstart, name, len))
- return 1;
- if (*p == '\0')
- break;
- p++;
- }
- return 0;
-}
-
-static void help_cmd1(term_cmd_t *cmds, const char *prefix, const char *name)
-{
- term_cmd_t *cmd;
-
- for(cmd = cmds; cmd->name != NULL; cmd++) {
- if (!name || !strcmp(name, cmd->name))
- term_printf("%s%s %s -- %s\n", prefix, cmd->name, cmd->params, cmd->help);
- }
-}
-
-static void help_cmd(const char *name)
-{
- if (name && !strcmp(name, "info")) {
- help_cmd1(info_cmds, "info ", NULL);
- } else {
- help_cmd1(term_cmds, "", name);
- if (name && !strcmp(name, "log")) {
- CPULogItem *item;
- term_printf("Log items (comma separated):\n");
- term_printf("%-10s %s\n", "none", "remove all logs");
- for(item = cpu_log_items; item->mask != 0; item++) {
- term_printf("%-10s %s\n", item->name, item->help);
- }
- }
- }
-}
-
-static void do_help(const char *name)
-{
- help_cmd(name);
-}
-
-static void do_commit(const char *device)
-{
- int i, all_devices;
-
- all_devices = !strcmp(device, "all");
- for (i = 0; i < nb_drives; i++) {
- if (all_devices ||
- !strcmp(bdrv_get_device_name(drives_table[i].bdrv), device))
- bdrv_commit(drives_table[i].bdrv);
- }
-}
-
-static void do_info(const char *item)
-{
- term_cmd_t *cmd;
- void (*handler)(void);
-
- if (!item)
- goto help;
- for(cmd = info_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(item, cmd->name))
- goto found;
- }
- help:
- help_cmd("info");
- return;
- found:
- handler = cmd->handler;
- handler();
-}
-
-static void do_info_version(void)
-{
- term_printf("%s\n", QEMU_VERSION);
-}
-
-static void do_info_name(void)
-{
- if (qemu_name)
- term_printf("%s\n", qemu_name);
-}
-
-static void do_info_block(void)
-{
- bdrv_info();
-}
-
-static void do_info_blockstats(void)
-{
- bdrv_info_stats();
-}
-
-/* get the current CPU defined by the user */
-static int mon_set_cpu(int cpu_index)
-{
- CPUState *env;
-
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- if (env->cpu_index == cpu_index) {
- mon_cpu = env;
- return 0;
- }
- }
- return -1;
-}
-
-static CPUState *mon_get_cpu(void)
-{
- if (!mon_cpu) {
- mon_set_cpu(0);
- }
- return mon_cpu;
-}
-
-static void do_info_registers(void)
-{
- CPUState *env;
- env = mon_get_cpu();
- if (!env)
- return;
-#ifdef TARGET_I386
- cpu_dump_state(env, NULL, monitor_fprintf,
- X86_DUMP_FPU);
-#else
- cpu_dump_state(env, NULL, monitor_fprintf,
- 0);
-#endif
-}
-
-static void do_info_cpus(void)
-{
- CPUState *env;
-
- /* just to set the default cpu if not already done */
- mon_get_cpu();
-
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- term_printf("%c CPU #%d:",
- (env == mon_cpu) ? '*' : ' ',
- env->cpu_index);
-#if defined(TARGET_I386)
- term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base);
-#elif defined(TARGET_PPC)
- term_printf(" nip=0x" TARGET_FMT_lx, env->nip);
-#elif defined(TARGET_SPARC)
- term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
-#elif defined(TARGET_MIPS)
- term_printf(" PC=0x" TARGET_FMT_lx, env->active_tc.PC);
-#endif
- if (env->halted)
- term_printf(" (halted)");
- term_printf("\n");
- }
-}
-
-static void do_cpu_set(int index)
-{
- if (mon_set_cpu(index) < 0)
- term_printf("Invalid CPU index\n");
-}
-
-static void do_info_jit(void)
-{
- dump_exec_info(NULL, monitor_fprintf);
-}
-
-static void do_info_history (void)
-{
- int i;
- const char *str;
-
- i = 0;
- for(;;) {
- str = readline_get_history(i);
- if (!str)
- break;
- term_printf("%d: '%s'\n", i, str);
- i++;
- }
-}
-
-#if defined(TARGET_PPC)
-/* XXX: not implemented in other targets */
-static void do_info_cpu_stats (void)
-{
- CPUState *env;
-
- env = mon_get_cpu();
- cpu_dump_statistics(env, NULL, &monitor_fprintf, 0);
-}
-#endif
-
-static void do_quit(void)
-{
- exit(0);
-}
-
-static int eject_device(BlockDriverState *bs, int force)
-{
- if (bdrv_is_inserted(bs)) {
- if (!force) {
- if (!bdrv_is_removable(bs)) {
- term_printf("device is not removable\n");
- return -1;
- }
- if (bdrv_is_locked(bs)) {
- term_printf("device is locked\n");
- return -1;
- }
- }
- bdrv_close(bs);
- }
- return 0;
-}
-
-static void do_eject(int force, const char *filename)
-{
- BlockDriverState *bs;
-
- bs = bdrv_find(filename);
- if (!bs) {
- term_printf("device not found\n");
- return;
- }
- eject_device(bs, force);
-}
-
-static void do_change_block(const char *device, const char *filename, const char *fmt)
-{
- BlockDriverState *bs;
- BlockDriver *drv = NULL;
-
- bs = bdrv_find(device);
- if (!bs) {
- term_printf("device not found\n");
- return;
- }
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv) {
- term_printf("invalid format %s\n", fmt);
- return;
- }
- }
- if (eject_device(bs, 0) < 0)
- return;
- bdrv_open2(bs, filename, 0, drv);
- qemu_key_check(bs, filename);
-}
-
-static void do_change_vnc(const char *target)
-{
- if (strcmp(target, "passwd") == 0 ||
- strcmp(target, "password") == 0) {
- char password[9];
- monitor_readline("Password: ", 1, password, sizeof(password)-1);
- password[sizeof(password)-1] = '\0';
- if (vnc_display_password(NULL, password) < 0)
- term_printf("could not set VNC server password\n");
- } else {
- if (vnc_display_open(NULL, target) < 0)
- term_printf("could not start VNC server on %s\n", target);
- }
-}
-
-static void do_change(const char *device, const char *target, const char *fmt)
-{
- if (strcmp(device, "vnc") == 0) {
- do_change_vnc(target);
- } else {
- do_change_block(device, target, fmt);
- }
-}
-
-static void do_screen_dump(const char *filename)
-{
- vga_hw_screen_dump(filename);
-}
-
-static void do_logfile(const char *filename)
-{
- cpu_set_log_filename(filename);
-}
-
-static void do_log(const char *items)
-{
- int mask;
-
- if (!strcmp(items, "none")) {
- mask = 0;
- } else {
- mask = cpu_str_to_log_mask(items);
- if (!mask) {
- help_cmd("log");
- return;
- }
- }
- cpu_set_log(mask);
-}
-
-static void do_stop(void)
-{
- vm_stop(EXCP_INTERRUPT);
-}
-
-static void do_cont(void)
-{
- vm_start();
-}
-
-#ifdef CONFIG_GDBSTUB
-static void do_gdbserver(const char *port)
-{
- if (!port)
- port = DEFAULT_GDBSTUB_PORT;
- if (gdbserver_start(port) < 0) {
- qemu_printf("Could not open gdbserver socket on port '%s'\n", port);
- } else {
- qemu_printf("Waiting gdb connection on port '%s'\n", port);
- }
-}
-#endif
-
-static void term_printc(int c)
-{
- term_printf("'");
- switch(c) {
- case '\'':
- term_printf("\\'");
- break;
- case '\\':
- term_printf("\\\\");
- break;
- case '\n':
- term_printf("\\n");
- break;
- case '\r':
- term_printf("\\r");
- break;
- default:
- if (c >= 32 && c <= 126) {
- term_printf("%c", c);
- } else {
- term_printf("\\x%02x", c);
- }
- break;
- }
- term_printf("'");
-}
-
-static void memory_dump(int count, int format, int wsize,
- target_phys_addr_t addr, int is_physical)
-{
- CPUState *env;
- int nb_per_line, l, line_size, i, max_digits, len;
- uint8_t buf[16];
- uint64_t v;
-
- if (format == 'i') {
- int flags;
- flags = 0;
- env = mon_get_cpu();
- if (!env && !is_physical)
- return;
-#ifdef TARGET_I386
- if (wsize == 2) {
- flags = 1;
- } else if (wsize == 4) {
- flags = 0;
- } else {
- /* as default we use the current CS size */
- flags = 0;
- if (env) {
-#ifdef TARGET_X86_64
- if ((env->efer & MSR_EFER_LMA) &&
- (env->segs[R_CS].flags & DESC_L_MASK))
- flags = 2;
- else
-#endif
- if (!(env->segs[R_CS].flags & DESC_B_MASK))
- flags = 1;
- }
- }
-#endif
- monitor_disas(env, addr, count, is_physical, flags);
- return;
- }
-
- len = wsize * count;
- if (wsize == 1)
- line_size = 8;
- else
- line_size = 16;
- nb_per_line = line_size / wsize;
- max_digits = 0;
-
- switch(format) {
- case 'o':
- max_digits = (wsize * 8 + 2) / 3;
- break;
- default:
- case 'x':
- max_digits = (wsize * 8) / 4;
- break;
- case 'u':
- case 'd':
- max_digits = (wsize * 8 * 10 + 32) / 33;
- break;
- case 'c':
- wsize = 1;
- break;
- }
-
- while (len > 0) {
- if (is_physical)
- term_printf(TARGET_FMT_plx ":", addr);
- else
- term_printf(TARGET_FMT_lx ":", (target_ulong)addr);
- l = len;
- if (l > line_size)
- l = line_size;
- if (is_physical) {
- cpu_physical_memory_rw(addr, buf, l, 0);
- } else {
- env = mon_get_cpu();
- if (!env)
- break;
- if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
- term_printf(" Cannot access memory\n");
- break;
- }
- }
- i = 0;
- while (i < l) {
- switch(wsize) {
- default:
- case 1:
- v = ldub_raw(buf + i);
- break;
- case 2:
- v = lduw_raw(buf + i);
- break;
- case 4:
- v = (uint32_t)ldl_raw(buf + i);
- break;
- case 8:
- v = ldq_raw(buf + i);
- break;
- }
- term_printf(" ");
- switch(format) {
- case 'o':
- term_printf("%#*" PRIo64, max_digits, v);
- break;
- case 'x':
- term_printf("0x%0*" PRIx64, max_digits, v);
- break;
- case 'u':
- term_printf("%*" PRIu64, max_digits, v);
- break;
- case 'd':
- term_printf("%*" PRId64, max_digits, v);
- break;
- case 'c':
- term_printc(v);
- break;
- }
- i += wsize;
- }
- term_printf("\n");
- addr += l;
- len -= l;
- }
-}
-
-#if TARGET_LONG_BITS == 64
-#define GET_TLONG(h, l) (((uint64_t)(h) << 32) | (l))
-#else
-#define GET_TLONG(h, l) (l)
-#endif
-
-static void do_memory_dump(int count, int format, int size,
- uint32_t addrh, uint32_t addrl)
-{
- target_long addr = GET_TLONG(addrh, addrl);
- memory_dump(count, format, size, addr, 0);
-}
-
-#if TARGET_PHYS_ADDR_BITS > 32
-#define GET_TPHYSADDR(h, l) (((uint64_t)(h) << 32) | (l))
-#else
-#define GET_TPHYSADDR(h, l) (l)
-#endif
-
-static void do_physical_memory_dump(int count, int format, int size,
- uint32_t addrh, uint32_t addrl)
-
-{
- target_phys_addr_t addr = GET_TPHYSADDR(addrh, addrl);
- memory_dump(count, format, size, addr, 1);
-}
-
-static void do_print(int count, int format, int size, unsigned int valh, unsigned int vall)
-{
- target_phys_addr_t val = GET_TPHYSADDR(valh, vall);
-#if TARGET_PHYS_ADDR_BITS == 32
- switch(format) {
- case 'o':
- term_printf("%#o", val);
- break;
- case 'x':
- term_printf("%#x", val);
- break;
- case 'u':
- term_printf("%u", val);
- break;
- default:
- case 'd':
- term_printf("%d", val);
- break;
- case 'c':
- term_printc(val);
- break;
- }
-#else
- switch(format) {
- case 'o':
- term_printf("%#" PRIo64, val);
- break;
- case 'x':
- term_printf("%#" PRIx64, val);
- break;
- case 'u':
- term_printf("%" PRIu64, val);
- break;
- default:
- case 'd':
- term_printf("%" PRId64, val);
- break;
- case 'c':
- term_printc(val);
- break;
- }
-#endif
- term_printf("\n");
-}
-
-static void do_memory_save(unsigned int valh, unsigned int vall,
- uint32_t size, const char *filename)
-{
- FILE *f;
- target_long addr = GET_TLONG(valh, vall);
- uint32_t l;
- CPUState *env;
- uint8_t buf[1024];
-
- env = mon_get_cpu();
- if (!env)
- return;
-
- f = fopen(filename, "wb");
- if (!f) {
- term_printf("could not open '%s'\n", filename);
- return;
- }
- while (size != 0) {
- l = sizeof(buf);
- if (l > size)
- l = size;
- cpu_memory_rw_debug(env, addr, buf, l, 0);
- fwrite(buf, 1, l, f);
- addr += l;
- size -= l;
- }
- fclose(f);
-}
-
-static void do_physical_memory_save(unsigned int valh, unsigned int vall,
- uint32_t size, const char *filename)
-{
- FILE *f;
- uint32_t l;
- uint8_t buf[1024];
- target_phys_addr_t addr = GET_TPHYSADDR(valh, vall);
-
- f = fopen(filename, "wb");
- if (!f) {
- term_printf("could not open '%s'\n", filename);
- return;
- }
- while (size != 0) {
- l = sizeof(buf);
- if (l > size)
- l = size;
- cpu_physical_memory_rw(addr, buf, l, 0);
- fwrite(buf, 1, l, f);
- fflush(f);
- addr += l;
- size -= l;
- }
- fclose(f);
-}
-
-static void do_sum(uint32_t start, uint32_t size)
-{
- uint32_t addr;
- uint8_t buf[1];
- uint16_t sum;
-
- sum = 0;
- for(addr = start; addr < (start + size); addr++) {
- cpu_physical_memory_rw(addr, buf, 1, 0);
- /* BSD sum algorithm ('sum' Unix command) */
- sum = (sum >> 1) | (sum << 15);
- sum += buf[0];
- }
- term_printf("%05d\n", sum);
-}
-
-typedef struct {
- int keycode;
- const char *name;
-} KeyDef;
-
-static const KeyDef key_defs[] = {
- { 0x2a, "shift" },
- { 0x36, "shift_r" },
-
- { 0x38, "alt" },
- { 0xb8, "alt_r" },
- { 0x64, "altgr" },
- { 0xe4, "altgr_r" },
- { 0x1d, "ctrl" },
- { 0x9d, "ctrl_r" },
-
- { 0xdd, "menu" },
-
- { 0x01, "esc" },
-
- { 0x02, "1" },
- { 0x03, "2" },
- { 0x04, "3" },
- { 0x05, "4" },
- { 0x06, "5" },
- { 0x07, "6" },
- { 0x08, "7" },
- { 0x09, "8" },
- { 0x0a, "9" },
- { 0x0b, "0" },
- { 0x0c, "minus" },
- { 0x0d, "equal" },
- { 0x0e, "backspace" },
-
- { 0x0f, "tab" },
- { 0x10, "q" },
- { 0x11, "w" },
- { 0x12, "e" },
- { 0x13, "r" },
- { 0x14, "t" },
- { 0x15, "y" },
- { 0x16, "u" },
- { 0x17, "i" },
- { 0x18, "o" },
- { 0x19, "p" },
-
- { 0x1c, "ret" },
-
- { 0x1e, "a" },
- { 0x1f, "s" },
- { 0x20, "d" },
- { 0x21, "f" },
- { 0x22, "g" },
- { 0x23, "h" },
- { 0x24, "j" },
- { 0x25, "k" },
- { 0x26, "l" },
-
- { 0x2c, "z" },
- { 0x2d, "x" },
- { 0x2e, "c" },
- { 0x2f, "v" },
- { 0x30, "b" },
- { 0x31, "n" },
- { 0x32, "m" },
-
- { 0x37, "asterisk" },
-
- { 0x39, "spc" },
- { 0x3a, "caps_lock" },
- { 0x3b, "f1" },
- { 0x3c, "f2" },
- { 0x3d, "f3" },
- { 0x3e, "f4" },
- { 0x3f, "f5" },
- { 0x40, "f6" },
- { 0x41, "f7" },
- { 0x42, "f8" },
- { 0x43, "f9" },
- { 0x44, "f10" },
- { 0x45, "num_lock" },
- { 0x46, "scroll_lock" },
-
- { 0xb5, "kp_divide" },
- { 0x37, "kp_multiply" },
- { 0x4a, "kp_subtract" },
- { 0x4e, "kp_add" },
- { 0x9c, "kp_enter" },
- { 0x53, "kp_decimal" },
- { 0x54, "sysrq" },
-
- { 0x52, "kp_0" },
- { 0x4f, "kp_1" },
- { 0x50, "kp_2" },
- { 0x51, "kp_3" },
- { 0x4b, "kp_4" },
- { 0x4c, "kp_5" },
- { 0x4d, "kp_6" },
- { 0x47, "kp_7" },
- { 0x48, "kp_8" },
- { 0x49, "kp_9" },
-
- { 0x56, "<" },
-
- { 0x57, "f11" },
- { 0x58, "f12" },
-
- { 0xb7, "print" },
-
- { 0xc7, "home" },
- { 0xc9, "pgup" },
- { 0xd1, "pgdn" },
- { 0xcf, "end" },
-
- { 0xcb, "left" },
- { 0xc8, "up" },
- { 0xd0, "down" },
- { 0xcd, "right" },
-
- { 0xd2, "insert" },
- { 0xd3, "delete" },
-#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
- { 0xf0, "stop" },
- { 0xf1, "again" },
- { 0xf2, "props" },
- { 0xf3, "undo" },
- { 0xf4, "front" },
- { 0xf5, "copy" },
- { 0xf6, "open" },
- { 0xf7, "paste" },
- { 0xf8, "find" },
- { 0xf9, "cut" },
- { 0xfa, "lf" },
- { 0xfb, "help" },
- { 0xfc, "meta_l" },
- { 0xfd, "meta_r" },
- { 0xfe, "compose" },
-#endif
- { 0, NULL },
-};
-
-static int get_keycode(const char *key)
-{
- const KeyDef *p;
- char *endp;
- int ret;
-
- for(p = key_defs; p->name != NULL; p++) {
- if (!strcmp(key, p->name))
- return p->keycode;
- }
- if (strstart(key, "0x", NULL)) {
- ret = strtoul(key, &endp, 0);
- if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
- return ret;
- }
- return -1;
-}
-
-#define MAX_KEYCODES 16
-static uint8_t keycodes[MAX_KEYCODES];
-static int nb_pending_keycodes;
-static QEMUTimer *key_timer;
-
-static void release_keys(void *opaque)
-{
- int keycode;
-
- while (nb_pending_keycodes > 0) {
- nb_pending_keycodes--;
- keycode = keycodes[nb_pending_keycodes];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80);
- }
-}
-
-static void do_sendkey(const char *string, int has_hold_time, int hold_time)
-{
- char keyname_buf[16];
- char *separator;
- int keyname_len, keycode, i;
-
- if (nb_pending_keycodes > 0) {
- qemu_del_timer(key_timer);
- release_keys(NULL);
- }
- if (!has_hold_time)
- hold_time = 100;
- i = 0;
- while (1) {
- separator = strchr(string, '-');
- keyname_len = separator ? separator - string : strlen(string);
- if (keyname_len > 0) {
- pstrcpy(keyname_buf, sizeof(keyname_buf), string);
- if (keyname_len > sizeof(keyname_buf) - 1) {
- term_printf("invalid key: '%s...'\n", keyname_buf);
- return;
- }
- if (i == MAX_KEYCODES) {
- term_printf("too many keys\n");
- return;
- }
- keyname_buf[keyname_len] = 0;
- keycode = get_keycode(keyname_buf);
- if (keycode < 0) {
- term_printf("unknown key: '%s'\n", keyname_buf);
- return;
- }
- keycodes[i++] = keycode;
- }
- if (!separator)
- break;
- string = separator + 1;
- }
- nb_pending_keycodes = i;
- /* key down events */
- for (i = 0; i < nb_pending_keycodes; i++) {
- keycode = keycodes[i];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f);
- }
- /* delayed key up events */
- qemu_mod_timer(key_timer, qemu_get_clock(vm_clock) +
- muldiv64(ticks_per_sec, hold_time, 1000));
-}
-
-static int mouse_button_state;
-
-static void do_mouse_move(const char *dx_str, const char *dy_str,
- const char *dz_str)
-{
- int dx, dy, dz;
- dx = strtol(dx_str, NULL, 0);
- dy = strtol(dy_str, NULL, 0);
- dz = 0;
- if (dz_str)
- dz = strtol(dz_str, NULL, 0);
- kbd_mouse_event(dx, dy, dz, mouse_button_state);
-}
-
-static void do_mouse_button(int button_state)
-{
- mouse_button_state = button_state;
- kbd_mouse_event(0, 0, 0, mouse_button_state);
-}
-
-static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
-{
- uint32_t val;
- int suffix;
-
- if (has_index) {
- cpu_outb(NULL, addr & 0xffff, index & 0xff);
- addr++;
- }
- addr &= 0xffff;
-
- switch(size) {
- default:
- case 1:
- val = cpu_inb(NULL, addr);
- suffix = 'b';
- break;
- case 2:
- val = cpu_inw(NULL, addr);
- suffix = 'w';
- break;
- case 4:
- val = cpu_inl(NULL, addr);
- suffix = 'l';
- break;
- }
- term_printf("port%c[0x%04x] = %#0*x\n",
- suffix, addr, size * 2, val);
-}
-
-static void do_system_reset(void)
-{
- qemu_system_reset_request();
-}
-
-static void do_system_powerdown(void)
-{
- qemu_system_powerdown_request();
-}
-
-#if defined(TARGET_I386)
-static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
-{
- term_printf("%08x: %08x %c%c%c%c%c%c%c%c\n",
- addr,
- pte & mask,
- pte & PG_GLOBAL_MASK ? 'G' : '-',
- pte & PG_PSE_MASK ? 'P' : '-',
- pte & PG_DIRTY_MASK ? 'D' : '-',
- pte & PG_ACCESSED_MASK ? 'A' : '-',
- pte & PG_PCD_MASK ? 'C' : '-',
- pte & PG_PWT_MASK ? 'T' : '-',
- pte & PG_USER_MASK ? 'U' : '-',
- pte & PG_RW_MASK ? 'W' : '-');
-}
-
-static void tlb_info(void)
-{
- CPUState *env;
- int l1, l2;
- uint32_t pgd, pde, pte;
-
- env = mon_get_cpu();
- if (!env)
- return;
-
- if (!(env->cr[0] & CR0_PG_MASK)) {
- term_printf("PG disabled\n");
- return;
- }
- pgd = env->cr[3] & ~0xfff;
- for(l1 = 0; l1 < 1024; l1++) {
- cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
- pde = le32_to_cpu(pde);
- if (pde & PG_PRESENT_MASK) {
- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
- print_pte((l1 << 22), pde, ~((1 << 20) - 1));
- } else {
- for(l2 = 0; l2 < 1024; l2++) {
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
- (uint8_t *)&pte, 4);
- pte = le32_to_cpu(pte);
- if (pte & PG_PRESENT_MASK) {
- print_pte((l1 << 22) + (l2 << 12),
- pte & ~PG_PSE_MASK,
- ~0xfff);
- }
- }
- }
- }
- }
-}
-
-static void mem_print(uint32_t *pstart, int *plast_prot,
- uint32_t end, int prot)
-{
- int prot1;
- prot1 = *plast_prot;
- if (prot != prot1) {
- if (*pstart != -1) {
- term_printf("%08x-%08x %08x %c%c%c\n",
- *pstart, end, end - *pstart,
- prot1 & PG_USER_MASK ? 'u' : '-',
- 'r',
- prot1 & PG_RW_MASK ? 'w' : '-');
- }
- if (prot != 0)
- *pstart = end;
- else
- *pstart = -1;
- *plast_prot = prot;
- }
-}
-
-static void mem_info(void)
-{
- CPUState *env;
- int l1, l2, prot, last_prot;
- uint32_t pgd, pde, pte, start, end;
-
- env = mon_get_cpu();
- if (!env)
- return;
-
- if (!(env->cr[0] & CR0_PG_MASK)) {
- term_printf("PG disabled\n");
- return;
- }
- pgd = env->cr[3] & ~0xfff;
- last_prot = 0;
- start = -1;
- for(l1 = 0; l1 < 1024; l1++) {
- cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
- pde = le32_to_cpu(pde);
- end = l1 << 22;
- if (pde & PG_PRESENT_MASK) {
- if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
- prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
- mem_print(&start, &last_prot, end, prot);
- } else {
- for(l2 = 0; l2 < 1024; l2++) {
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
- (uint8_t *)&pte, 4);
- pte = le32_to_cpu(pte);
- end = (l1 << 22) + (l2 << 12);
- if (pte & PG_PRESENT_MASK) {
- prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
- } else {
- prot = 0;
- }
- mem_print(&start, &last_prot, end, prot);
- }
- }
- } else {
- prot = 0;
- mem_print(&start, &last_prot, end, prot);
- }
- }
-}
-#endif
-
-static void do_info_kqemu(void)
-{
-#ifdef USE_KQEMU
- CPUState *env;
- int val;
- val = 0;
- env = mon_get_cpu();
- if (!env) {
- term_printf("No cpu initialized yet");
- return;
- }
- val = env->kqemu_enabled;
- term_printf("kqemu support: ");
- switch(val) {
- default:
- case 0:
- term_printf("disabled\n");
- break;
- case 1:
- term_printf("enabled for user code\n");
- break;
- case 2:
- term_printf("enabled for user and kernel code\n");
- break;
- }
-#else
- term_printf("kqemu support: not compiled\n");
-#endif
-}
-
-#ifdef CONFIG_PROFILER
-
-int64_t kqemu_time;
-int64_t qemu_time;
-int64_t kqemu_exec_count;
-int64_t dev_time;
-int64_t kqemu_ret_int_count;
-int64_t kqemu_ret_excp_count;
-int64_t kqemu_ret_intr_count;
-
-static void do_info_profile(void)
-{
- int64_t total;
- total = qemu_time;
- if (total == 0)
- total = 1;
- term_printf("async time %" PRId64 " (%0.3f)\n",
- dev_time, dev_time / (double)ticks_per_sec);
- term_printf("qemu time %" PRId64 " (%0.3f)\n",
- qemu_time, qemu_time / (double)ticks_per_sec);
- term_printf("kqemu time %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
- kqemu_time, kqemu_time / (double)ticks_per_sec,
- kqemu_time / (double)total * 100.0,
- kqemu_exec_count,
- kqemu_ret_int_count,
- kqemu_ret_excp_count,
- kqemu_ret_intr_count);
- qemu_time = 0;
- kqemu_time = 0;
- kqemu_exec_count = 0;
- dev_time = 0;
- kqemu_ret_int_count = 0;
- kqemu_ret_excp_count = 0;
- kqemu_ret_intr_count = 0;
-#ifdef USE_KQEMU
- kqemu_record_dump();
-#endif
-}
-#else
-static void do_info_profile(void)
-{
- term_printf("Internal profiler not compiled\n");
-}
-#endif
-
-/* Capture support */
-static LIST_HEAD (capture_list_head, CaptureState) capture_head;
-
-static void do_info_capture (void)
-{
- int i;
- CaptureState *s;
-
- for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
- term_printf ("[%d]: ", i);
- s->ops.info (s->opaque);
- }
-}
-
-static void do_stop_capture (int n)
-{
- int i;
- CaptureState *s;
-
- for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
- if (i == n) {
- s->ops.destroy (s->opaque);
- LIST_REMOVE (s, entries);
- qemu_free (s);
- return;
- }
- }
-}
-
-#ifdef HAS_AUDIO
-int wav_start_capture (CaptureState *s, const char *path, int freq,
- int bits, int nchannels);
-
-static void do_wav_capture (const char *path,
- int has_freq, int freq,
- int has_bits, int bits,
- int has_channels, int nchannels)
-{
- CaptureState *s;
-
- s = qemu_mallocz (sizeof (*s));
- if (!s) {
- term_printf ("Not enough memory to add wave capture\n");
- return;
- }
-
- freq = has_freq ? freq : 44100;
- bits = has_bits ? bits : 16;
- nchannels = has_channels ? nchannels : 2;
-
- if (wav_start_capture (s, path, freq, bits, nchannels)) {
- term_printf ("Faied to add wave capture\n");
- qemu_free (s);
- return;
- }
- LIST_INSERT_HEAD (&capture_head, s, entries);
-}
-#endif
-
-static term_cmd_t term_cmds[] = {
- { "help|?", "s?", do_help,
- "[cmd]", "show the help" },
- { "commit", "s", do_commit,
- "device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
- { "info", "s?", do_info,
- "subcommand", "show various information about the system state" },
- { "q|quit", "", do_quit,
- "", "quit the emulator" },
- { "eject", "-fB", do_eject,
- "[-f] device", "eject a removable media (use -f to force it)" },
- { "change", "BF", do_change,
- "device filename", "change a removable media" },
- { "screendump", "F", do_screen_dump,
- "filename", "save screen into PPM image 'filename'" },
- { "log", "s", do_log,
- "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
-#if 0
- { "savevm", "F", do_savevm,
- "filename", "save the whole virtual machine state to 'filename'" },
- { "loadvm", "F", do_loadvm,
- "filename", "restore the whole virtual machine state from 'filename'" },
-#endif
- { "stop", "", do_stop,
- "", "stop emulation", },
- { "c|cont", "", do_cont,
- "", "resume emulation", },
-#ifdef CONFIG_GDBSTUB
- { "gdbserver", "s?", do_gdbserver,
- "[port]", "start gdbserver session (default port=1234)", },
-#endif
- { "x", "/l", do_memory_dump,
- "/fmt addr", "virtual memory dump starting at 'addr'", },
- { "xp", "/l", do_physical_memory_dump,
- "/fmt addr", "physical memory dump starting at 'addr'", },
- { "p|print", "/l", do_print,
- "/fmt expr", "print expression value (use $reg for CPU register access)", },
- { "i", "/ii.", do_ioport_read,
- "/fmt addr", "I/O port read" },
-
- { "sendkey", "si?", do_sendkey,
- "keys [hold_ms]", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" },
- { "system_reset", "", do_system_reset,
- "", "reset the system" },
- { "system_powerdown", "", do_system_powerdown,
- "", "send system power down event" },
- { "sum", "ii", do_sum,
- "addr size", "compute the checksum of a memory region" },
- { "usb_add", "s", do_usb_add,
- "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
- { "usb_del", "s", do_usb_del,
- "device", "remove USB device 'bus.addr'" },
- { "cpu", "i", do_cpu_set,
- "index", "set the default CPU" },
- { "mouse_move", "sss?", do_mouse_move,
- "dx dy [dz]", "send mouse move events" },
- { "mouse_button", "i", do_mouse_button,
- "state", "change mouse button state (1=L, 2=M, 4=R)" },
-#ifdef HAS_AUDIO
- { "wavcapture", "si?i?i?", do_wav_capture,
- "path [frequency bits channels]",
- "capture audio to a wave file (default frequency=44100 bits=16 channels=2)" },
-#endif
- { "stopcapture", "i", do_stop_capture,
- "capture index", "stop capture" },
- { NULL, NULL, },
-};
-
-static term_cmd_t info_cmds[] = {
- { "version", "", do_info_version,
- "", "show the version of qemu" },
- { "network", "", do_info_network,
- "", "show the network state" },
- { "block", "", do_info_block,
- "", "show the block devices" },
- { "registers", "", do_info_registers,
- "", "show the cpu registers" },
- { "cpus", "", do_info_cpus,
- "", "show infos for each CPU" },
- { "history", "", do_info_history,
- "", "show the command line history", },
- { "irq", "", irq_info,
- "", "show the interrupts statistics (if available)", },
- { "pic", "", pic_info,
- "", "show i8259 (PIC) state", },
- { "pci", "", pci_info,
- "", "show PCI info", },
-#if defined(TARGET_I386)
- { "tlb", "", tlb_info,
- "", "show virtual to physical memory mappings", },
- { "mem", "", mem_info,
- "", "show the active virtual memory mappings", },
-#endif
- { "jit", "", do_info_jit,
- "", "show dynamic compiler info", },
- { "kqemu", "", do_info_kqemu,
- "", "show kqemu information", },
- { "usb", "", usb_info,
- "", "show guest USB devices", },
- { "usbhost", "", usb_host_info,
- "", "show host USB devices", },
- { "profile", "", do_info_profile,
- "", "show profiling information", },
- { "capture", "", do_info_capture,
- "show capture information" },
- { NULL, NULL, },
-};
-
-/*******************************************************************/
-
-static const char *pch;
-static jmp_buf expr_env;
-
-#define MD_TLONG 0
-#define MD_I32 1
-
-typedef struct MonitorDef {
- const char *name;
- int offset;
- target_long (*get_value)(struct MonitorDef *md, int val);
- int type;
-} MonitorDef;
-
-#if defined(TARGET_I386)
-static target_long monitor_get_pc (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return env->eip + env->segs[R_CS].base;
-}
-#endif
-
-#if defined(TARGET_PPC)
-static target_long monitor_get_ccr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- unsigned int u;
- int i;
-
- if (!env)
- return 0;
-
- u = 0;
- for (i = 0; i < 8; i++)
- u |= env->crf[i] << (32 - (4 * i));
-
- return u;
-}
-
-static target_long monitor_get_msr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return env->msr;
-}
-
-static target_long monitor_get_xer (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return ppc_load_xer(env);
-}
-
-static target_long monitor_get_decr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return cpu_ppc_load_decr(env);
-}
-
-static target_long monitor_get_tbu (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return cpu_ppc_load_tbu(env);
-}
-
-static target_long monitor_get_tbl (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return cpu_ppc_load_tbl(env);
-}
-#endif
-
-#if defined(TARGET_SPARC)
-#ifndef TARGET_SPARC64
-static target_long monitor_get_psr (struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return GET_PSR(env);
-}
-#endif
-
-static target_long monitor_get_reg(struct MonitorDef *md, int val)
-{
- CPUState *env = mon_get_cpu();
- if (!env)
- return 0;
- return env->regwptr[val];
-}
-#endif
-
-static MonitorDef monitor_defs[] = {
-#ifdef TARGET_I386
-
-#define SEG(name, seg) \
- { name, offsetof(CPUState, segs[seg].selector), NULL, MD_I32 },\
- { name ".base", offsetof(CPUState, segs[seg].base) },\
- { name ".limit", offsetof(CPUState, segs[seg].limit), NULL, MD_I32 },
-
- { "eax", offsetof(CPUState, regs[0]) },
- { "ecx", offsetof(CPUState, regs[1]) },
- { "edx", offsetof(CPUState, regs[2]) },
- { "ebx", offsetof(CPUState, regs[3]) },
- { "esp|sp", offsetof(CPUState, regs[4]) },
- { "ebp|fp", offsetof(CPUState, regs[5]) },
- { "esi", offsetof(CPUState, regs[6]) },
- { "edi", offsetof(CPUState, regs[7]) },
-#ifdef TARGET_X86_64
- { "r8", offsetof(CPUState, regs[8]) },
- { "r9", offsetof(CPUState, regs[9]) },
- { "r10", offsetof(CPUState, regs[10]) },
- { "r11", offsetof(CPUState, regs[11]) },
- { "r12", offsetof(CPUState, regs[12]) },
- { "r13", offsetof(CPUState, regs[13]) },
- { "r14", offsetof(CPUState, regs[14]) },
- { "r15", offsetof(CPUState, regs[15]) },
-#endif
- { "eflags", offsetof(CPUState, eflags) },
- { "eip", offsetof(CPUState, eip) },
- SEG("cs", R_CS)
- SEG("ds", R_DS)
- SEG("es", R_ES)
- SEG("ss", R_SS)
- SEG("fs", R_FS)
- SEG("gs", R_GS)
- { "pc", 0, monitor_get_pc, },
-#elif defined(TARGET_PPC)
- /* General purpose registers */
- { "r0", offsetof(CPUState, gpr[0]) },
- { "r1", offsetof(CPUState, gpr[1]) },
- { "r2", offsetof(CPUState, gpr[2]) },
- { "r3", offsetof(CPUState, gpr[3]) },
- { "r4", offsetof(CPUState, gpr[4]) },
- { "r5", offsetof(CPUState, gpr[5]) },
- { "r6", offsetof(CPUState, gpr[6]) },
- { "r7", offsetof(CPUState, gpr[7]) },
- { "r8", offsetof(CPUState, gpr[8]) },
- { "r9", offsetof(CPUState, gpr[9]) },
- { "r10", offsetof(CPUState, gpr[10]) },
- { "r11", offsetof(CPUState, gpr[11]) },
- { "r12", offsetof(CPUState, gpr[12]) },
- { "r13", offsetof(CPUState, gpr[13]) },
- { "r14", offsetof(CPUState, gpr[14]) },
- { "r15", offsetof(CPUState, gpr[15]) },
- { "r16", offsetof(CPUState, gpr[16]) },
- { "r17", offsetof(CPUState, gpr[17]) },
- { "r18", offsetof(CPUState, gpr[18]) },
- { "r19", offsetof(CPUState, gpr[19]) },
- { "r20", offsetof(CPUState, gpr[20]) },
- { "r21", offsetof(CPUState, gpr[21]) },
- { "r22", offsetof(CPUState, gpr[22]) },
- { "r23", offsetof(CPUState, gpr[23]) },
- { "r24", offsetof(CPUState, gpr[24]) },
- { "r25", offsetof(CPUState, gpr[25]) },
- { "r26", offsetof(CPUState, gpr[26]) },
- { "r27", offsetof(CPUState, gpr[27]) },
- { "r28", offsetof(CPUState, gpr[28]) },
- { "r29", offsetof(CPUState, gpr[29]) },
- { "r30", offsetof(CPUState, gpr[30]) },
- { "r31", offsetof(CPUState, gpr[31]) },
- /* Floating point registers */
- { "f0", offsetof(CPUState, fpr[0]) },
- { "f1", offsetof(CPUState, fpr[1]) },
- { "f2", offsetof(CPUState, fpr[2]) },
- { "f3", offsetof(CPUState, fpr[3]) },
- { "f4", offsetof(CPUState, fpr[4]) },
- { "f5", offsetof(CPUState, fpr[5]) },
- { "f6", offsetof(CPUState, fpr[6]) },
- { "f7", offsetof(CPUState, fpr[7]) },
- { "f8", offsetof(CPUState, fpr[8]) },
- { "f9", offsetof(CPUState, fpr[9]) },
- { "f10", offsetof(CPUState, fpr[10]) },
- { "f11", offsetof(CPUState, fpr[11]) },
- { "f12", offsetof(CPUState, fpr[12]) },
- { "f13", offsetof(CPUState, fpr[13]) },
- { "f14", offsetof(CPUState, fpr[14]) },
- { "f15", offsetof(CPUState, fpr[15]) },
- { "f16", offsetof(CPUState, fpr[16]) },
- { "f17", offsetof(CPUState, fpr[17]) },
- { "f18", offsetof(CPUState, fpr[18]) },
- { "f19", offsetof(CPUState, fpr[19]) },
- { "f20", offsetof(CPUState, fpr[20]) },
- { "f21", offsetof(CPUState, fpr[21]) },
- { "f22", offsetof(CPUState, fpr[22]) },
- { "f23", offsetof(CPUState, fpr[23]) },
- { "f24", offsetof(CPUState, fpr[24]) },
- { "f25", offsetof(CPUState, fpr[25]) },
- { "f26", offsetof(CPUState, fpr[26]) },
- { "f27", offsetof(CPUState, fpr[27]) },
- { "f28", offsetof(CPUState, fpr[28]) },
- { "f29", offsetof(CPUState, fpr[29]) },
- { "f30", offsetof(CPUState, fpr[30]) },
- { "f31", offsetof(CPUState, fpr[31]) },
- { "fpscr", offsetof(CPUState, fpscr) },
- /* Next instruction pointer */
- { "nip|pc", offsetof(CPUState, nip) },
- { "lr", offsetof(CPUState, lr) },
- { "ctr", offsetof(CPUState, ctr) },
- { "decr", 0, &monitor_get_decr, },
- { "ccr", 0, &monitor_get_ccr, },
- /* Machine state register */
- { "msr", 0, &monitor_get_msr, },
- { "xer", 0, &monitor_get_xer, },
- { "tbu", 0, &monitor_get_tbu, },
- { "tbl", 0, &monitor_get_tbl, },
-#if defined(TARGET_PPC64)
- /* Address space register */
- { "asr", offsetof(CPUState, asr) },
-#endif
- /* Segment registers */
- { "sdr1", offsetof(CPUState, sdr1) },
- { "sr0", offsetof(CPUState, sr[0]) },
- { "sr1", offsetof(CPUState, sr[1]) },
- { "sr2", offsetof(CPUState, sr[2]) },
- { "sr3", offsetof(CPUState, sr[3]) },
- { "sr4", offsetof(CPUState, sr[4]) },
- { "sr5", offsetof(CPUState, sr[5]) },
- { "sr6", offsetof(CPUState, sr[6]) },
- { "sr7", offsetof(CPUState, sr[7]) },
- { "sr8", offsetof(CPUState, sr[8]) },
- { "sr9", offsetof(CPUState, sr[9]) },
- { "sr10", offsetof(CPUState, sr[10]) },
- { "sr11", offsetof(CPUState, sr[11]) },
- { "sr12", offsetof(CPUState, sr[12]) },
- { "sr13", offsetof(CPUState, sr[13]) },
- { "sr14", offsetof(CPUState, sr[14]) },
- { "sr15", offsetof(CPUState, sr[15]) },
- /* Too lazy to put BATs and SPRs ... */
-#elif defined(TARGET_SPARC)
- { "g0", offsetof(CPUState, gregs[0]) },
- { "g1", offsetof(CPUState, gregs[1]) },
- { "g2", offsetof(CPUState, gregs[2]) },
- { "g3", offsetof(CPUState, gregs[3]) },
- { "g4", offsetof(CPUState, gregs[4]) },
- { "g5", offsetof(CPUState, gregs[5]) },
- { "g6", offsetof(CPUState, gregs[6]) },
- { "g7", offsetof(CPUState, gregs[7]) },
- { "o0", 0, monitor_get_reg },
- { "o1", 1, monitor_get_reg },
- { "o2", 2, monitor_get_reg },
- { "o3", 3, monitor_get_reg },
- { "o4", 4, monitor_get_reg },
- { "o5", 5, monitor_get_reg },
- { "o6", 6, monitor_get_reg },
- { "o7", 7, monitor_get_reg },
- { "l0", 8, monitor_get_reg },
- { "l1", 9, monitor_get_reg },
- { "l2", 10, monitor_get_reg },
- { "l3", 11, monitor_get_reg },
- { "l4", 12, monitor_get_reg },
- { "l5", 13, monitor_get_reg },
- { "l6", 14, monitor_get_reg },
- { "l7", 15, monitor_get_reg },
- { "i0", 16, monitor_get_reg },
- { "i1", 17, monitor_get_reg },
- { "i2", 18, monitor_get_reg },
- { "i3", 19, monitor_get_reg },
- { "i4", 20, monitor_get_reg },
- { "i5", 21, monitor_get_reg },
- { "i6", 22, monitor_get_reg },
- { "i7", 23, monitor_get_reg },
- { "pc", offsetof(CPUState, pc) },
- { "npc", offsetof(CPUState, npc) },
- { "y", offsetof(CPUState, y) },
-#ifndef TARGET_SPARC64
- { "psr", 0, &monitor_get_psr, },
- { "wim", offsetof(CPUState, wim) },
-#endif
- { "tbr", offsetof(CPUState, tbr) },
- { "fsr", offsetof(CPUState, fsr) },
- { "f0", offsetof(CPUState, fpr[0]) },
- { "f1", offsetof(CPUState, fpr[1]) },
- { "f2", offsetof(CPUState, fpr[2]) },
- { "f3", offsetof(CPUState, fpr[3]) },
- { "f4", offsetof(CPUState, fpr[4]) },
- { "f5", offsetof(CPUState, fpr[5]) },
- { "f6", offsetof(CPUState, fpr[6]) },
- { "f7", offsetof(CPUState, fpr[7]) },
- { "f8", offsetof(CPUState, fpr[8]) },
- { "f9", offsetof(CPUState, fpr[9]) },
- { "f10", offsetof(CPUState, fpr[10]) },
- { "f11", offsetof(CPUState, fpr[11]) },
- { "f12", offsetof(CPUState, fpr[12]) },
- { "f13", offsetof(CPUState, fpr[13]) },
- { "f14", offsetof(CPUState, fpr[14]) },
- { "f15", offsetof(CPUState, fpr[15]) },
- { "f16", offsetof(CPUState, fpr[16]) },
- { "f17", offsetof(CPUState, fpr[17]) },
- { "f18", offsetof(CPUState, fpr[18]) },
- { "f19", offsetof(CPUState, fpr[19]) },
- { "f20", offsetof(CPUState, fpr[20]) },
- { "f21", offsetof(CPUState, fpr[21]) },
- { "f22", offsetof(CPUState, fpr[22]) },
- { "f23", offsetof(CPUState, fpr[23]) },
- { "f24", offsetof(CPUState, fpr[24]) },
- { "f25", offsetof(CPUState, fpr[25]) },
- { "f26", offsetof(CPUState, fpr[26]) },
- { "f27", offsetof(CPUState, fpr[27]) },
- { "f28", offsetof(CPUState, fpr[28]) },
- { "f29", offsetof(CPUState, fpr[29]) },
- { "f30", offsetof(CPUState, fpr[30]) },
- { "f31", offsetof(CPUState, fpr[31]) },
-#ifdef TARGET_SPARC64
- { "f32", offsetof(CPUState, fpr[32]) },
- { "f34", offsetof(CPUState, fpr[34]) },
- { "f36", offsetof(CPUState, fpr[36]) },
- { "f38", offsetof(CPUState, fpr[38]) },
- { "f40", offsetof(CPUState, fpr[40]) },
- { "f42", offsetof(CPUState, fpr[42]) },
- { "f44", offsetof(CPUState, fpr[44]) },
- { "f46", offsetof(CPUState, fpr[46]) },
- { "f48", offsetof(CPUState, fpr[48]) },
- { "f50", offsetof(CPUState, fpr[50]) },
- { "f52", offsetof(CPUState, fpr[52]) },
- { "f54", offsetof(CPUState, fpr[54]) },
- { "f56", offsetof(CPUState, fpr[56]) },
- { "f58", offsetof(CPUState, fpr[58]) },
- { "f60", offsetof(CPUState, fpr[60]) },
- { "f62", offsetof(CPUState, fpr[62]) },
- { "asi", offsetof(CPUState, asi) },
- { "pstate", offsetof(CPUState, pstate) },
- { "cansave", offsetof(CPUState, cansave) },
- { "canrestore", offsetof(CPUState, canrestore) },
- { "otherwin", offsetof(CPUState, otherwin) },
- { "wstate", offsetof(CPUState, wstate) },
- { "cleanwin", offsetof(CPUState, cleanwin) },
- { "fprs", offsetof(CPUState, fprs) },
-#endif
-#elif defined(TARGET_ARM)
- { "r0", offsetof(CPUState, regs[0]) },
- { "r1", offsetof(CPUState, regs[1]) },
- { "r2", offsetof(CPUState, regs[2]) },
- { "r3", offsetof(CPUState, regs[3]) },
- { "r4", offsetof(CPUState, regs[4]) },
- { "r5", offsetof(CPUState, regs[5]) },
- { "r6", offsetof(CPUState, regs[6]) },
- { "r7", offsetof(CPUState, regs[7]) },
- { "r8", offsetof(CPUState, regs[8]) },
- { "r9", offsetof(CPUState, regs[9]) },
- { "r10", offsetof(CPUState, regs[10]) },
- { "r11", offsetof(CPUState, regs[11]) },
- { "r12", offsetof(CPUState, regs[12]) },
- { "r13", offsetof(CPUState, regs[13]) },
- { "r14", offsetof(CPUState, regs[14]) },
- { "r15", offsetof(CPUState, regs[15]) },
- /* some interesting aliases */
- { "sp", offsetof(CPUState, regs[13]) },
- { "lr", offsetof(CPUState, regs[14]) },
- { "pc", offsetof(CPUState, regs[15]) },
-#endif
- { NULL },
-};
-
-static void expr_error(const char *fmt)
-{
- term_printf(fmt);
- term_printf("\n");
- longjmp(expr_env, 1);
-}
-
-/* return 0 if OK, -1 if not found, -2 if no CPU defined */
-static int get_monitor_def(target_long *pval, const char *name)
-{
- MonitorDef *md;
- void *ptr;
-
- for(md = monitor_defs; md->name != NULL; md++) {
- if (compare_cmd(name, md->name)) {
- if (md->get_value) {
- *pval = md->get_value(md, md->offset);
- } else {
- CPUState *env = mon_get_cpu();
- if (!env)
- return -2;
- ptr = (uint8_t *)env + md->offset;
- switch(md->type) {
- case MD_I32:
- *pval = *(int32_t *)ptr;
- break;
- case MD_TLONG:
- *pval = *(target_long *)ptr;
- break;
- default:
- *pval = 0;
- break;
- }
- }
- return 0;
- }
- }
- return -1;
-}
-
-static void next(void)
-{
- if (pch != '\0') {
- pch++;
- while (isspace(*pch))
- pch++;
- }
-}
-
-static int64_t expr_sum(void);
-
-static int64_t expr_unary(void)
-{
- int64_t n;
- char *p;
- int ret;
-
- switch(*pch) {
- case '+':
- next();
- n = expr_unary();
- break;
- case '-':
- next();
- n = -expr_unary();
- break;
- case '~':
- next();
- n = ~expr_unary();
- break;
- case '(':
- next();
- n = expr_sum();
- if (*pch != ')') {
- expr_error("')' expected");
- }
- next();
- break;
- case '\'':
- pch++;
- if (*pch == '\0')
- expr_error("character constant expected");
- n = *pch;
- pch++;
- if (*pch != '\'')
- expr_error("missing terminating \' character");
- next();
- break;
- case '$':
- {
- char buf[128], *q;
- target_long reg=0;
-
- pch++;
- q = buf;
- while ((*pch >= 'a' && *pch <= 'z') ||
- (*pch >= 'A' && *pch <= 'Z') ||
- (*pch >= '0' && *pch <= '9') ||
- *pch == '_' || *pch == '.') {
- if ((q - buf) < sizeof(buf) - 1)
- *q++ = *pch;
- pch++;
- }
- while (isspace(*pch))
- pch++;
- *q = 0;
- ret = get_monitor_def(&reg, buf);
- if (ret == -1)
- expr_error("unknown register");
- else if (ret == -2)
- expr_error("no cpu defined");
- n = reg;
- }
- break;
- case '\0':
- expr_error("unexpected end of expression");
- n = 0;
- break;
- default:
-#if TARGET_PHYS_ADDR_BITS > 32
- n = strtoull(pch, &p, 0);
-#else
- n = strtoul(pch, &p, 0);
-#endif
- if (pch == p) {
- expr_error("invalid char in expression");
- }
- pch = p;
- while (isspace(*pch))
- pch++;
- break;
- }
- return n;
-}
-
-
-static int64_t expr_prod(void)
-{
- int64_t val, val2;
- int op;
-
- val = expr_unary();
- for(;;) {
- op = *pch;
- if (op != '*' && op != '/' && op != '%')
- break;
- next();
- val2 = expr_unary();
- switch(op) {
- default:
- case '*':
- val *= val2;
- break;
- case '/':
- case '%':
- if (val2 == 0)
- expr_error("division by zero");
- if (op == '/')
- val /= val2;
- else
- val %= val2;
- break;
- }
- }
- return val;
-}
-
-static int64_t expr_logic(void)
-{
- int64_t val, val2;
- int op;
-
- val = expr_prod();
- for(;;) {
- op = *pch;
- if (op != '&' && op != '|' && op != '^')
- break;
- next();
- val2 = expr_prod();
- switch(op) {
- default:
- case '&':
- val &= val2;
- break;
- case '|':
- val |= val2;
- break;
- case '^':
- val ^= val2;
- break;
- }
- }
- return val;
-}
-
-static int64_t expr_sum(void)
-{
- int64_t val, val2;
- int op;
-
- val = expr_logic();
- for(;;) {
- op = *pch;
- if (op != '+' && op != '-')
- break;
- next();
- val2 = expr_logic();
- if (op == '+')
- val += val2;
- else
- val -= val2;
- }
- return val;
-}
-
-static int get_expr(int64_t *pval, const char **pp)
-{
- pch = *pp;
- if (setjmp(expr_env)) {
- *pp = pch;
- return -1;
- }
- while (isspace(*pch))
- pch++;
- *pval = expr_sum();
- *pp = pch;
- return 0;
-}
-
-static int get_str(char *buf, int buf_size, const char **pp)
-{
- const char *p;
- char *q;
- int c;
-
- q = buf;
- p = *pp;
- while (isspace(*p))
- p++;
- if (*p == '\0') {
- fail:
- *q = '\0';
- *pp = p;
- return -1;
- }
- if (*p == '\"') {
- p++;
- while (*p != '\0' && *p != '\"') {
- if (*p == '\\') {
- p++;
- c = *p++;
- switch(c) {
- case 'n':
- c = '\n';
- break;
- case 'r':
- c = '\r';
- break;
- case '\\':
- case '\'':
- case '\"':
- break;
- default:
- qemu_printf("unsupported escape code: '\\%c'\n", c);
- goto fail;
- }
- if ((q - buf) < buf_size - 1) {
- *q++ = c;
- }
- } else {
- if ((q - buf) < buf_size - 1) {
- *q++ = *p;
- }
- p++;
- }
- }
- if (*p != '\"') {
- qemu_printf("unterminated string\n");
- goto fail;
- }
- p++;
- } else {
- while (*p != '\0' && !isspace(*p)) {
- if ((q - buf) < buf_size - 1) {
- *q++ = *p;
- }
- p++;
- }
- }
- *q = '\0';
- *pp = p;
- return 0;
-}
-
-static int default_fmt_format = 'x';
-static int default_fmt_size = 4;
-
-#define MAX_ARGS 16
-
-static void monitor_handle_command(const char *cmdline)
-{
- const char *p, *pstart, *typestr;
- char *q;
- int c, nb_args, len, i, has_arg;
- term_cmd_t *cmd;
- char cmdname[256];
- char buf[1024];
- void *str_allocated[MAX_ARGS];
- void *args[MAX_ARGS];
- void (*handler_0)(void);
- void (*handler_1)(void *arg0);
- void (*handler_2)(void *arg0, void *arg1);
- void (*handler_3)(void *arg0, void *arg1, void *arg2);
- void (*handler_4)(void *arg0, void *arg1, void *arg2, void *arg3);
- void (*handler_5)(void *arg0, void *arg1, void *arg2, void *arg3,
- void *arg4);
- void (*handler_6)(void *arg0, void *arg1, void *arg2, void *arg3,
- void *arg4, void *arg5);
- void (*handler_7)(void *arg0, void *arg1, void *arg2, void *arg3,
- void *arg4, void *arg5, void *arg6);
-
-#ifdef DEBUG
- term_printf("command='%s'\n", cmdline);
-#endif
-
- /* extract the command name */
- p = cmdline;
- q = cmdname;
- while (isspace(*p))
- p++;
- if (*p == '\0')
- return;
- pstart = p;
- while (*p != '\0' && *p != '/' && !isspace(*p))
- p++;
- len = p - pstart;
- if (len > sizeof(cmdname) - 1)
- len = sizeof(cmdname) - 1;
- memcpy(cmdname, pstart, len);
- cmdname[len] = '\0';
-
- /* find the command */
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(cmdname, cmd->name))
- goto found;
- }
- term_printf("unknown command: '%s'\n", cmdname);
- return;
- found:
-
- for(i = 0; i < MAX_ARGS; i++)
- str_allocated[i] = NULL;
-
- /* parse the parameters */
- typestr = cmd->args_type;
- nb_args = 0;
- for(;;) {
- c = *typestr;
- if (c == '\0')
- break;
- typestr++;
- switch(c) {
- case 'F':
- case 'B':
- case 's':
- {
- int ret;
- char *str;
-
- while (isspace(*p))
- p++;
- if (*typestr == '?') {
- typestr++;
- if (*p == '\0') {
- /* no optional string: NULL argument */
- str = NULL;
- goto add_str;
- }
- }
- ret = get_str(buf, sizeof(buf), &p);
- if (ret < 0) {
- switch(c) {
- case 'F':
- term_printf("%s: filename expected\n", cmdname);
- break;
- case 'B':
- term_printf("%s: block device name expected\n", cmdname);
- break;
- default:
- term_printf("%s: string expected\n", cmdname);
- break;
- }
- goto fail;
- }
- str = qemu_malloc(strlen(buf) + 1);
- pstrcpy(str, sizeof(buf), buf);
- str_allocated[nb_args] = str;
- add_str:
- if (nb_args >= MAX_ARGS) {
- error_args:
- term_printf("%s: too many arguments\n", cmdname);
- goto fail;
- }
- args[nb_args++] = str;
- }
- break;
- case '/':
- {
- int count, format, size;
-
- while (isspace(*p))
- p++;
- if (*p == '/') {
- /* format found */
- p++;
- count = 1;
- if (isdigit(*p)) {
- count = 0;
- while (isdigit(*p)) {
- count = count * 10 + (*p - '0');
- p++;
- }
- }
- size = -1;
- format = -1;
- for(;;) {
- switch(*p) {
- case 'o':
- case 'd':
- case 'u':
- case 'x':
- case 'i':
- case 'c':
- format = *p++;
- break;
- case 'b':
- size = 1;
- p++;
- break;
- case 'h':
- size = 2;
- p++;
- break;
- case 'w':
- size = 4;
- p++;
- break;
- case 'g':
- case 'L':
- size = 8;
- p++;
- break;
- default:
- goto next;
- }
- }
- next:
- if (*p != '\0' && !isspace(*p)) {
- term_printf("invalid char in format: '%c'\n", *p);
- goto fail;
- }
- if (format < 0)
- format = default_fmt_format;
- if (format != 'i') {
- /* for 'i', not specifying a size gives -1 as size */
- if (size < 0)
- size = default_fmt_size;
- }
- default_fmt_size = size;
- default_fmt_format = format;
- } else {
- count = 1;
- format = default_fmt_format;
- if (format != 'i') {
- size = default_fmt_size;
- } else {
- size = -1;
- }
- }
- if (nb_args + 3 > MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void*)(long)count;
- args[nb_args++] = (void*)(long)format;
- args[nb_args++] = (void*)(long)size;
- }
- break;
- case 'i':
- case 'l':
- {
- int64_t val;
-
- while (isspace(*p))
- p++;
- if (*typestr == '?' || *typestr == '.') {
- if (*typestr == '?') {
- if (*p == '\0')
- has_arg = 0;
- else
- has_arg = 1;
- } else {
- if (*p == '.') {
- p++;
- while (isspace(*p))
- p++;
- has_arg = 1;
- } else {
- has_arg = 0;
- }
- }
- typestr++;
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)(long)has_arg;
- if (!has_arg) {
- if (nb_args >= MAX_ARGS)
- goto error_args;
- val = -1;
- goto add_num;
- }
- }
- if (get_expr(&val, &p))
- goto fail;
- add_num:
- if (c == 'i') {
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)(long)val;
- } else {
- if ((nb_args + 1) >= MAX_ARGS)
- goto error_args;
-#if TARGET_PHYS_ADDR_BITS > 32
- args[nb_args++] = (void *)(long)((val >> 32) & 0xffffffff);
-#else
- args[nb_args++] = (void *)0;
-#endif
- args[nb_args++] = (void *)(long)(val & 0xffffffff);
- }
- }
- break;
- case '-':
- {
- int has_option;
- /* option */
-
- c = *typestr++;
- if (c == '\0')
- goto bad_type;
- while (isspace(*p))
- p++;
- has_option = 0;
- if (*p == '-') {
- p++;
- if (*p != c) {
- term_printf("%s: unsupported option -%c\n",
- cmdname, *p);
- goto fail;
- }
- p++;
- has_option = 1;
- }
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)(long)has_option;
- }
- break;
- default:
- bad_type:
- term_printf("%s: unknown type '%c'\n", cmdname, c);
- goto fail;
- }
- }
- /* check that all arguments were parsed */
- while (isspace(*p))
- p++;
- if (*p != '\0') {
- term_printf("%s: extraneous characters at the end of line\n",
- cmdname);
- goto fail;
- }
-
- switch(nb_args) {
- case 0:
- handler_0 = cmd->handler;
- handler_0();
- break;
- case 1:
- handler_1 = cmd->handler;
- handler_1(args[0]);
- break;
- case 2:
- handler_2 = cmd->handler;
- handler_2(args[0], args[1]);
- break;
- case 3:
- handler_3 = cmd->handler;
- handler_3(args[0], args[1], args[2]);
- break;
- case 4:
- handler_4 = cmd->handler;
- handler_4(args[0], args[1], args[2], args[3]);
- break;
- case 5:
- handler_5 = cmd->handler;
- handler_5(args[0], args[1], args[2], args[3], args[4]);
- break;
- case 6:
- handler_6 = cmd->handler;
- handler_6(args[0], args[1], args[2], args[3], args[4], args[5]);
- break;
- case 7:
- handler_7 = cmd->handler;
- handler_7(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
- break;
- default:
- term_printf("unsupported number of arguments: %d\n", nb_args);
- goto fail;
- }
- fail:
- for(i = 0; i < MAX_ARGS; i++)
- qemu_free(str_allocated[i]);
- return;
-}
-
-static void cmd_completion(const char *name, const char *list)
-{
- const char *p, *pstart;
- char cmd[128];
- int len;
-
- p = list;
- for(;;) {
- pstart = p;
- p = strchr(p, '|');
- if (!p)
- p = pstart + strlen(pstart);
- len = p - pstart;
- if (len > sizeof(cmd) - 2)
- len = sizeof(cmd) - 2;
- memcpy(cmd, pstart, len);
- cmd[len] = '\0';
- if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
- add_completion(cmd);
- }
- if (*p == '\0')
- break;
- p++;
- }
-}
-
-static void file_completion(const char *input)
-{
- DIR *ffs;
- struct dirent *d;
- char path[1024];
- char file[1024], file_prefix[1024];
- int input_path_len;
- const char *p;
-
- p = strrchr(input, '/');
- if (!p) {
- input_path_len = 0;
- pstrcpy(file_prefix, sizeof(file_prefix), input);
- pstrcpy(path, sizeof(path), ".");
- } else {
- input_path_len = p - input + 1;
- memcpy(path, input, input_path_len);
- if (input_path_len > sizeof(path) - 1)
- input_path_len = sizeof(path) - 1;
- path[input_path_len] = '\0';
- pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
- }
-#ifdef DEBUG_COMPLETION
- term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);
-#endif
- ffs = opendir(path);
- if (!ffs)
- return;
- for(;;) {
- struct stat sb;
- d = readdir(ffs);
- if (!d)
- break;
- if (strstart(d->d_name, file_prefix, NULL)) {
- memcpy(file, input, input_path_len);
- if (input_path_len < sizeof(file))
- pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
- d->d_name);
- /* stat the file to find out if it's a directory.
- * In that case add a slash to speed up typing long paths
- */
- stat(file, &sb);
- if(S_ISDIR(sb.st_mode))
- pstrcat(file, sizeof(file), "/");
- add_completion(file);
- }
- }
- closedir(ffs);
-}
-
-static void block_completion_it(void *opaque, const char *name)
-{
- const char *input = opaque;
-
- if (input[0] == '\0' ||
- !strncmp(name, (char *)input, strlen(input))) {
- add_completion(name);
- }
-}
-
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
- int *pnb_args, char **args)
-{
- const char *p;
- int nb_args, ret;
- char buf[1024];
-
- p = cmdline;
- nb_args = 0;
- for(;;) {
- while (isspace(*p))
- p++;
- if (*p == '\0')
- break;
- if (nb_args >= MAX_ARGS)
- break;
- ret = get_str(buf, sizeof(buf), &p);
- args[nb_args] = qemu_strdup(buf);
- nb_args++;
- if (ret < 0)
- break;
- }
- *pnb_args = nb_args;
-}
-
-void readline_find_completion(const char *cmdline)
-{
- const char *cmdname;
- char *args[MAX_ARGS];
- int nb_args, i, len;
- const char *ptype, *str;
- term_cmd_t *cmd;
- const KeyDef *key;
-
- parse_cmdline(cmdline, &nb_args, args);
-#ifdef DEBUG_COMPLETION
- for(i = 0; i < nb_args; i++) {
- term_printf("arg%d = '%s'\n", i, (char *)args[i]);
- }
-#endif
-
- /* if the line ends with a space, it means we want to complete the
- next arg */
- len = strlen(cmdline);
- if (len > 0 && isspace(cmdline[len - 1])) {
- if (nb_args >= MAX_ARGS)
- return;
- args[nb_args++] = qemu_strdup("");
- }
- if (nb_args <= 1) {
- /* command completion */
- if (nb_args == 0)
- cmdname = "";
- else
- cmdname = args[0];
- completion_index = strlen(cmdname);
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- cmd_completion(cmdname, cmd->name);
- }
- } else {
- /* find the command */
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(args[0], cmd->name))
- goto found;
- }
- return;
- found:
- ptype = cmd->args_type;
- for(i = 0; i < nb_args - 2; i++) {
- if (*ptype != '\0') {
- ptype++;
- while (*ptype == '?')
- ptype++;
- }
- }
- str = args[nb_args - 1];
- switch(*ptype) {
- case 'F':
- /* file completion */
- completion_index = strlen(str);
- file_completion(str);
- break;
- case 'B':
- /* block device name completion */
- completion_index = strlen(str);
- bdrv_iterate(block_completion_it, (void *)str);
- break;
- case 's':
- /* XXX: more generic ? */
- if (!strcmp(cmd->name, "info")) {
- completion_index = strlen(str);
- for(cmd = info_cmds; cmd->name != NULL; cmd++) {
- cmd_completion(str, cmd->name);
- }
- } else if (!strcmp(cmd->name, "sendkey")) {
- completion_index = strlen(str);
- for(key = key_defs; key->name != NULL; key++) {
- cmd_completion(str, key->name);
- }
- }
- break;
- default:
- break;
- }
- }
- for(i = 0; i < nb_args; i++)
- qemu_free(args[i]);
-}
-
-static int term_can_read(void *opaque)
-{
- return 128;
-}
-
-static void term_read(void *opaque, const uint8_t *buf, int size)
-{
- int i;
- for(i = 0; i < size; i++)
- readline_handle_byte(buf[i]);
-}
-
-static void monitor_start_input(void);
-
-static void monitor_handle_command1(void *opaque, const char *cmdline)
-{
- monitor_handle_command(cmdline);
- monitor_start_input();
-}
-
-static void monitor_start_input(void)
-{
- readline_start("(qemu) ", 0, monitor_handle_command1, NULL);
-}
-
-static void term_event(void *opaque, int event)
-{
- if (event != CHR_EVENT_RESET)
- return;
-
- if (!hide_banner)
- term_printf("QEMU %s monitor - type 'help' for more information\n",
- QEMU_VERSION);
- monitor_start_input();
-}
-
-static int is_first_init = 1;
-
-void monitor_init(CharDriverState *hd, int show_banner)
-{
- int i;
-
- if (is_first_init) {
- key_timer = qemu_new_timer(vm_clock, release_keys, NULL);
- if (!key_timer)
- return;
- for (i = 0; i < MAX_MON; i++) {
- monitor_hd[i] = NULL;
- }
- is_first_init = 0;
- }
- for (i = 0; i < MAX_MON; i++) {
- if (monitor_hd[i] == NULL) {
- monitor_hd[i] = hd;
- break;
- }
- }
-
- hide_banner = !show_banner;
-
- qemu_chr_add_handlers(hd, term_can_read, term_read, term_event, NULL);
-
- readline_start("", 0, monitor_handle_command1, NULL);
-}
-
-/* XXX: use threads ? */
-/* modal monitor readline */
-static int monitor_readline_started;
-static char *monitor_readline_buf;
-static int monitor_readline_buf_size;
-
-static void monitor_readline_cb(void *opaque, const char *input)
-{
- pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);
- monitor_readline_started = 0;
-}
-
-void monitor_readline(const char *prompt, int is_password,
- char *buf, int buf_size)
-{
- int i;
- int old_focus[MAX_MON];
-
- if (is_password) {
- for (i = 0; i < MAX_MON; i++) {
- old_focus[i] = 0;
- if (monitor_hd[i]) {
- old_focus[i] = monitor_hd[i]->focus;
- monitor_hd[i]->focus = 0;
- qemu_chr_send_event(monitor_hd[i], CHR_EVENT_FOCUS);
- }
- }
- }
-
- readline_start(prompt, is_password, monitor_readline_cb, NULL);
- monitor_readline_buf = buf;
- monitor_readline_buf_size = buf_size;
- monitor_readline_started = 1;
- while (monitor_readline_started) {
- main_loop_wait(10);
- }
- /* restore original focus */
- if (is_password) {
- for (i = 0; i < MAX_MON; i++)
- if (old_focus[i])
- monitor_hd[i]->focus = old_focus[i];
- }
-}
diff --git a/net.h b/net.h
deleted file mode 100644
index 5212b48..0000000
--- a/net.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef QEMU_NET_H
-#define QEMU_NET_H
-
-/* VLANs support */
-
-typedef struct VLANClientState VLANClientState;
-
-struct VLANClientState {
- IOReadHandler *fd_read;
- /* Packets may still be sent if this returns zero. It's used to
- rate-limit the slirp code. */
- IOCanRWHandler *fd_can_read;
- void *opaque;
- struct VLANClientState *next;
- struct VLANState *vlan;
- char info_str[256];
-};
-
-struct VLANState {
- int id;
- VLANClientState *first_client;
- struct VLANState *next;
- unsigned int nb_guest_devs, nb_host_devs;
-};
-
-VLANState *qemu_find_vlan(int id);
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque);
-void qemu_del_vlan_client(VLANClientState *vc);
-int qemu_can_send_packet(VLANClientState *vc);
-void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
-void qemu_handler_true(void *opaque);
-
-void do_info_network(void);
-
-/* NIC info */
-
-#define MAX_NICS 8
-
-struct NICInfo {
- uint8_t macaddr[6];
- const char *model;
- VLANState *vlan;
-};
-
-extern int nb_nics;
-extern NICInfo nd_table[MAX_NICS];
-
-/* checksumming functions (net-checksum.c) */
-uint32_t net_checksum_add(int len, uint8_t *buf);
-uint16_t net_checksum_finish(uint32_t sum);
-uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
- uint8_t *addrs, uint8_t *buf);
-void net_checksum_calculate(uint8_t *data, int length);
-
-#endif
diff --git a/offset_layout.py b/offset_layout.py
deleted file mode 100755
index 6c2f879..0000000
--- a/offset_layout.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/python
-
-import re
-import sys
-import getopt
-
-DX = DY = PX = PY = KX = KY = 0
-
-_RE_LINE = re.compile("^\s*(?P<keyword>[\w-]+)\s+{\s*$")
-_RE_XY = re.compile("^(?P<start>\s*)(?P<xy>[x|y]\s+)(?P<num>\d+)(?P<end>\s*)$")
-
-def main():
- ParseArgs()
- ParseInput()
-
-def Usage():
- print >>sys.stderr, """
- Usage: %s --dx offset-x-display --dy offset-y-display --px offset-x-phone-buttons --py offset-y-phone-buttons --kx offset-x-keyboard --ky offset-y-keyboard < layout > layout2.
-
- Unspecified offsets default to 0 (unchanged).
- Reads from stdin, outputs to stdout.
- Phone buttons: soft-left/top/righ/bottom, home, dpad, dial, power, etc.
- Keyboard is the soft keyboard.
-
- If your shell doesn't let you use negative integers, use _ for minus sign,
- i.e. --dx _40 --dy _42 for <-40,-42).
- """ % (sys.argv[0])
- sys.exit(1)
-
-def ParseArgs():
- global DX, DY, PX, PY, KX, KY
- try:
- options, args = getopt.getopt(sys.argv[1:], "", ["dx=", "dy=", "px=", "py=", "kx=", "ky="])
- for opt, value in options:
- if opt in ["--dx"]:
- DX = int(value.replace("_", "-"))
- elif opt in ["--dy"]:
- DY = int(value.replace("_", "-"))
- elif opt in ["--px"]:
- PX = int(value.replace("_", "-"))
- elif opt in ["--py"]:
- PY = int(value.replace("_", "-"))
- elif opt in ["--kx"]:
- KX = int(value.replace("_", "-"))
- elif opt in ["--ky"]:
- KY = int(value.replace("_", "-"))
- else:
- Usage()
- except getopt.error, msg:
- Usage()
-
-def ParseInput():
- global DX, DY, PX, PY, KX, KY
-
- PHONE = [ "soft-left", "home", "back", "dpad-up", "dpad-down", "dpad-left", "dpad-right", "dpad-center", "phone-dial", "phone-hangup", "power", "volume-up", "volume-down" ]
- KEYBOARD = [ "DEL", "CAP", "CAP2", "PERIOD", "ENTER", "ALT", "SYM", "AT", "SPACE", "SLASH", "COMMA", "ALT2" ]
-
- mode = None
- while True:
- line = sys.stdin.readline()
- if not line:
- return
- m_line = _RE_LINE.match(line)
- if m_line:
- keyword = m_line.group("keyword")
- if keyword in ["display", "button"]:
- mode = keyword
- is_phone = False
- is_keyboard = False
- print >>sys.stderr, "Mode:", mode
- else:
- if mode == "button" and "{" in line:
- is_phone = keyword in PHONE
- is_keyboard = (len(keyword) == 1 and keyword.isalnum())
- if not is_keyboard:
- is_keyboard = keyword in KEYBOARD
- elif "}" in line:
- is_phone = False
- is_keyboard = False
- if mode == "display":
- mode = None
- else:
- m_xy = _RE_XY.match(line)
- if m_xy:
- x = 0
- y = 0
- if mode == "display":
- x = DX
- y = DY
- elif mode == "button" and is_phone:
- x = PX
- y = PY
- elif mode == "button" and is_keyboard:
- x = KX
- y = KY
- if x or y:
- d = m_xy.groupdict()
- n = int(d["num"])
- if d["xy"].startswith("x"):
- n += x
- else:
- n += y
- d["num"] = n
- line = "%(start)s%(xy)s%(num)s%(end)s" % d
- sys.stdout.write(line)
-
-
-
-
-if __name__ == "__main__":
- main()
diff --git a/osdep.c b/osdep.c
deleted file mode 100644
index 49193e9..0000000
--- a/osdep.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * QEMU low level functions
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#ifdef HOST_SOLARIS
-#include <sys/types.h>
-#include <sys/statvfs.h>
-#endif
-
-#include "qemu-common.h"
-#include "sysemu.h"
-
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#elif defined(_BSD)
-#include <stdlib.h>
-#else
-#include <malloc.h>
-#endif
-
-
-#if defined(_WIN32)
-void *qemu_memalign(size_t alignment, size_t size)
-{
- return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
-}
-
-void *qemu_vmalloc(size_t size)
-{
- /* FIXME: this is not exactly optimal solution since VirtualAlloc
- has 64Kb granularity, but at least it guarantees us that the
- memory is page aligned. */
- return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
-}
-
-void qemu_vfree(void *ptr)
-{
- VirtualFree(ptr, 0, MEM_RELEASE);
-}
-
-#else
-
-#if defined(USE_KQEMU)
-
-#ifdef __OpenBSD__
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#else
-#include <sys/vfs.h>
-#endif
-
-#include <sys/mman.h>
-#include <fcntl.h>
-
-static void *kqemu_vmalloc(size_t size)
-{
- static int phys_ram_fd = -1;
- static int phys_ram_size = 0;
- void *ptr;
-
-#ifdef __OpenBSD__ /* no need (?) for a dummy file on OpenBSD */
- int map_anon = MAP_ANON;
-#else
- int map_anon = 0;
- const char *tmpdir;
- char phys_ram_file[1024];
-#ifdef HOST_SOLARIS
- struct statvfs stfs;
-#else
- struct statfs stfs;
-#endif
-
- if (phys_ram_fd < 0) {
- tmpdir = getenv("QEMU_TMPDIR");
- if (!tmpdir)
-#ifdef HOST_SOLARIS
- tmpdir = "/tmp";
- if (statvfs(tmpdir, &stfs) == 0) {
-#else
- tmpdir = "/dev/shm";
- if (statfs(tmpdir, &stfs) == 0) {
-#endif
- int64_t free_space;
- int ram_mb;
-
- free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
- if ((ram_size + 8192 * 1024) >= free_space) {
- ram_mb = (ram_size / (1024 * 1024));
- fprintf(stderr,
- "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
- tmpdir, ram_mb);
- if (strcmp(tmpdir, "/dev/shm") == 0) {
- fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
- "mount -o remount,size=%dm /dev/shm\n",
- ram_mb + 16);
- } else {
- fprintf(stderr,
- "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
- "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
- "temporary RAM file will be opened.\n");
- }
- fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
- exit(1);
- }
- }
- snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
- tmpdir);
- phys_ram_fd = mkstemp(phys_ram_file);
- if (phys_ram_fd < 0) {
- fprintf(stderr,
- "warning: could not create temporary file in '%s'.\n"
- "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
- "Using '/tmp' as fallback.\n",
- tmpdir);
- snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
- "/tmp");
- phys_ram_fd = mkstemp(phys_ram_file);
- if (phys_ram_fd < 0) {
- fprintf(stderr, "Could not create temporary memory file '%s'\n",
- phys_ram_file);
- exit(1);
- }
- }
- unlink(phys_ram_file);
- }
- size = (size + 4095) & ~4095;
- ftruncate(phys_ram_fd, phys_ram_size + size);
-#endif /* !__OpenBSD__ */
- ptr = mmap(NULL,
- size,
- PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
- phys_ram_fd, phys_ram_size);
- if (ptr == MAP_FAILED) {
- fprintf(stderr, "Could not map physical memory\n");
- exit(1);
- }
- phys_ram_size += size;
- return ptr;
-}
-
-static void kqemu_vfree(void *ptr)
-{
- /* may be useful some day, but currently we do not need to free */
-}
-
-#endif
-
-void *qemu_memalign(size_t alignment, size_t size)
-{
-#if defined(_POSIX_C_SOURCE)
- int ret;
- void *ptr;
- ret = posix_memalign(&ptr, alignment, size);
- if (ret != 0)
- return NULL;
- return ptr;
-#elif defined(_BSD)
- return valloc(size);
-#else
- return memalign(alignment, size);
-#endif
-}
-
-/* alloc shared memory pages */
-void *qemu_vmalloc(size_t size)
-{
-#if defined(USE_KQEMU)
- if (kqemu_allowed)
- return kqemu_vmalloc(size);
-#endif
-#ifdef _BSD
- return valloc(size);
-#else
- return memalign(4096, size);
-#endif
-}
-
-void qemu_vfree(void *ptr)
-{
-#if defined(USE_KQEMU)
- if (kqemu_allowed)
- kqemu_vfree(ptr);
-#endif
- free(ptr);
-}
-
-#endif
-
-int qemu_create_pidfile(const char *filename)
-{
- char buffer[128];
- int len;
-#ifndef _WIN32
- int fd;
-
- fd = open(filename, O_RDWR | O_CREAT, 0600);
- if (fd == -1)
- return -1;
-
- if (lockf(fd, F_TLOCK, 0) == -1)
- return -1;
-
- len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
- if (write(fd, buffer, len) != len)
- return -1;
-#else
- HANDLE file;
- DWORD flags;
- OVERLAPPED overlap;
- BOOL ret;
-
- /* Open for writing with no sharing. */
- file = CreateFile(filename, GENERIC_WRITE, 0, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (file == INVALID_HANDLE_VALUE)
- return -1;
-
- flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY;
- overlap.hEvent = 0;
- /* Lock 1 byte. */
- ret = LockFileEx(file, flags, 0, 0, 1, &overlap);
- if (ret == 0)
- return -1;
-
- /* Write PID to file. */
- len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
- ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
- &overlap, NULL);
- if (ret == 0)
- return -1;
-#endif
- return 0;
-}
-
-#ifdef _WIN32
-
-/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
-#define _W32_FT_OFFSET (116444736000000000ULL)
-
-int qemu_gettimeofday(qemu_timeval *tp)
-{
- union {
- unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
- FILETIME ft;
- } _now;
-
- if(tp)
- {
- GetSystemTimeAsFileTime (&_now.ft);
- tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
- tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
- }
- /* Always return 0 as per Open Group Base Specifications Issue 6.
- Do not set errno on error. */
- return 0;
-}
-#endif /* _WIN32 */
-
-
diff --git a/osdep.h b/osdep.h
deleted file mode 100644
index 626cea1..0000000
--- a/osdep.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef QEMU_OSDEP_H
-#define QEMU_OSDEP_H
-
-#include <stdarg.h>
-#ifdef __OpenBSD__
-#include <sys/types.h>
-#include <sys/signal.h>
-#endif
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof(((type *) 0)->member) *__mptr = (ptr); \
- (type *) ((char *) __mptr - offsetof(type, member));})
-#endif
-
-#ifndef likely
-#if __GNUC__ < 3
-#define __builtin_expect(x, n) (x)
-#endif
-
-#define likely(x) __builtin_expect(!!(x), 1)
-#define unlikely(x) __builtin_expect(!!(x), 0)
-#endif
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
-#endif
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof(((type *) 0)->member) *__mptr = (ptr); \
- (type *) ((char *) __mptr - offsetof(type, member));})
-#endif
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-
-#ifndef always_inline
-#if (__GNUC__ < 3) || defined(__APPLE__)
-#define always_inline inline
-#else
-#define always_inline __attribute__ (( always_inline )) __inline__
-#define inline always_inline
-#endif
-#else
-#define inline always_inline
-#endif
-
-#ifdef __i386__
-#define REGPARM __attribute((regparm(3)))
-#else
-#define REGPARM
-#endif
-
-#define qemu_printf printf
-
-void *qemu_memalign(size_t alignment, size_t size);
-void *qemu_vmalloc(size_t size);
-void qemu_vfree(void *ptr);
-
-int qemu_create_pidfile(const char *filename);
-
-#ifdef _WIN32
-int ffs(int i);
-
-typedef struct {
- long tv_sec;
- long tv_usec;
-} qemu_timeval;
-int qemu_gettimeofday(qemu_timeval *tp);
-#else
-typedef struct timeval qemu_timeval;
-#define qemu_gettimeofday(tp) gettimeofday(tp, NULL);
-#endif /* !_WIN32 */
-
-#endif
diff --git a/ppc-dis.c b/ppc-dis.c
deleted file mode 100644
index f9ae53e..0000000
--- a/ppc-dis.c
+++ /dev/null
@@ -1,3246 +0,0 @@
-/* ppc-dis.c -- Disassemble PowerPC instructions
- Copyright 1994 Free Software Foundation, Inc.
- Written by Ian Lance Taylor, Cygnus Support
-
-This file is part of GDB, GAS, and the GNU binutils.
-
-GDB, GAS, and the GNU binutils are free software; you can redistribute
-them and/or modify them under the terms of the GNU General Public
-License as published by the Free Software Foundation; either version
-2, or (at your option) any later version.
-
-GDB, GAS, and the GNU binutils are distributed in the hope that they
-will be useful, but WITHOUT ANY WARRANTY; without even the implied
-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
-the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this file; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#include "dis-asm.h"
-
-/* ppc.h -- Header file for PowerPC opcode table
- Copyright 1994 Free Software Foundation, Inc.
- Written by Ian Lance Taylor, Cygnus Support
-
-This file is part of GDB, GAS, and the GNU binutils.
-
-GDB, GAS, and the GNU binutils are free software; you can redistribute
-them and/or modify them under the terms of the GNU General Public
-License as published by the Free Software Foundation; either version
-1, or (at your option) any later version.
-
-GDB, GAS, and the GNU binutils are distributed in the hope that they
-will be useful, but WITHOUT ANY WARRANTY; without even the implied
-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
-the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this file; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* The opcode table is an array of struct powerpc_opcode. */
-
-struct powerpc_opcode
-{
- /* The opcode name. */
- const char *name;
-
- /* The opcode itself. Those bits which will be filled in with
- operands are zeroes. */
- uint32_t opcode;
-
- /* The opcode mask. This is used by the disassembler. This is a
- mask containing ones indicating those bits which must match the
- opcode field, and zeroes indicating those bits which need not
- match (and are presumably filled in by operands). */
- uint32_t mask;
-
- /* One bit flags for the opcode. These are used to indicate which
- specific processors support the instructions. The defined values
- are listed below. */
- uint32_t flags;
-
- /* An array of operand codes. Each code is an index into the
- operand table. They appear in the order which the operands must
- appear in assembly code, and are terminated by a zero. */
- unsigned char operands[8];
-};
-
-/* The table itself is sorted by major opcode number, and is otherwise
- in the order in which the disassembler should consider
- instructions. */
-extern const struct powerpc_opcode powerpc_opcodes[];
-extern const int powerpc_num_opcodes;
-
-/* Values defined for the flags field of a struct powerpc_opcode. */
-
-/* Opcode is defined for the PowerPC architecture. */
-#define PPC_OPCODE_PPC (01)
-
-/* Opcode is defined for the POWER (RS/6000) architecture. */
-#define PPC_OPCODE_POWER (02)
-
-/* Opcode is defined for the POWER2 (Rios 2) architecture. */
-#define PPC_OPCODE_POWER2 (04)
-
-/* Opcode is only defined on 32 bit architectures. */
-#define PPC_OPCODE_32 (010)
-
-/* Opcode is only defined on 64 bit architectures. */
-#define PPC_OPCODE_64 (020)
-
-/* Opcode is supported by the Motorola PowerPC 601 processor. The 601
- is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
- but it also supports many additional POWER instructions. */
-#define PPC_OPCODE_601 (040)
-
-/* A macro to extract the major opcode from an instruction. */
-#define PPC_OP(i) (((i) >> 26) & 0x3f)
-
-/* The operands table is an array of struct powerpc_operand. */
-
-struct powerpc_operand
-{
- /* The number of bits in the operand. */
- int bits;
-
- /* How far the operand is left shifted in the instruction. */
- int shift;
-
- /* Insertion function. This is used by the assembler. To insert an
- operand value into an instruction, check this field.
-
- If it is NULL, execute
- i |= (op & ((1 << o->bits) - 1)) << o->shift;
- (i is the instruction which we are filling in, o is a pointer to
- this structure, and op is the opcode value; this assumes twos
- complement arithmetic).
-
- If this field is not NULL, then simply call it with the
- instruction and the operand value. It will return the new value
- of the instruction. If the ERRMSG argument is not NULL, then if
- the operand value is illegal, *ERRMSG will be set to a warning
- string (the operand will be inserted in any case). If the
- operand value is legal, *ERRMSG will be unchanged (most operands
- can accept any value). */
- unsigned long (*insert)(uint32_t instruction, int32_t op,
- const char **errmsg);
-
- /* Extraction function. This is used by the disassembler. To
- extract this operand type from an instruction, check this field.
-
- If it is NULL, compute
- op = ((i) >> o->shift) & ((1 << o->bits) - 1);
- if ((o->flags & PPC_OPERAND_SIGNED) != 0
- && (op & (1 << (o->bits - 1))) != 0)
- op -= 1 << o->bits;
- (i is the instruction, o is a pointer to this structure, and op
- is the result; this assumes twos complement arithmetic).
-
- If this field is not NULL, then simply call it with the
- instruction value. It will return the value of the operand. If
- the INVALID argument is not NULL, *INVALID will be set to
- non-zero if this operand type can not actually be extracted from
- this operand (i.e., the instruction does not match). If the
- operand is valid, *INVALID will not be changed. */
- long (*extract) (uint32_t instruction, int *invalid);
-
- /* One bit syntax flags. */
- uint32_t flags;
-};
-
-/* Elements in the table are retrieved by indexing with values from
- the operands field of the powerpc_opcodes table. */
-
-extern const struct powerpc_operand powerpc_operands[];
-
-/* Values defined for the flags field of a struct powerpc_operand. */
-
-/* This operand takes signed values. */
-#define PPC_OPERAND_SIGNED (01)
-
-/* This operand takes signed values, but also accepts a full positive
- range of values when running in 32 bit mode. That is, if bits is
- 16, it takes any value from -0x8000 to 0xffff. In 64 bit mode,
- this flag is ignored. */
-#define PPC_OPERAND_SIGNOPT (02)
-
-/* This operand does not actually exist in the assembler input. This
- is used to support extended mnemonics such as mr, for which two
- operands fields are identical. The assembler should call the
- insert function with any op value. The disassembler should call
- the extract function, ignore the return value, and check the value
- placed in the valid argument. */
-#define PPC_OPERAND_FAKE (04)
-
-/* The next operand should be wrapped in parentheses rather than
- separated from this one by a comma. This is used for the load and
- store instructions which want their operands to look like
- reg,displacement(reg)
- */
-#define PPC_OPERAND_PARENS (010)
-
-/* This operand may use the symbolic names for the CR fields, which
- are
- lt 0 gt 1 eq 2 so 3 un 3
- cr0 0 cr1 1 cr2 2 cr3 3
- cr4 4 cr5 5 cr6 6 cr7 7
- These may be combined arithmetically, as in cr2*4+gt. These are
- only supported on the PowerPC, not the POWER. */
-#define PPC_OPERAND_CR (020)
-
-/* This operand names a register. The disassembler uses this to print
- register names with a leading 'r'. */
-#define PPC_OPERAND_GPR (040)
-
-/* This operand names a floating point register. The disassembler
- prints these with a leading 'f'. */
-#define PPC_OPERAND_FPR (0100)
-
-/* This operand is a relative branch displacement. The disassembler
- prints these symbolically if possible. */
-#define PPC_OPERAND_RELATIVE (0200)
-
-/* This operand is an absolute branch address. The disassembler
- prints these symbolically if possible. */
-#define PPC_OPERAND_ABSOLUTE (0400)
-
-/* This operand is optional, and is zero if omitted. This is used for
- the optional BF and L fields in the comparison instructions. The
- assembler must count the number of operands remaining on the line,
- and the number of operands remaining for the opcode, and decide
- whether this operand is present or not. The disassembler should
- print this operand out only if it is not zero. */
-#define PPC_OPERAND_OPTIONAL (01000)
-
-/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
- is omitted, then for the next operand use this operand value plus
- 1, ignoring the next operand field for the opcode. This wretched
- hack is needed because the Power rotate instructions can take
- either 4 or 5 operands. The disassembler should print this operand
- out regardless of the PPC_OPERAND_OPTIONAL field. */
-#define PPC_OPERAND_NEXT (02000)
-
-/* This operand should be regarded as a negative number for the
- purposes of overflow checking (i.e., the normal most negative
- number is disallowed and one more than the normal most positive
- number is allowed). This flag will only be set for a signed
- operand. */
-#define PPC_OPERAND_NEGATIVE (04000)
-
-/* The POWER and PowerPC assemblers use a few macros. We keep them
- with the operands table for simplicity. The macro table is an
- array of struct powerpc_macro. */
-
-struct powerpc_macro
-{
- /* The macro name. */
- const char *name;
-
- /* The number of operands the macro takes. */
- unsigned int operands;
-
- /* One bit flags for the opcode. These are used to indicate which
- specific processors support the instructions. The values are the
- same as those for the struct powerpc_opcode flags field. */
- uint32_t flags;
-
- /* A format string to turn the macro into a normal instruction.
- Each %N in the string is replaced with operand number N (zero
- based). */
- const char *format;
-};
-
-extern const struct powerpc_macro powerpc_macros[];
-extern const int powerpc_num_macros;
-
-/* ppc-opc.c -- PowerPC opcode list
- Copyright 1994 Free Software Foundation, Inc.
- Written by Ian Lance Taylor, Cygnus Support
-
-This file is part of GDB, GAS, and the GNU binutils.
-
-GDB, GAS, and the GNU binutils are free software; you can redistribute
-them and/or modify them under the terms of the GNU General Public
-License as published by the Free Software Foundation; either version
-2, or (at your option) any later version.
-
-GDB, GAS, and the GNU binutils are distributed in the hope that they
-will be useful, but WITHOUT ANY WARRANTY; without even the implied
-warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
-the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this file; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* This file holds the PowerPC opcode table. The opcode table
- includes almost all of the extended instruction mnemonics. This
- permits the disassembler to use them, and simplifies the assembler
- logic, at the cost of increasing the table size. The table is
- strictly constant data, so the compiler should be able to put it in
- the .text section.
-
- This file also holds the operand table. All knowledge about
- inserting operands into instructions and vice-versa is kept in this
- file. */
-
-/* Local insertion and extraction functions. */
-
-static unsigned long insert_bat (uint32_t, int32_t, const char **);
-static long extract_bat(uint32_t, int *);
-static unsigned long insert_bba(uint32_t, int32_t, const char **);
-static long extract_bba(uint32_t, int *);
-static unsigned long insert_bd(uint32_t, int32_t, const char **);
-static long extract_bd(uint32_t, int *);
-static unsigned long insert_bdm(uint32_t, int32_t, const char **);
-static long extract_bdm(uint32_t, int *);
-static unsigned long insert_bdp(uint32_t, int32_t, const char **);
-static long extract_bdp(uint32_t, int *);
-static unsigned long insert_bo(uint32_t, int32_t, const char **);
-static long extract_bo(uint32_t, int *);
-static unsigned long insert_boe(uint32_t, int32_t, const char **);
-static long extract_boe(uint32_t, int *);
-static unsigned long insert_ds(uint32_t, int32_t, const char **);
-static long extract_ds(uint32_t, int *);
-static unsigned long insert_li(uint32_t, int32_t, const char **);
-static long extract_li(uint32_t, int *);
-static unsigned long insert_mbe(uint32_t, int32_t, const char **);
-static long extract_mbe(uint32_t, int *);
-static unsigned long insert_mb6(uint32_t, int32_t, const char **);
-static long extract_mb6(uint32_t, int *);
-static unsigned long insert_nb(uint32_t, int32_t, const char **);
-static long extract_nb(uint32_t, int *);
-static unsigned long insert_nsi(uint32_t, int32_t, const char **);
-static long extract_nsi(uint32_t, int *);
-static unsigned long insert_ral(uint32_t, int32_t, const char **);
-static unsigned long insert_ram(uint32_t, int32_t, const char **);
-static unsigned long insert_ras(uint32_t, int32_t, const char **);
-static unsigned long insert_rbs(uint32_t, int32_t, const char **);
-static long extract_rbs(uint32_t, int *);
-static unsigned long insert_sh6(uint32_t, int32_t, const char **);
-static long extract_sh6(uint32_t, int *);
-static unsigned long insert_spr(uint32_t, int32_t, const char **);
-static long extract_spr(uint32_t, int *);
-static unsigned long insert_tbr(uint32_t, int32_t, const char **);
-static long extract_tbr(uint32_t, int *);
-
-/* The operands table.
-
- The fields are bits, shift, signed, insert, extract, flags. */
-
-const struct powerpc_operand powerpc_operands[] =
-{
- /* The zero index is used to indicate the end of the list of
- operands. */
-#define UNUSED (0)
- { 0, 0, 0, 0, 0 },
-
- /* The BA field in an XL form instruction. */
-#define BA (1)
-#define BA_MASK (0x1f << 16)
- { 5, 16, 0, 0, PPC_OPERAND_CR },
-
- /* The BA field in an XL form instruction when it must be the same
- as the BT field in the same instruction. */
-#define BAT (2)
- { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
-
- /* The BB field in an XL form instruction. */
-#define BB (3)
-#define BB_MASK (0x1f << 11)
- { 5, 11, 0, 0, PPC_OPERAND_CR },
-
- /* The BB field in an XL form instruction when it must be the same
- as the BA field in the same instruction. */
-#define BBA (4)
- { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
-
- /* The BD field in a B form instruction. The lower two bits are
- forced to zero. */
-#define BD (5)
- { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
-
- /* The BD field in a B form instruction when absolute addressing is
- used. */
-#define BDA (6)
- { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
-
- /* The BD field in a B form instruction when the - modifier is used.
- This sets the y bit of the BO field appropriately. */
-#define BDM (7)
- { 16, 0, insert_bdm, extract_bdm,
- PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
-
- /* The BD field in a B form instruction when the - modifier is used
- and absolute address is used. */
-#define BDMA (8)
- { 16, 0, insert_bdm, extract_bdm,
- PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
-
- /* The BD field in a B form instruction when the + modifier is used.
- This sets the y bit of the BO field appropriately. */
-#define BDP (9)
- { 16, 0, insert_bdp, extract_bdp,
- PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
-
- /* The BD field in a B form instruction when the + modifier is used
- and absolute addressing is used. */
-#define BDPA (10)
- { 16, 0, insert_bdp, extract_bdp,
- PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
-
- /* The BF field in an X or XL form instruction. */
-#define BF (11)
- { 3, 23, 0, 0, PPC_OPERAND_CR },
-
- /* An optional BF field. This is used for comparison instructions,
- in which an omitted BF field is taken as zero. */
-#define OBF (12)
- { 3, 23, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
-
- /* The BFA field in an X or XL form instruction. */
-#define BFA (13)
- { 3, 18, 0, 0, PPC_OPERAND_CR },
-
- /* The BI field in a B form or XL form instruction. */
-#define BI (14)
-#define BI_MASK (0x1f << 16)
- { 5, 16, 0, 0, PPC_OPERAND_CR },
-
- /* The BO field in a B form instruction. Certain values are
- illegal. */
-#define BO (15)
-#define BO_MASK (0x1f << 21)
- { 5, 21, insert_bo, extract_bo, 0 },
-
- /* The BO field in a B form instruction when the + or - modifier is
- used. This is like the BO field, but it must be even. */
-#define BOE (16)
- { 5, 21, insert_boe, extract_boe, 0 },
-
- /* The BT field in an X or XL form instruction. */
-#define BT (17)
- { 5, 21, 0, 0, PPC_OPERAND_CR },
-
- /* The condition register number portion of the BI field in a B form
- or XL form instruction. This is used for the extended
- conditional branch mnemonics, which set the lower two bits of the
- BI field. This field is optional. */
-#define CR (18)
- { 3, 18, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
-
- /* The D field in a D form instruction. This is a displacement off
- a register, and implies that the next operand is a register in
- parentheses. */
-#define D (19)
- { 16, 0, 0, 0, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
-
- /* The DS field in a DS form instruction. This is like D, but the
- lower two bits are forced to zero. */
-#define DS (20)
- { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
-
- /* The FL1 field in a POWER SC form instruction. */
-#define FL1 (21)
- { 4, 12, 0, 0, 0 },
-
- /* The FL2 field in a POWER SC form instruction. */
-#define FL2 (22)
- { 3, 2, 0, 0, 0 },
-
- /* The FLM field in an XFL form instruction. */
-#define FLM (23)
- { 8, 17, 0, 0, 0 },
-
- /* The FRA field in an X or A form instruction. */
-#define FRA (24)
-#define FRA_MASK (0x1f << 16)
- { 5, 16, 0, 0, PPC_OPERAND_FPR },
-
- /* The FRB field in an X or A form instruction. */
-#define FRB (25)
-#define FRB_MASK (0x1f << 11)
- { 5, 11, 0, 0, PPC_OPERAND_FPR },
-
- /* The FRC field in an A form instruction. */
-#define FRC (26)
-#define FRC_MASK (0x1f << 6)
- { 5, 6, 0, 0, PPC_OPERAND_FPR },
-
- /* The FRS field in an X form instruction or the FRT field in a D, X
- or A form instruction. */
-#define FRS (27)
-#define FRT (FRS)
- { 5, 21, 0, 0, PPC_OPERAND_FPR },
-
- /* The FXM field in an XFX instruction. */
-#define FXM (28)
-#define FXM_MASK (0xff << 12)
- { 8, 12, 0, 0, 0 },
-
- /* The L field in a D or X form instruction. */
-#define L (29)
- { 1, 21, 0, 0, PPC_OPERAND_OPTIONAL },
-
- /* The LEV field in a POWER SC form instruction. */
-#define LEV (30)
- { 7, 5, 0, 0, 0 },
-
- /* The LI field in an I form instruction. The lower two bits are
- forced to zero. */
-#define LI (31)
- { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
-
- /* The LI field in an I form instruction when used as an absolute
- address. */
-#define LIA (32)
- { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
-
- /* The MB field in an M form instruction. */
-#define MB (33)
-#define MB_MASK (0x1f << 6)
- { 5, 6, 0, 0, 0 },
-
- /* The ME field in an M form instruction. */
-#define ME (34)
-#define ME_MASK (0x1f << 1)
- { 5, 1, 0, 0, 0 },
-
- /* The MB and ME fields in an M form instruction expressed a single
- operand which is a bitmask indicating which bits to select. This
- is a two operand form using PPC_OPERAND_NEXT. See the
- description in opcode/ppc.h for what this means. */
-#define MBE (35)
- { 5, 6, 0, 0, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
- { 32, 0, insert_mbe, extract_mbe, 0 },
-
- /* The MB or ME field in an MD or MDS form instruction. The high
- bit is wrapped to the low end. */
-#define MB6 (37)
-#define ME6 (MB6)
-#define MB6_MASK (0x3f << 5)
- { 6, 5, insert_mb6, extract_mb6, 0 },
-
- /* The NB field in an X form instruction. The value 32 is stored as
- 0. */
-#define NB (38)
- { 6, 11, insert_nb, extract_nb, 0 },
-
- /* The NSI field in a D form instruction. This is the same as the
- SI field, only negated. */
-#define NSI (39)
- { 16, 0, insert_nsi, extract_nsi,
- PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
-
- /* The RA field in an D, DS, X, XO, M, or MDS form instruction. */
-#define RA (40)
-#define RA_MASK (0x1f << 16)
- { 5, 16, 0, 0, PPC_OPERAND_GPR },
-
- /* The RA field in a D or X form instruction which is an updating
- load, which means that the RA field may not be zero and may not
- equal the RT field. */
-#define RAL (41)
- { 5, 16, insert_ral, 0, PPC_OPERAND_GPR },
-
- /* The RA field in an lmw instruction, which has special value
- restrictions. */
-#define RAM (42)
- { 5, 16, insert_ram, 0, PPC_OPERAND_GPR },
-
- /* The RA field in a D or X form instruction which is an updating
- store or an updating floating point load, which means that the RA
- field may not be zero. */
-#define RAS (43)
- { 5, 16, insert_ras, 0, PPC_OPERAND_GPR },
-
- /* The RB field in an X, XO, M, or MDS form instruction. */
-#define RB (44)
-#define RB_MASK (0x1f << 11)
- { 5, 11, 0, 0, PPC_OPERAND_GPR },
-
- /* The RB field in an X form instruction when it must be the same as
- the RS field in the instruction. This is used for extended
- mnemonics like mr. */
-#define RBS (45)
- { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
-
- /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
- instruction or the RT field in a D, DS, X, XFX or XO form
- instruction. */
-#define RS (46)
-#define RT (RS)
-#define RT_MASK (0x1f << 21)
- { 5, 21, 0, 0, PPC_OPERAND_GPR },
-
- /* The SH field in an X or M form instruction. */
-#define SH (47)
-#define SH_MASK (0x1f << 11)
- { 5, 11, 0, 0, 0 },
-
- /* The SH field in an MD form instruction. This is split. */
-#define SH6 (48)
-#define SH6_MASK ((0x1f << 11) | (1 << 1))
- { 6, 1, insert_sh6, extract_sh6, 0 },
-
- /* The SI field in a D form instruction. */
-#define SI (49)
- { 16, 0, 0, 0, PPC_OPERAND_SIGNED },
-
- /* The SI field in a D form instruction when we accept a wide range
- of positive values. */
-#define SISIGNOPT (50)
- { 16, 0, 0, 0, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
-
- /* The SPR field in an XFX form instruction. This is flipped--the
- lower 5 bits are stored in the upper 5 and vice- versa. */
-#define SPR (51)
-#define SPR_MASK (0x3ff << 11)
- { 10, 11, insert_spr, extract_spr, 0 },
-
- /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */
-#define SPRBAT (52)
-#define SPRBAT_MASK (0x3 << 17)
- { 2, 17, 0, 0, 0 },
-
- /* The SPRG register number in an XFX form m[ft]sprg instruction. */
-#define SPRG (53)
-#define SPRG_MASK (0x3 << 16)
- { 2, 16, 0, 0, 0 },
-
- /* The SR field in an X form instruction. */
-#define SR (54)
- { 4, 16, 0, 0, 0 },
-
- /* The SV field in a POWER SC form instruction. */
-#define SV (55)
- { 14, 2, 0, 0, 0 },
-
- /* The TBR field in an XFX form instruction. This is like the SPR
- field, but it is optional. */
-#define TBR (56)
- { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
-
- /* The TO field in a D or X form instruction. */
-#define TO (57)
-#define TO_MASK (0x1f << 21)
- { 5, 21, 0, 0, 0 },
-
- /* The U field in an X form instruction. */
-#define U (58)
- { 4, 12, 0, 0, 0 },
-
- /* The UI field in a D form instruction. */
-#define UI (59)
- { 16, 0, 0, 0, 0 },
-};
-
-/* The functions used to insert and extract complicated operands. */
-
-/* The BA field in an XL form instruction when it must be the same as
- the BT field in the same instruction. This operand is marked FAKE.
- The insertion function just copies the BT field into the BA field,
- and the extraction function just checks that the fields are the
- same. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_bat (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | (((insn >> 21) & 0x1f) << 16);
-}
-
-static long
-extract_bat (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if (invalid != (int *) NULL
- && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
- *invalid = 1;
- return 0;
-}
-
-/* The BB field in an XL form instruction when it must be the same as
- the BA field in the same instruction. This operand is marked FAKE.
- The insertion function just copies the BA field into the BB field,
- and the extraction function just checks that the fields are the
- same. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_bba (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | (((insn >> 16) & 0x1f) << 11);
-}
-
-static long
-extract_bba (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if (invalid != (int *) NULL
- && ((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
- *invalid = 1;
- return 0;
-}
-
-/* The BD field in a B form instruction. The lower two bits are
- forced to zero. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_bd (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | (value & 0xfffc);
-}
-
-/*ARGSUSED*/
-static long
-extract_bd (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if ((insn & 0x8000) != 0)
- return (insn & 0xfffc) - 0x10000;
- else
- return insn & 0xfffc;
-}
-
-/* The BD field in a B form instruction when the - modifier is used.
- This modifier means that the branch is not expected to be taken.
- We must set the y bit of the BO field to 1 if the offset is
- negative. When extracting, we require that the y bit be 1 and that
- the offset be positive, since if the y bit is 0 we just want to
- print the normal form of the instruction. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_bdm (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if ((value & 0x8000) != 0)
- insn |= 1 << 21;
- return insn | (value & 0xfffc);
-}
-
-static long
-extract_bdm (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if (invalid != (int *) NULL
- && ((insn & (1 << 21)) == 0
- || (insn & (1 << 15)) == 0))
- *invalid = 1;
- if ((insn & 0x8000) != 0)
- return (insn & 0xfffc) - 0x10000;
- else
- return insn & 0xfffc;
-}
-
-/* The BD field in a B form instruction when the + modifier is used.
- This is like BDM, above, except that the branch is expected to be
- taken. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_bdp (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if ((value & 0x8000) == 0)
- insn |= 1 << 21;
- return insn | (value & 0xfffc);
-}
-
-static long
-extract_bdp (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if (invalid != (int *) NULL
- && ((insn & (1 << 21)) == 0
- || (insn & (1 << 15)) != 0))
- *invalid = 1;
- if ((insn & 0x8000) != 0)
- return (insn & 0xfffc) - 0x10000;
- else
- return insn & 0xfffc;
-}
-
-/* Check for legal values of a BO field. */
-
-static int
-valid_bo (int32_t value)
-{
- /* Certain encodings have bits that are required to be zero. These
- are (z must be zero, y may be anything):
- 001zy
- 011zy
- 1z00y
- 1z01y
- 1z1zz
- */
- switch (value & 0x14)
- {
- default:
- case 0:
- return 1;
- case 0x4:
- return (value & 0x2) == 0;
- case 0x10:
- return (value & 0x8) == 0;
- case 0x14:
- return value == 0x14;
- }
-}
-
-/* The BO field in a B form instruction. Warn about attempts to set
- the field to an illegal value. */
-
-static unsigned long
-insert_bo (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (errmsg != (const char **) NULL
- && ! valid_bo (value))
- *errmsg = "invalid conditional option";
- return insn | ((value & 0x1f) << 21);
-}
-
-static long
-extract_bo (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- int32_t value;
-
- value = (insn >> 21) & 0x1f;
- if (invalid != (int *) NULL
- && ! valid_bo (value))
- *invalid = 1;
- return value;
-}
-
-/* The BO field in a B form instruction when the + or - modifier is
- used. This is like the BO field, but it must be even. When
- extracting it, we force it to be even. */
-
-static unsigned long
-insert_boe (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (errmsg != (const char **) NULL)
- {
- if (! valid_bo (value))
- *errmsg = "invalid conditional option";
- else if ((value & 1) != 0)
- *errmsg = "attempt to set y bit when using + or - modifier";
- }
- return insn | ((value & 0x1f) << 21);
-}
-
-static long
-extract_boe (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- int32_t value;
-
- value = (insn >> 21) & 0x1f;
- if (invalid != (int *) NULL
- && ! valid_bo (value))
- *invalid = 1;
- return value & 0x1e;
-}
-
-/* The DS field in a DS form instruction. This is like D, but the
- lower two bits are forced to zero. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_ds (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | (value & 0xfffc);
-}
-
-/*ARGSUSED*/
-static long
-extract_ds (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if ((insn & 0x8000) != 0)
- return (insn & 0xfffc) - 0x10000;
- else
- return insn & 0xfffc;
-}
-
-/* The LI field in an I form instruction. The lower two bits are
- forced to zero. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_li (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | (value & 0x3fffffc);
-}
-
-/*ARGSUSED*/
-static long
-extract_li (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if ((insn & 0x2000000) != 0)
- return (insn & 0x3fffffc) - 0x4000000;
- else
- return insn & 0x3fffffc;
-}
-
-/* The MB and ME fields in an M form instruction expressed as a single
- operand which is itself a bitmask. The extraction function always
- marks it as invalid, since we never want to recognize an
- instruction which uses a field of this type. */
-
-static unsigned long
-insert_mbe (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- uint32_t uval;
- int mb, me;
-
- uval = value;
-
- if (uval == 0)
- {
- if (errmsg != (const char **) NULL)
- *errmsg = "illegal bitmask";
- return insn;
- }
-
- me = 31;
- while ((uval & 1) == 0)
- {
- uval >>= 1;
- --me;
- }
-
- mb = me;
- uval >>= 1;
- while ((uval & 1) != 0)
- {
- uval >>= 1;
- --mb;
- }
-
- if (uval != 0)
- {
- if (errmsg != (const char **) NULL)
- *errmsg = "illegal bitmask";
- }
-
- return insn | (mb << 6) | (me << 1);
-}
-
-static long
-extract_mbe (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- long ret;
- int mb, me;
- int i;
-
- if (invalid != (int *) NULL)
- *invalid = 1;
-
- ret = 0;
- mb = (insn >> 6) & 0x1f;
- me = (insn >> 1) & 0x1f;
- for (i = mb; i < me; i++)
- ret |= 1 << (31 - i);
- return ret;
-}
-
-/* The MB or ME field in an MD or MDS form instruction. The high bit
- is wrapped to the low end. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_mb6 (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | ((value & 0x1f) << 6) | (value & 0x20);
-}
-
-/*ARGSUSED*/
-static long
-extract_mb6 (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- return ((insn >> 6) & 0x1f) | (insn & 0x20);
-}
-
-/* The NB field in an X form instruction. The value 32 is stored as
- 0. */
-
-static unsigned long
-insert_nb (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (value < 0 || value > 32)
- *errmsg = "value out of range";
- if (value == 32)
- value = 0;
- return insn | ((value & 0x1f) << 11);
-}
-
-/*ARGSUSED*/
-static long
-extract_nb (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- long ret;
-
- ret = (insn >> 11) & 0x1f;
- if (ret == 0)
- ret = 32;
- return ret;
-}
-
-/* The NSI field in a D form instruction. This is the same as the SI
- field, only negated. The extraction function always marks it as
- invalid, since we never want to recognize an instruction which uses
- a field of this type. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_nsi (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | ((- value) & 0xffff);
-}
-
-static long
-extract_nsi (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if (invalid != (int *) NULL)
- *invalid = 1;
- if ((insn & 0x8000) != 0)
- return - ((insn & 0xffff) - 0x10000);
- else
- return - (insn & 0xffff);
-}
-
-/* The RA field in a D or X form instruction which is an updating
- load, which means that the RA field may not be zero and may not
- equal the RT field. */
-
-static unsigned long
-insert_ral (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (value == 0
- || value == ((insn >> 21) & 0x1f))
- *errmsg = "invalid register operand when updating";
- return insn | ((value & 0x1f) << 16);
-}
-
-/* The RA field in an lmw instruction, which has special value
- restrictions. */
-
-static unsigned long
-insert_ram (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (value >= ((insn >> 21) & 0x1f))
- *errmsg = "index register in load range";
- return insn | ((value & 0x1f) << 16);
-}
-
-/* The RA field in a D or X form instruction which is an updating
- store or an updating floating point load, which means that the RA
- field may not be zero. */
-
-static unsigned long
-insert_ras (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (value == 0)
- *errmsg = "invalid register operand when updating";
- return insn | ((value & 0x1f) << 16);
-}
-
-/* The RB field in an X form instruction when it must be the same as
- the RS field in the instruction. This is used for extended
- mnemonics like mr. This operand is marked FAKE. The insertion
- function just copies the BT field into the BA field, and the
- extraction function just checks that the fields are the same. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_rbs (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | (((insn >> 21) & 0x1f) << 11);
-}
-
-static long
-extract_rbs (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- if (invalid != (int *) NULL
- && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
- *invalid = 1;
- return 0;
-}
-
-/* The SH field in an MD form instruction. This is split. */
-
-/*ARGSUSED*/
-static unsigned long
-insert_sh6 (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
-}
-
-/*ARGSUSED*/
-static long
-extract_sh6 (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
-}
-
-/* The SPR field in an XFX form instruction. This is flipped--the
- lower 5 bits are stored in the upper 5 and vice- versa. */
-
-static unsigned long
-insert_spr (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
-}
-
-static long
-extract_spr (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
-}
-
-/* The TBR field in an XFX instruction. This is just like SPR, but it
- is optional. When TBR is omitted, it must be inserted as 268 (the
- magic number of the TB register). These functions treat 0
- (indicating an omitted optional operand) as 268. This means that
- ``mftb 4,0'' is not handled correctly. This does not matter very
- much, since the architecture manual does not define mftb as
- accepting any values other than 268 or 269. */
-
-#define TB (268)
-
-static unsigned long
-insert_tbr (insn, value, errmsg)
- uint32_t insn;
- int32_t value;
- const char **errmsg;
-{
- if (value == 0)
- value = TB;
- return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
-}
-
-static long
-extract_tbr (insn, invalid)
- uint32_t insn;
- int *invalid;
-{
- long ret;
-
- ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
- if (ret == TB)
- ret = 0;
- return ret;
-}
-
-/* Macros used to form opcodes. */
-
-/* The main opcode. */
-#define OP(x) (((x) & 0x3f) << 26)
-#define OP_MASK OP (0x3f)
-
-/* The main opcode combined with a trap code in the TO field of a D
- form instruction. Used for extended mnemonics for the trap
- instructions. */
-#define OPTO(x,to) (OP (x) | (((to) & 0x1f) << 21))
-#define OPTO_MASK (OP_MASK | TO_MASK)
-
-/* The main opcode combined with a comparison size bit in the L field
- of a D form or X form instruction. Used for extended mnemonics for
- the comparison instructions. */
-#define OPL(x,l) (OP (x) | (((l) & 1) << 21))
-#define OPL_MASK OPL (0x3f,1)
-
-/* An A form instruction. */
-#define A(op, xop, rc) (OP (op) | (((xop) & 0x1f) << 1) | ((rc) & 1))
-#define A_MASK A (0x3f, 0x1f, 1)
-
-/* An A_MASK with the FRB field fixed. */
-#define AFRB_MASK (A_MASK | FRB_MASK)
-
-/* An A_MASK with the FRC field fixed. */
-#define AFRC_MASK (A_MASK | FRC_MASK)
-
-/* An A_MASK with the FRA and FRC fields fixed. */
-#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
-
-/* A B form instruction. */
-#define B(op, aa, lk) (OP (op) | (((aa) & 1) << 1) | ((lk) & 1))
-#define B_MASK B (0x3f, 1, 1)
-
-/* A B form instruction setting the BO field. */
-#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | (((bo) & 0x1f) << 21))
-#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
-
-/* A BBO_MASK with the y bit of the BO field removed. This permits
- matching a conditional branch regardless of the setting of the y
- bit. */
-#define Y_MASK (1 << 21)
-#define BBOY_MASK (BBO_MASK &~ Y_MASK)
-
-/* A B form instruction setting the BO field and the condition bits of
- the BI field. */
-#define BBOCB(op, bo, cb, aa, lk) \
- (BBO ((op), (bo), (aa), (lk)) | (((cb) & 0x3) << 16))
-#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
-
-/* A BBOCB_MASK with the y bit of the BO field removed. */
-#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
-
-/* A BBOYCB_MASK in which the BI field is fixed. */
-#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
-
-/* The main opcode mask with the RA field clear. */
-#define DRA_MASK (OP_MASK | RA_MASK)
-
-/* A DS form instruction. */
-#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
-#define DS_MASK DSO (0x3f, 3)
-
-/* An M form instruction. */
-#define M(op, rc) (OP (op) | ((rc) & 1))
-#define M_MASK M (0x3f, 1)
-
-/* An M form instruction with the ME field specified. */
-#define MME(op, me, rc) (M ((op), (rc)) | (((me) & 0x1f) << 1))
-
-/* An M_MASK with the MB and ME fields fixed. */
-#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
-
-/* An M_MASK with the SH and ME fields fixed. */
-#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
-
-/* An MD form instruction. */
-#define MD(op, xop, rc) (OP (op) | (((xop) & 0x7) << 2) | ((rc) & 1))
-#define MD_MASK MD (0x3f, 0x7, 1)
-
-/* An MD_MASK with the MB field fixed. */
-#define MDMB_MASK (MD_MASK | MB6_MASK)
-
-/* An MD_MASK with the SH field fixed. */
-#define MDSH_MASK (MD_MASK | SH6_MASK)
-
-/* An MDS form instruction. */
-#define MDS(op, xop, rc) (OP (op) | (((xop) & 0xf) << 1) | ((rc) & 1))
-#define MDS_MASK MDS (0x3f, 0xf, 1)
-
-/* An MDS_MASK with the MB field fixed. */
-#define MDSMB_MASK (MDS_MASK | MB6_MASK)
-
-/* An SC form instruction. */
-#define SC(op, sa, lk) (OP (op) | (((sa) & 1) << 1) | ((lk) & 1))
-#define SC_MASK (OP_MASK | (0x3ff << 16) | (1 << 1) | 1)
-
-/* An X form instruction. */
-#define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
-
-/* An X form instruction with the RC bit specified. */
-#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
-
-/* The mask for an X form instruction. */
-#define X_MASK XRC (0x3f, 0x3ff, 1)
-
-/* An X_MASK with the RA field fixed. */
-#define XRA_MASK (X_MASK | RA_MASK)
-
-/* An X_MASK with the RB field fixed. */
-#define XRB_MASK (X_MASK | RB_MASK)
-
-/* An X_MASK with the RT field fixed. */
-#define XRT_MASK (X_MASK | RT_MASK)
-
-/* An X_MASK with the RA and RB fields fixed. */
-#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
-
-/* An X_MASK with the RT and RA fields fixed. */
-#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
-
-/* An X form comparison instruction. */
-#define XCMPL(op, xop, l) (X ((op), (xop)) | (((l) & 1) << 21))
-
-/* The mask for an X form comparison instruction. */
-#define XCMP_MASK (X_MASK | (1 << 22))
-
-/* The mask for an X form comparison instruction with the L field
- fixed. */
-#define XCMPL_MASK (XCMP_MASK | (1 << 21))
-
-/* An X form trap instruction with the TO field specified. */
-#define XTO(op, xop, to) (X ((op), (xop)) | (((to) & 0x1f) << 21))
-#define XTO_MASK (X_MASK | TO_MASK)
-
-/* An XFL form instruction. */
-#define XFL(op, xop, rc) (OP (op) | (((xop) & 0x3ff) << 1) | ((rc) & 1))
-#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (1 << 25) | (1 << 16))
-
-/* An XL form instruction with the LK field set to 0. */
-#define XL(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
-
-/* An XL form instruction which uses the LK field. */
-#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
-
-/* The mask for an XL form instruction. */
-#define XL_MASK XLLK (0x3f, 0x3ff, 1)
-
-/* An XL form instruction which explicitly sets the BO field. */
-#define XLO(op, bo, xop, lk) \
- (XLLK ((op), (xop), (lk)) | (((bo) & 0x1f) << 21))
-#define XLO_MASK (XL_MASK | BO_MASK)
-
-/* An XL form instruction which explicitly sets the y bit of the BO
- field. */
-#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | (((y) & 1) << 21))
-#define XLYLK_MASK (XL_MASK | Y_MASK)
-
-/* An XL form instruction which sets the BO field and the condition
- bits of the BI field. */
-#define XLOCB(op, bo, cb, xop, lk) \
- (XLO ((op), (bo), (xop), (lk)) | (((cb) & 3) << 16))
-#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
-
-/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */
-#define XLBB_MASK (XL_MASK | BB_MASK)
-#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
-#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
-
-/* An XL_MASK with the BO and BB fields fixed. */
-#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
-
-/* An XL_MASK with the BO, BI and BB fields fixed. */
-#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
-
-/* An XO form instruction. */
-#define XO(op, xop, oe, rc) \
- (OP (op) | (((xop) & 0x1ff) << 1) | (((oe) & 1) << 10) | ((rc) & 1))
-#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
-
-/* An XO_MASK with the RB field fixed. */
-#define XORB_MASK (XO_MASK | RB_MASK)
-
-/* An XS form instruction. */
-#define XS(op, xop, rc) (OP (op) | (((xop) & 0x1ff) << 2) | ((rc) & 1))
-#define XS_MASK XS (0x3f, 0x1ff, 1)
-
-/* A mask for the FXM version of an XFX form instruction. */
-#define XFXFXM_MASK (X_MASK | (1 << 20) | (1 << 11))
-
-/* An XFX form instruction with the FXM field filled in. */
-#define XFXM(op, xop, fxm) \
- (X ((op), (xop)) | (((fxm) & 0xff) << 12))
-
-/* An XFX form instruction with the SPR field filled in. */
-#define XSPR(op, xop, spr) \
- (X ((op), (xop)) | (((spr) & 0x1f) << 16) | (((spr) & 0x3e0) << 6))
-#define XSPR_MASK (X_MASK | SPR_MASK)
-
-/* An XFX form instruction with the SPR field filled in except for the
- SPRBAT field. */
-#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
-
-/* An XFX form instruction with the SPR field filled in except for the
- SPRG field. */
-#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
-
-/* The BO encodings used in extended conditional branch mnemonics. */
-#define BODNZF (0x0)
-#define BODNZFP (0x1)
-#define BODZF (0x2)
-#define BODZFP (0x3)
-#define BOF (0x4)
-#define BOFP (0x5)
-#define BODNZT (0x8)
-#define BODNZTP (0x9)
-#define BODZT (0xa)
-#define BODZTP (0xb)
-#define BOT (0xc)
-#define BOTP (0xd)
-#define BODNZ (0x10)
-#define BODNZP (0x11)
-#define BODZ (0x12)
-#define BODZP (0x13)
-#define BOU (0x14)
-
-/* The BI condition bit encodings used in extended conditional branch
- mnemonics. */
-#define CBLT (0)
-#define CBGT (1)
-#define CBEQ (2)
-#define CBSO (3)
-
-/* The TO encodings used in extended trap mnemonics. */
-#define TOLGT (0x1)
-#define TOLLT (0x2)
-#define TOEQ (0x4)
-#define TOLGE (0x5)
-#define TOLNL (0x5)
-#define TOLLE (0x6)
-#define TOLNG (0x6)
-#define TOGT (0x8)
-#define TOGE (0xc)
-#define TONL (0xc)
-#define TOLT (0x10)
-#define TOLE (0x14)
-#define TONG (0x14)
-#define TONE (0x18)
-#define TOU (0x1f)
-
-/* Smaller names for the flags so each entry in the opcodes table will
- fit on a single line. */
-#undef PPC
-#define PPC PPC_OPCODE_PPC
-#define POWER PPC_OPCODE_POWER
-#define POWER2 PPC_OPCODE_POWER2
-#define B32 PPC_OPCODE_32
-#define B64 PPC_OPCODE_64
-#define M601 PPC_OPCODE_601
-
-/* The opcode table.
-
- The format of the opcode table is:
-
- NAME OPCODE MASK FLAGS { OPERANDS }
-
- NAME is the name of the instruction.
- OPCODE is the instruction opcode.
- MASK is the opcode mask; this is used to tell the disassembler
- which bits in the actual opcode must match OPCODE.
- FLAGS are flags indicated what processors support the instruction.
- OPERANDS is the list of operands.
-
- The disassembler reads the table in order and prints the first
- instruction which matches, so this table is sorted to put more
- specific instructions before more general instructions. It is also
- sorted by major opcode. */
-
-const struct powerpc_opcode powerpc_opcodes[] = {
-{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdlgei", OPTO(2,TOLGE), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdlnli", OPTO(2,TOLNL), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdllei", OPTO(2,TOLLE), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdlngi", OPTO(2,TOLNG), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdgti", OPTO(2,TOGT), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdgei", OPTO(2,TOGE), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdnli", OPTO(2,TONL), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdlti", OPTO(2,TOLT), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdlei", OPTO(2,TOLE), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdngi", OPTO(2,TONG), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdnei", OPTO(2,TONE), OPTO_MASK, PPC|B64, { RA, SI } },
-{ "tdi", OP(2), OP_MASK, PPC|B64, { TO, RA, SI } },
-
-{ "twlgti", OPTO(3,TOLGT), OPTO_MASK, PPC, { RA, SI } },
-{ "tlgti", OPTO(3,TOLGT), OPTO_MASK, POWER, { RA, SI } },
-{ "twllti", OPTO(3,TOLLT), OPTO_MASK, PPC, { RA, SI } },
-{ "tllti", OPTO(3,TOLLT), OPTO_MASK, POWER, { RA, SI } },
-{ "tweqi", OPTO(3,TOEQ), OPTO_MASK, PPC, { RA, SI } },
-{ "teqi", OPTO(3,TOEQ), OPTO_MASK, POWER, { RA, SI } },
-{ "twlgei", OPTO(3,TOLGE), OPTO_MASK, PPC, { RA, SI } },
-{ "tlgei", OPTO(3,TOLGE), OPTO_MASK, POWER, { RA, SI } },
-{ "twlnli", OPTO(3,TOLNL), OPTO_MASK, PPC, { RA, SI } },
-{ "tlnli", OPTO(3,TOLNL), OPTO_MASK, POWER, { RA, SI } },
-{ "twllei", OPTO(3,TOLLE), OPTO_MASK, PPC, { RA, SI } },
-{ "tllei", OPTO(3,TOLLE), OPTO_MASK, POWER, { RA, SI } },
-{ "twlngi", OPTO(3,TOLNG), OPTO_MASK, PPC, { RA, SI } },
-{ "tlngi", OPTO(3,TOLNG), OPTO_MASK, POWER, { RA, SI } },
-{ "twgti", OPTO(3,TOGT), OPTO_MASK, PPC, { RA, SI } },
-{ "tgti", OPTO(3,TOGT), OPTO_MASK, POWER, { RA, SI } },
-{ "twgei", OPTO(3,TOGE), OPTO_MASK, PPC, { RA, SI } },
-{ "tgei", OPTO(3,TOGE), OPTO_MASK, POWER, { RA, SI } },
-{ "twnli", OPTO(3,TONL), OPTO_MASK, PPC, { RA, SI } },
-{ "tnli", OPTO(3,TONL), OPTO_MASK, POWER, { RA, SI } },
-{ "twlti", OPTO(3,TOLT), OPTO_MASK, PPC, { RA, SI } },
-{ "tlti", OPTO(3,TOLT), OPTO_MASK, POWER, { RA, SI } },
-{ "twlei", OPTO(3,TOLE), OPTO_MASK, PPC, { RA, SI } },
-{ "tlei", OPTO(3,TOLE), OPTO_MASK, POWER, { RA, SI } },
-{ "twngi", OPTO(3,TONG), OPTO_MASK, PPC, { RA, SI } },
-{ "tngi", OPTO(3,TONG), OPTO_MASK, POWER, { RA, SI } },
-{ "twnei", OPTO(3,TONE), OPTO_MASK, PPC, { RA, SI } },
-{ "tnei", OPTO(3,TONE), OPTO_MASK, POWER, { RA, SI } },
-{ "twi", OP(3), OP_MASK, PPC, { TO, RA, SI } },
-{ "ti", OP(3), OP_MASK, POWER, { TO, RA, SI } },
-
-{ "mulli", OP(7), OP_MASK, PPC, { RT, RA, SI } },
-{ "muli", OP(7), OP_MASK, POWER, { RT, RA, SI } },
-
-{ "subfic", OP(8), OP_MASK, PPC, { RT, RA, SI } },
-{ "sfi", OP(8), OP_MASK, POWER, { RT, RA, SI } },
-
-{ "dozi", OP(9), OP_MASK, POWER|M601, { RT, RA, SI } },
-
-{ "cmplwi", OPL(10,0), OPL_MASK, PPC, { OBF, RA, UI } },
-{ "cmpldi", OPL(10,1), OPL_MASK, PPC|B64, { OBF, RA, UI } },
-{ "cmpli", OP(10), OP_MASK, PPC, { BF, L, RA, UI } },
-{ "cmpli", OP(10), OP_MASK, POWER, { BF, RA, UI } },
-
-{ "cmpwi", OPL(11,0), OPL_MASK, PPC, { OBF, RA, SI } },
-{ "cmpdi", OPL(11,1), OPL_MASK, PPC|B64, { OBF, RA, SI } },
-{ "cmpi", OP(11), OP_MASK, PPC, { BF, L, RA, SI } },
-{ "cmpi", OP(11), OP_MASK, POWER, { BF, RA, SI } },
-
-{ "addic", OP(12), OP_MASK, PPC, { RT, RA, SI } },
-{ "ai", OP(12), OP_MASK, POWER, { RT, RA, SI } },
-{ "subic", OP(12), OP_MASK, PPC, { RT, RA, NSI } },
-
-{ "addic.", OP(13), OP_MASK, PPC, { RT, RA, SI } },
-{ "ai.", OP(13), OP_MASK, POWER, { RT, RA, SI } },
-{ "subic.", OP(13), OP_MASK, PPC, { RT, RA, NSI } },
-
-{ "li", OP(14), DRA_MASK, PPC, { RT, SI } },
-{ "lil", OP(14), DRA_MASK, POWER, { RT, SI } },
-{ "addi", OP(14), OP_MASK, PPC, { RT, RA, SI } },
-{ "cal", OP(14), OP_MASK, POWER, { RT, D, RA } },
-{ "subi", OP(14), OP_MASK, PPC, { RT, RA, NSI } },
-{ "la", OP(14), OP_MASK, PPC, { RT, D, RA } },
-
-{ "lis", OP(15), DRA_MASK, PPC, { RT, SISIGNOPT } },
-{ "liu", OP(15), DRA_MASK, POWER, { RT, SISIGNOPT } },
-{ "addis", OP(15), OP_MASK, PPC, { RT,RA,SISIGNOPT } },
-{ "cau", OP(15), OP_MASK, POWER, { RT,RA,SISIGNOPT } },
-{ "subis", OP(15), OP_MASK, PPC, { RT, RA, NSI } },
-
-{ "bdnz-", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDM } },
-{ "bdnz+", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDP } },
-{ "bdnz", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BD } },
-{ "bdn", BBO(16,BODNZ,0,0), BBOYBI_MASK, POWER, { BD } },
-{ "bdnzl-", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDM } },
-{ "bdnzl+", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDP } },
-{ "bdnzl", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BD } },
-{ "bdnl", BBO(16,BODNZ,0,1), BBOYBI_MASK, POWER, { BD } },
-{ "bdnza-", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
-{ "bdnza+", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
-{ "bdnza", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDA } },
-{ "bdna", BBO(16,BODNZ,1,0), BBOYBI_MASK, POWER, { BDA } },
-{ "bdnzla-", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
-{ "bdnzla+", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
-{ "bdnzla", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDA } },
-{ "bdnla", BBO(16,BODNZ,1,1), BBOYBI_MASK, POWER, { BDA } },
-{ "bdz-", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDM } },
-{ "bdz+", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDP } },
-{ "bdz", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC|POWER, { BD } },
-{ "bdzl-", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDM } },
-{ "bdzl+", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDP } },
-{ "bdzl", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC|POWER, { BD } },
-{ "bdza-", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
-{ "bdza+", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
-{ "bdza", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC|POWER, { BDA } },
-{ "bdzla-", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
-{ "bdzla+", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
-{ "bdzla", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC|POWER, { BDA } },
-{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "blt+", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "blt", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bltl-", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bltl+", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bltl", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "blta-", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "blta+", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "blta", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bltla-", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bltla+", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bltla", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bgt-", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bgt+", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bgt", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bgtl-", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bgtl+", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bgtl", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bgta-", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bgta+", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bgta", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bgtla-", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bgtla+", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bgtla", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "beq-", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "beq+", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "beq", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "beql-", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "beql+", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "beql", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "beqa-", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "beqa+", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "beqa", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "beqla-", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "beqla+", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "beqla", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bso-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bso+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bso", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bsol-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bsol+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bsol", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bsoa-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bsoa+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bsoa", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bsola-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bsola+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bsola", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bun-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bun+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bun", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BD } },
-{ "bunl-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bunl+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bunl", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BD } },
-{ "buna-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "buna+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "buna", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDA } },
-{ "bunla-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bunla+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bunla", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDA } },
-{ "bge-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bge+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bge", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bgel-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bgel+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bgel", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bgea-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bgea+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bgea", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bgela-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bgela+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bgela", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bnl-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bnl+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bnl", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnll-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bnll+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bnll", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnla-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnla+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnla", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bnlla-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnlla+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnlla", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "ble-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "ble+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "ble", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "blel-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "blel+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "blel", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "blea-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "blea+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "blea", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "blela-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "blela+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "blela", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bng-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bng+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bng", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bngl-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bngl+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bngl", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnga-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnga+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnga", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bngla-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bngla+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bngla", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bne-", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bne+", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bne", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnel-", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bnel+", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bnel", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnea-", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnea+", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnea", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bnela-", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnela+", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnela", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bns-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bns+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bns", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnsl-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bnsl+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bnsl", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
-{ "bnsa-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnsa+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnsa", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bnsla-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnsla+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnsla", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
-{ "bnu-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bnu+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bnu", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BD } },
-{ "bnul-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
-{ "bnul+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
-{ "bnul", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BD } },
-{ "bnua-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnua+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnua", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDA } },
-{ "bnula-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
-{ "bnula+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
-{ "bnula", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDA } },
-{ "bdnzt-", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdnzt+", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdnzt", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BD } },
-{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdnztl", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BD } },
-{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdnzta", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDA } },
-{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDA } },
-{ "bdnzf-", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdnzf+", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdnzf", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BD } },
-{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdnzfl", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BD } },
-{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdnzfa", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDA } },
-{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDA } },
-{ "bt-", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDM } },
-{ "bt+", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDP } },
-{ "bt", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BD } },
-{ "bbt", BBO(16,BOT,0,0), BBOY_MASK, POWER, { BI, BD } },
-{ "btl-", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDM } },
-{ "btl+", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDP } },
-{ "btl", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BD } },
-{ "bbtl", BBO(16,BOT,0,1), BBOY_MASK, POWER, { BI, BD } },
-{ "bta-", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bta+", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bta", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDA } },
-{ "bbta", BBO(16,BOT,1,0), BBOY_MASK, POWER, { BI, BDA } },
-{ "btla-", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
-{ "btla+", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
-{ "btla", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDA } },
-{ "bbtla", BBO(16,BOT,1,1), BBOY_MASK, POWER, { BI, BDA } },
-{ "bf-", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDM } },
-{ "bf+", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDP } },
-{ "bf", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BD } },
-{ "bbf", BBO(16,BOF,0,0), BBOY_MASK, POWER, { BI, BD } },
-{ "bfl-", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDM } },
-{ "bfl+", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDP } },
-{ "bfl", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BD } },
-{ "bbfl", BBO(16,BOF,0,1), BBOY_MASK, POWER, { BI, BD } },
-{ "bfa-", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bfa+", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bfa", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDA } },
-{ "bbfa", BBO(16,BOF,1,0), BBOY_MASK, POWER, { BI, BDA } },
-{ "bfla-", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bfla+", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bfla", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDA } },
-{ "bbfla", BBO(16,BOF,1,1), BBOY_MASK, POWER, { BI, BDA } },
-{ "bdzt-", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdzt+", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdzt", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BD } },
-{ "bdztl-", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdztl+", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdztl", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BD } },
-{ "bdzta-", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdzta+", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdzta", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDA } },
-{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdztla", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDA } },
-{ "bdzf-", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdzf+", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdzf", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BD } },
-{ "bdzfl-", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
-{ "bdzfl+", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
-{ "bdzfl", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BD } },
-{ "bdzfa-", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdzfa+", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdzfa", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDA } },
-{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
-{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
-{ "bdzfla", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDA } },
-{ "bc-", B(16,0,0), B_MASK, PPC, { BOE, BI, BDM } },
-{ "bc+", B(16,0,0), B_MASK, PPC, { BOE, BI, BDP } },
-{ "bc", B(16,0,0), B_MASK, PPC|POWER, { BO, BI, BD } },
-{ "bcl-", B(16,0,1), B_MASK, PPC, { BOE, BI, BDM } },
-{ "bcl+", B(16,0,1), B_MASK, PPC, { BOE, BI, BDP } },
-{ "bcl", B(16,0,1), B_MASK, PPC|POWER, { BO, BI, BD } },
-{ "bca-", B(16,1,0), B_MASK, PPC, { BOE, BI, BDMA } },
-{ "bca+", B(16,1,0), B_MASK, PPC, { BOE, BI, BDPA } },
-{ "bca", B(16,1,0), B_MASK, PPC|POWER, { BO, BI, BDA } },
-{ "bcla-", B(16,1,1), B_MASK, PPC, { BOE, BI, BDMA } },
-{ "bcla+", B(16,1,1), B_MASK, PPC, { BOE, BI, BDPA } },
-{ "bcla", B(16,1,1), B_MASK, PPC|POWER, { BO, BI, BDA } },
-
-{ "sc", SC(17,1,0), 0xffffffff, PPC, { 0 } },
-{ "svc", SC(17,0,0), SC_MASK, POWER, { LEV, FL1, FL2 } },
-{ "svcl", SC(17,0,1), SC_MASK, POWER, { LEV, FL1, FL2 } },
-{ "svca", SC(17,1,0), SC_MASK, POWER, { SV } },
-{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV } },
-
-{ "b", B(18,0,0), B_MASK, PPC|POWER, { LI } },
-{ "bl", B(18,0,1), B_MASK, PPC|POWER, { LI } },
-{ "ba", B(18,1,0), B_MASK, PPC|POWER, { LIA } },
-{ "bla", B(18,1,1), B_MASK, PPC|POWER, { LIA } },
-
-{ "mcrf", XL(19,0), XLBB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
-
-{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "br", XLO(19,BOU,16,0), XLBOBIBB_MASK, POWER, { 0 } },
-{ "blrl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "brl", XLO(19,BOU,16,1), XLBOBIBB_MASK, POWER, { 0 } },
-{ "bdnzlr", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdzlr", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdzlr-", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdzlr+", XLO(19,BODZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdzlrl", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
-{ "bltlr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltlr-", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltlr+", XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bltlrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bgtlr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtlr-", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtlr+", XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bgtlrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "beqlr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqlr-", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqlr+", XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "beqlrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bsolr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsolr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsolr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsor", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bsolrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsorl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bunlr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunlr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunlr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunlrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgelr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgelr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgelr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bger", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bgelrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgerl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnllr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnllr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnllr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnllrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "blelr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "blelr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "blelr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bler", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "blelrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "blerl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnglr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnglr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnglr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnglrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnelr", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnelr-", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnelr+", XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bner", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnelrl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnerl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnslr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnslr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnslr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnslrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
-{ "bnulr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnulr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnulr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnulrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "btlr", XLO(19,BOT,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "btlr-", XLO(19,BOT,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "btlr+", XLO(19,BOTP,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bbtr", XLO(19,BOT,16,0), XLBOBB_MASK, POWER, { BI } },
-{ "btlrl", XLO(19,BOT,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "btlrl-", XLO(19,BOT,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "btlrl+", XLO(19,BOTP,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bbtrl", XLO(19,BOT,16,1), XLBOBB_MASK, POWER, { BI } },
-{ "bflr", XLO(19,BOF,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bflr-", XLO(19,BOF,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bflr+", XLO(19,BOFP,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bbfr", XLO(19,BOF,16,0), XLBOBB_MASK, POWER, { BI } },
-{ "bflrl", XLO(19,BOF,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bflrl-", XLO(19,BOF,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bflrl+", XLO(19,BOFP,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bbfrl", XLO(19,BOF,16,1), XLBOBB_MASK, POWER, { BI } },
-{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdztlr", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdzflr", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, PPC, { BI } },
-{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, PPC, { BI } },
-{ "bclr", XLLK(19,16,0), XLYBB_MASK, PPC, { BO, BI } },
-{ "bclrl", XLLK(19,16,1), XLYBB_MASK, PPC, { BO, BI } },
-{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bcr", XLLK(19,16,0), XLBB_MASK, POWER, { BO, BI } },
-{ "bcrl", XLLK(19,16,1), XLBB_MASK, POWER, { BO, BI } },
-
-{ "crnot", XL(19,33), XL_MASK, PPC, { BT, BA, BBA } },
-{ "crnor", XL(19,33), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "rfi", XL(19,50), 0xffffffff, PPC|POWER, { 0 } },
-{ "rfci", XL(19,51), 0xffffffff, PPC, { 0 } },
-
-{ "rfsvc", XL(19,82), 0xffffffff, POWER, { 0 } },
-
-{ "crandc", XL(19,129), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "isync", XL(19,150), 0xffffffff, PPC, { 0 } },
-{ "ics", XL(19,150), 0xffffffff, POWER, { 0 } },
-
-{ "crclr", XL(19,193), XL_MASK, PPC, { BT, BAT, BBA } },
-{ "crxor", XL(19,193), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "crnand", XL(19,225), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "crand", XL(19,257), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "crset", XL(19,289), XL_MASK, PPC, { BT, BAT, BBA } },
-{ "creqv", XL(19,289), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "crorc", XL(19,417), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "crmove", XL(19,449), XL_MASK, PPC, { BT, BA, BBA } },
-{ "cror", XL(19,449), XL_MASK, PPC|POWER, { BT, BA, BB } },
-
-{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, PPC|POWER, { 0 } },
-{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, PPC|POWER, { 0 } },
-{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtctr", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqctr", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsoctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgectr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlctr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "blectr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngctr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnectr", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnuctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
-{ "btctr", XLO(19,BOT,528,0), XLBOBB_MASK, PPC, { BI } },
-{ "btctr-", XLO(19,BOT,528,0), XLBOBB_MASK, PPC, { BI } },
-{ "btctr+", XLO(19,BOTP,528,0), XLBOBB_MASK, PPC, { BI } },
-{ "btctrl", XLO(19,BOT,528,1), XLBOBB_MASK, PPC, { BI } },
-{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, PPC, { BI } },
-{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, PPC, { BI } },
-{ "bfctr", XLO(19,BOF,528,0), XLBOBB_MASK, PPC, { BI } },
-{ "bfctr-", XLO(19,BOF,528,0), XLBOBB_MASK, PPC, { BI } },
-{ "bfctr+", XLO(19,BOFP,528,0), XLBOBB_MASK, PPC, { BI } },
-{ "bfctrl", XLO(19,BOF,528,1), XLBOBB_MASK, PPC, { BI } },
-{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, PPC, { BI } },
-{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, PPC, { BI } },
-{ "bcctr", XLLK(19,528,0), XLYBB_MASK, PPC, { BO, BI } },
-{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bcctrl", XLLK(19,528,1), XLYBB_MASK, PPC, { BO, BI } },
-{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPC, { BOE, BI } },
-{ "bcc", XLLK(19,528,0), XLBB_MASK, POWER, { BO, BI } },
-{ "bccl", XLLK(19,528,1), XLBB_MASK, POWER, { BO, BI } },
-
-{ "rlwimi", M(20,0), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
-{ "rlimi", M(20,0), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
-
-{ "rlwimi.", M(20,1), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
-{ "rlimi.", M(20,1), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
-
-{ "rotlwi", MME(21,31,0), MMBME_MASK, PPC, { RA, RS, SH } },
-{ "clrlwi", MME(21,31,0), MSHME_MASK, PPC, { RA, RS, MB } },
-{ "rlwinm", M(21,0), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
-{ "rlinm", M(21,0), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
-{ "rotlwi.", MME(21,31,1), MMBME_MASK, PPC, { RA,RS,SH } },
-{ "clrlwi.", MME(21,31,1), MSHME_MASK, PPC, { RA, RS, MB } },
-{ "rlwinm.", M(21,1), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
-{ "rlinm.", M(21,1), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
-
-{ "rlmi", M(22,0), M_MASK, POWER|M601, { RA,RS,RB,MBE,ME } },
-{ "rlmi.", M(22,1), M_MASK, POWER|M601, { RA,RS,RB,MBE,ME } },
-
-{ "rotlw", MME(23,31,0), MMBME_MASK, PPC, { RA, RS, RB } },
-{ "rlwnm", M(23,0), M_MASK, PPC, { RA,RS,RB,MBE,ME } },
-{ "rlnm", M(23,0), M_MASK, POWER, { RA,RS,RB,MBE,ME } },
-{ "rotlw.", MME(23,31,1), MMBME_MASK, PPC, { RA, RS, RB } },
-{ "rlwnm.", M(23,1), M_MASK, PPC, { RA,RS,RB,MBE,ME } },
-{ "rlnm.", M(23,1), M_MASK, POWER, { RA,RS,RB,MBE,ME } },
-
-{ "nop", OP(24), 0xffffffff, PPC, { 0 } },
-{ "ori", OP(24), OP_MASK, PPC, { RA, RS, UI } },
-{ "oril", OP(24), OP_MASK, POWER, { RA, RS, UI } },
-
-{ "oris", OP(25), OP_MASK, PPC, { RA, RS, UI } },
-{ "oriu", OP(25), OP_MASK, POWER, { RA, RS, UI } },
-
-{ "xori", OP(26), OP_MASK, PPC, { RA, RS, UI } },
-{ "xoril", OP(26), OP_MASK, POWER, { RA, RS, UI } },
-
-{ "xoris", OP(27), OP_MASK, PPC, { RA, RS, UI } },
-{ "xoriu", OP(27), OP_MASK, POWER, { RA, RS, UI } },
-
-{ "andi.", OP(28), OP_MASK, PPC, { RA, RS, UI } },
-{ "andil.", OP(28), OP_MASK, POWER, { RA, RS, UI } },
-
-{ "andis.", OP(29), OP_MASK, PPC, { RA, RS, UI } },
-{ "andiu.", OP(29), OP_MASK, POWER, { RA, RS, UI } },
-
-{ "rotldi", MD(30,0,0), MDMB_MASK, PPC|B64, { RA, RS, SH6 } },
-{ "clrldi", MD(30,0,0), MDSH_MASK, PPC|B64, { RA, RS, MB6 } },
-{ "rldicl", MD(30,0,0), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
-{ "rotldi.", MD(30,0,1), MDMB_MASK, PPC|B64, { RA, RS, SH6 } },
-{ "clrldi.", MD(30,0,1), MDSH_MASK, PPC|B64, { RA, RS, MB6 } },
-{ "rldicl.", MD(30,0,1), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
-
-{ "rldicr", MD(30,1,0), MD_MASK, PPC|B64, { RA, RS, SH6, ME6 } },
-{ "rldicr.", MD(30,1,1), MD_MASK, PPC|B64, { RA, RS, SH6, ME6 } },
-
-{ "rldic", MD(30,2,0), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
-{ "rldic.", MD(30,2,1), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
-
-{ "rldimi", MD(30,3,0), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
-{ "rldimi.", MD(30,3,1), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
-
-{ "rotld", MDS(30,8,0), MDSMB_MASK, PPC|B64, { RA, RS, RB } },
-{ "rldcl", MDS(30,8,0), MDS_MASK, PPC|B64, { RA, RS, RB, MB6 } },
-{ "rotld.", MDS(30,8,1), MDSMB_MASK, PPC|B64, { RA, RS, RB } },
-{ "rldcl.", MDS(30,8,1), MDS_MASK, PPC|B64, { RA, RS, RB, MB6 } },
-
-{ "rldcr", MDS(30,9,0), MDS_MASK, PPC|B64, { RA, RS, RB, ME6 } },
-{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC|B64, { RA, RS, RB, ME6 } },
-
-{ "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPC, { OBF, RA, RB } },
-{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC|B64, { OBF, RA, RB } },
-{ "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB } },
-{ "cmp", X(31,0), XCMPL_MASK, POWER, { BF, RA, RB } },
-
-{ "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPC, { RA, RB } },
-{ "tlgt", XTO(31,4,TOLGT), XTO_MASK, POWER, { RA, RB } },
-{ "twllt", XTO(31,4,TOLLT), XTO_MASK, PPC, { RA, RB } },
-{ "tllt", XTO(31,4,TOLLT), XTO_MASK, POWER, { RA, RB } },
-{ "tweq", XTO(31,4,TOEQ), XTO_MASK, PPC, { RA, RB } },
-{ "teq", XTO(31,4,TOEQ), XTO_MASK, POWER, { RA, RB } },
-{ "twlge", XTO(31,4,TOLGE), XTO_MASK, PPC, { RA, RB } },
-{ "tlge", XTO(31,4,TOLGE), XTO_MASK, POWER, { RA, RB } },
-{ "twlnl", XTO(31,4,TOLNL), XTO_MASK, PPC, { RA, RB } },
-{ "tlnl", XTO(31,4,TOLNL), XTO_MASK, POWER, { RA, RB } },
-{ "twlle", XTO(31,4,TOLLE), XTO_MASK, PPC, { RA, RB } },
-{ "tlle", XTO(31,4,TOLLE), XTO_MASK, POWER, { RA, RB } },
-{ "twlng", XTO(31,4,TOLNG), XTO_MASK, PPC, { RA, RB } },
-{ "tlng", XTO(31,4,TOLNG), XTO_MASK, POWER, { RA, RB } },
-{ "twgt", XTO(31,4,TOGT), XTO_MASK, PPC, { RA, RB } },
-{ "tgt", XTO(31,4,TOGT), XTO_MASK, POWER, { RA, RB } },
-{ "twge", XTO(31,4,TOGE), XTO_MASK, PPC, { RA, RB } },
-{ "tge", XTO(31,4,TOGE), XTO_MASK, POWER, { RA, RB } },
-{ "twnl", XTO(31,4,TONL), XTO_MASK, PPC, { RA, RB } },
-{ "tnl", XTO(31,4,TONL), XTO_MASK, POWER, { RA, RB } },
-{ "twlt", XTO(31,4,TOLT), XTO_MASK, PPC, { RA, RB } },
-{ "tlt", XTO(31,4,TOLT), XTO_MASK, POWER, { RA, RB } },
-{ "twle", XTO(31,4,TOLE), XTO_MASK, PPC, { RA, RB } },
-{ "tle", XTO(31,4,TOLE), XTO_MASK, POWER, { RA, RB } },
-{ "twng", XTO(31,4,TONG), XTO_MASK, PPC, { RA, RB } },
-{ "tng", XTO(31,4,TONG), XTO_MASK, POWER, { RA, RB } },
-{ "twne", XTO(31,4,TONE), XTO_MASK, PPC, { RA, RB } },
-{ "tne", XTO(31,4,TONE), XTO_MASK, POWER, { RA, RB } },
-{ "trap", XTO(31,4,TOU), 0xffffffff, PPC, { 0 } },
-{ "tw", X(31,4), X_MASK, PPC, { TO, RA, RB } },
-{ "t", X(31,4), X_MASK, POWER, { TO, RA, RB } },
-
-{ "subfc", XO(31,8,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "sf", XO(31,8,0,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "subc", XO(31,8,0,0), XO_MASK, PPC, { RT, RB, RA } },
-{ "subfc.", XO(31,8,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "sf.", XO(31,8,0,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "subc.", XO(31,8,0,1), XO_MASK, PPC, { RT, RB, RA } },
-{ "subfco", XO(31,8,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "sfo", XO(31,8,1,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "subco", XO(31,8,1,0), XO_MASK, PPC, { RT, RB, RA } },
-{ "subfco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "sfo.", XO(31,8,1,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "subco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RB, RA } },
-
-{ "mulhdu", XO(31,9,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "mulhdu.", XO(31,9,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "addc", XO(31,10,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "a", XO(31,10,0,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "addc.", XO(31,10,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "a.", XO(31,10,0,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "addco", XO(31,10,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "ao", XO(31,10,1,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "addco.", XO(31,10,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "ao.", XO(31,10,1,1), XO_MASK, POWER, { RT, RA, RB } },
-
-{ "mulhwu", XO(31,11,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "mulhwu.", XO(31,11,0,1), XO_MASK, PPC, { RT, RA, RB } },
-
-{ "mfcr", X(31,19), XRARB_MASK, POWER|PPC, { RT } },
-
-{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } },
-
-{ "ldx", X(31,21), X_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "lwzx", X(31,23), X_MASK, PPC, { RT, RA, RB } },
-{ "lx", X(31,23), X_MASK, POWER, { RT, RA, RB } },
-
-{ "slw", XRC(31,24,0), X_MASK, PPC, { RA, RS, RB } },
-{ "sl", XRC(31,24,0), X_MASK, POWER, { RA, RS, RB } },
-{ "slw.", XRC(31,24,1), X_MASK, PPC, { RA, RS, RB } },
-{ "sl.", XRC(31,24,1), X_MASK, POWER, { RA, RS, RB } },
-
-{ "cntlzw", XRC(31,26,0), XRB_MASK, PPC, { RA, RS } },
-{ "cntlz", XRC(31,26,0), XRB_MASK, POWER, { RA, RS } },
-{ "cntlzw.", XRC(31,26,1), XRB_MASK, PPC, { RA, RS } },
-{ "cntlz.", XRC(31,26,1), XRB_MASK, POWER, { RA, RS } },
-
-{ "sld", XRC(31,27,0), X_MASK, PPC|B64, { RA, RS, RB } },
-{ "sld.", XRC(31,27,1), X_MASK, PPC|B64, { RA, RS, RB } },
-
-{ "and", XRC(31,28,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "and.", XRC(31,28,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "maskg", XRC(31,29,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "maskg.", XRC(31,29,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPC, { OBF, RA, RB } },
-{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC|B64, { OBF, RA, RB } },
-{ "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB } },
-{ "cmpl", X(31,32), XCMPL_MASK, POWER, { BF, RA, RB } },
-
-{ "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA } },
-{ "subf.", XO(31,40,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "sub.", XO(31,40,0,1), XO_MASK, PPC, { RT, RB, RA } },
-{ "subfo", XO(31,40,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "subo", XO(31,40,1,0), XO_MASK, PPC, { RT, RB, RA } },
-{ "subfo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "subo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RB, RA } },
-
-{ "ldux", X(31,53), X_MASK, PPC|B64, { RT, RAL, RB } },
-
-{ "dcbst", X(31,54), XRT_MASK, PPC, { RA, RB } },
-
-{ "lwzux", X(31,55), X_MASK, PPC, { RT, RAL, RB } },
-{ "lux", X(31,55), X_MASK, POWER, { RT, RA, RB } },
-
-{ "cntlzd", XRC(31,58,0), XRB_MASK, PPC|B64, { RA, RS } },
-{ "cntlzd.", XRC(31,58,1), XRB_MASK, PPC|B64, { RA, RS } },
-
-{ "andc", XRC(31,60,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "andc.", XRC(31,60,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "tdlgt", XTO(31,68,TOLGT), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdllt", XTO(31,68,TOLLT), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdeq", XTO(31,68,TOEQ), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdlge", XTO(31,68,TOLGE), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdlnl", XTO(31,68,TOLNL), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdlle", XTO(31,68,TOLLE), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdlng", XTO(31,68,TOLNG), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdgt", XTO(31,68,TOGT), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdge", XTO(31,68,TOGE), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdnl", XTO(31,68,TONL), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdlt", XTO(31,68,TOLT), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdle", XTO(31,68,TOLE), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdng", XTO(31,68,TONG), XTO_MASK, PPC|B64, { RA, RB } },
-{ "tdne", XTO(31,68,TONE), XTO_MASK, PPC|B64, { RA, RB } },
-{ "td", X(31,68), X_MASK, PPC|B64, { TO, RA, RB } },
-
-{ "mulhd", XO(31,73,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "mulhd.", XO(31,73,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "mulhw", XO(31,75,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "mulhw.", XO(31,75,0,1), XO_MASK, PPC, { RT, RA, RB } },
-
-{ "mfmsr", X(31,83), XRARB_MASK, PPC|POWER, { RT } },
-
-{ "ldarx", X(31,84), X_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "dcbf", X(31,86), XRT_MASK, PPC, { RA, RB } },
-
-{ "lbzx", X(31,87), X_MASK, PPC|POWER, { RT, RA, RB } },
-
-{ "neg", XO(31,104,0,0), XORB_MASK, PPC|POWER, { RT, RA } },
-{ "neg.", XO(31,104,0,1), XORB_MASK, PPC|POWER, { RT, RA } },
-{ "nego", XO(31,104,1,0), XORB_MASK, PPC|POWER, { RT, RA } },
-{ "nego.", XO(31,104,1,1), XORB_MASK, PPC|POWER, { RT, RA } },
-
-{ "mul", XO(31,107,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "mul.", XO(31,107,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "mulo", XO(31,107,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "mulo.", XO(31,107,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-
-{ "clf", X(31,118), XRB_MASK, POWER, { RT, RA } },
-
-{ "lbzux", X(31,119), X_MASK, PPC|POWER, { RT, RAL, RB } },
-
-{ "not", XRC(31,124,0), X_MASK, PPC|POWER, { RA, RS, RBS } },
-{ "nor", XRC(31,124,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "not.", XRC(31,124,1), X_MASK, PPC|POWER, { RA, RS, RBS } },
-{ "nor.", XRC(31,124,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "subfe", XO(31,136,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "sfe", XO(31,136,0,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "subfe.", XO(31,136,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "sfe.", XO(31,136,0,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "subfeo", XO(31,136,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "sfeo", XO(31,136,1,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "subfeo.", XO(31,136,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "sfeo.", XO(31,136,1,1), XO_MASK, POWER, { RT, RA, RB } },
-
-{ "adde", XO(31,138,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "ae", XO(31,138,0,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "adde.", XO(31,138,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "ae.", XO(31,138,0,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "addeo", XO(31,138,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "aeo", XO(31,138,1,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "addeo.", XO(31,138,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "aeo.", XO(31,138,1,1), XO_MASK, POWER, { RT, RA, RB } },
-
-{ "mtcr", XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, PPC|POWER, { RS }},
-{ "mtcrf", X(31,144), XFXFXM_MASK, PPC|POWER, { FXM, RS } },
-
-{ "mtmsr", X(31,146), XRARB_MASK, PPC|POWER, { RS } },
-
-{ "stdx", X(31,149), X_MASK, PPC|B64, { RS, RA, RB } },
-
-{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA, RB } },
-
-{ "stwx", X(31,151), X_MASK, PPC, { RS, RA, RB } },
-{ "stx", X(31,151), X_MASK, POWER, { RS, RA, RB } },
-
-{ "slq", XRC(31,152,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "slq.", XRC(31,152,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "sle", XRC(31,153,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "sle.", XRC(31,153,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "stdux", X(31,181), X_MASK, PPC|B64, { RS, RAS, RB } },
-
-{ "stwux", X(31,183), X_MASK, PPC, { RS, RAS, RB } },
-{ "stux", X(31,183), X_MASK, POWER, { RS, RA, RB } },
-
-{ "sliq", XRC(31,184,0), X_MASK, POWER|M601, { RA, RS, SH } },
-{ "sliq.", XRC(31,184,1), X_MASK, POWER|M601, { RA, RS, SH } },
-
-{ "subfze", XO(31,200,0,0), XORB_MASK, PPC, { RT, RA } },
-{ "sfze", XO(31,200,0,0), XORB_MASK, POWER, { RT, RA } },
-{ "subfze.", XO(31,200,0,1), XORB_MASK, PPC, { RT, RA } },
-{ "sfze.", XO(31,200,0,1), XORB_MASK, POWER, { RT, RA } },
-{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPC, { RT, RA } },
-{ "sfzeo", XO(31,200,1,0), XORB_MASK, POWER, { RT, RA } },
-{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPC, { RT, RA } },
-{ "sfzeo.", XO(31,200,1,1), XORB_MASK, POWER, { RT, RA } },
-
-{ "addze", XO(31,202,0,0), XORB_MASK, PPC, { RT, RA } },
-{ "aze", XO(31,202,0,0), XORB_MASK, POWER, { RT, RA } },
-{ "addze.", XO(31,202,0,1), XORB_MASK, PPC, { RT, RA } },
-{ "aze.", XO(31,202,0,1), XORB_MASK, POWER, { RT, RA } },
-{ "addzeo", XO(31,202,1,0), XORB_MASK, PPC, { RT, RA } },
-{ "azeo", XO(31,202,1,0), XORB_MASK, POWER, { RT, RA } },
-{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPC, { RT, RA } },
-{ "azeo.", XO(31,202,1,1), XORB_MASK, POWER, { RT, RA } },
-
-{ "mtsr", X(31,210), XRB_MASK|(1<<20), PPC|POWER|B32, { SR, RS } },
-
-{ "stdcx.", XRC(31,214,1), X_MASK, PPC|B64, { RS, RA, RB } },
-
-{ "stbx", X(31,215), X_MASK, PPC|POWER, { RS, RA, RB } },
-
-{ "sllq", XRC(31,216,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "sllq.", XRC(31,216,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "sleq", XRC(31,217,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "sleq.", XRC(31,217,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "subfme", XO(31,232,0,0), XORB_MASK, PPC, { RT, RA } },
-{ "sfme", XO(31,232,0,0), XORB_MASK, POWER, { RT, RA } },
-{ "subfme.", XO(31,232,0,1), XORB_MASK, PPC, { RT, RA } },
-{ "sfme.", XO(31,232,0,1), XORB_MASK, POWER, { RT, RA } },
-{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPC, { RT, RA } },
-{ "sfmeo", XO(31,232,1,0), XORB_MASK, POWER, { RT, RA } },
-{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPC, { RT, RA } },
-{ "sfmeo.", XO(31,232,1,1), XORB_MASK, POWER, { RT, RA } },
-
-{ "mulld", XO(31,233,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "mulld.", XO(31,233,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "mulldo", XO(31,233,1,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "mulldo.", XO(31,233,1,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "addme", XO(31,234,0,0), XORB_MASK, PPC, { RT, RA } },
-{ "ame", XO(31,234,0,0), XORB_MASK, POWER, { RT, RA } },
-{ "addme.", XO(31,234,0,1), XORB_MASK, PPC, { RT, RA } },
-{ "ame.", XO(31,234,0,1), XORB_MASK, POWER, { RT, RA } },
-{ "addmeo", XO(31,234,1,0), XORB_MASK, PPC, { RT, RA } },
-{ "ameo", XO(31,234,1,0), XORB_MASK, POWER, { RT, RA } },
-{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPC, { RT, RA } },
-{ "ameo.", XO(31,234,1,1), XORB_MASK, POWER, { RT, RA } },
-
-{ "mullw", XO(31,235,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "muls", XO(31,235,0,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "mullw.", XO(31,235,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "muls.", XO(31,235,0,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "mullwo", XO(31,235,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "mulso", XO(31,235,1,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "mullwo.", XO(31,235,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "mulso.", XO(31,235,1,1), XO_MASK, POWER, { RT, RA, RB } },
-
-{ "mtsrin", X(31,242), XRA_MASK, PPC|B32, { RS, RB } },
-{ "mtsri", X(31,242), XRA_MASK, POWER|B32, { RS, RB } },
-
-{ "dcbtst", X(31,246), XRT_MASK, PPC, { RA, RB } },
-
-{ "stbux", X(31,247), X_MASK, PPC|POWER, { RS, RAS, RB } },
-
-{ "slliq", XRC(31,248,0), X_MASK, POWER|M601, { RA, RS, SH } },
-{ "slliq.", XRC(31,248,1), X_MASK, POWER|M601, { RA, RS, SH } },
-
-{ "doz", XO(31,264,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "doz.", XO(31,264,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "dozo", XO(31,264,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "dozo.", XO(31,264,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-
-{ "add", XO(31,266,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "cax", XO(31,266,0,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "add.", XO(31,266,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "cax.", XO(31,266,0,1), XO_MASK, POWER, { RT, RA, RB } },
-{ "addo", XO(31,266,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "caxo", XO(31,266,1,0), XO_MASK, POWER, { RT, RA, RB } },
-{ "addo.", XO(31,266,1,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "caxo.", XO(31,266,1,1), XO_MASK, POWER, { RT, RA, RB } },
-
-{ "lscbx", XRC(31,277,0), X_MASK, POWER|M601, { RT, RA, RB } },
-{ "lscbx.", XRC(31,277,1), X_MASK, POWER|M601, { RT, RA, RB } },
-
-{ "dcbt", X(31,278), XRT_MASK, PPC, { RA, RB } },
-
-{ "lhzx", X(31,279), X_MASK, PPC|POWER, { RT, RA, RB } },
-
-{ "icbt", X(31,262), XRT_MASK, PPC, { RA, RB } },
-
-{ "eqv", XRC(31,284,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "eqv.", XRC(31,284,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "tlbie", X(31,306), XRTRA_MASK, PPC, { RB } },
-{ "tlbi", X(31,306), XRTRA_MASK, POWER, { RB } },
-
-{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB } },
-
-{ "lhzux", X(31,311), X_MASK, PPC|POWER, { RT, RAL, RB } },
-
-{ "xor", XRC(31,316,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "xor.", XRC(31,316,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "mfdcr", X(31,323), X_MASK, PPC, { RT, SPR } },
-
-{ "div", XO(31,331,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "div.", XO(31,331,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "divo", XO(31,331,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "divo.", XO(31,331,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-
-{ "mfmq", XSPR(31,339,0), XSPR_MASK, POWER|M601, { RT } },
-{ "mfxer", XSPR(31,339,1), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfrtcu", XSPR(31,339,4), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfrtcl", XSPR(31,339,5), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfdec", XSPR(31,339,6), XSPR_MASK, POWER|M601, { RT } },
-{ "mflr", XSPR(31,339,8), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfctr", XSPR(31,339,9), XSPR_MASK, PPC|POWER, { RT } },
-{ "mftid", XSPR(31,339,17), XSPR_MASK, POWER, { RT } },
-{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfdar", XSPR(31,339,19), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfdec", XSPR(31,339,22), XSPR_MASK, PPC, { RT } },
-{ "mfsdr0", XSPR(31,339,24), XSPR_MASK, POWER, { RT } },
-{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, PPC|POWER, { RT } },
-{ "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } },
-{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC|B64, { RT } },
-{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } },
-{ "mfpvr", XSPR(31,339,287), XSPR_MASK, PPC, { RT } },
-{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
-{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
-{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
-{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
-{ "mfspr", X(31,339), X_MASK, PPC|POWER, { RT, SPR } },
-
-{ "lwax", X(31,341), X_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "lhax", X(31,343), X_MASK, PPC|POWER, { RT, RA, RB } },
-
-{ "dccci", X(31,454), XRT_MASK, PPC, { RA, RB } },
-
-{ "abs", XO(31,360,0,0), XORB_MASK, POWER|M601, { RT, RA } },
-{ "abs.", XO(31,360,0,1), XORB_MASK, POWER|M601, { RT, RA } },
-{ "abso", XO(31,360,1,0), XORB_MASK, POWER|M601, { RT, RA } },
-{ "abso.", XO(31,360,1,1), XORB_MASK, POWER|M601, { RT, RA } },
-
-{ "divs", XO(31,363,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "divs.", XO(31,363,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "divso", XO(31,363,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
-{ "divso.", XO(31,363,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
-
-{ "tlbia", X(31,370), 0xffffffff, PPC, { 0 } },
-
-{ "mftbu", XSPR(31,371,269), XSPR_MASK, PPC, { RT } },
-{ "mftb", X(31,371), X_MASK, PPC, { RT, TBR } },
-
-{ "lwaux", X(31,373), X_MASK, PPC|B64, { RT, RAL, RB } },
-
-{ "lhaux", X(31,375), X_MASK, PPC|POWER, { RT, RAL, RB } },
-
-{ "sthx", X(31,407), X_MASK, PPC|POWER, { RS, RA, RB } },
-
-{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB } },
-
-{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB } },
-
-{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB } },
-
-{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB } },
-
-{ "orc", XRC(31,412,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "orc.", XRC(31,412,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "sradi", XS(31,413,0), XS_MASK, PPC|B64, { RA, RS, SH6 } },
-{ "sradi.", XS(31,413,1), XS_MASK, PPC|B64, { RA, RS, SH6 } },
-
-{ "slbie", X(31,434), XRTRA_MASK, PPC|B64, { RB } },
-
-{ "ecowx", X(31,438), X_MASK, PPC, { RT, RA, RB } },
-
-{ "sthux", X(31,439), X_MASK, PPC|POWER, { RS, RAS, RB } },
-
-{ "mr", XRC(31,444,0), X_MASK, PPC|POWER, { RA, RS, RBS } },
-{ "or", XRC(31,444,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "mr.", XRC(31,444,1), X_MASK, PPC|POWER, { RA, RS, RBS } },
-{ "or.", XRC(31,444,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "mtdcr", X(31,451), X_MASK, PPC, { SPR, RS } },
-
-{ "divdu", XO(31,457,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "divdu.", XO(31,457,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "divduo", XO(31,457,1,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "divduo.", XO(31,457,1,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "divwu.", XO(31,459,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "divwuo", XO(31,459,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "divwuo.", XO(31,459,1,1), XO_MASK, PPC, { RT, RA, RB } },
-
-{ "mtmq", XSPR(31,467,0), XSPR_MASK, POWER|M601, { RS } },
-{ "mtxer", XSPR(31,467,1), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtlr", XSPR(31,467,8), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtctr", XSPR(31,467,9), XSPR_MASK, PPC|POWER, { RS } },
-{ "mttid", XSPR(31,467,17), XSPR_MASK, POWER, { RS } },
-{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtdar", XSPR(31,467,19), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtrtcu", XSPR(31,467,20), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtrtcl", XSPR(31,467,21), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtdec", XSPR(31,467,22), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtsdr0", XSPR(31,467,24), XSPR_MASK, POWER, { RS } },
-{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, PPC|POWER, { RS } },
-{ "mtsprg", XSPR(31,467,272), XSPRG_MASK, PPC, { SPRG, RS } },
-{ "mtasr", XSPR(31,467,280), XSPR_MASK, PPC|B64, { RS } },
-{ "mtear", XSPR(31,467,282), XSPR_MASK, PPC, { RS } },
-{ "mttbl", XSPR(31,467,284), XSPR_MASK, PPC, { RS } },
-{ "mttbu", XSPR(31,467,285), XSPR_MASK, PPC, { RS } },
-{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
-{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
-{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
-{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
-{ "mtspr", X(31,467), X_MASK, PPC|POWER, { SPR, RS } },
-
-{ "dcbi", X(31,470), XRT_MASK, PPC, { RA, RB } },
-
-{ "nand", XRC(31,476,0), X_MASK, PPC|POWER, { RA, RS, RB } },
-{ "nand.", XRC(31,476,1), X_MASK, PPC|POWER, { RA, RS, RB } },
-
-{ "nabs", XO(31,488,0,0), XORB_MASK, POWER|M601, { RT, RA } },
-{ "nabs.", XO(31,488,0,1), XORB_MASK, POWER|M601, { RT, RA } },
-{ "nabso", XO(31,488,1,0), XORB_MASK, POWER|M601, { RT, RA } },
-{ "nabso.", XO(31,488,1,1), XORB_MASK, POWER|M601, { RT, RA } },
-
-{ "divd", XO(31,489,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "divd.", XO(31,489,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "divdo", XO(31,489,1,0), XO_MASK, PPC|B64, { RT, RA, RB } },
-{ "divdo.", XO(31,489,1,1), XO_MASK, PPC|B64, { RT, RA, RB } },
-
-{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "divw.", XO(31,491,0,1), XO_MASK, PPC, { RT, RA, RB } },
-{ "divwo", XO(31,491,1,0), XO_MASK, PPC, { RT, RA, RB } },
-{ "divwo.", XO(31,491,1,1), XO_MASK, PPC, { RT, RA, RB } },
-
-{ "slbia", X(31,498), 0xffffffff, PPC|B64, { 0 } },
-
-{ "cli", X(31,502), XRB_MASK, POWER, { RT, RA } },
-
-{ "mcrxr", X(31,512), XRARB_MASK|(3<<21), PPC|POWER, { BF } },
-
-{ "clcs", X(31,531), XRB_MASK, POWER|M601, { RT, RA } },
-
-{ "lswx", X(31,533), X_MASK, PPC, { RT, RA, RB } },
-{ "lsx", X(31,533), X_MASK, POWER, { RT, RA, RB } },
-
-{ "lwbrx", X(31,534), X_MASK, PPC, { RT, RA, RB } },
-{ "lbrx", X(31,534), X_MASK, POWER, { RT, RA, RB } },
-
-{ "lfsx", X(31,535), X_MASK, PPC|POWER, { FRT, RA, RB } },
-
-{ "srw", XRC(31,536,0), X_MASK, PPC, { RA, RS, RB } },
-{ "sr", XRC(31,536,0), X_MASK, POWER, { RA, RS, RB } },
-{ "srw.", XRC(31,536,1), X_MASK, PPC, { RA, RS, RB } },
-{ "sr.", XRC(31,536,1), X_MASK, POWER, { RA, RS, RB } },
-
-{ "rrib", XRC(31,537,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "rrib.", XRC(31,537,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "srd", XRC(31,539,0), X_MASK, PPC|B64, { RA, RS, RB } },
-{ "srd.", XRC(31,539,1), X_MASK, PPC|B64, { RA, RS, RB } },
-
-{ "maskir", XRC(31,541,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "maskir.", XRC(31,541,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } },
-
-{ "lfsux", X(31,567), X_MASK, PPC|POWER, { FRT, RAS, RB } },
-
-{ "mfsr", X(31,595), XRB_MASK|(1<<20), PPC|POWER|B32, { RT, SR } },
-
-{ "lswi", X(31,597), X_MASK, PPC, { RT, RA, NB } },
-{ "lsi", X(31,597), X_MASK, POWER, { RT, RA, NB } },
-
-{ "sync", X(31,598), 0xffffffff, PPC, { 0 } },
-{ "dcs", X(31,598), 0xffffffff, POWER, { 0 } },
-
-{ "lfdx", X(31,599), X_MASK, PPC|POWER, { FRT, RA, RB } },
-
-{ "mfsri", X(31,627), X_MASK, POWER, { RT, RA, RB } },
-
-{ "dclst", X(31,630), XRB_MASK, POWER, { RS, RA } },
-
-{ "lfdux", X(31,631), X_MASK, PPC|POWER, { FRT, RAS, RB } },
-
-{ "mfsrin", X(31,659), XRA_MASK, PPC|B32, { RT, RB } },
-
-{ "stswx", X(31,661), X_MASK, PPC, { RS, RA, RB } },
-{ "stsx", X(31,661), X_MASK, POWER, { RS, RA, RB } },
-
-{ "stwbrx", X(31,662), X_MASK, PPC, { RS, RA, RB } },
-{ "stbrx", X(31,662), X_MASK, POWER, { RS, RA, RB } },
-
-{ "stfsx", X(31,663), X_MASK, PPC|POWER, { FRS, RA, RB } },
-
-{ "srq", XRC(31,664,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "srq.", XRC(31,664,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "sre", XRC(31,665,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "sre.", XRC(31,665,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "stfsux", X(31,695), X_MASK, PPC|POWER, { FRS, RAS, RB } },
-
-{ "sriq", XRC(31,696,0), X_MASK, POWER|M601, { RA, RS, SH } },
-{ "sriq.", XRC(31,696,1), X_MASK, POWER|M601, { RA, RS, SH } },
-
-{ "stswi", X(31,725), X_MASK, PPC, { RS, RA, NB } },
-{ "stsi", X(31,725), X_MASK, POWER, { RS, RA, NB } },
-
-{ "stfdx", X(31,727), X_MASK, PPC|POWER, { FRS, RA, RB } },
-
-{ "srlq", XRC(31,728,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "srlq.", XRC(31,728,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "sreq", XRC(31,729,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "sreq.", XRC(31,729,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "stfdux", X(31,759), X_MASK, PPC|POWER, { FRS, RAS, RB } },
-
-{ "srliq", XRC(31,760,0), X_MASK, POWER|M601, { RA, RS, SH } },
-{ "srliq.", XRC(31,760,1), X_MASK, POWER|M601, { RA, RS, SH } },
-
-{ "lhbrx", X(31,790), X_MASK, PPC|POWER, { RT, RA, RB } },
-
-{ "sraw", XRC(31,792,0), X_MASK, PPC, { RA, RS, RB } },
-{ "sra", XRC(31,792,0), X_MASK, POWER, { RA, RS, RB } },
-{ "sraw.", XRC(31,792,1), X_MASK, PPC, { RA, RS, RB } },
-{ "sra.", XRC(31,792,1), X_MASK, POWER, { RA, RS, RB } },
-
-{ "srad", XRC(31,794,0), X_MASK, PPC|B64, { RA, RS, RB } },
-{ "srad.", XRC(31,794,1), X_MASK, PPC|B64, { RA, RS, RB } },
-
-{ "rac", X(31,818), X_MASK, POWER, { RT, RA, RB } },
-
-{ "srawi", XRC(31,824,0), X_MASK, PPC, { RA, RS, SH } },
-{ "srai", XRC(31,824,0), X_MASK, POWER, { RA, RS, SH } },
-{ "srawi.", XRC(31,824,1), X_MASK, PPC, { RA, RS, SH } },
-{ "srai.", XRC(31,824,1), X_MASK, POWER, { RA, RS, SH } },
-
-{ "eieio", X(31,854), 0xffffffff, PPC, { 0 } },
-
-{ "sthbrx", X(31,918), X_MASK, PPC|POWER, { RS, RA, RB } },
-
-{ "sraq", XRC(31,920,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "sraq.", XRC(31,920,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "srea", XRC(31,921,0), X_MASK, POWER|M601, { RA, RS, RB } },
-{ "srea.", XRC(31,921,1), X_MASK, POWER|M601, { RA, RS, RB } },
-
-{ "extsh", XRC(31,922,0), XRB_MASK, PPC, { RA, RS } },
-{ "exts", XRC(31,922,0), XRB_MASK, POWER, { RA, RS } },
-{ "extsh.", XRC(31,922,1), XRB_MASK, PPC, { RA, RS } },
-{ "exts.", XRC(31,922,1), XRB_MASK, POWER, { RA, RS } },
-
-{ "sraiq", XRC(31,952,0), X_MASK, POWER|M601, { RA, RS, SH } },
-{ "sraiq.", XRC(31,952,1), X_MASK, POWER|M601, { RA, RS, SH } },
-
-{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS} },
-{ "extsb.", XRC(31,954,1), XRB_MASK, PPC, { RA, RS} },
-
-{ "iccci", X(31,966), XRT_MASK, PPC, { RA, RB } },
-
-{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } },
-
-{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA, RB } },
-
-{ "extsw", XRC(31,986,0), XRB_MASK, PPC, { RA, RS } },
-{ "extsw.", XRC(31,986,1), XRB_MASK, PPC, { RA, RS } },
-
-{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
-{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
-
-{ "lwz", OP(32), OP_MASK, PPC, { RT, D, RA } },
-{ "l", OP(32), OP_MASK, POWER, { RT, D, RA } },
-
-{ "lwzu", OP(33), OP_MASK, PPC, { RT, D, RAL } },
-{ "lu", OP(33), OP_MASK, POWER, { RT, D, RA } },
-
-{ "lbz", OP(34), OP_MASK, PPC|POWER, { RT, D, RA } },
-
-{ "lbzu", OP(35), OP_MASK, PPC|POWER, { RT, D, RAL } },
-
-{ "stw", OP(36), OP_MASK, PPC, { RS, D, RA } },
-{ "st", OP(36), OP_MASK, POWER, { RS, D, RA } },
-
-{ "stwu", OP(37), OP_MASK, PPC, { RS, D, RAS } },
-{ "stu", OP(37), OP_MASK, POWER, { RS, D, RA } },
-
-{ "stb", OP(38), OP_MASK, PPC|POWER, { RS, D, RA } },
-
-{ "stbu", OP(39), OP_MASK, PPC|POWER, { RS, D, RAS } },
-
-{ "lhz", OP(40), OP_MASK, PPC|POWER, { RT, D, RA } },
-
-{ "lhzu", OP(41), OP_MASK, PPC|POWER, { RT, D, RAL } },
-
-{ "lha", OP(42), OP_MASK, PPC|POWER, { RT, D, RA } },
-
-{ "lhau", OP(43), OP_MASK, PPC|POWER, { RT, D, RAL } },
-
-{ "sth", OP(44), OP_MASK, PPC|POWER, { RS, D, RA } },
-
-{ "sthu", OP(45), OP_MASK, PPC|POWER, { RS, D, RAS } },
-
-{ "lmw", OP(46), OP_MASK, PPC, { RT, D, RAM } },
-{ "lm", OP(46), OP_MASK, POWER, { RT, D, RA } },
-
-{ "stmw", OP(47), OP_MASK, PPC, { RS, D, RA } },
-{ "stm", OP(47), OP_MASK, POWER, { RS, D, RA } },
-
-{ "lfs", OP(48), OP_MASK, PPC|POWER, { FRT, D, RA } },
-
-{ "lfsu", OP(49), OP_MASK, PPC|POWER, { FRT, D, RAS } },
-
-{ "lfd", OP(50), OP_MASK, PPC|POWER, { FRT, D, RA } },
-
-{ "lfdu", OP(51), OP_MASK, PPC|POWER, { FRT, D, RAS } },
-
-{ "stfs", OP(52), OP_MASK, PPC|POWER, { FRS, D, RA } },
-
-{ "stfsu", OP(53), OP_MASK, PPC|POWER, { FRS, D, RAS } },
-
-{ "stfd", OP(54), OP_MASK, PPC|POWER, { FRS, D, RA } },
-
-{ "stfdu", OP(55), OP_MASK, PPC|POWER, { FRS, D, RAS } },
-
-{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } },
-
-{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } },
-
-{ "ld", DSO(58,0), DS_MASK, PPC|B64, { RT, DS, RA } },
-
-{ "ldu", DSO(58,1), DS_MASK, PPC|B64, { RT, DS, RAL } },
-
-{ "lwa", DSO(58,2), DS_MASK, PPC|B64, { RT, DS, RA } },
-
-{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-
-{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fsubs.", A(59,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-
-{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fadds.", A(59,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-
-{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
-{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
-
-{ "fres", A(59,24,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
-{ "fres.", A(59,24,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
-
-{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
-{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
-
-{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-
-{ "fmadds", A(59,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fmadds.", A(59,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-
-{ "fnmsubs", A(59,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fnmsubs.",A(59,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-
-{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-
-{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } },
-
-{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } },
-
-{ "std", DSO(62,0), DS_MASK, PPC|B64, { RS, DS, RA } },
-
-{ "stdu", DSO(62,1), DS_MASK, PPC|B64, { RS, DS, RAS } },
-
-{ "fcmpu", X(63,0), X_MASK|(3<<21), PPC|POWER, { BF, FRA, FRB } },
-
-{ "frsp", XRC(63,12,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
-{ "frsp.", XRC(63,12,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
-
-{ "fctiw", XRC(63,14,0), XRA_MASK, PPC, { FRT, FRB } },
-{ "fcir", XRC(63,14,0), XRA_MASK, POWER2, { FRT, FRB } },
-{ "fctiw.", XRC(63,14,1), XRA_MASK, PPC, { FRT, FRB } },
-{ "fcir.", XRC(63,14,1), XRA_MASK, POWER2, { FRT, FRB } },
-
-{ "fctiwz", XRC(63,15,0), XRA_MASK, PPC, { FRT, FRB } },
-{ "fcirz", XRC(63,15,0), XRA_MASK, POWER2, { FRT, FRB } },
-{ "fctiwz.", XRC(63,15,1), XRA_MASK, PPC, { FRT, FRB } },
-{ "fcirz.", XRC(63,15,1), XRA_MASK, POWER2, { FRT, FRB } },
-
-{ "fdiv", A(63,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fd", A(63,18,0), AFRC_MASK, POWER, { FRT, FRA, FRB } },
-{ "fdiv.", A(63,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fd.", A(63,18,1), AFRC_MASK, POWER, { FRT, FRA, FRB } },
-
-{ "fsub", A(63,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fs", A(63,20,0), AFRC_MASK, POWER, { FRT, FRA, FRB } },
-{ "fsub.", A(63,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fs.", A(63,20,1), AFRC_MASK, POWER, { FRT, FRA, FRB } },
-
-{ "fadd", A(63,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fa", A(63,21,0), AFRC_MASK, POWER, { FRT, FRA, FRB } },
-{ "fadd.", A(63,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
-{ "fa.", A(63,21,1), AFRC_MASK, POWER, { FRT, FRA, FRB } },
-
-{ "fsqrt", A(63,22,0), AFRAFRC_MASK, PPC|POWER2, { FRT, FRB } },
-{ "fsqrt.", A(63,22,1), AFRAFRC_MASK, PPC|POWER2, { FRT, FRB } },
-
-{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-
-{ "fmul", A(63,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
-{ "fm", A(63,25,0), AFRB_MASK, POWER, { FRT, FRA, FRC } },
-{ "fmul.", A(63,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
-{ "fm.", A(63,25,1), AFRB_MASK, POWER, { FRT, FRA, FRC } },
-
-{ "frsqrte", A(63,26,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
-{ "frsqrte.",A(63,26,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
-
-{ "fmsub", A(63,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fms", A(63,28,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-{ "fmsub.", A(63,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fms.", A(63,28,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-
-{ "fmadd", A(63,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fma", A(63,29,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-{ "fmadd.", A(63,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fma.", A(63,29,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-
-{ "fnmsub", A(63,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fnms", A(63,30,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-{ "fnmsub.", A(63,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fnms.", A(63,30,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-
-{ "fnmadd", A(63,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fnma", A(63,31,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-{ "fnmadd.", A(63,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
-{ "fnma.", A(63,31,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
-
-{ "fcmpo", X(63,30), X_MASK|(3<<21), PPC|POWER, { BF, FRA, FRB } },
-
-{ "mtfsb1", XRC(63,38,0), XRARB_MASK, PPC|POWER, { BT } },
-{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, PPC|POWER, { BT } },
-
-{ "fneg", XRC(63,40,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
-{ "fneg.", XRC(63,40,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
-
-{ "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
-
-{ "mtfsb0", XRC(63,70,0), XRARB_MASK, PPC|POWER, { BT } },
-{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, PPC|POWER, { BT } },
-
-{ "fmr", XRC(63,72,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
-{ "fmr.", XRC(63,72,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
-
-{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
-{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
-
-{ "fnabs", XRC(63,136,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
-{ "fnabs.", XRC(63,136,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
-
-{ "fabs", XRC(63,264,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
-{ "fabs.", XRC(63,264,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
-
-{ "mffs", XRC(63,583,0), XRARB_MASK, PPC|POWER, { FRT } },
-{ "mffs.", XRC(63,583,1), XRARB_MASK, PPC|POWER, { FRT } },
-
-{ "mtfsf", XFL(63,711,0), XFL_MASK, PPC|POWER, { FLM, FRB } },
-{ "mtfsf.", XFL(63,711,1), XFL_MASK, PPC|POWER, { FLM, FRB } },
-
-{ "fctid", XRC(63,814,0), XRA_MASK, PPC|B64, { FRT, FRB } },
-{ "fctid.", XRC(63,814,1), XRA_MASK, PPC|B64, { FRT, FRB } },
-
-{ "fctidz", XRC(63,815,0), XRA_MASK, PPC|B64, { FRT, FRB } },
-{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC|B64, { FRT, FRB } },
-
-{ "fcfid", XRC(63,846,0), XRA_MASK, PPC|B64, { FRT, FRB } },
-{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC|B64, { FRT, FRB } },
-
-};
-
-const int powerpc_num_opcodes =
- sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
-
-/* The macro table. This is only used by the assembler. */
-
-const struct powerpc_macro powerpc_macros[] = {
-{ "extldi", 4, PPC|B64, "rldicr %0,%1,%3,(%2)-1" },
-{ "extldi.", 4, PPC|B64, "rldicr. %0,%1,%3,(%2)-1" },
-{ "extrdi", 4, PPC|B64, "rldicl %0,%1,(%2)+(%3),64-(%2)" },
-{ "extrdi.", 4, PPC|B64, "rldicl. %0,%1,(%2)+(%3),64-(%2)" },
-{ "insrdi", 4, PPC|B64, "rldimi %0,%1,64-((%2)+(%3)),%3" },
-{ "insrdi.", 4, PPC|B64, "rldimi. %0,%1,64-((%2)+(%3)),%3" },
-{ "rotrdi", 3, PPC|B64, "rldicl %0,%1,64-(%2),0" },
-{ "rotrdi.", 3, PPC|B64, "rldicl. %0,%1,64-(%2),0" },
-{ "sldi", 3, PPC|B64, "rldicr %0,%1,%2,63-(%2)" },
-{ "sldi.", 3, PPC|B64, "rldicr. %0,%1,%2,63-(%2)" },
-{ "srdi", 3, PPC|B64, "rldicl %0,%1,64-(%2),%2" },
-{ "srdi.", 3, PPC|B64, "rldicl. %0,%1,64-(%2),%2" },
-{ "clrrdi", 3, PPC|B64, "rldicr %0,%1,0,63-(%2)" },
-{ "clrrdi.", 3, PPC|B64, "rldicr. %0,%1,0,63-(%2)" },
-{ "clrlsldi",4, PPC|B64, "rldic %0,%1,%3,(%2)-(%3)" },
-{ "clrlsldi.",4, PPC|B64, "rldic. %0,%1,%3,(%2)-(%3)" },
-
-{ "extlwi", 4, PPC, "rlwinm %0,%1,%3,0,(%2)-1" },
-{ "extlwi.", 4, PPC, "rlwinm. %0,%1,%3,0,(%2)-1" },
-{ "extrwi", 4, PPC, "rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
-{ "extrwi.", 4, PPC, "rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
-{ "inslwi", 4, PPC, "rlwimi %0,%1,32-(%3),%3,(%2)+(%3)-1" },
-{ "inslwi.", 4, PPC, "rlwimi. %0,%1,32-(%3),%3,(%2)+(%3)-1" },
-{ "insrwi", 4, PPC, "rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
-{ "insrwi.", 4, PPC, "rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
-{ "rotrwi", 3, PPC, "rlwinm %0,%1,32-(%2),0,31" },
-{ "rotrwi.", 3, PPC, "rlwinm. %0,%1,32-(%2),0,31" },
-{ "slwi", 3, PPC, "rlwinm %0,%1,%2,0,31-(%2)" },
-{ "sli", 3, POWER, "rlinm %0,%1,%2,0,31-(%2)" },
-{ "slwi.", 3, PPC, "rlwinm. %0,%1,%2,0,31-(%2)" },
-{ "sli.", 3, POWER, "rlinm. %0,%1,%2,0,31-(%2)" },
-{ "srwi", 3, PPC, "rlwinm %0,%1,32-(%2),%2,31" },
-{ "sri", 3, POWER, "rlinm %0,%1,32-(%2),%2,31" },
-{ "srwi.", 3, PPC, "rlwinm. %0,%1,32-(%2),%2,31" },
-{ "sri.", 3, POWER, "rlinm. %0,%1,32-(%2),%2,31" },
-{ "clrrwi", 3, PPC, "rlwinm %0,%1,0,0,31-(%2)" },
-{ "clrrwi.", 3, PPC, "rlwinm. %0,%1,0,0,31-(%2)" },
-{ "clrlslwi",4, PPC, "rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
-{ "clrlslwi.",4, PPC, "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
-
-};
-
-const int powerpc_num_macros =
- sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
-
-static int
-print_insn_powerpc (disassemble_info *info, uint32_t insn, unsigned memaddr,
- int dialect);
-
-/* Print a big endian PowerPC instruction. For convenience, also
- disassemble instructions supported by the Motorola PowerPC 601. */
-
-int print_insn_ppc (bfd_vma pc, disassemble_info *info)
-{
- uint32_t opc;
- bfd_byte buf[4];
-
- (*info->read_memory_func)(pc, buf, 4, info);
- if (info->endian == BFD_ENDIAN_BIG)
- opc = bfd_getb32(buf);
- else
- opc = bfd_getl32(buf);
- if (info->mach == bfd_mach_ppc64) {
- return print_insn_powerpc (info, opc, pc,
- PPC | B64);
- } else {
- return print_insn_powerpc (info, opc, pc,
- PPC | B32 | M601);
- }
-}
-
-/* Print a PowerPC or POWER instruction. */
-
-static int
-print_insn_powerpc (disassemble_info *info, uint32_t insn, unsigned memaddr,
- int dialect)
-{
- const struct powerpc_opcode *opcode;
- const struct powerpc_opcode *opcode_end;
- uint32_t op;
-
- /* Get the major opcode of the instruction. */
- op = PPC_OP (insn);
-
- /* Find the first match in the opcode table. We could speed this up
- a bit by doing a binary search on the major opcode. */
- opcode_end = powerpc_opcodes + powerpc_num_opcodes;
- for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
- {
- uint32_t table_op;
- const unsigned char *opindex;
- const struct powerpc_operand *operand;
- int invalid;
- int need_comma;
- int need_paren;
-
- table_op = PPC_OP (opcode->opcode);
- if (op < table_op)
- break;
- if (op > table_op)
- continue;
-
- if ((insn & opcode->mask) != opcode->opcode
- || (opcode->flags & dialect) == 0)
- continue;
-
- /* Make two passes over the operands. First see if any of them
- have extraction functions, and, if they do, make sure the
- instruction is valid. */
- invalid = 0;
- for (opindex = opcode->operands; *opindex != 0; opindex++)
- {
- operand = powerpc_operands + *opindex;
- if (operand->extract)
- (*operand->extract) (insn, &invalid);
- }
- if (invalid)
- continue;
-
- /* The instruction is valid. */
- (*info->fprintf_func)(info->stream, "%s", opcode->name);
- if (opcode->operands[0] != 0)
- (*info->fprintf_func)(info->stream, "\t");
-
- /* Now extract and print the operands. */
- need_comma = 0;
- need_paren = 0;
- for (opindex = opcode->operands; *opindex != 0; opindex++)
- {
- int32_t value;
-
- operand = powerpc_operands + *opindex;
-
- /* Operands that are marked FAKE are simply ignored. We
- already made sure that the extract function considered
- the instruction to be valid. */
- if ((operand->flags & PPC_OPERAND_FAKE) != 0)
- continue;
-
- /* Extract the value from the instruction. */
- if (operand->extract)
- value = (*operand->extract) (insn, (int *) 0);
- else
- {
- value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
- if ((operand->flags & PPC_OPERAND_SIGNED) != 0
- && (value & (1 << (operand->bits - 1))) != 0)
- value -= 1 << operand->bits;
- }
-
- /* If the operand is optional, and the value is zero, don't
- print anything. */
- if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
- && (operand->flags & PPC_OPERAND_NEXT) == 0
- && value == 0)
- continue;
-
- if (need_comma)
- {
- (*info->fprintf_func)(info->stream, ",");
- need_comma = 0;
- }
-
- /* Print the operand as directed by the flags. */
- if ((operand->flags & PPC_OPERAND_GPR) != 0)
- (*info->fprintf_func)(info->stream, "r%d", value);
- else if ((operand->flags & PPC_OPERAND_FPR) != 0)
- (*info->fprintf_func)(info->stream, "f%d", value);
- else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
- (*info->fprintf_func)(info->stream, "%08X", memaddr + value);
- else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
- (*info->fprintf_func)(info->stream, "%08X", value & 0xffffffff);
- else if ((operand->flags & PPC_OPERAND_CR) == 0
- || (dialect & PPC_OPCODE_PPC) == 0)
- (*info->fprintf_func)(info->stream, "%d", value);
- else
- {
- if (operand->bits == 3)
- (*info->fprintf_func)(info->stream, "cr%d", value);
- else
- {
- static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
- int cr;
- int cc;
-
- cr = value >> 2;
- if (cr != 0)
- (*info->fprintf_func)(info->stream, "4*cr%d", cr);
- cc = value & 3;
- if (cc != 0)
- {
- if (cr != 0)
- (*info->fprintf_func)(info->stream, "+");
- (*info->fprintf_func)(info->stream, "%s", cbnames[cc]);
- }
- }
- }
-
- if (need_paren)
- {
- (*info->fprintf_func)(info->stream, ")");
- need_paren = 0;
- }
-
- if ((operand->flags & PPC_OPERAND_PARENS) == 0)
- need_comma = 1;
- else
- {
- (*info->fprintf_func)(info->stream, "(");
- need_paren = 1;
- }
- }
-
- /* We have found and printed an instruction; return. */
- return 4;
- }
-
- /* We could not find a match. */
- (*info->fprintf_func)(info->stream, ".long 0x%x", insn);
-
- return 4;
-}
diff --git a/ppc.ld b/ppc.ld
deleted file mode 100644
index 1e6bbe9..0000000
--- a/ppc.ld
+++ /dev/null
@@ -1,228 +0,0 @@
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
-OUTPUT_ARCH(powerpc:common)
-SEARCH_DIR(/usr/powerpc-linux-gnu/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib)
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
- .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) }
- .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) }
- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rela.got1 : { *(.rela.got1) }
- .rela.got2 : { *(.rela.got2) }
- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- KEEP (*(.text.*personality*))
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.glink)
- } =0x47ff041f
- .fini :
- {
- KEEP (*(.fini))
- } =0x47ff041f
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .sdata2 :
- {
- PROVIDE (_SDA2_BASE_ = 32768);
- *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
- }
- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000);
- /* Exception handling */
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
- /* Thread Local Storage sections */
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- }
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- PROVIDE_HIDDEN (__init_array_end = .);
- }
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- PROVIDE_HIDDEN (__fini_array_end = .);
- }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin*.o(.ctors))
- /* We don't want to include the .ctor section from
- the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin*.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
- .got1 : { *(.got1) }
- .got2 : { *(.got2) }
- .dynamic : { *(.dynamic) }
- .got : SPECIAL { *(.got) }
- . = DATA_SEGMENT_RELRO_END (0, .);
- .plt : SPECIAL { *(.plt) }
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- KEEP (*(.gnu.linkonce.d.*personality*))
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .got : SPECIAL { *(.got) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata :
- {
- PROVIDE (_SDA_BASE_ = 32768);
- *(.sdata .sdata.* .gnu.linkonce.s.*)
- }
- _edata = .; PROVIDE (edata = .);
- __bss_start = .;
- .sbss :
- {
- PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);
- *(.dynsbss)
- *(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
- PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);
- }
- .plt : SPECIAL { *(.plt) }
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections.
- FIXME: Why do we need it? When there is no .bss section, we don't
- pad the .data section. */
- . = ALIGN(. != 0 ? 32 / 8 : 1);
- }
- . = ALIGN(32 / 8);
- . = ALIGN(32 / 8);
- _end = .; PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
- /DISCARD/ : { *(.fixup) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/proxy/proxy_common.c b/proxy/proxy_common.c
deleted file mode 100644
index 7794a62..0000000
--- a/proxy/proxy_common.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "proxy_int.h"
-#include "sockets.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include "android/utils/misc.h"
-#include "android/utils/system.h"
-#include <stdlib.h>
-
-int proxy_log = 0;
-
-void
-proxy_LOG(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- fprintf(stderr, "\n");
-}
-
-void
-proxy_set_verbose(int mode)
-{
- proxy_log = mode;
-}
-
-/** Global connection list
- **/
-
-static ProxyConnection s_connections[1];
-
-#define MAX_HEX_DUMP 512
-
-static void
-hex_dump( void* base, int size, const char* prefix )
-{
- STRALLOC_DEFINE(s);
- if (size > MAX_HEX_DUMP)
- size = MAX_HEX_DUMP;
- stralloc_add_hexdump(s, base, size, prefix);
- proxy_LOG( "%s", stralloc_cstr(s) );
- stralloc_reset(s);
-}
-
-void
-proxy_connection_init( ProxyConnection* conn,
- int socket,
- SockAddress* address,
- ProxyService* service,
- ProxyConnectionFreeFunc conn_free,
- ProxyConnectionSelectFunc conn_select,
- ProxyConnectionPollFunc conn_poll )
-{
- conn->socket = socket;
- conn->address = address[0];
- conn->service = service;
- conn->next = NULL;
-
- conn->conn_free = conn_free;
- conn->conn_select = conn_select;
- conn->conn_poll = conn_poll;
-
- socket_set_nonblock(socket);
-
- {
- SocketType type = socket_get_type(socket);
-
- snprintf( conn->name, sizeof(conn->name),
- "%s:%s(%d)",
- (type == SOCKET_STREAM) ? "tcp" : "udp",
- sock_address_to_string(address), socket );
-
- /* just in case */
- conn->name[sizeof(conn->name)-1] = 0;
- }
-
- stralloc_reset(conn->str);
- conn->str_pos = 0;
-}
-
-void
-proxy_connection_done( ProxyConnection* conn )
-{
- stralloc_reset( conn->str );
- if (conn->socket >= 0) {
- socket_close(conn->socket);
- conn->socket = -1;
- }
-}
-
-
-void
-proxy_connection_rewind( ProxyConnection* conn )
-{
- stralloc_t* str = conn->str;
-
- /* only keep a small buffer in the heap */
- conn->str_pos = 0;
- str->n = 0;
- if (str->a > 1024)
- stralloc_reset(str);
-}
-
-DataStatus
-proxy_connection_send( ProxyConnection* conn, int fd )
-{
- stralloc_t* str = conn->str;
- int avail = str->n - conn->str_pos;
-
- conn->str_sent = 0;
-
- if (avail <= 0)
- return 1;
-
- if (proxy_log) {
- PROXY_LOG("%s: sending %d bytes:", conn->name, avail );
- hex_dump( str->s + conn->str_pos, avail, ">> " );
- }
-
- while (avail > 0) {
- int n = socket_send(fd, str->s + conn->str_pos, avail);
- if (n == 0) {
- PROXY_LOG("%s: connection reset by peer (send)",
- conn->name);
- return DATA_ERROR;
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- return DATA_NEED_MORE;
-
- PROXY_LOG("%s: error: %s", conn->name, errno_str);
- return DATA_ERROR;
- }
- conn->str_pos += n;
- conn->str_sent += n;
- avail -= n;
- }
-
- proxy_connection_rewind(conn);
- return DATA_COMPLETED;
-}
-
-
-DataStatus
-proxy_connection_receive( ProxyConnection* conn, int fd, int wanted )
-{
- stralloc_t* str = conn->str;
-
- conn->str_recv = 0;
-
- while (wanted > 0) {
- int n;
-
- stralloc_readyplus( str, wanted );
- n = socket_recv(fd, str->s + str->n, wanted);
- if (n == 0) {
- PROXY_LOG("%s: connection reset by peer (receive)",
- conn->name);
- return DATA_ERROR;
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- return DATA_NEED_MORE;
-
- PROXY_LOG("%s: error: %s", conn->name, errno_str);
- return DATA_ERROR;
- }
-
- if (proxy_log) {
- PROXY_LOG("%s: received %d bytes:", conn->name, n );
- hex_dump( str->s + str->n, n, "<< " );
- }
-
- str->n += n;
- wanted -= n;
- conn->str_recv += n;
- }
- return DATA_COMPLETED;
-}
-
-
-DataStatus
-proxy_connection_receive_line( ProxyConnection* conn, int fd )
-{
- stralloc_t* str = conn->str;
-
- for (;;) {
- char c;
- int n = socket_recv(fd, &c, 1);
- if (n == 0) {
- PROXY_LOG("%s: disconnected from server", conn->name );
- return DATA_ERROR;
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK || errno == EAGAIN) {
- PROXY_LOG("%s: blocked", conn->name);
- return DATA_NEED_MORE;
- }
- PROXY_LOG("%s: error: %s", conn->name, errno_str);
- return DATA_ERROR;
- }
-
- stralloc_add_c(str, c);
- if (c == '\n') {
- str->s[--str->n] = 0;
- if (str->n > 0 && str->s[str->n-1] == '\r')
- str->s[--str->n] = 0;
-
- PROXY_LOG("%s: received '%s'", conn->name,
- quote_bytes(str->s, str->n));
- return DATA_COMPLETED;
- }
- }
-}
-
-static void
-proxy_connection_insert( ProxyConnection* conn, ProxyConnection* after )
-{
- conn->next = after->next;
- after->next->prev = conn;
- after->next = conn;
- conn->prev = after;
-}
-
-static void
-proxy_connection_remove( ProxyConnection* conn )
-{
- conn->prev->next = conn->next;
- conn->next->prev = conn->prev;
-
- conn->next = conn->prev = conn;
-}
-
-/** Global service list
- **/
-
-#define MAX_SERVICES 4
-
-static ProxyService* s_services[ MAX_SERVICES ];
-static int s_num_services;
-static int s_init;
-
-static void proxy_manager_atexit( void );
-
-static void
-proxy_manager_init(void)
-{
- s_init = 1;
- s_connections->next = s_connections;
- s_connections->prev = s_connections;
- atexit( proxy_manager_atexit );
-}
-
-
-extern int
-proxy_manager_add_service( ProxyService* service )
-{
- if (!service || s_num_services >= MAX_SERVICES)
- return -1;
-
- if (!s_init)
- proxy_manager_init();
-
- s_services[s_num_services++] = service;
- return 0;
-}
-
-
-extern void
-proxy_manager_atexit( void )
-{
- ProxyConnection* conn = s_connections->next;
- int n;
-
- /* free all proxy connections */
- while (conn != s_connections) {
- ProxyConnection* next = conn->next;
- conn->conn_free( conn );
- conn = next;
- }
- conn->next = conn;
- conn->prev = conn;
-
- /* free all proxy services */
- for (n = s_num_services; n-- > 0;) {
- ProxyService* service = s_services[n];
- service->serv_free( service->opaque );
- }
- s_num_services = 0;
-}
-
-
-void
-proxy_connection_free( ProxyConnection* conn,
- int keep_alive,
- ProxyEvent event )
-{
- if (conn) {
- int fd = conn->socket;
-
- proxy_connection_remove(conn);
-
- if (event != PROXY_EVENT_NONE)
- conn->ev_func( conn->ev_opaque, fd, event );
-
- if (keep_alive)
- conn->socket = -1;
-
- conn->conn_free(conn);
- }
-}
-
-
-int
-proxy_manager_add( SockAddress* address,
- SocketType sock_type,
- ProxyEventFunc ev_func,
- void* ev_opaque )
-{
- int n;
-
- if (!s_init) {
- proxy_manager_init();
- }
-
- for (n = 0; n < s_num_services; n++) {
- ProxyService* service = s_services[n];
- ProxyConnection* conn = service->serv_connect( service->opaque,
- sock_type,
- address );
- if (conn != NULL) {
- conn->ev_func = ev_func;
- conn->ev_opaque = ev_opaque;
- proxy_connection_insert(conn, s_connections->prev);
- return 0;
- }
- }
- return -1;
-}
-
-
-/* remove an on-going proxified socket connection from the manager's list.
- * this is only necessary when the socket connection must be canceled before
- * the connection accept/refusal occured
- */
-void
-proxy_manager_del( void* ev_opaque )
-{
- ProxyConnection* conn = s_connections->next;
- for ( ; conn != s_connections; conn = conn->next ) {
- if (conn->ev_opaque == ev_opaque) {
- proxy_connection_remove(conn);
- conn->conn_free(conn);
- return;
- }
- }
-}
-
-void
-proxy_select_set( ProxySelect* sel,
- int fd,
- unsigned flags )
-{
- if (fd < 0 || !flags)
- return;
-
- if (*sel->pcount < fd+1)
- *sel->pcount = fd+1;
-
- if (flags & PROXY_SELECT_READ) {
- FD_SET( fd, sel->reads );
- } else {
- FD_CLR( fd, sel->reads );
- }
- if (flags & PROXY_SELECT_WRITE) {
- FD_SET( fd, sel->writes );
- } else {
- FD_CLR( fd, sel->writes );
- }
- if (flags & PROXY_SELECT_ERROR) {
- FD_SET( fd, sel->errors );
- } else {
- FD_CLR( fd, sel->errors );
- }
-}
-
-unsigned
-proxy_select_poll( ProxySelect* sel, int fd )
-{
- unsigned flags = 0;
-
- if (fd >= 0) {
- if ( FD_ISSET(fd, sel->reads) )
- flags |= PROXY_SELECT_READ;
- if ( FD_ISSET(fd, sel->writes) )
- flags |= PROXY_SELECT_WRITE;
- if ( FD_ISSET(fd, sel->errors) )
- flags |= PROXY_SELECT_ERROR;
- }
- return flags;
-}
-
-/* this function is called to update the select file descriptor sets
- * with those of the proxified connection sockets that are currently managed */
-void
-proxy_manager_select_fill( int *pcount, fd_set* read_fds, fd_set* write_fds, fd_set* err_fds)
-{
- ProxyConnection* conn;
- ProxySelect sel[1];
-
- if (!s_init)
- proxy_manager_init();
-
- sel->pcount = pcount;
- sel->reads = read_fds;
- sel->writes = write_fds;
- sel->errors = err_fds;
-
- conn = s_connections->next;
- while (conn != s_connections) {
- ProxyConnection* next = conn->next;
- conn->conn_select(conn, sel);
- conn = next;
- }
-}
-
-/* this function is called to act on proxified connection sockets when network events arrive */
-void
-proxy_manager_poll( fd_set* read_fds, fd_set* write_fds, fd_set* err_fds )
-{
- ProxyConnection* conn = s_connections->next;
- ProxySelect sel[1];
-
- sel->pcount = NULL;
- sel->reads = read_fds;
- sel->writes = write_fds;
- sel->errors = err_fds;
-
- while (conn != s_connections) {
- ProxyConnection* next = conn->next;
- conn->conn_poll( conn, sel );
- conn = next;
- }
-}
-
-
-int
-proxy_base64_encode( const char* src, int srclen,
- char* dst, int dstlen )
-{
- static const char cb64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- const char* srcend = src + srclen;
- int result = 0;
-
- while (src+3 <= srcend && result+4 <= dstlen)
- {
- dst[result+0] = cb64[ src[0] >> 2 ];
- dst[result+1] = cb64[ ((src[0] & 3) << 4) | ((src[1] & 0xf0) >> 4) ];
- dst[result+2] = cb64[ ((src[1] & 0xf) << 2) | ((src[2] & 0xc0) >> 6) ];
- dst[result+3] = cb64[ src[2] & 0x3f ];
- src += 3;
- result += 4;
- }
-
- if (src < srcend) {
- unsigned char in[4];
-
- if (result+4 > dstlen)
- return -1;
-
- in[0] = src[0];
- in[1] = src+1 < srcend ? src[1] : 0;
- in[2] = src+2 < srcend ? src[2] : 0;
-
- dst[result+0] = cb64[ in[0] >> 2 ];
- dst[result+1] = cb64[ ((in[0] & 3) << 4) | ((in[1] & 0xf0) >> 4) ];
- dst[result+2] = (unsigned char) (src+1 < srcend ? cb64[ ((in[1] & 0xf) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
- dst[result+3] = (unsigned char) (src+2 < srcend ? cb64[ in[2] & 0x3f ] : '=');
- result += 4;
- }
- return result;
-}
-
-int
-proxy_resolve_server( SockAddress* addr,
- const char* servername,
- int servernamelen,
- int serverport )
-{
- char name0[64], *name = name0;
- int result = -1;
-
- if (servernamelen < 0)
- servernamelen = strlen(servername);
-
- if (servernamelen >= sizeof(name0)) {
- AARRAY_NEW(name, servernamelen+1);
- }
-
- memcpy(name, servername, servernamelen);
- name[servernamelen] = 0;
-
- if (sock_address_init_resolve( addr, name, serverport, 0 ) < 0) {
- PROXY_LOG("%s: can't resolve proxy server name '%s'",
- __FUNCTION__, name);
- goto Exit;
- }
-
- PROXY_LOG("server name '%s' resolved to %s", name, sock_address_to_string(addr));
- result = 0;
-
-Exit:
- if (name != name0)
- AFREE(name);
-
- return result;
-}
-
-
diff --git a/proxy/proxy_common.h b/proxy/proxy_common.h
deleted file mode 100644
index 78eddd8..0000000
--- a/proxy/proxy_common.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _PROXY_COMMON_H_
-#define _PROXY_COMMON_H_
-
-#include "sockets.h"
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <sys/select.h>
-#endif
-
-/* types and definitions used by all proxy connections */
-
-typedef enum {
- PROXY_EVENT_NONE,
- PROXY_EVENT_CONNECTED,
- PROXY_EVENT_CONNECTION_REFUSED,
- PROXY_EVENT_SERVER_ERROR
-} ProxyEvent;
-
-/* event can't be NONE when this callback is called */
-typedef void (*ProxyEventFunc)( void* opaque, int fd, ProxyEvent event );
-
-extern void proxy_set_verbose(int mode);
-
-
-typedef enum {
- PROXY_OPTION_AUTH_USERNAME = 1,
- PROXY_OPTION_AUTH_PASSWORD,
-
- PROXY_OPTION_HTTP_NOCACHE = 100,
- PROXY_OPTION_HTTP_KEEPALIVE,
- PROXY_OPTION_HTTP_USER_AGENT,
-
- PROXY_OPTION_MAX
-
-} ProxyOptionType;
-
-
-typedef struct {
- ProxyOptionType type;
- const char* string;
- int string_len;
-} ProxyOption;
-
-
-/* add a new proxified socket connection to the manager's list. the event function
- * will be called when the connection is established or refused.
- *
- * only IPv4 is supported at the moment, since our slirp code cannot handle IPv6
- *
- * returns 0 on success, or -1 if there is no proxy service for this type of connection
- */
-extern int proxy_manager_add( SockAddress* address,
- SocketType sock_type,
- ProxyEventFunc ev_func,
- void* ev_opaque );
-
-/* remove an on-going proxified socket connection from the manager's list.
- * this is only necessary when the socket connection must be canceled before
- * the connection accept/refusal occured
- */
-extern void proxy_manager_del( void* ev_opaque );
-
-/* this function is called to update the select file descriptor sets
- * with those of the proxified connection sockets that are currently managed */
-extern void proxy_manager_select_fill( int *pcount,
- fd_set* read_fds,
- fd_set* write_fds,
- fd_set* err_fds);
-
-/* this function is called to act on proxified connection sockets when network events arrive */
-extern void proxy_manager_poll( fd_set* read_fds,
- fd_set* write_fds,
- fd_set* err_fds );
-
-#endif /* END */
diff --git a/proxy/proxy_http.c b/proxy/proxy_http.c
deleted file mode 100644
index f753587..0000000
--- a/proxy/proxy_http.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "proxy_int.h"
-#include "proxy_http_int.h"
-#include "qemu-common.h"
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#define HTTP_VERSION "1.1"
-
-static void
-http_service_free( HttpService* service )
-{
- PROXY_LOG("%s", __FUNCTION__);
- if (service->footer != service->footer0)
- qemu_free(service->footer);
- qemu_free(service);
-}
-
-
-static ProxyConnection*
-http_service_connect( HttpService* service,
- SocketType sock_type,
- SockAddress* address )
-{
- /* the HTTP proxy can only handle TCP connections */
- if (sock_type != SOCKET_STREAM)
- return NULL;
-
- /* if the client tries to directly connect to the proxy, let it do so */
- if (sock_address_equal( address, &service->server_addr ))
- return NULL;
-
- PROXY_LOG("%s: trying to connect to %s",
- __FUNCTION__, sock_address_to_string(address));
-
- if (sock_address_get_port(address) == 80) {
- /* use the rewriter for HTTP */
- PROXY_LOG("%s: using HTTP rewriter", __FUNCTION__);
- return http_rewriter_connect(service, address);
- } else {
- PROXY_LOG("%s: using HTTP rewriter", __FUNCTION__);
- return http_connector_connect(service, address);
- }
-}
-
-
-int
-proxy_http_setup( const char* servername,
- int servernamelen,
- int serverport,
- int num_options,
- const ProxyOption* options )
-{
- HttpService* service;
- SockAddress server_addr;
- const ProxyOption* opt_nocache = NULL;
- const ProxyOption* opt_keepalive = NULL;
- const ProxyOption* opt_auth_user = NULL;
- const ProxyOption* opt_auth_pass = NULL;
- const ProxyOption* opt_user_agent = NULL;
-
- if (servernamelen < 0)
- servernamelen = strlen(servername);
-
- PROXY_LOG( "%s: creating http proxy service connecting to: %.*s:%d",
- __FUNCTION__, servernamelen, servername, serverport );
-
- /* resolve server address */
- if (proxy_resolve_server(&server_addr, servername,
- servernamelen, serverport) < 0)
- {
- return -1;
- }
-
- /* create service object */
- service = qemu_mallocz(sizeof(*service));
- if (service == NULL) {
- PROXY_LOG("%s: not enough memory to allocate new proxy service", __FUNCTION__);
- return -1;
- }
-
- service->server_addr = server_addr;
-
- /* parse options */
- {
- const ProxyOption* opt = options;
- const ProxyOption* end = opt + num_options;
-
- for ( ; opt < end; opt++ ) {
- switch (opt->type) {
- case PROXY_OPTION_HTTP_NOCACHE: opt_nocache = opt; break;
- case PROXY_OPTION_HTTP_KEEPALIVE: opt_keepalive = opt; break;
- case PROXY_OPTION_AUTH_USERNAME: opt_auth_user = opt; break;
- case PROXY_OPTION_AUTH_PASSWORD: opt_auth_pass = opt; break;
- case PROXY_OPTION_HTTP_USER_AGENT: opt_user_agent = opt; break;
- default: ;
- }
- }
- }
-
- /* prepare footer */
- {
- int wlen;
- char* p = service->footer0;
- char* end = p + sizeof(service->footer0);
-
- /* no-cache */
- if (opt_nocache) {
- p += snprintf(p, end-p, "Pragma: no-cache\r\nCache-Control: no-cache\r\n");
- if (p >= end) goto FooterOverflow;
- }
- /* keep-alive */
- if (opt_keepalive) {
- p += snprintf(p, end-p, "Connection: Keep-Alive\r\nProxy-Connection: Keep-Alive\r\n");
- if (p >= end) goto FooterOverflow;
- }
- /* authentication */
- if (opt_auth_user && opt_auth_pass) {
- char user_pass[256];
- char encoded[512];
- int uplen;
-
- uplen = snprintf( user_pass, sizeof(user_pass), "%.*s:%.*s",
- opt_auth_user->string_len, opt_auth_user->string,
- opt_auth_pass->string_len, opt_auth_pass->string );
-
- if (uplen >= sizeof(user_pass)) goto FooterOverflow;
-
- wlen = proxy_base64_encode(user_pass, uplen, encoded, (int)sizeof(encoded));
- if (wlen < 0) {
- PROXY_LOG( "could not base64 encode '%.*s'", uplen, user_pass);
- goto FooterOverflow;
- }
-
- p += snprintf(p, end-p, "Proxy-authorization: Basic %.*s\r\n", wlen, encoded);
- if (p >= end) goto FooterOverflow;
- }
- /* user agent */
- if (opt_user_agent) {
- p += snprintf(p, end-p, "User-Agent: %.*s\r\n",
- opt_user_agent->string_len,
- opt_user_agent->string);
- if (p >= end) goto FooterOverflow;
- }
-
- p += snprintf(p, end-p, "\r\n");
-
- if (p >= end) {
- FooterOverflow:
- PROXY_LOG( "%s: buffer overflow when creating connection footer",
- __FUNCTION__);
- http_service_free(service);
- return -1;
- }
-
- service->footer = service->footer0;
- service->footer_len = (p - service->footer);
- }
-
- PROXY_LOG( "%s: creating HTTP Proxy Service Footer is (len=%d):\n'%.*s'",
- __FUNCTION__, service->footer_len,
- service->footer_len, service->footer );
-
- service->root->opaque = service;
- service->root->serv_free = (ProxyServiceFreeFunc) http_service_free;
- service->root->serv_connect = (ProxyServiceConnectFunc) http_service_connect;
-
- if (proxy_manager_add_service( service->root ) < 0) {
- PROXY_LOG("%s: could not register service ?", __FUNCTION__);
- http_service_free(service);
- return -1;
- }
- return 0;
-}
-
diff --git a/proxy/proxy_http.h b/proxy/proxy_http.h
deleted file mode 100644
index a2e2917..0000000
--- a/proxy/proxy_http.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _PROXY_HTTP_H
-#define _PROXY_HTTP_H
-
-#include "proxy_common.h"
-
-extern int
-proxy_http_setup( const char* servername,
- int servernamelen,
- int serverport,
- int num_options,
- const ProxyOption* options );
-
-#endif /* END */
diff --git a/proxy/proxy_http_connector.c b/proxy/proxy_http_connector.c
deleted file mode 100644
index 6f03d9b..0000000
--- a/proxy/proxy_http_connector.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "proxy_http_int.h"
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include "qemu-common.h"
-
-/* A HttpConnector implements a non-HTTP proxied connection
- * through the CONNECT method. Many firewalls are configured
- * to reject these for port 80, so these connections should
- * use a HttpRewriter instead.
- */
-
-typedef enum {
- STATE_NONE = 0,
- STATE_CONNECTING, /* connecting to the server */
- STATE_SEND_HEADER, /* connected, sending header to the server */
- STATE_RECEIVE_ANSWER_LINE1,
- STATE_RECEIVE_ANSWER_LINE2 /* connected, reading server's answer */
-} ConnectorState;
-
-typedef struct Connection {
- ProxyConnection root[1];
- ConnectorState state;
-} Connection;
-
-
-static void
-connection_free( ProxyConnection* root )
-{
- proxy_connection_done(root);
- qemu_free(root);
-}
-
-
-
-#define HTTP_VERSION "1.1"
-
-static int
-connection_init( Connection* conn )
-{
- HttpService* service = (HttpService*) conn->root->service;
- ProxyConnection* root = conn->root;
- stralloc_t* str = root->str;
-
- proxy_connection_rewind(root);
- stralloc_add_format(str, "CONNECT %s HTTP/" HTTP_VERSION "\r\n",
- sock_address_to_string(&root->address));
-
- stralloc_add_bytes(str, service->footer, service->footer_len);
-
- if (!socket_connect( root->socket, &service->server_addr )) {
- /* immediate connection ?? */
- conn->state = STATE_SEND_HEADER;
- PROXY_LOG("%s: immediate connection", root->name);
- }
- else {
- if (errno == EINPROGRESS || errno == EWOULDBLOCK) {
- conn->state = STATE_CONNECTING;
- PROXY_LOG("%s: connecting", root->name);
- }
- else {
- PROXY_LOG("%s: cannot connect to proxy: %s", root->name, errno_str);
- return -1;
- }
- }
- return 0;
-}
-
-
-static void
-connection_select( ProxyConnection* root,
- ProxySelect* sel )
-{
- unsigned flags;
- Connection* conn = (Connection*)root;
-
- switch (conn->state) {
- case STATE_RECEIVE_ANSWER_LINE1:
- case STATE_RECEIVE_ANSWER_LINE2:
- flags = PROXY_SELECT_READ;
- break;
-
- case STATE_CONNECTING:
- case STATE_SEND_HEADER:
- flags = PROXY_SELECT_WRITE;
- break;
-
- default:
- flags = 0;
- };
- proxy_select_set(sel, root->socket, flags);
-}
-
-static void
-connection_poll( ProxyConnection* root,
- ProxySelect* sel )
-{
- DataStatus ret = DATA_NEED_MORE;
- Connection* conn = (Connection*)root;
- int fd = root->socket;
-
- if (!proxy_select_poll(sel, fd))
- return;
-
- switch (conn->state)
- {
- case STATE_CONNECTING:
- PROXY_LOG("%s: connected to http proxy, sending header", root->name);
- conn->state = STATE_SEND_HEADER;
- break;
-
- case STATE_SEND_HEADER:
- ret = proxy_connection_send(root, fd);
- if (ret == DATA_COMPLETED) {
- conn->state = STATE_RECEIVE_ANSWER_LINE1;
- PROXY_LOG("%s: header sent, receiving first answer line", root->name);
- }
- break;
-
- case STATE_RECEIVE_ANSWER_LINE1:
- case STATE_RECEIVE_ANSWER_LINE2:
- ret = proxy_connection_receive_line(root, root->socket);
- if (ret == DATA_COMPLETED) {
- if (conn->state == STATE_RECEIVE_ANSWER_LINE1) {
- int http1, http2, codenum;
- const char* line = root->str->s;
-
- if ( sscanf(line, "HTTP/%d.%d %d", &http1, &http2, &codenum) != 3 ) {
- PROXY_LOG( "%s: invalid answer from proxy: '%s'",
- root->name, line );
- ret = DATA_ERROR;
- break;
- }
-
- /* success is 2xx */
- if (codenum/2 != 100) {
- PROXY_LOG( "%s: connection refused, error=%d",
- root->name, codenum );
- proxy_connection_free( root, 0, PROXY_EVENT_CONNECTION_REFUSED );
- return;
- }
- PROXY_LOG("%s: receiving second answer line", root->name);
- conn->state = STATE_RECEIVE_ANSWER_LINE2;
- proxy_connection_rewind(root);
- } else {
- /* ok, we're connected */
- PROXY_LOG("%s: connection succeeded", root->name);
- proxy_connection_free( root, 1, PROXY_EVENT_CONNECTED );
- }
- }
- break;
-
- default:
- PROXY_LOG("%s: invalid state for read event: %d", root->name, conn->state);
- }
-
- if (ret == DATA_ERROR) {
- proxy_connection_free( root, 0, PROXY_EVENT_SERVER_ERROR );
- }
-}
-
-
-
-ProxyConnection*
-http_connector_connect( HttpService* service,
- SockAddress* address )
-{
- Connection* conn;
- int s;
-
- s = socket_create_inet( SOCKET_STREAM );
- if (s < 0)
- return NULL;
-
- conn = qemu_mallocz(sizeof(*conn));
- if (conn == NULL) {
- socket_close(s);
- return NULL;
- }
-
- proxy_connection_init( conn->root, s, address, service->root,
- connection_free,
- connection_select,
- connection_poll );
-
- if ( connection_init( conn ) < 0 ) {
- connection_free( conn->root );
- return NULL;
- }
-
- return conn->root;
-}
diff --git a/proxy/proxy_http_int.h b/proxy/proxy_http_int.h
deleted file mode 100644
index 6daa9cb..0000000
--- a/proxy/proxy_http_int.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _PROXY_HTTP_INT_H
-#define _PROXY_HTTP_INT_H
-
-#include "proxy_http.h"
-#include "proxy_int.h"
-
-/* the HttpService object */
-typedef struct HttpService {
- ProxyService root[1];
- SockAddress server_addr; /* server address and port */
- char* footer; /* the footer contains the static parts of the */
- int footer_len; /* connection header, we generate it only once */
- char footer0[512];
-} HttpService;
-
-/* create a CONNECT connection (for port != 80) */
-extern ProxyConnection* http_connector_connect(
- HttpService* service,
- SockAddress* address );
-
-/* create a HTTP rewriting connection (for port == 80) */
-extern ProxyConnection* http_rewriter_connect(
- HttpService* service,
- SockAddress* address );
-
-
-#endif /* _PROXY_HTTP_INT_H */
diff --git a/proxy/proxy_http_rewriter.c b/proxy/proxy_http_rewriter.c
deleted file mode 100644
index 812bf9c..0000000
--- a/proxy/proxy_http_rewriter.c
+++ /dev/null
@@ -1,1125 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "proxy_http_int.h"
-#include <stdio.h>
-#include <string.h>
-#include "qemu-common.h"
-#include "android/utils/system.h" /* strsep */
-
-/* this implements a transparent HTTP rewriting proxy
- *
- * this is needed because the HTTP spec mandates that
- * any query made to a proxy uses an absolute URI as
- * in:
- *
- * GET http://www.example.com/index.html HTTP/1.1
- *
- * while the Android browser will think it's talking to
- * a normal web server and will issue a:
- *
- * GET /index.html HTTP/1.1
- * Host: www.example.com
- *
- * what we do here is thus the following:
- *
- * - read the request header
- * - rewrite the request's URI to use absolute URI
- * - send the rewritten header to the proxy
- * - then read the rest of the request, and tunnel it to the
- * proxy as well
- * - read the answer as-is and send it back to the system
- *
- * this sounds all easy, but the rules for computing the
- * sizes of HTTP Message Bodies makes the implementation
- * a *bit* funky.
- */
-
-/* define D_ACTIVE to 1 to dump additionnal debugging
- * info when -debug-proxy is used. These are only needed
- * when debugging the proxy code.
- */
-#define D_ACTIVE 1
-
-#if D_ACTIVE
-# define D(...) PROXY_LOG(__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-
-/** *************************************************************
- **
- ** HTTP HEADERS
- **
- **/
-
-typedef struct HttpHeader {
- struct HttpHeader* next;
- const char* key;
- const char* value;
-} HttpHeader;
-
-static void
-http_header_free( HttpHeader* h )
-{
- if (h) {
- qemu_free((char*)h->value);
- qemu_free(h);
- }
-}
-
-static int
-http_header_append( HttpHeader* h, const char* value )
-{
- int old = strlen(h->value);
- int new = strlen(value);
- char* s = realloc((char*)h->value, old+new+1);
- if (s == NULL)
- return -1;
- memcpy(s + old, value, new+1);
- h->value = (const char*)s;
- return 0;
-}
-
-static HttpHeader*
-http_header_alloc( const char* key, const char* value )
-{
- int len = strlen(key)+1;
- HttpHeader* h = malloc(sizeof(*h) + len+1);
- if (h) {
- h->next = NULL;
- h->key = (const char*)(h+1);
- memcpy( (char*)h->key, key, len );
- h->value = qemu_strdup(value);
- }
- return h;
-}
-
-typedef struct {
- HttpHeader* first;
- HttpHeader* last;
-} HttpHeaderList;
-
-static void
-http_header_list_init( HttpHeaderList* l )
-{
- l->first = l->last = NULL;
-}
-
-static void
-http_header_list_done( HttpHeaderList* l )
-{
- while (l->first) {
- HttpHeader* h = l->first;
- l->first = h->next;
- http_header_free(h);
- }
- l->last = NULL;
-}
-
-static void
-http_header_list_add( HttpHeaderList* l,
- HttpHeader* h )
-{
- if (!l->first) {
- l->first = h;
- } else {
- l->last->next = h;
- }
- h->next = NULL;
- l->last = h;
-}
-
-static const char*
-http_header_list_find( HttpHeaderList* l,
- const char* key )
-{
- HttpHeader* h;
- for (h = l->first; h; h = h->next)
- if (!strcasecmp(h->key, key))
- return h->value;
-
- return NULL;
-}
-
-/** *************************************************************
- **
- ** HTTP REQUEST AND REPLY
- **
- **/
-
-typedef enum {
- HTTP_REQUEST_UNSUPPORTED = 0,
- HTTP_REQUEST_GET,
- HTTP_REQUEST_HEAD,
- HTTP_REQUEST_POST,
- HTTP_REQUEST_PUT,
- HTTP_REQUEST_DELETE,
-} HttpRequestType;
-
-typedef struct {
- HttpRequestType req_type;
- char* req_method;
- char* req_uri;
- char* req_version;
- char* rep_version;
- int rep_code;
- char* rep_readable;
- HttpHeaderList headers[1];
-} HttpRequest;
-
-
-static HttpRequest*
-http_request_alloc( const char* method,
- const char* uri,
- const char* version )
-{
- HttpRequest* r = malloc(sizeof(*r));
-
- r->req_method = qemu_strdup(method);
- r->req_uri = qemu_strdup(uri);
- r->req_version = qemu_strdup(version);
- r->rep_version = NULL;
- r->rep_code = -1;
- r->rep_readable = NULL;
-
- if (!strcmp(method,"GET")) {
- r->req_type = HTTP_REQUEST_GET;
- } else if (!strcmp(method,"POST")) {
- r->req_type = HTTP_REQUEST_POST;
- } else if (!strcmp(method,"HEAD")) {
- r->req_type = HTTP_REQUEST_HEAD;
- } else if (!strcmp(method,"PUT")) {
- r->req_type = HTTP_REQUEST_PUT;
- } else if (!strcmp(method,"DELETE")) {
- r->req_type = HTTP_REQUEST_DELETE;
- } else
- r->req_type = HTTP_REQUEST_UNSUPPORTED;
-
- http_header_list_init(r->headers);
- return r;
-}
-
-static void
-http_request_replace_uri( HttpRequest* r,
- const char* uri )
-{
- const char* old = r->req_uri;
- r->req_uri = qemu_strdup(uri);
- qemu_free((char*)old);
-}
-
-static void
-http_request_free( HttpRequest* r )
-{
- if (r) {
- http_header_list_done(r->headers);
-
- qemu_free(r->req_method);
- qemu_free(r->req_uri);
- qemu_free(r->req_version);
- qemu_free(r->rep_version);
- qemu_free(r->rep_readable);
- qemu_free(r);
- }
-}
-
-static char*
-http_request_find_header( HttpRequest* r,
- const char* key )
-{
- return (char*)http_header_list_find(r->headers, key);
-}
-
-
-static int
-http_request_add_header( HttpRequest* r,
- const char* key,
- const char* value )
-{
- HttpHeader* h = http_header_alloc(key,value);
- if (h) {
- http_header_list_add(r->headers, h);
- return 0;
- }
- return -1;
-}
-
-static int
-http_request_add_to_last_header( HttpRequest* r,
- const char* line )
-{
- if (r->headers->last) {
- return http_header_append( r->headers->last, line );
- } else {
- return -1;
- }
-}
-
-static int
-http_request_set_reply( HttpRequest* r,
- const char* version,
- const char* code,
- const char* readable )
-{
- if (strcmp(version,"HTTP/1.0") && strcmp(version,"HTTP/1.1")) {
- PROXY_LOG("%s: bad reply protocol: %s", __FUNCTION__, version);
- return -1;
- }
- r->rep_code = atoi(code);
- if (r->rep_code == 0) {
- PROXY_LOG("%s: bad reply code: %d", __FUNCTION__, code);
- return -1;
- }
-
- r->rep_version = qemu_strdup(version);
- r->rep_readable = qemu_strdup(readable);
-
- /* reset the list of headers */
- http_header_list_done(r->headers);
- return 0;
-}
-
-/** *************************************************************
- **
- ** REWRITER CONNECTION
- **
- **/
-
-typedef enum {
- STATE_CONNECTING = 0,
- STATE_CREATE_SOCKET_PAIR,
- STATE_REQUEST_FIRST_LINE,
- STATE_REQUEST_HEADERS,
- STATE_REQUEST_SEND,
- STATE_REQUEST_BODY,
- STATE_REPLY_FIRST_LINE,
- STATE_REPLY_HEADERS,
- STATE_REPLY_SEND,
- STATE_REPLY_BODY,
-} ConnectionState;
-
-/* root->socket is connected to the proxy server. while
- * slirp_fd is connected to the slirp code through a
- * socket_pair() we created for this specific purpose.
- */
-
-typedef enum {
- BODY_NONE = 0,
- BODY_KNOWN_LENGTH,
- BODY_UNTIL_CLOSE,
- BODY_CHUNKED,
- BODY_MODE_MAX
-} BodyMode;
-
-static const char* const body_mode_str[BODY_MODE_MAX] = {
- "NONE", "KNOWN_LENGTH", "UNTIL_CLOSE", "CHUNKED"
-};
-
-typedef struct {
- ProxyConnection root[1];
- int slirp_fd;
- ConnectionState state;
- HttpRequest* request;
- BodyMode body_mode;
- int64_t body_length;
- int64_t body_total;
- int64_t body_sent;
- int64_t chunk_length;
- int64_t chunk_total;
- char body_has_data;
- char body_is_full;
- char body_is_closed;
- char parse_chunk_header;
- char parse_chunk_trailer;
-} RewriteConnection;
-
-
-static void
-rewrite_connection_free( ProxyConnection* root )
-{
- RewriteConnection* conn = (RewriteConnection*)root;
-
- if (conn->slirp_fd >= 0) {
- socket_close(conn->slirp_fd);
- conn->slirp_fd = -1;
- }
- http_request_free(conn->request);
- proxy_connection_done(root);
- qemu_free(conn);
-}
-
-
-static int
-rewrite_connection_init( RewriteConnection* conn )
-{
- HttpService* service = (HttpService*) conn->root->service;
- ProxyConnection* root = conn->root;
-
- conn->slirp_fd = -1;
- conn->state = STATE_CONNECTING;
-
- if (socket_connect( root->socket, &service->server_addr ) < 0) {
- if (errno == EINPROGRESS || errno == EWOULDBLOCK) {
- PROXY_LOG("%s: connecting", conn->root->name);
- }
- else {
- PROXY_LOG("%s: cannot connect to proxy: %s", root->name, errno_str);
- return -1;
- }
- }
- else {
- PROXY_LOG("%s: immediate connection", root->name);
- conn->state = STATE_CREATE_SOCKET_PAIR;
- }
- return 0;
-}
-
-static int
-rewrite_connection_create_sockets( RewriteConnection* conn )
-{
- /* immediate connection to the proxy. now create a socket
- * pair and send a 'success' event to slirp */
- int slirp_1;
- ProxyConnection* root = conn->root;
-
- if (socket_pair( &slirp_1, &conn->slirp_fd ) < 0) {
- PROXY_LOG("%s: coult not create socket pair: %s",
- root->name, errno_str);
- return -1;
- }
-
- root->ev_func( root->ev_opaque, slirp_1, PROXY_EVENT_CONNECTED );
- conn->state = STATE_REQUEST_FIRST_LINE;
- return 0;
-}
-
-
-/* read the first line of a given HTTP request. returns -1/0/+1 */
-static DataStatus
-rewrite_connection_read_request( RewriteConnection* conn )
-{
- ProxyConnection* root = conn->root;
- DataStatus ret;
-
- ret = proxy_connection_receive_line(root, conn->slirp_fd);
- if (ret == DATA_COMPLETED) {
- /* now parse the first line to see if we can handle it */
- char* line = root->str->s;
- char* method;
- char* uri;
- char* version;
- char* p = line;
-
- method = strsep(&p, " ");
- if (p == NULL) {
- PROXY_LOG("%s: can't parse method in '%'",
- root->name, line);
- return DATA_ERROR;
- }
- uri = strsep(&p, " ");
- if (p == NULL) {
- PROXY_LOG( "%s: can't parse URI in '%s'",
- root->name, line);
- return DATA_ERROR;
- }
- version = strsep(&p, " ");
- if (p != NULL) {
- PROXY_LOG( "%s: extra data after version in '%s'",
- root->name, line);
- return DATA_ERROR;
- }
- if (conn->request)
- http_request_free(conn->request);
-
- conn->request = http_request_alloc( method, uri, version );
- if (!conn->request)
- return DATA_ERROR;
-
- proxy_connection_rewind(root);
- }
- return ret;
-}
-
-
-static DataStatus
-rewrite_connection_read_reply( RewriteConnection* conn )
-{
- ProxyConnection* root = conn->root;
- DataStatus ret;
-
- ret = proxy_connection_receive_line( root, root->socket );
- if (ret == DATA_COMPLETED) {
- HttpRequest* request = conn->request;
-
- char* line = stralloc_cstr( root->str );
- char* p = line;
- char* protocol;
- char* number;
- char* readable;
-
- protocol = strsep(&p, " ");
- if (p == NULL) {
- PROXY_LOG("%s: can't parse response protocol: '%s'",
- root->name, line);
- return DATA_ERROR;
- }
- number = strsep(&p, " ");
- if (p == NULL) {
- PROXY_LOG("%s: can't parse response number: '%s'",
- root->name, line);
- return DATA_ERROR;
- }
- readable = p;
-
- if (http_request_set_reply(request, protocol, number, readable) < 0)
- return DATA_ERROR;
-
- proxy_connection_rewind(root);
- }
- return ret;
-}
-
-
-static DataStatus
-rewrite_connection_read_headers( RewriteConnection* conn,
- int fd )
-{
- int ret;
- ProxyConnection* root = conn->root;
-
- for (;;) {
- char* line;
- stralloc_t* str = root->str;
-
- ret = proxy_connection_receive_line(root, fd);
- if (ret != DATA_COMPLETED)
- break;
-
- str->n = 0;
- line = str->s;
-
- if (line[0] == 0) {
- /* an empty line means the end of headers */
- ret = 1;
- break;
- }
-
- /* it this a continuation ? */
- if (line[0] == ' ' || line[0] == '\t') {
- ret = http_request_add_to_last_header( conn->request, line );
- }
- else {
- char* key;
- char* value;
-
- value = line;
- key = strsep(&value, ":");
- if (value == NULL) {
- PROXY_LOG("%s: can't parse header '%s'", root->name, line);
- ret = -1;
- break;
- }
- value += strspn(value, " ");
- if (http_request_add_header(conn->request, key, value) < 0)
- ret = -1;
- }
- if (ret == DATA_ERROR)
- break;
- }
- return ret;
-}
-
-static int
-rewrite_connection_rewrite_request( RewriteConnection* conn )
-{
- ProxyConnection* root = conn->root;
- HttpService* service = (HttpService*) root->service;
- HttpRequest* r = conn->request;
- stralloc_t* str = root->str;
- HttpHeader* h;
-
- proxy_connection_rewind(conn->root);
-
- /* only rewrite the URI if it is not absolute */
- if (r->req_uri[0] == '/') {
- char* host = http_request_find_header(r, "Host");
- if (host == NULL) {
- PROXY_LOG("%s: uh oh, not Host: in request ?", root->name);
- } else {
- /* now create new URI */
- stralloc_add_str(str, "http://");
- stralloc_add_str(str, host);
- stralloc_add_str(str, r->req_uri);
- http_request_replace_uri(r, stralloc_cstr(str));
- proxy_connection_rewind(root);
- }
- }
-
- stralloc_format( str, "%s %s %s\r\n", r->req_method, r->req_uri, r->req_version );
- for (h = r->headers->first; h; h = h->next) {
- stralloc_add_format( str, "%s: %s\r\n", h->key, h->value );
- }
- /* add the service's footer - includes final \r\n */
- stralloc_add_bytes( str, service->footer, service->footer_len );
-
- return 0;
-}
-
-static int
-rewrite_connection_rewrite_reply( RewriteConnection* conn )
-{
- HttpRequest* r = conn->request;
- ProxyConnection* root = conn->root;
- stralloc_t* str = root->str;
- HttpHeader* h;
-
- proxy_connection_rewind(root);
- stralloc_format(str, "%s %d %s\r\n", r->rep_version, r->rep_code, r->rep_readable);
- for (h = r->headers->first; h; h = h->next) {
- stralloc_add_format(str, "%s: %s\r\n", h->key, h->value);
- }
- stralloc_add_str(str, "\r\n");
-
- return 0;
-}
-
-
-static int
-rewrite_connection_get_body_length( RewriteConnection* conn,
- int is_request )
-{
- HttpRequest* r = conn->request;
- ProxyConnection* root = conn->root;
- char* content_length;
- char* transfer_encoding;
-
- conn->body_mode = BODY_NONE;
- conn->body_length = 0;
- conn->body_total = 0;
- conn->body_sent = 0;
- conn->body_is_closed = 0;
- conn->body_is_full = 0;
- conn->body_has_data = 0;
-
- proxy_connection_rewind(root);
-
- if (is_request) {
- /* only POST and PUT should have a body */
- if (r->req_type != HTTP_REQUEST_POST &&
- r->req_type != HTTP_REQUEST_PUT)
- {
- return 0;
- }
- } else {
- /* HTTP 1.1 Section 4.3 Message Body states that HEAD requests must not have
- * a message body, as well as any 1xx, 204 and 304 replies */
- if (r->req_type == HTTP_REQUEST_HEAD || r->rep_code/100 == 1 ||
- r->rep_code == 204 || r->rep_code == 304)
- return 0;
- }
-
- content_length = http_request_find_header(r, "Content-Length");
- if (content_length != NULL) {
- char* end;
- int64_t body_len = strtoll( content_length, &end, 10 );
- if (*end != '\0' || *content_length == '\0' || body_len < 0) {
- PROXY_LOG("%s: bad content length: %s", root->name, content_length);
- return DATA_ERROR;
- }
- if (body_len > 0) {
- conn->body_mode = BODY_KNOWN_LENGTH;
- conn->body_length = body_len;
- }
- } else {
- char* connection = http_request_find_header(r, "Proxy-Connection");
-
- if (!connection)
- connection = http_request_find_header(r, "Connection");
-
- if (!connection || strcasecmp(connection, "Close")) {
- /* hum, we can't support this at all */
- PROXY_LOG("%s: can't determine content length, and client wants"
- " to keep connection opened",
- root->name);
- return -1;
- }
- /* a negative value means that the data ends when the client
- * disconnects the connection.
- */
- conn->body_mode = BODY_UNTIL_CLOSE;
- }
- transfer_encoding = http_request_find_header(r, "Transfer-Encoding");
- if (transfer_encoding && !strcasecmp(transfer_encoding, "Chunked")) {
- conn->body_mode = BODY_CHUNKED;
- conn->parse_chunk_header = 0;
- conn->parse_chunk_trailer = 0;
- conn->chunk_length = -1;
- conn->chunk_total = 0;
- }
- D("%s: body_length=%lld body_mode=%s",
- root->name, conn->body_length,
- body_mode_str[conn->body_mode]);
-
- proxy_connection_rewind(root);
- return 0;
-}
-
-#define MAX_BODY_BUFFER 65536
-
-static DataStatus
-rewrite_connection_read_body( RewriteConnection* conn, int fd )
-{
- ProxyConnection* root = conn->root;
- stralloc_t* str = root->str;
- int wanted = 0, current, avail;
- DataStatus ret;
-
- if (conn->body_is_closed) {
- return DATA_NEED_MORE;
- }
-
- /* first, determine how many bytes we want to read. */
- switch (conn->body_mode) {
- case BODY_NONE:
- D("%s: INTERNAL ERROR: SHOULDN'T BE THERE", root->name);
- return DATA_COMPLETED;
-
- case BODY_KNOWN_LENGTH:
- {
- if (conn->body_length == 0)
- return DATA_COMPLETED;
-
- if (conn->body_length > MAX_BODY_BUFFER)
- wanted = MAX_BODY_BUFFER;
- else
- wanted = (int)conn->body_length;
- }
- break;
-
- case BODY_UNTIL_CLOSE:
- wanted = MAX_BODY_BUFFER;
- break;
-
- case BODY_CHUNKED:
- if (conn->chunk_length < 0) {
- /* chunk_length < 0 means we need to read a chunk header */
- /* ensure that 'str' is flushed before doing this */
- if (!conn->parse_chunk_header) {
- if (conn->body_has_data)
- return DATA_NEED_MORE;
- D("%s: waiting chunk header", root->name);
- conn->parse_chunk_header = 1;
- }
- ret = proxy_connection_receive_line(root, fd);
- if (ret == DATA_COMPLETED) {
- char* line = str->s;
- char* end;
- long long length;
-
- length = strtoll(line, &end, 16);
- if (line[0] == ' ' || (end[0] != '\0' && end[0] != ';')) {
- PROXY_LOG("%s: invalid chunk header: %s",
- root->name, line);
- return DATA_ERROR;
- }
- if (length < 0) {
- PROXY_LOG("%s: invalid chunk length %lld",
- root->name, length);
- return DATA_ERROR;
- }
- conn->chunk_length = length;
- conn->chunk_total = 0;
- if (length == 0) {
- /* the last chunk, no we need to add the trailer */
- conn->parse_chunk_trailer = 0;
- }
- conn->parse_chunk_header = 0;
- }
- }
-
- if (conn->chunk_length == 0) {
- /* chunk_length == 0 means we're reading the chunk trailer */
- /* ensure that 'str' is flushed before reading the trailer */
- if (!conn->parse_chunk_trailer) {
- if (conn->body_has_data)
- return DATA_NEED_MORE;
- conn->parse_chunk_trailer = 1;
- }
- ret = rewrite_connection_read_headers(conn, fd);
- if (ret == DATA_COMPLETED) {
- conn->body_is_closed = 1;
- }
- return ret;
- }
-
- /* if we get here, body_length > 0 */
- if (conn->chunk_length > MAX_BODY_BUFFER)
- wanted = MAX_BODY_BUFFER;
- else
- wanted = (int)conn->chunk_length;
- break;
-
- default:
- ;
- }
-
- /* we don't want more than MAX_BODY_BUFFER bytes in the
- * buffer we used to pass the body */
- current = str->n;
- avail = MAX_BODY_BUFFER - current;
- if (avail <= 0) {
- /* wait for some flush */
- conn->body_is_full = 1;
- D("%s: waiting to flush %d bytes",
- root->name, current);
- return DATA_NEED_MORE;
- }
-
- if (wanted > avail)
- wanted = avail;
-
- ret = proxy_connection_receive(root, fd, wanted);
- conn->body_has_data = (str->n > 0);
- conn->body_is_full = (str->n == MAX_BODY_BUFFER);
-
- if (ret == DATA_ERROR) {
- if (conn->body_mode == BODY_UNTIL_CLOSE) {
- /* a disconnection here is normal and signals the
- * end of the body */
- conn->body_total += root->str_recv;
- D("%s: body completed by close (%lld bytes)",
- root->name, conn->body_total);
- conn->body_is_closed = 1;
- ret = DATA_COMPLETED;
- }
- } else {
- avail = root->str_recv;
- ret = DATA_NEED_MORE; /* we're not really done yet */
-
- switch (conn->body_mode) {
- case BODY_CHUNKED:
- conn->chunk_total += avail;
- conn->chunk_length -= avail;
-
- if (conn->chunk_length == 0) {
- D("%s: chunk completed (%lld bytes)",
- root->name, conn->chunk_length);
- conn->body_total += conn->chunk_total;
- conn->chunk_total = 0;
- conn->chunk_length = -1;
- }
- break;
-
- case BODY_KNOWN_LENGTH:
- conn->body_length -= avail;
- conn->body_total += avail;
-
- if (conn->body_length == 0) {
- D("%s: body completed (%lld bytes)",
- root->name, conn->body_total);
- conn->body_is_closed = 1;
- ret = DATA_COMPLETED;
- }
- break;
-
- case BODY_UNTIL_CLOSE:
- conn->body_total += avail;
- break;
-
- default:
- ;
- }
- }
- return ret;
-}
-
-static DataStatus
-rewrite_connection_send_body( RewriteConnection* conn, int fd )
-{
- ProxyConnection* root = conn->root;
- stralloc_t* str = root->str;
- DataStatus ret = DATA_NEED_MORE;
-
- if (conn->body_has_data) {
- ret = proxy_connection_send(root, fd);
- if (ret != DATA_ERROR) {
- int pos = root->str_pos;
-
- memmove(str->s, str->s+pos, str->n-pos);
- str->n -= pos;
- root->str_pos = 0;
- conn->body_is_full = (str->n == MAX_BODY_BUFFER);
- conn->body_has_data = (str->n > 0);
- conn->body_sent += root->str_sent;
-
- /* ensure that we return DATA_COMPLETED only when
- * we have sent everything, and there is no more
- * body pieces to read */
- if (ret == DATA_COMPLETED) {
- if (!conn->body_is_closed || conn->body_has_data)
- ret = DATA_NEED_MORE;
- else {
- D("%s: sent all body (%lld bytes)",
- root->name, conn->body_sent);
- }
- }
- D("%s: sent closed=%d data=%d n=%d ret=%d",
- root->name, conn->body_is_closed,
- conn->body_has_data, str->n,
- ret);
- }
- }
- return ret;
-}
-
-
-static void
-rewrite_connection_select( ProxyConnection* root,
- ProxySelect* sel )
-{
- RewriteConnection* conn = (RewriteConnection*)root;
- int slirp = conn->slirp_fd;
- int proxy = root->socket;
-
- switch (conn->state) {
- case STATE_CONNECTING:
- case STATE_CREATE_SOCKET_PAIR:
- /* try to connect to the proxy server */
- proxy_select_set( sel, proxy, PROXY_SELECT_WRITE );
- break;
-
- case STATE_REQUEST_FIRST_LINE:
- case STATE_REQUEST_HEADERS:
- proxy_select_set( sel, slirp, PROXY_SELECT_READ );
- break;
-
- case STATE_REQUEST_SEND:
- proxy_select_set( sel, proxy, PROXY_SELECT_WRITE );
- break;
-
- case STATE_REQUEST_BODY:
- if (!conn->body_is_closed && !conn->body_is_full)
- proxy_select_set( sel, slirp, PROXY_SELECT_READ );
-
- if (conn->body_has_data)
- proxy_select_set( sel, proxy, PROXY_SELECT_WRITE );
- break;
-
- case STATE_REPLY_FIRST_LINE:
- case STATE_REPLY_HEADERS:
- proxy_select_set( sel, proxy, PROXY_SELECT_READ );
- break;
-
- case STATE_REPLY_SEND:
- proxy_select_set( sel, slirp, PROXY_SELECT_WRITE );
- break;
-
- case STATE_REPLY_BODY:
- if (conn->body_has_data)
- proxy_select_set( sel, slirp, PROXY_SELECT_WRITE );
-
- if (!conn->body_is_closed && !conn->body_is_full)
- proxy_select_set( sel, proxy, PROXY_SELECT_READ );
- break;
- default:
- ;
- };
-}
-
-static void
-rewrite_connection_poll( ProxyConnection* root,
- ProxySelect* sel )
-{
- RewriteConnection* conn = (RewriteConnection*)root;
-
- int slirp = conn->slirp_fd;
- int proxy = root->socket;
- int has_slirp = proxy_select_poll(sel, slirp);
- int has_proxy = proxy_select_poll(sel, proxy);
- DataStatus ret = DATA_NEED_MORE;
-
- switch (conn->state) {
- case STATE_CONNECTING:
- if (has_proxy) {
- PROXY_LOG("%s: connected to proxy", root->name);
- conn->state = STATE_CREATE_SOCKET_PAIR;
- }
- break;
-
- case STATE_CREATE_SOCKET_PAIR:
- if (has_proxy) {
- if (rewrite_connection_create_sockets(conn) < 0) {
- ret = DATA_ERROR;
- } else {
- D("%s: socket pair created", root->name);
- conn->state = STATE_REQUEST_FIRST_LINE;
- }
- }
- break;
-
- case STATE_REQUEST_FIRST_LINE:
- if (has_slirp) {
- ret = rewrite_connection_read_request(conn);
- if (ret == DATA_COMPLETED) {
- PROXY_LOG("%s: request first line ok", root->name);
- conn->state = STATE_REQUEST_HEADERS;
- }
- }
- break;
-
- case STATE_REQUEST_HEADERS:
- if (has_slirp) {
- ret = rewrite_connection_read_headers(conn, slirp);
- if (ret == DATA_COMPLETED) {
- PROXY_LOG("%s: request headers ok", root->name);
- if (rewrite_connection_rewrite_request(conn) < 0)
- ret = DATA_ERROR;
- else
- conn->state = STATE_REQUEST_SEND;
- }
- }
- break;
-
- case STATE_REQUEST_SEND:
- if (has_proxy) {
- ret = proxy_connection_send(root, proxy);
- if (ret == DATA_COMPLETED) {
- if (rewrite_connection_get_body_length(conn, 1) < 0) {
- ret = DATA_ERROR;
- } else if (conn->body_mode != BODY_NONE) {
- PROXY_LOG("%s: request sent, waiting for body",
- root->name);
- conn->state = STATE_REQUEST_BODY;
- } else {
- PROXY_LOG("%s: request sent, waiting for reply",
- root->name);
- conn->state = STATE_REPLY_FIRST_LINE;
- }
- }
- }
- break;
-
- case STATE_REQUEST_BODY:
- if (has_slirp) {
- ret = rewrite_connection_read_body(conn, slirp);
- }
- if (ret != DATA_ERROR && has_proxy) {
- ret = rewrite_connection_send_body(conn, proxy);
- if (ret == DATA_COMPLETED) {
- PROXY_LOG("%s: request body ok, waiting for reply",
- root->name);
- conn->state = STATE_REPLY_FIRST_LINE;
- }
- }
- break;
-
- case STATE_REPLY_FIRST_LINE:
- if (has_proxy) {
- ret = rewrite_connection_read_reply(conn);
- if (ret == DATA_COMPLETED) {
- PROXY_LOG("%s: reply first line ok", root->name);
- conn->state = STATE_REPLY_HEADERS;
- }
- }
- break;
-
- case STATE_REPLY_HEADERS:
- if (has_proxy) {
- ret = rewrite_connection_read_headers(conn, proxy);
- if (ret == DATA_COMPLETED) {
- PROXY_LOG("%s: reply headers ok", root->name);
- if (rewrite_connection_rewrite_reply(conn) < 0)
- ret = DATA_ERROR;
- else
- conn->state = STATE_REPLY_SEND;
- }
- }
- break;
-
- case STATE_REPLY_SEND:
- if (has_slirp) {
- ret = proxy_connection_send(conn->root, slirp);
- if (ret == DATA_COMPLETED) {
- if (rewrite_connection_get_body_length(conn, 0) < 0) {
- ret = DATA_ERROR;
- } else if (conn->body_mode != BODY_NONE) {
- PROXY_LOG("%s: reply sent, waiting for body",
- root->name);
- conn->state = STATE_REPLY_BODY;
- } else {
- PROXY_LOG("%s: reply sent, looping to waiting request",
- root->name);
- conn->state = STATE_REQUEST_FIRST_LINE;
- }
- }
- }
- break;
-
- case STATE_REPLY_BODY:
- if (has_proxy) {
- ret = rewrite_connection_read_body(conn, proxy);
- }
- if (ret != DATA_ERROR && has_slirp) {
- ret = rewrite_connection_send_body(conn, slirp);
- if (ret == DATA_COMPLETED) {
- if (conn->body_mode == BODY_UNTIL_CLOSE) {
- PROXY_LOG("%s: closing connection", root->name);
- ret = DATA_ERROR;
- } else {
- PROXY_LOG("%s: reply body ok, looping to waiting request",
- root->name);
- conn->state = STATE_REQUEST_FIRST_LINE;
- }
- }
- }
- break;
-
- default:
- ;
- }
- if (ret == DATA_ERROR)
- proxy_connection_free(root, 0, PROXY_EVENT_NONE);
-
- return;
-}
-
-
-ProxyConnection*
-http_rewriter_connect( HttpService* service,
- SockAddress* address )
-{
- RewriteConnection* conn;
- int s;
-
- s = socket_create_inet( SOCKET_STREAM );
- if (s < 0)
- return NULL;
-
- conn = qemu_mallocz(sizeof(*conn));
- if (conn == NULL) {
- socket_close(s);
- return NULL;
- }
-
- proxy_connection_init( conn->root, s, address, service->root,
- rewrite_connection_free,
- rewrite_connection_select,
- rewrite_connection_poll );
-
- if ( rewrite_connection_init( conn ) < 0 ) {
- rewrite_connection_free( conn->root );
- return NULL;
- }
-
- return conn->root;
-}
diff --git a/proxy/proxy_int.h b/proxy/proxy_int.h
deleted file mode 100644
index 739bb75..0000000
--- a/proxy/proxy_int.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _PROXY_INT_H
-#define _PROXY_INT_H
-
-#include "proxy_common.h"
-#include "sockets.h"
-#include "android/utils/stralloc.h"
-
-extern int proxy_log;
-
-extern void
-proxy_LOG(const char* fmt, ...);
-
-#define PROXY_LOG(...) \
- do { if (proxy_log) proxy_LOG(__VA_ARGS__); } while (0)
-
-
-/* ProxySelect is used to handle events */
-
-enum {
- PROXY_SELECT_READ = (1 << 0),
- PROXY_SELECT_WRITE = (1 << 1),
- PROXY_SELECT_ERROR = (1 << 2)
-};
-
-typedef struct {
- int* pcount;
- fd_set* reads;
- fd_set* writes;
- fd_set* errors;
-} ProxySelect;
-
-extern void proxy_select_set( ProxySelect* sel,
- int fd,
- unsigned flags );
-
-extern unsigned proxy_select_poll( ProxySelect* sel, int fd );
-
-
-/* sockets proxy manager internals */
-
-typedef struct ProxyConnection ProxyConnection;
-typedef struct ProxyService ProxyService;
-
-/* free a given proxified connection */
-typedef void (*ProxyConnectionFreeFunc) ( ProxyConnection* conn );
-
-/* modify the ProxySelect to tell which events to listen to */
-typedef void (*ProxyConnectionSelectFunc) ( ProxyConnection* conn,
- ProxySelect* sel );
-
-/* action a proxy connection when select() returns certain events for its socket */
-typedef void (*ProxyConnectionPollFunc) ( ProxyConnection* conn,
- ProxySelect* sel );
-
-
-/* root ProxyConnection object */
-struct ProxyConnection {
- int socket;
- SockAddress address; /* for debugging */
- ProxyConnection* next;
- ProxyConnection* prev;
- ProxyEventFunc ev_func;
- void* ev_opaque;
- ProxyService* service;
-
- /* the following is useful for all types of services */
- char name[64]; /* for debugging purposes */
-
- stralloc_t str[1]; /* network buffer (dynamic) */
- int str_pos; /* see proxy_connection_send() */
- int str_sent; /* see proxy_connection_send() */
- int str_recv; /* see proxy_connection_receive() */
-
- /* connection methods */
- ProxyConnectionFreeFunc conn_free;
- ProxyConnectionSelectFunc conn_select;
- ProxyConnectionPollFunc conn_poll;
-
- /* rest of data depend on exact implementation */
-};
-
-
-
-extern void
-proxy_connection_init( ProxyConnection* conn,
- int socket,
- SockAddress* address,
- ProxyService* service,
- ProxyConnectionFreeFunc conn_free,
- ProxyConnectionSelectFunc conn_select,
- ProxyConnectionPollFunc conn_poll );
-
-extern void
-proxy_connection_done( ProxyConnection* conn );
-
-/* free the proxy connection object. this will also
- * close the corresponding socket unless the
- * 'keep_alive' flag is set to TRUE.
- */
-extern void
-proxy_connection_free( ProxyConnection* conn,
- int keep_alive,
- ProxyEvent event );
-
-/* status of data transfer operations */
-typedef enum {
- DATA_ERROR = -1,
- DATA_NEED_MORE = 0,
- DATA_COMPLETED = 1
-} DataStatus;
-
-/* try to send data from the connection's buffer to a socket.
- * starting from offset conn->str_pos in the buffer
- *
- * returns DATA_COMPLETED if everything could be written
- * returns DATA_ERROR for a socket disconnection or error
- * returns DATA_NEED_MORE if all data could not be sent.
- *
- * on exit, conn->str_sent contains the number of bytes
- * that were really sent. conn->str_pos will be incremented
- * by conn->str_sent as well.
- *
- * note that in case of success (DATA_COMPLETED), this also
- * performs a proxy_connection_rewind which sets conn->str_pos
- * to 0.
- */
-extern DataStatus
-proxy_connection_send( ProxyConnection* conn, int fd );
-
-/* try to read 'wanted' bytes into conn->str from a socket
- *
- * returns DATA_COMPLETED if all bytes could be read
- * returns DATA_NEED_MORE if not all bytes could be read
- * returns DATA_ERROR in case of socket disconnection or error
- *
- * on exit, the amount of data received is in conn->str_recv
- */
-extern DataStatus
-proxy_connection_receive( ProxyConnection* conn, int fd, int wanted );
-
-/* tries to receive a line of text from the proxy.
- * when an entire line is read, the trailing \r\n is stripped
- * and replaced by a terminating zero. str->n will be the
- * lenght of the line, exclusing the terminating zero.
- * returns 1 when a line has been received
- * returns 0 if there is still some data to receive
- * returns -1 in case of error
- */
-extern DataStatus
-proxy_connection_receive_line( ProxyConnection* conn, int fd );
-
-/* rewind the string buffer for a new operation */
-extern void
-proxy_connection_rewind( ProxyConnection* conn );
-
-/* base64 encode a source string, returns size of encoded result,
- * or -1 if there was not enough room in the destination buffer
- */
-extern int
-proxy_base64_encode( const char* src, int srclen,
- char* dst, int dstlen );
-
-extern int
-proxy_resolve_server( SockAddress* addr,
- const char* servername,
- int servernamelen,
- int serverport );
-
-/* a ProxyService is really a proxy server and associated options */
-
-/* destroy a given proxy service */
-typedef void (*ProxyServiceFreeFunc) ( void* opaque );
-
-/* tries to create a new proxified connection, returns NULL if the service can't
- * handle this address */
-typedef ProxyConnection* (*ProxyServiceConnectFunc)( void* opaque,
- SocketType socket_type,
- const SockAddress* address );
-
-struct ProxyService {
- void* opaque;
- ProxyServiceFreeFunc serv_free;
- ProxyServiceConnectFunc serv_connect;
-};
-
-extern int
-proxy_manager_add_service( ProxyService* service );
-
-
-#endif /* _PROXY_INT_H */
diff --git a/qemu-char.h b/qemu-char.h
deleted file mode 100644
index 439e2c8..0000000
--- a/qemu-char.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef QEMU_CHAR_H
-#define QEMU_CHAR_H
-
-#include "qemu-common.h"
-
-/* character device */
-
-#define CHR_EVENT_BREAK 0 /* serial break char */
-#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
-#define CHR_EVENT_RESET 2 /* new connection established */
-
-
-#define CHR_IOCTL_SERIAL_SET_PARAMS 1
-typedef struct {
- int speed;
- int parity;
- int data_bits;
- int stop_bits;
-} QEMUSerialSetParams;
-
-#define CHR_IOCTL_SERIAL_SET_BREAK 2
-
-#define CHR_IOCTL_PP_READ_DATA 3
-#define CHR_IOCTL_PP_WRITE_DATA 4
-#define CHR_IOCTL_PP_READ_CONTROL 5
-#define CHR_IOCTL_PP_WRITE_CONTROL 6
-#define CHR_IOCTL_PP_READ_STATUS 7
-#define CHR_IOCTL_PP_EPP_READ_ADDR 8
-#define CHR_IOCTL_PP_EPP_READ 9
-#define CHR_IOCTL_PP_EPP_WRITE_ADDR 10
-#define CHR_IOCTL_PP_EPP_WRITE 11
-#define CHR_IOCTL_PP_DATA_DIR 12
-
-#define CHR_IOCTL_SERIAL_SET_TIOCM 13
-#define CHR_IOCTL_SERIAL_GET_TIOCM 14
-
-#define CHR_TIOCM_CTS 0x020
-#define CHR_TIOCM_CAR 0x040
-#define CHR_TIOCM_DSR 0x100
-#define CHR_TIOCM_RI 0x080
-#define CHR_TIOCM_DTR 0x002
-#define CHR_TIOCM_RTS 0x004
-
-typedef void IOEventHandler(void *opaque, int event);
-
-struct CharDriverState {
- int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
- void (*chr_update_read_handler)(struct CharDriverState *s);
- int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
- IOEventHandler *chr_event;
- IOCanRWHandler *chr_can_read;
- IOReadHandler *chr_read;
- void *handler_opaque;
- void (*chr_send_event)(struct CharDriverState *chr, int event);
- void (*chr_close)(struct CharDriverState *chr);
- void (*chr_accept_input)(struct CharDriverState *chr);
- void *opaque;
- int focus;
- QEMUBH *bh;
-};
-
-CharDriverState *qemu_chr_open(const char *filename);
-void qemu_chr_close(CharDriverState *chr);
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
-void qemu_chr_send_event(CharDriverState *s, int event);
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque);
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
-void qemu_chr_reset(CharDriverState *s);
-int qemu_chr_can_read(CharDriverState *s);
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
-void qemu_chr_accept_input(CharDriverState *s);
-
-/* async I/O support */
-
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-
-#endif
diff --git a/qemu-common.h b/qemu-common.h
deleted file mode 100644
index 391717c..0000000
--- a/qemu-common.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Common header file that is included by all of qemu. */
-#ifndef QEMU_COMMON_H
-#define QEMU_COMMON_H
-
-/* we put basic includes here to avoid repeating them in device drivers */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#ifndef ENOMEDIUM
-#define ENOMEDIUM ENODEV
-#endif
-
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#define fsync _commit
-#define lseek _lseeki64
-#define ENOTSUP 4096
-extern int qemu_ftruncate64(int, int64_t);
-#define ftruncate qemu_ftruncate64
-
-
-static inline char *realpath(const char *path, char *resolved_path)
-{
- _fullpath(resolved_path, path, _MAX_PATH);
- return resolved_path;
-}
-
-#define PRId64 "I64d"
-#define PRIx64 "I64x"
-#define PRIu64 "I64u"
-#define PRIo64 "I64o"
-#endif
-
-/* FIXME: Remove NEED_CPU_H. */
-#ifndef NEED_CPU_H
-
-#include "config-host.h"
-#include <setjmp.h>
-#include "osdep.h"
-#include "bswap.h"
-
-#else
-
-#include "cpu.h"
-
-#endif /* !defined(NEED_CPU_H) */
-
-/* bottom halves */
-typedef struct QEMUBH QEMUBH;
-
-typedef void QEMUBHFunc(void *opaque);
-
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
-void qemu_bh_schedule(QEMUBH *bh);
-void qemu_bh_cancel(QEMUBH *bh);
-void qemu_bh_delete(QEMUBH *bh);
-int qemu_bh_poll(void);
-
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
-void qemu_get_timedate(struct tm *tm, int offset);
-int qemu_timedate_diff(struct tm *tm);
-
-/* cutils.c */
-void pstrcpy(char *buf, int buf_size, const char *str);
-char *pstrcat(char *buf, int buf_size, const char *s);
-int strstart(const char *str, const char *val, const char **ptr);
-int stristart(const char *str, const char *val, const char **ptr);
-time_t mktimegm(struct tm *tm);
-
-void *qemu_malloc(size_t size);
-void *qemu_realloc(void *ptr, size_t size);
-void *qemu_mallocz(size_t size);
-void qemu_free(void *ptr);
-char *qemu_strdup(const char *str);
-
-void *get_mmap_addr(unsigned long size);
-
-
-/* Error handling. */
-
-void hw_error(const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)))
- __attribute__ ((__noreturn__));
-
-/* IO callbacks. */
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
-typedef void IOHandler(void *opaque);
-
-struct ParallelIOArg {
- void *buffer;
- int count;
-};
-
-typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
-
-/* A load of opaque types so that device init declarations don't have to
- pull in all the real definitions. */
-typedef struct NICInfo NICInfo;
-typedef struct AudioState AudioState;
-typedef struct BlockDriverState BlockDriverState;
-typedef struct DisplayState DisplayState;
-typedef struct TextConsole TextConsole;
-typedef TextConsole QEMUConsole;
-typedef struct CharDriverState CharDriverState;
-typedef struct VLANState VLANState;
-typedef struct QEMUFile QEMUFile;
-typedef struct i2c_bus i2c_bus;
-typedef struct i2c_slave i2c_slave;
-typedef struct SMBusDevice SMBusDevice;
-typedef struct QEMUTimer QEMUTimer;
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-typedef struct SerialState SerialState;
-typedef struct IRQState *qemu_irq;
-struct pcmcia_card_s;
-
-/* CPU save/load. */
-void cpu_save(QEMUFile *f, void *opaque);
-int cpu_load(QEMUFile *f, void *opaque, int version_id);
-
-#endif
diff --git a/qemu-lock.h b/qemu-lock.h
deleted file mode 100644
index fdd8da9..0000000
--- a/qemu-lock.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Locking primitives. Most of this code should be redundant -
- system emulation doesn't need/use locking, NPTL userspace uses
- pthread mutexes, and non-NPTL userspace isn't threadsafe anyway.
- In either case a spinlock is probably the wrong kind of lock.
- Spinlocks are only good if you know annother CPU has the lock and is
- likely to release it soon. In environments where you have more threads
- than physical CPUs (the extreme case being a single CPU host) a spinlock
- simply wastes CPU until the OS decides to preempt it. */
-#if defined(USE_NPTL)
-
-#include <pthread.h>
-#define spin_lock pthread_mutex_lock
-#define spin_unlock pthread_mutex_unlock
-#define spinlock_t pthread_mutex_t
-#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
-
-#else
-
-#if defined(__hppa__)
-
-typedef int spinlock_t[4];
-
-#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 }
-
-static inline void resetlock (spinlock_t *p)
-{
- (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1;
-}
-
-#else
-
-typedef int spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED 0
-
-static inline void resetlock (spinlock_t *p)
-{
- *p = SPIN_LOCK_UNLOCKED;
-}
-
-#endif
-
-#if defined(__powerpc__)
-static inline int testandset (int *p)
-{
- int ret;
- __asm__ __volatile__ (
- "0: lwarx %0,0,%1\n"
- " xor. %0,%3,%0\n"
- " bne 1f\n"
- " stwcx. %2,0,%1\n"
- " bne- 0b\n"
- "1: "
- : "=&r" (ret)
- : "r" (p), "r" (1), "r" (0)
- : "cr0", "memory");
- return ret;
-}
-#elif defined(__i386__)
-static inline int testandset (int *p)
-{
- long int readval = 0;
-
- __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
- : "+m" (*p), "+a" (readval)
- : "r" (1)
- : "cc");
- return readval;
-}
-#elif defined(__x86_64__)
-static inline int testandset (int *p)
-{
- long int readval = 0;
-
- __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
- : "+m" (*p), "+a" (readval)
- : "r" (1)
- : "cc");
- return readval;
-}
-#elif defined(__s390__)
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
- " jl 0b"
- : "=&d" (ret)
- : "r" (1), "a" (p), "0" (*p)
- : "cc", "memory" );
- return ret;
-}
-#elif defined(__alpha__)
-static inline int testandset (int *p)
-{
- int ret;
- unsigned long one;
-
- __asm__ __volatile__ ("0: mov 1,%2\n"
- " ldl_l %0,%1\n"
- " stl_c %2,%1\n"
- " beq %2,1f\n"
- ".subsection 2\n"
- "1: br 0b\n"
- ".previous"
- : "=r" (ret), "=m" (*p), "=r" (one)
- : "m" (*p));
- return ret;
-}
-#elif defined(__sparc__)
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__("ldstub [%1], %0"
- : "=r" (ret)
- : "r" (p)
- : "memory");
-
- return (ret ? 1 : 0);
-}
-#elif defined(__arm__)
-static inline int testandset (int *spinlock)
-{
- register unsigned int ret;
- __asm__ __volatile__("swp %0, %1, [%2]"
- : "=r"(ret)
- : "0"(1), "r"(spinlock));
-
- return ret;
-}
-#elif defined(__mc68000)
-static inline int testandset (int *p)
-{
- char ret;
- __asm__ __volatile__("tas %1; sne %0"
- : "=r" (ret)
- : "m" (p)
- : "cc","memory");
- return ret;
-}
-#elif defined(__hppa__)
-
-/* Because malloc only guarantees 8-byte alignment for malloc'd data,
- and GCC only guarantees 8-byte alignment for stack locals, we can't
- be assured of 16-byte alignment for atomic lock data even if we
- specify "__attribute ((aligned(16)))" in the type declaration. So,
- we use a struct containing an array of four ints for the atomic lock
- type and dynamically select the 16-byte aligned int from the array
- for the semaphore. */
-#define __PA_LDCW_ALIGNMENT 16
-static inline void *ldcw_align (void *p) {
- unsigned long a = (unsigned long)p;
- a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1);
- return (void *)a;
-}
-
-static inline int testandset (spinlock_t *p)
-{
- unsigned int ret;
- p = ldcw_align(p);
- __asm__ __volatile__("ldcw 0(%1),%0"
- : "=r" (ret)
- : "r" (p)
- : "memory" );
- return !ret;
-}
-
-#elif defined(__ia64)
-
-#include <ia64intrin.h>
-
-static inline int testandset (int *p)
-{
- return __sync_lock_test_and_set (p, 1);
-}
-#elif defined(__mips__)
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__ (
- " .set push \n"
- " .set noat \n"
- " .set mips2 \n"
- "1: li $1, 1 \n"
- " ll %0, %1 \n"
- " sc $1, %1 \n"
- " beqz $1, 1b \n"
- " .set pop "
- : "=r" (ret), "+R" (*p)
- :
- : "memory");
-
- return ret;
-}
-#else
-#error unimplemented CPU support
-#endif
-
-#if defined(CONFIG_USER_ONLY)
-static inline void spin_lock(spinlock_t *lock)
-{
- while (testandset(lock));
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
- resetlock(lock);
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return !testandset(lock);
-}
-#else
-static inline void spin_lock(spinlock_t *lock)
-{
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return 1;
-}
-#endif
-
-#endif
diff --git a/qemu-log.h b/qemu-log.h
deleted file mode 100644
index 1ebea81..0000000
--- a/qemu-log.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef QEMU_LOG_H
-#define QEMU_LOG_H
-
-extern FILE *logfile;
-extern int loglevel;
-
-#endif
diff --git a/qemu-timer.h b/qemu-timer.h
deleted file mode 100644
index 8264f3e..0000000
--- a/qemu-timer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef QEMU_TIMER_H
-#define QEMU_TIMER_H
-
-#include "qemu-common.h"
-
-/* timers */
-
-typedef struct QEMUClock QEMUClock;
-typedef void QEMUTimerCB(void *opaque);
-
-/* The real time clock should be used only for stuff which does not
- change the virtual machine state, as it is run even if the virtual
- machine is stopped. The real time clock has a frequency of 1000
- Hz. */
-extern QEMUClock *rt_clock;
-
-/* The virtual clock is only run during the emulation. It is stopped
- when the virtual machine is stopped. Virtual timers use a high
- precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
-
-int64_t qemu_get_clock(QEMUClock *clock);
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
-void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-int qemu_timer_pending(QEMUTimer *ts);
-
-extern int64_t ticks_per_sec;
-
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
-/* ptimer.c */
-typedef struct ptimer_state ptimer_state;
-typedef void (*ptimer_cb)(void *opaque);
-
-ptimer_state *ptimer_init(QEMUBH *bh);
-void ptimer_set_period(ptimer_state *s, int64_t period);
-void ptimer_set_freq(ptimer_state *s, uint32_t freq);
-void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
-uint64_t ptimer_get_count(ptimer_state *s);
-void ptimer_set_count(ptimer_state *s, uint64_t count);
-void ptimer_run(ptimer_state *s, int oneshot);
-void ptimer_stop(ptimer_state *s);
-void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
-void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
-
-#endif
diff --git a/qemu_debug.h b/qemu_debug.h
deleted file mode 100644
index 809a157..0000000
--- a/qemu_debug.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/* this is a transitional header. It should only be included
- * by non-specific source files. Later, a non-Android specific
- * implementation will be hooked in
- */
-#include "android/utils/debug.h"
diff --git a/qemu_file.h b/qemu_file.h
deleted file mode 100644
index 682e092..0000000
--- a/qemu_file.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _QEMU_FILE_H
-#define _QEMU_FILE_H
-
-#include "hw/hw.h"
-
-typedef enum {
- Q_FIELD_END, /* mark end of field list */
- Q_FIELD_BYTE, /* for 1-byte fields */
- Q_FIELD_INT16, /* for 2-byte fields */
- Q_FIELD_INT32, /* for 4-byte fields */
- Q_FIELD_INT64, /* for 8-byte fields */
- Q_FIELD_BUFFER, /* for buffer fields */
- Q_FIELD_BUFFER_SIZE, /* to specify the size of buffers */
-
-#if TARGET_LONG_BITS == 64
- Q_FIELD_TL = Q_FIELD_INT64, /* target long, either 4 or 8 bytes */
-#else
- Q_FIELD_TL = Q_FIELD_INT32
-#endif
-
-} QFieldType;
-
-typedef struct {
- QFieldType type : 16; /* field type */
- uint16_t offset; /* offset of field in structure */
-} QField;
-
-#define QFIELD_BEGIN(name) \
- static const QField name[] = {
-
-#define _QFIELD_(t, f) { t, offsetof(QFIELD_STRUCT,f) }
-#define QFIELD_BYTE(f) _QFIELD_(Q_FIELD_BYTE, f)
-#define QFIELD_INT16(f) _QFIELD_(Q_FIELD_INT16, f)
-#define QFIELD_INT32(f) _QFIELD_(Q_FIELD_INT32, f)
-#define QFIELD_INT64(f) _QFIELD_(Q_FIELD_INT64, f)
-#define QFIELD_TL(f) _QFIELD_(Q_FIELD_TL, f)
-
-#define _QFIELD_SIZEOF(f) sizeof(((QFIELD_STRUCT*)0)->f)
-
-#define QFIELD_BUFFER(f) \
- _QFIELD_(Q_FIELD_BUFFER, f), \
- { Q_FIELD_BUFFER_SIZE, (uint16_t)(_QFIELD_SIZEOF(f) >> 16) }, \
- { Q_FIELD_BUFFER_SIZE, (uint16_t) _QFIELD_SIZEOF(f) }
-
-#define QFIELD_END \
- { Q_FIELD_END, 0 }, \
- };
-
-extern void qemu_put_struct(QEMUFile* f, const QField* fields, const void* s);
-extern int qemu_get_struct(QEMUFile* f, const QField* fields, void* s);
-
-#endif /* _QEMU_FILE_H */
diff --git a/qemu_socket.h b/qemu_socket.h
deleted file mode 100644
index 896a0b5..0000000
--- a/qemu_socket.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _qemu_socket_h
-#define _qemu_socket_h
-
-#include "sockets.h"
-#define socket_error() socket_errno
-#define closesocket socket_close
-
-#endif /* _qemu_socket_h */
diff --git a/qemu_timers.h b/qemu_timers.h
deleted file mode 100644
index 9642301..0000000
--- a/qemu_timers.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _QEMU_TIMERS_H
-#define _QEMU_TIMERS_H
-
-#include "qemu_file.h"
-#include "qemu-timer.h"
-
-#endif /* _QEMU_TIMERS_H */
diff --git a/readline.c b/readline.c
deleted file mode 100644
index 81bc491..0000000
--- a/readline.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * QEMU readline utility
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "console.h"
-
-#define TERM_CMD_BUF_SIZE 4095
-#define TERM_MAX_CMDS 64
-#define NB_COMPLETIONS_MAX 256
-
-#define IS_NORM 0
-#define IS_ESC 1
-#define IS_CSI 2
-
-#define printf do_not_use_printf
-
-static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1];
-static int term_cmd_buf_index;
-static int term_cmd_buf_size;
-
-static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1];
-static int term_last_cmd_buf_index;
-static int term_last_cmd_buf_size;
-
-static int term_esc_state;
-static int term_esc_param;
-
-static char *term_history[TERM_MAX_CMDS];
-static int term_hist_entry = -1;
-
-static int nb_completions;
-int completion_index;
-static char *completions[NB_COMPLETIONS_MAX];
-
-static ReadLineFunc *term_readline_func;
-static int term_is_password;
-static char term_prompt[256];
-static void *term_readline_opaque;
-
-static void term_show_prompt2(void)
-{
- term_printf("%s", term_prompt);
- term_flush();
- term_last_cmd_buf_index = 0;
- term_last_cmd_buf_size = 0;
- term_esc_state = IS_NORM;
-}
-
-static void term_show_prompt(void)
-{
- term_show_prompt2();
- term_cmd_buf_index = 0;
- term_cmd_buf_size = 0;
-}
-
-/* update the displayed command line */
-static void term_update(void)
-{
- int i, delta, len;
-
- if (term_cmd_buf_size != term_last_cmd_buf_size ||
- memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
- for(i = 0; i < term_last_cmd_buf_index; i++) {
- term_printf("\033[D");
- }
- term_cmd_buf[term_cmd_buf_size] = '\0';
- if (term_is_password) {
- len = strlen(term_cmd_buf);
- for(i = 0; i < len; i++)
- term_printf("*");
- } else {
- term_printf("%s", term_cmd_buf);
- }
- term_printf("\033[K");
- memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
- term_last_cmd_buf_size = term_cmd_buf_size;
- term_last_cmd_buf_index = term_cmd_buf_size;
- }
- if (term_cmd_buf_index != term_last_cmd_buf_index) {
- delta = term_cmd_buf_index - term_last_cmd_buf_index;
- if (delta > 0) {
- for(i = 0;i < delta; i++) {
- term_printf("\033[C");
- }
- } else {
- delta = -delta;
- for(i = 0;i < delta; i++) {
- term_printf("\033[D");
- }
- }
- term_last_cmd_buf_index = term_cmd_buf_index;
- }
- term_flush();
-}
-
-static void term_insert_char(int ch)
-{
- if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {
- memmove(term_cmd_buf + term_cmd_buf_index + 1,
- term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf_size - term_cmd_buf_index);
- term_cmd_buf[term_cmd_buf_index] = ch;
- term_cmd_buf_size++;
- term_cmd_buf_index++;
- }
-}
-
-static void term_backward_char(void)
-{
- if (term_cmd_buf_index > 0) {
- term_cmd_buf_index--;
- }
-}
-
-static void term_forward_char(void)
-{
- if (term_cmd_buf_index < term_cmd_buf_size) {
- term_cmd_buf_index++;
- }
-}
-
-static void term_delete_char(void)
-{
- if (term_cmd_buf_index < term_cmd_buf_size) {
- memmove(term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf + term_cmd_buf_index + 1,
- term_cmd_buf_size - term_cmd_buf_index - 1);
- term_cmd_buf_size--;
- }
-}
-
-static void term_backspace(void)
-{
- if (term_cmd_buf_index > 0) {
- term_backward_char();
- term_delete_char();
- }
-}
-
-static void term_backword(void)
-{
- int start;
-
- if (term_cmd_buf_index == 0 || term_cmd_buf_index > term_cmd_buf_size) {
- return;
- }
-
- start = term_cmd_buf_index - 1;
-
- /* find first word (backwards) */
- while (start > 0) {
- if (!isspace(term_cmd_buf[start])) {
- break;
- }
-
- --start;
- }
-
- /* find first space (backwards) */
- while (start > 0) {
- if (isspace(term_cmd_buf[start])) {
- ++start;
- break;
- }
-
- --start;
- }
-
- /* remove word */
- if (start < term_cmd_buf_index) {
- memmove(term_cmd_buf + start,
- term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf_size - term_cmd_buf_index);
- term_cmd_buf_size -= term_cmd_buf_index - start;
- term_cmd_buf_index = start;
- }
-}
-
-static void term_bol(void)
-{
- term_cmd_buf_index = 0;
-}
-
-static void term_eol(void)
-{
- term_cmd_buf_index = term_cmd_buf_size;
-}
-
-static void term_up_char(void)
-{
- int idx;
-
- if (term_hist_entry == 0)
- return;
- if (term_hist_entry == -1) {
- /* Find latest entry */
- for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
- if (term_history[idx] == NULL)
- break;
- }
- term_hist_entry = idx;
- }
- term_hist_entry--;
- if (term_hist_entry >= 0) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
- term_history[term_hist_entry]);
- term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
- }
-}
-
-static void term_down_char(void)
-{
- if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
- return;
- if (term_history[++term_hist_entry] != NULL) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
- term_history[term_hist_entry]);
- } else {
- term_hist_entry = -1;
- }
- term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
-}
-
-static void term_hist_add(const char *cmdline)
-{
- char *hist_entry, *new_entry;
- int idx;
-
- if (cmdline[0] == '\0')
- return;
- new_entry = NULL;
- if (term_hist_entry != -1) {
- /* We were editing an existing history entry: replace it */
- hist_entry = term_history[term_hist_entry];
- idx = term_hist_entry;
- if (strcmp(hist_entry, cmdline) == 0) {
- goto same_entry;
- }
- }
- /* Search cmdline in history buffers */
- for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
- hist_entry = term_history[idx];
- if (hist_entry == NULL)
- break;
- if (strcmp(hist_entry, cmdline) == 0) {
- same_entry:
- new_entry = hist_entry;
- /* Put this entry at the end of history */
- memmove(&term_history[idx], &term_history[idx + 1],
- (TERM_MAX_CMDS - idx + 1) * sizeof(char *));
- term_history[TERM_MAX_CMDS - 1] = NULL;
- for (; idx < TERM_MAX_CMDS; idx++) {
- if (term_history[idx] == NULL)
- break;
- }
- break;
- }
- }
- if (idx == TERM_MAX_CMDS) {
- /* Need to get one free slot */
- free(term_history[0]);
- memcpy(term_history, &term_history[1],
- (TERM_MAX_CMDS - 1) * sizeof(char *));
- term_history[TERM_MAX_CMDS - 1] = NULL;
- idx = TERM_MAX_CMDS - 1;
- }
- if (new_entry == NULL)
- new_entry = strdup(cmdline);
- term_history[idx] = new_entry;
- term_hist_entry = -1;
-}
-
-/* completion support */
-
-void add_completion(const char *str)
-{
- if (nb_completions < NB_COMPLETIONS_MAX) {
- completions[nb_completions++] = qemu_strdup(str);
- }
-}
-
-static void term_completion(void)
-{
- int len, i, j, max_width, nb_cols, max_prefix;
- char *cmdline;
-
- nb_completions = 0;
-
- cmdline = qemu_malloc(term_cmd_buf_index + 1);
- if (!cmdline)
- return;
- memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);
- cmdline[term_cmd_buf_index] = '\0';
- readline_find_completion(cmdline);
- qemu_free(cmdline);
-
- /* no completion found */
- if (nb_completions <= 0)
- return;
- if (nb_completions == 1) {
- len = strlen(completions[0]);
- for(i = completion_index; i < len; i++) {
- term_insert_char(completions[0][i]);
- }
- /* extra space for next argument. XXX: make it more generic */
- if (len > 0 && completions[0][len - 1] != '/')
- term_insert_char(' ');
- } else {
- term_printf("\n");
- max_width = 0;
- max_prefix = 0;
- for(i = 0; i < nb_completions; i++) {
- len = strlen(completions[i]);
- if (i==0) {
- max_prefix = len;
- } else {
- if (len < max_prefix)
- max_prefix = len;
- for(j=0; j<max_prefix; j++) {
- if (completions[i][j] != completions[0][j])
- max_prefix = j;
- }
- }
- if (len > max_width)
- max_width = len;
- }
- if (max_prefix > 0)
- for(i = completion_index; i < max_prefix; i++) {
- term_insert_char(completions[0][i]);
- }
- max_width += 2;
- if (max_width < 10)
- max_width = 10;
- else if (max_width > 80)
- max_width = 80;
- nb_cols = 80 / max_width;
- j = 0;
- for(i = 0; i < nb_completions; i++) {
- term_printf("%-*s", max_width, completions[i]);
- if (++j == nb_cols || i == (nb_completions - 1)) {
- term_printf("\n");
- j = 0;
- }
- }
- term_show_prompt2();
- }
-}
-
-/* return true if command handled */
-void readline_handle_byte(int ch)
-{
- switch(term_esc_state) {
- case IS_NORM:
- switch(ch) {
- case 1:
- term_bol();
- break;
- case 4:
- term_delete_char();
- break;
- case 5:
- term_eol();
- break;
- case 9:
- term_completion();
- break;
- case 10:
- case 13:
- term_cmd_buf[term_cmd_buf_size] = '\0';
- if (!term_is_password)
- term_hist_add(term_cmd_buf);
- term_printf("\n");
- term_cmd_buf_index = 0;
- term_cmd_buf_size = 0;
- term_last_cmd_buf_index = 0;
- term_last_cmd_buf_size = 0;
- /* NOTE: readline_start can be called here */
- term_readline_func(term_readline_opaque, term_cmd_buf);
- break;
- case 23:
- /* ^W */
- term_backword();
- break;
- case 27:
- term_esc_state = IS_ESC;
- break;
- case 127:
- case 8:
- term_backspace();
- break;
- case 155:
- term_esc_state = IS_CSI;
- break;
- default:
- if (ch >= 32) {
- term_insert_char(ch);
- }
- break;
- }
- break;
- case IS_ESC:
- if (ch == '[') {
- term_esc_state = IS_CSI;
- term_esc_param = 0;
- } else {
- term_esc_state = IS_NORM;
- }
- break;
- case IS_CSI:
- switch(ch) {
- case 'A':
- case 'F':
- term_up_char();
- break;
- case 'B':
- case 'E':
- term_down_char();
- break;
- case 'D':
- term_backward_char();
- break;
- case 'C':
- term_forward_char();
- break;
- case '0' ... '9':
- term_esc_param = term_esc_param * 10 + (ch - '0');
- goto the_end;
- case '~':
- switch(term_esc_param) {
- case 1:
- term_bol();
- break;
- case 3:
- term_delete_char();
- break;
- case 4:
- term_eol();
- break;
- }
- break;
- default:
- break;
- }
- term_esc_state = IS_NORM;
- the_end:
- break;
- }
- term_update();
-}
-
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque)
-{
- pstrcpy(term_prompt, sizeof(term_prompt), prompt);
- term_readline_func = readline_func;
- term_readline_opaque = opaque;
- term_is_password = is_password;
- term_show_prompt();
-}
-
-const char *readline_get_history(unsigned int index)
-{
- if (index >= TERM_MAX_CMDS)
- return NULL;
- return term_history[index];
-}
-
-
diff --git a/sdl_keysym.h b/sdl_keysym.h
deleted file mode 100644
index 9a74142..0000000
--- a/sdl_keysym.h
+++ /dev/null
@@ -1,278 +0,0 @@
-typedef struct {
- const char* name;
- int keysym;
-} name2keysym_t;
-static name2keysym_t name2keysym[]={
-/* ascii */
- { "space", 0x020},
- { "exclam", 0x021},
- { "quotedbl", 0x022},
- { "numbersign", 0x023},
- { "dollar", 0x024},
- { "percent", 0x025},
- { "ampersand", 0x026},
- { "apostrophe", 0x027},
- { "parenleft", 0x028},
- { "parenright", 0x029},
- { "asterisk", 0x02a},
- { "plus", 0x02b},
- { "comma", 0x02c},
- { "minus", 0x02d},
- { "period", 0x02e},
- { "slash", 0x02f},
- { "0", 0x030},
- { "1", 0x031},
- { "2", 0x032},
- { "3", 0x033},
- { "4", 0x034},
- { "5", 0x035},
- { "6", 0x036},
- { "7", 0x037},
- { "8", 0x038},
- { "9", 0x039},
- { "colon", 0x03a},
- { "semicolon", 0x03b},
- { "less", 0x03c},
- { "equal", 0x03d},
- { "greater", 0x03e},
- { "question", 0x03f},
- { "at", 0x040},
- { "A", 0x041},
- { "B", 0x042},
- { "C", 0x043},
- { "D", 0x044},
- { "E", 0x045},
- { "F", 0x046},
- { "G", 0x047},
- { "H", 0x048},
- { "I", 0x049},
- { "J", 0x04a},
- { "K", 0x04b},
- { "L", 0x04c},
- { "M", 0x04d},
- { "N", 0x04e},
- { "O", 0x04f},
- { "P", 0x050},
- { "Q", 0x051},
- { "R", 0x052},
- { "S", 0x053},
- { "T", 0x054},
- { "U", 0x055},
- { "V", 0x056},
- { "W", 0x057},
- { "X", 0x058},
- { "Y", 0x059},
- { "Z", 0x05a},
- { "bracketleft", 0x05b},
- { "backslash", 0x05c},
- { "bracketright", 0x05d},
- { "asciicircum", 0x05e},
- { "underscore", 0x05f},
- { "grave", 0x060},
- { "a", 0x061},
- { "b", 0x062},
- { "c", 0x063},
- { "d", 0x064},
- { "e", 0x065},
- { "f", 0x066},
- { "g", 0x067},
- { "h", 0x068},
- { "i", 0x069},
- { "j", 0x06a},
- { "k", 0x06b},
- { "l", 0x06c},
- { "m", 0x06d},
- { "n", 0x06e},
- { "o", 0x06f},
- { "p", 0x070},
- { "q", 0x071},
- { "r", 0x072},
- { "s", 0x073},
- { "t", 0x074},
- { "u", 0x075},
- { "v", 0x076},
- { "w", 0x077},
- { "x", 0x078},
- { "y", 0x079},
- { "z", 0x07a},
- { "braceleft", 0x07b},
- { "bar", 0x07c},
- { "braceright", 0x07d},
- { "asciitilde", 0x07e},
-
-/* latin 1 extensions */
-{ "nobreakspace", 0x0a0},
-{ "exclamdown", 0x0a1},
-{ "cent", 0x0a2},
-{ "sterling", 0x0a3},
-{ "currency", 0x0a4},
-{ "yen", 0x0a5},
-{ "brokenbar", 0x0a6},
-{ "section", 0x0a7},
-{ "diaeresis", 0x0a8},
-{ "copyright", 0x0a9},
-{ "ordfeminine", 0x0aa},
-{ "guillemotleft", 0x0ab},
-{ "notsign", 0x0ac},
-{ "hyphen", 0x0ad},
-{ "registered", 0x0ae},
-{ "macron", 0x0af},
-{ "degree", 0x0b0},
-{ "plusminus", 0x0b1},
-{ "twosuperior", 0x0b2},
-{ "threesuperior", 0x0b3},
-{ "acute", 0x0b4},
-{ "mu", 0x0b5},
-{ "paragraph", 0x0b6},
-{ "periodcentered", 0x0b7},
-{ "cedilla", 0x0b8},
-{ "onesuperior", 0x0b9},
-{ "masculine", 0x0ba},
-{ "guillemotright", 0x0bb},
-{ "onequarter", 0x0bc},
-{ "onehalf", 0x0bd},
-{ "threequarters", 0x0be},
-{ "questiondown", 0x0bf},
-{ "Agrave", 0x0c0},
-{ "Aacute", 0x0c1},
-{ "Acircumflex", 0x0c2},
-{ "Atilde", 0x0c3},
-{ "Adiaeresis", 0x0c4},
-{ "Aring", 0x0c5},
-{ "AE", 0x0c6},
-{ "Ccedilla", 0x0c7},
-{ "Egrave", 0x0c8},
-{ "Eacute", 0x0c9},
-{ "Ecircumflex", 0x0ca},
-{ "Ediaeresis", 0x0cb},
-{ "Igrave", 0x0cc},
-{ "Iacute", 0x0cd},
-{ "Icircumflex", 0x0ce},
-{ "Idiaeresis", 0x0cf},
-{ "ETH", 0x0d0},
-{ "Eth", 0x0d0},
-{ "Ntilde", 0x0d1},
-{ "Ograve", 0x0d2},
-{ "Oacute", 0x0d3},
-{ "Ocircumflex", 0x0d4},
-{ "Otilde", 0x0d5},
-{ "Odiaeresis", 0x0d6},
-{ "multiply", 0x0d7},
-{ "Ooblique", 0x0d8},
-{ "Oslash", 0x0d8},
-{ "Ugrave", 0x0d9},
-{ "Uacute", 0x0da},
-{ "Ucircumflex", 0x0db},
-{ "Udiaeresis", 0x0dc},
-{ "Yacute", 0x0dd},
-{ "THORN", 0x0de},
-{ "Thorn", 0x0de},
-{ "ssharp", 0x0df},
-{ "agrave", 0x0e0},
-{ "aacute", 0x0e1},
-{ "acircumflex", 0x0e2},
-{ "atilde", 0x0e3},
-{ "adiaeresis", 0x0e4},
-{ "aring", 0x0e5},
-{ "ae", 0x0e6},
-{ "ccedilla", 0x0e7},
-{ "egrave", 0x0e8},
-{ "eacute", 0x0e9},
-{ "ecircumflex", 0x0ea},
-{ "ediaeresis", 0x0eb},
-{ "igrave", 0x0ec},
-{ "iacute", 0x0ed},
-{ "icircumflex", 0x0ee},
-{ "idiaeresis", 0x0ef},
-{ "eth", 0x0f0},
-{ "ntilde", 0x0f1},
-{ "ograve", 0x0f2},
-{ "oacute", 0x0f3},
-{ "ocircumflex", 0x0f4},
-{ "otilde", 0x0f5},
-{ "odiaeresis", 0x0f6},
-{ "division", 0x0f7},
-{ "oslash", 0x0f8},
-{ "ooblique", 0x0f8},
-{ "ugrave", 0x0f9},
-{ "uacute", 0x0fa},
-{ "ucircumflex", 0x0fb},
-{ "udiaeresis", 0x0fc},
-{ "yacute", 0x0fd},
-{ "thorn", 0x0fe},
-{ "ydiaeresis", 0x0ff},
-{"EuroSign", SDLK_EURO},
-
- /* modifiers */
-{"Control_L", SDLK_LCTRL},
-{"Control_R", SDLK_RCTRL},
-{"Alt_L", SDLK_LALT},
-{"Alt_R", SDLK_RALT},
-{"Caps_Lock", SDLK_CAPSLOCK},
-{"Meta_L", SDLK_LMETA},
-{"Meta_R", SDLK_RMETA},
-{"Shift_L", SDLK_LSHIFT},
-{"Shift_R", SDLK_RSHIFT},
-{"Super_L", SDLK_LSUPER},
-{"Super_R", SDLK_RSUPER},
-
- /* special keys */
-{"BackSpace", SDLK_BACKSPACE},
-{"Tab", SDLK_TAB},
-{"Return", SDLK_RETURN},
-{"Right", SDLK_RIGHT},
-{"Left", SDLK_LEFT},
-{"Up", SDLK_UP},
-{"Down", SDLK_DOWN},
-{"Page_Down", SDLK_PAGEDOWN},
-{"Page_Up", SDLK_PAGEUP},
-{"Insert", SDLK_INSERT},
-{"Delete", SDLK_DELETE},
-{"Home", SDLK_HOME},
-{"End", SDLK_END},
-{"Scroll_Lock", SDLK_SCROLLOCK},
-{"F1", SDLK_F1},
-{"F2", SDLK_F2},
-{"F3", SDLK_F3},
-{"F4", SDLK_F4},
-{"F5", SDLK_F5},
-{"F6", SDLK_F6},
-{"F7", SDLK_F7},
-{"F8", SDLK_F8},
-{"F9", SDLK_F9},
-{"F10", SDLK_F10},
-{"F11", SDLK_F11},
-{"F12", SDLK_F12},
-{"F13", SDLK_F13},
-{"F14", SDLK_F14},
-{"F15", SDLK_F15},
-{"Sys_Req", SDLK_SYSREQ},
-{"KP_0", SDLK_KP0},
-{"KP_1", SDLK_KP1},
-{"KP_2", SDLK_KP2},
-{"KP_3", SDLK_KP3},
-{"KP_4", SDLK_KP4},
-{"KP_5", SDLK_KP5},
-{"KP_6", SDLK_KP6},
-{"KP_7", SDLK_KP7},
-{"KP_8", SDLK_KP8},
-{"KP_9", SDLK_KP9},
-{"KP_Add", SDLK_KP_PLUS},
-{"KP_Decimal", SDLK_KP_PERIOD},
-{"KP_Divide", SDLK_KP_DIVIDE},
-{"KP_Enter", SDLK_KP_ENTER},
-{"KP_Equal", SDLK_KP_EQUALS},
-{"KP_Multiply", SDLK_KP_MULTIPLY},
-{"KP_Subtract", SDLK_KP_MINUS},
-{"help", SDLK_HELP},
-{"Menu", SDLK_MENU},
-{"Power", SDLK_POWER},
-{"Print", SDLK_PRINT},
-{"Mode_switch", SDLK_MODE},
-{"Multi_Key", SDLK_COMPOSE},
-{"Num_Lock", SDLK_NUMLOCK},
-{"Pause", SDLK_PAUSE},
-{"Escape", SDLK_ESCAPE},
-
-{0,0},
-};
diff --git a/shaper.c b/shaper.c
deleted file mode 100644
index a522919..0000000
--- a/shaper.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "shaper.h"
-#include "qemu-common.h"
-#include "qemu-timer.h"
-#include <stdlib.h>
-
-#define SHAPER_CLOCK rt_clock
-#define SHAPER_CLOCK_UNIT 1000.
-
-static int
-_packet_is_internal( const uint8_t* data, size_t size )
-{
- const uint8_t* end = data + size;
-
- /* must have room for Mac + IP header */
- if (data + 40 > end)
- return 0;
-
- if (data[12] != 0x08 || data[13] != 0x00 )
- return 0;
-
- /* must have valid IP header */
- data += 14;
- if ((data[0] >> 4) != 4 || (data[0] & 15) < 5)
- return 0;
-
- /* internal if both source and dest addresses are in 10.x.x.x */
- return ( data[12] == 10 && data[16] == 10);
-}
-
-/* here's how we implement network shaping. we want to limit the network
- * rate to a given constant MAX_RATE expressed as bits/second. this means
- * that it takes 1/MAX_RATE seconds to send a single bit, and count*8/MAX_RATE
- * seconds to send 'count' bytes.
- *
- * we're going to implement a scheme where, when we send a packet of
- * 'count' bytes, no other packet will go through in the same direction for
- * at least 'count*8/MAX_RATE' seconds. any successive packet that is "sent"
- * in this interval is placed in a queue, associated to a timer
- *
- * there are different (queue/timer/rate) values for the input and output
- * direction of the user vlan.
- */
-typedef struct QueuedPacketRec_ {
- int64_t expiration;
- struct QueuedPacketRec_* next;
- size_t size;
- void* opaque;
- void* data;
-} QueuedPacketRec, *QueuedPacket;
-
-
-static QueuedPacket
-queued_packet_create( const void* data,
- size_t size,
- void* opaque,
- int do_copy )
-{
- QueuedPacket packet;
- size_t packet_size = sizeof(*packet);
-
- if (do_copy)
- packet_size += size;
-
- packet = qemu_malloc(packet_size);
- packet->next = NULL;
- packet->expiration = 0;
- packet->size = (size_t)size;
- packet->opaque = opaque;
-
- if (do_copy) {
- packet->data = (void*)(packet+1);
- memcpy( (char*)packet->data, (char*)data, packet->size );
- } else {
- packet->data = (void*)data;
- }
- return packet;
-}
-
-static void
-queued_packet_free( QueuedPacket packet )
-{
- if (packet) {
- qemu_free( packet );
- }
-}
-
-typedef struct NetShaperRec_ {
- QueuedPacket packets; /* list of queued packets, ordered by expiration date */
- int num_packets;
- int active; /* is this shaper active ? */
- int64_t block_until;
- double max_rate; /* max rate expressed in bytes/second */
- double inv_rate; /* inverse of max rate */
- QEMUTimer* timer; /* QEMU timer */
-
- int do_copy;
- NetShaperSendFunc send_func;
-
-} NetShaperRec;
-
-
-void
-netshaper_destroy( NetShaper shaper )
-{
- if (shaper) {
- shaper->active = 0;
-
- while (shaper->packets) {
- QueuedPacket packet = shaper->packets;
- shaper->packets = packet->next;
- packet->next = NULL;
- queued_packet_free(packet);
- }
-
- qemu_del_timer(shaper->timer);
- qemu_free_timer(shaper->timer);
- shaper->timer = NULL;
- qemu_free(shaper);
- }
-}
-
-/* this function is called when the shaper's timer expires */
-static void
-netshaper_expires( NetShaper shaper )
-{
- QueuedPacket packet;
-
- while ((packet = shaper->packets) != NULL) {
- int64_t now = qemu_get_clock( SHAPER_CLOCK );
-
- if (packet->expiration > now)
- break;
-
- shaper->packets = packet->next;
- shaper->send_func( packet->data, packet->size, packet->opaque );
- queued_packet_free(packet);
- shaper->num_packets--;
- }
-
- /* reprogram timer if needed */
- if (shaper->packets) {
- shaper->block_until = shaper->packets->expiration;
- qemu_mod_timer( shaper->timer, shaper->block_until );
- } else {
- shaper->block_until = -1;
- }
-}
-
-
-NetShaper
-netshaper_create( int do_copy,
- NetShaperSendFunc send_func )
-{
- NetShaper shaper = qemu_malloc(sizeof(*shaper));
-
- shaper->active = 0;
- shaper->packets = NULL;
- shaper->num_packets = 0;
- shaper->timer = qemu_new_timer( SHAPER_CLOCK,
- (QEMUTimerCB*) netshaper_expires,
- shaper );
- shaper->send_func = send_func;
- shaper->max_rate = 1e6;
- shaper->inv_rate = 0.;
-
- shaper->block_until = -1; /* magic value, means to not block */
-
- return shaper;
-}
-
-void
-netshaper_set_rate( NetShaper shaper,
- double rate )
-{
- /* send all current packets when changing the rate */
- while (shaper->packets) {
- QueuedPacket packet = shaper->packets;
- shaper->packets = packet->next;
- shaper->send_func(packet->data, packet->size, packet->opaque);
- qemu_free(packet);
- shaper->num_packets = 0;
- }
-
- shaper->max_rate = rate;
- if (rate > 1.) {
- shaper->inv_rate = (8.*SHAPER_CLOCK_UNIT)/rate; /* qemu_get_clock returns time in ms */
- shaper->active = 1; /* for the real-time clock */
- } else {
- shaper->active = 0;
- }
-
- shaper->block_until = -1;
-}
-
-void
-netshaper_send_aux( NetShaper shaper,
- void* data,
- size_t size,
- void* opaque )
-{
- int64_t now;
-
- if (!shaper->active || _packet_is_internal(data, size)) {
- shaper->send_func( data, size, opaque );
- return;
- }
-
- now = qemu_get_clock( SHAPER_CLOCK );
- if (now >= shaper->block_until) {
- shaper->send_func( data, size, opaque );
- shaper->block_until = now + size*shaper->inv_rate;
- //fprintf(stderr, "NETSHAPER: block for %.2fms\n", (shaper->block_until - now)*1.0 );
- return;
- }
-
- /* create new packet, add it to the queue */
- {
- QueuedPacket packet;
-
- packet = queued_packet_create( data, size, opaque, shaper->do_copy );
-
- packet->expiration = shaper->block_until;
-
- {
- QueuedPacket *pnode, node;
-
- pnode = &shaper->packets;
- for (;;) {
- node = *pnode;
- if (node == NULL || node->expiration > packet->expiration )
- break;
- pnode = &node->next;
- }
- packet->next = *pnode;
- *pnode = packet;
-
- if (packet == shaper->packets)
- qemu_mod_timer( shaper->timer, packet->expiration );
- }
- shaper->num_packets += 1;
- }
- shaper->block_until += size*shaper->inv_rate;
- //fprintf(stderr, "NETSHAPER: block2 for %.2fms\n", (shaper->block_until - now)*1.0 );
-}
-
-void
-netshaper_send( NetShaper shaper,
- void* data,
- size_t size )
-{
- netshaper_send_aux(shaper, data, size, NULL);
-}
-
-
-int
-netshaper_can_send( NetShaper shaper )
-{
- int64_t now;
-
- if (!shaper->active || shaper->block_until < 0)
- return 1;
-
- if (shaper->packets)
- return 0;
-
- now = qemu_get_clock( SHAPER_CLOCK );
- return (now >= shaper->block_until);
-}
-
-
-
-
-
-
-/* this type is used to model a session connection/state
- * if session->packet is != NULL, then the connection is delayed
- */
-typedef struct SessionRec_ {
- int64_t expiration;
- struct SessionRec_* next;
- unsigned src_ip;
- unsigned dst_ip;
- unsigned short src_port;
- unsigned short dst_port;
- uint8_t protocol;
- QueuedPacket packet;
-
-} SessionRec, *Session;
-
-#define _PROTOCOL_TCP 6
-#define _PROTOCOL_UDP 17
-
-
-
-static void
-session_free( Session session )
-{
- if (session) {
- if (session->packet) {
- queued_packet_free(session->packet);
- session->packet = NULL;
- }
- qemu_free( session );
- }
-}
-
-
-#if 0 /* useful for debugging */
-static const char*
-session_to_string( Session session )
-{
- static char temp[256];
- const char* format = (session->protocol == _PROTOCOL_TCP) ? "TCP" : "UDP";
- sprintf( temp, "%s[%d.%d.%d.%d:%d / %d.%d.%d.%d:%d]", format,
- (session->src_ip >> 24) & 255, (session->src_ip >> 16) & 255,
- (session->src_ip >> 8) & 255, (session->src_ip) & 255, session->src_port,
- (session->dst_ip >> 24) & 255, (session->dst_ip >> 16) & 255,
- (session->dst_ip >> 8) & 255, (session->dst_ip) & 255, session->dst_port);
-
- return temp;
-}
-#endif
-
-/* returns TRUE if this corresponds to a SYN packet */
-int
-_packet_SYN_flags( const void* _data, size_t size, Session info )
-{
- const uint8_t* data = (const uint8_t*)_data;
- const uint8_t* end = data + size;
-
- /* enough room for a Ethernet MAC packet ? */
- if (data + 14 > end - 4)
- return 0;
-
- /* is it an IP packet ? */
- if (data[12] != 0x8 || data[13] != 0)
- return 0;
-
- data += 14;
- end -= 4;
-
- if (data + 20 > end)
- return 0;
-
- /* IP version must be 4, and the header length in words at least 5 */
- if ((data[0] & 0xF) < 5 || (data[0] >> 4) != 4)
- return 0;
-
- /* time-to-live must be > 0 */
- if (data[8] == 0)
- return 0;
-
- /* must be TCP or UDP packet */
- if (data[9] != _PROTOCOL_TCP && data[9] != _PROTOCOL_UDP)
- return 0;
-
- info->protocol = data[9];
- info->src_ip = (data[12] << 24) | (data[13] << 16) | (data[14] << 8) | data[15];
- info->dst_ip = (data[16] << 24) | (data[17] << 16) | (data[18] << 8) | data[19];
-
- data += 4*(data[0] & 15);
- if (data + 20 > end)
- return 0;
-
- info->src_port = (unsigned short)((data[0] << 8) | data[1]);
- info->dst_port = (unsigned short)((data[2] << 8) | data[3]);
-
- return (data[13] & 0x1f);
-}
-
-
-typedef struct NetDelayRec_
-{
- Session sessions;
- int num_sessions;
- QEMUTimer* timer;
- int active;
- int min_ms;
- int max_ms;
-
- NetShaperSendFunc send_func;
-
-} NetDelayRec;
-
-
-static Session*
-netdelay_lookup_session( NetDelay delay, Session info )
-{
- Session* pnode = &delay->sessions;
- Session node;
-
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
-
- if (node->src_ip == info->src_ip &&
- node->dst_ip == info->dst_ip &&
- node->src_port == info->src_port &&
- node->dst_port == info->dst_port &&
- node->protocol == info->protocol )
- break;
-
- pnode = &node->next;
- }
- return pnode;
-}
-
-
-
-/* called by the delay's timer on expiration */
-static void
-netdelay_expires( NetDelay delay )
-{
- Session session;
- int64_t now = qemu_get_clock( SHAPER_CLOCK );
- int rearm = 0;
- int64_t rearm_time = 0;
-
- for (session = delay->sessions; session != NULL; session = session->next)
- {
- QueuedPacket packet = session->packet;
-
- if (packet == NULL)
- continue;
-
- if (session->expiration <= now) {
- /* send the SYN packet now */
- //fprintf(stderr, "NetDelay:RST: sending creation for %s\n", session_to_string(session) );
- delay->send_func( packet->data, packet->size, packet->opaque );
- session->packet = NULL;
- queued_packet_free( packet );
- } else {
- if (!rearm) {
- rearm = 1;
- rearm_time = session->expiration;
- }
- else if ( session->expiration < rearm_time )
- rearm_time = session->expiration;
- }
- }
-
- if (rearm)
- qemu_mod_timer( delay->timer, rearm_time );
-}
-
-
-NetDelay
-netdelay_create( NetShaperSendFunc send_func )
-{
- NetDelay delay = qemu_malloc(sizeof(*delay));
-
- delay->sessions = NULL;
- delay->num_sessions = 0;
- delay->timer = qemu_new_timer( SHAPER_CLOCK,
- (QEMUTimerCB*) netdelay_expires,
- delay );
- delay->active = 0;
- delay->min_ms = 0;
- delay->max_ms = 0;
-
- delay->send_func = send_func;
-
- return delay;
-}
-
-
-void
-netdelay_set_latency( NetDelay delay, int min_ms, int max_ms )
-{
- /* when changing the latency, accept all sessions */
- while (delay->sessions) {
- Session session = delay->sessions;
- delay->sessions = session->next;
- session->next = NULL;
- if (session->packet) {
- QueuedPacket packet = session->packet;
- delay->send_func( packet->data, packet->size, packet->opaque );
- }
- session_free(session);
- delay->num_sessions--;
- }
-
- delay->min_ms = min_ms;
- delay->max_ms = max_ms;
- delay->active = (min_ms <= max_ms) && min_ms > 0;
-}
-
-void
-netdelay_send( NetDelay delay, const void* data, size_t size )
-{
- netdelay_send_aux(delay, data, size, NULL);
-}
-
-
-void
-netdelay_send_aux( NetDelay delay, const void* data, size_t size, void* opaque )
-{
- if (delay->active && !_packet_is_internal(data, size)) {
- SessionRec info[1];
- int flags;
-
- flags = _packet_SYN_flags( data, size, info );
- if ((flags & 0x05) != 0)
- { /* FIN or RST: drop connection */
- Session* lookup = netdelay_lookup_session( delay, info );
- Session session = *lookup;
- if (session != NULL) {
- //fprintf(stderr, "NetDelay:RST: dropping %s\n", session_to_string(info) );
-
- *lookup = session->next;
- session_free( session );
- delay->num_sessions -= 1;
- }
- }
- else if ((flags & 0x12) == 0x02)
- {
- /* SYN: create connection */
- Session* lookup = netdelay_lookup_session( delay, info );
- Session session = *lookup;
-
- if (session != NULL) {
- if (session->packet != NULL) {
- /* this is a SYN re-transmission, since we didn't
- * send the original SYN packet yet, just eat this one
- */
- //fprintf(stderr, "NetDelay:RST: swallow SYN re-send for %s\n", session_to_string(info) );
- return;
- }
- } else {
- /* establish a new session slightly in the future */
- int latency = delay->min_ms;
- int range = delay->max_ms - delay->min_ms;
-
- if (range > 0)
- latency += rand() % range;
-
- //fprintf(stderr, "NetDelay:RST: delay creation for %s\n", session_to_string(info) );
- session = qemu_malloc( sizeof(*session) );
-
- session->next = delay->sessions;
- delay->sessions = session;
- delay->num_sessions += 1;
-
- session->expiration = qemu_get_clock( SHAPER_CLOCK ) + latency;
-
- session->src_ip = info->src_ip;
- session->dst_ip = info->dst_ip;
- session->src_port = info->src_port;
- session->dst_port = info->dst_port;
- session->protocol = info->protocol;
-
- session->packet = queued_packet_create( data, size, opaque, 1 );
-
- netdelay_expires(delay);
- return;
- }
- }
- }
-
- delay->send_func( (void*)data, size, opaque );
-}
-
-
-void
-netdelay_destroy( NetDelay delay )
-{
- if (delay) {
- while (delay->sessions) {
- Session session = delay->sessions;
- delay->sessions = session->next;
- session_free(session);
- delay->num_sessions -= 1;
- }
- delay->active = 0;
- qemu_free( delay );
- }
-}
-
diff --git a/shaper.h b/shaper.h
deleted file mode 100644
index 45dbd5b..0000000
--- a/shaper.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _SLIRP_SHAPER_H_
-#define _SLIRP_SHAPER_H_
-
-#include <stddef.h>
-
-/* a NetShaper object is used to limit the throughput of data packets
- * at a fixed rate expressed in bits/seconds
- */
-typedef struct NetShaperRec_* NetShaper;
-typedef void (*NetShaperSendFunc)( void* data, size_t size, void* opaque);
-
-NetShaper netshaper_create ( int do_copy,
- NetShaperSendFunc send_func );
-
-void netshaper_set_rate(NetShaper shaper, double rate );
-
-void netshaper_send( NetShaper shaper, void* data, size_t size );
-
-void netshaper_send_aux( NetShaper shaper, void* data, size_t size, void* opaque );
-
-int netshaper_can_send( NetShaper shaper );
-
-void netshaper_destroy (NetShaper shaper);
-
-/* a NetDelay object is used to simulate network connection latencies */
-typedef struct NetDelayRec_* NetDelay;
-
-NetDelay netdelay_create( NetShaperSendFunc send_func );
-void netdelay_set_latency( NetDelay delay, int min_ms, int max_ms );
-void netdelay_send( NetDelay delay, const void* data, size_t size );
-void netdelay_send_aux( NetDelay delay, const void* data, size_t size, void* opaque );
-void netdelay_destroy( NetDelay delay );
-
-/** in vl.c */
-/* network traffic shaper and delayer */
-extern NetShaper slirp_shaper_in;
-extern NetShaper slirp_shaper_out;
-extern NetDelay slirp_delay_in;
-
-#endif /* _SLIRP_SHAPER_H_ */
diff --git a/slirp2/COPYRIGHT b/slirp2/COPYRIGHT
deleted file mode 100644
index 2e86862..0000000
--- a/slirp2/COPYRIGHT
+++ /dev/null
@@ -1,64 +0,0 @@
-Slirp was written by Danny Gasparovski.
-Copyright (c), 1995,1996 All Rights Reserved.
-
-Slirp is maintained by Kelly Price <tygris+slirp@erols.com>
-
-Slirp is free software; "free" as in you don't have to pay for it, and you
-are free to do whatever you want with it. I do not accept any donations,
-monetary or otherwise, for Slirp. Instead, I would ask you to pass this
-potential donation to your favorite charity. In fact, I encourage
-*everyone* who finds Slirp useful to make a small donation to their
-favorite charity (for example, GreenPeace). This is not a requirement, but
-a suggestion from someone who highly values the service they provide.
-
-The copyright terms and conditions:
-
----BEGIN---
-
- Copyright (c) 1995,1996 Danny Gasparovski. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this software
- must display the following acknowledgment:
- This product includes software developed by Danny Gasparovski.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- DANNY GASPAROVSKI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
----END---
-
-This basically means you can do anything you want with the software, except
-1) call it your own, and 2) claim warranty on it. There is no warranty for
-this software. None. Nada. If you lose a million dollars while using
-Slirp, that's your loss not mine. So, ***USE AT YOUR OWN RISK!***.
-
-If these conditions cannot be met due to legal restrictions (E.g. where it
-is against the law to give out Software without warranty), you must cease
-using the software and delete all copies you have.
-
-Slirp uses code that is copyrighted by the following people/organizations:
-
-Juha Pirkola.
-Gregory M. Christy.
-The Regents of the University of California.
-Carnegie Mellon University.
-The Australian National University.
-RSA Data Security, Inc.
-
-Please read the top of each source file for the details on the various
-copyrights.
diff --git a/slirp2/bootp.c b/slirp2/bootp.c
deleted file mode 100644
index 9ab4b15..0000000
--- a/slirp2/bootp.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * QEMU BOOTP/DHCP server
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <slirp.h>
-
-/* XXX: only DHCP is supported */
-
-#define NB_ADDR 16
-
-#define START_ADDR 15
-
-#define LEASE_TIME (24 * 3600)
-
-typedef struct {
- uint8_t allocated;
- uint8_t macaddr[6];
-} BOOTPClient;
-
-BOOTPClient bootp_clients[NB_ADDR];
-
-const char *bootp_filename;
-
-static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
-
-#ifdef DEBUG
-#define dprintf(fmt, args...) \
-if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ## args); fflush(dfd); }
-#else
-#define dprintf(fmt, args...)
-#endif
-
-static BOOTPClient *get_new_addr(SockAddress* paddr)
-{
- BOOTPClient *bc;
- int i;
-
- for(i = 0; i < NB_ADDR; i++) {
- if (!bootp_clients[i].allocated)
- goto found;
- }
- return NULL;
- found:
- bc = &bootp_clients[i];
- bc->allocated = 1;
- sock_address_init_inet( paddr,
- special_addr_ip | (i+START_ADDR),
- BOOTP_CLIENT );
- return bc;
-}
-
-static BOOTPClient *find_addr(SockAddress* paddr, const uint8_t *macaddr)
-{
- BOOTPClient *bc;
- int i;
-
- for(i = 0; i < NB_ADDR; i++) {
- if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
- goto found;
- }
- return NULL;
- found:
- bc = &bootp_clients[i];
- bc->allocated = 1;
- sock_address_init_inet( paddr,
- special_addr_ip | (i + START_ADDR),
- BOOTP_CLIENT );
- return bc;
-}
-
-static void dhcp_decode(const uint8_t *buf, int size,
- int *pmsg_type)
-{
- const uint8_t *p, *p_end;
- int len, tag;
-
- *pmsg_type = 0;
-
- p = buf;
- p_end = buf + size;
- if (size < 5)
- return;
- if (memcmp(p, rfc1533_cookie, 4) != 0)
- return;
- p += 4;
- while (p < p_end) {
- tag = p[0];
- if (tag == RFC1533_PAD) {
- p++;
- } else if (tag == RFC1533_END) {
- break;
- } else {
- p++;
- if (p >= p_end)
- break;
- len = *p++;
- dprintf("dhcp: tag=0x%02x len=%d\n", tag, len);
-
- switch(tag) {
- case RFC2132_MSG_TYPE:
- if (len >= 1)
- *pmsg_type = p[0];
- break;
- default:
- break;
- }
- p += len;
- }
- }
-}
-
-static void bootp_reply(struct bootp_t *bp)
-{
- BOOTPClient *bc;
- MBuf m;
- struct bootp_t *rbp;
- SockAddress saddr, daddr;
- uint32_t dns_addr;
- int dhcp_msg_type, val;
- uint8_t *q;
-
- /* extract exact DHCP msg type */
- dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
- dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
-
- if (dhcp_msg_type == 0)
- dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
-
- if (dhcp_msg_type != DHCPDISCOVER &&
- dhcp_msg_type != DHCPREQUEST)
- return;
- /* XXX: this is a hack to get the client mac address */
- memcpy(client_ethaddr, bp->bp_hwaddr, 6);
-
- if ((m = mbuf_alloc()) == NULL)
- return;
- m->m_data += if_maxlinkhdr;
- rbp = (struct bootp_t *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
- memset(rbp, 0, sizeof(struct bootp_t));
-
- if (dhcp_msg_type == DHCPDISCOVER) {
- new_addr:
- bc = get_new_addr(&daddr);
- if (!bc) {
- dprintf("no address left\n");
- return;
- }
- memcpy(bc->macaddr, client_ethaddr, 6);
- } else {
- bc = find_addr(&daddr, bp->bp_hwaddr);
- if (!bc) {
- /* if never assigned, behaves as if it was already
- assigned (windows fix because it remembers its address) */
- goto new_addr;
- }
- }
- if (bootp_filename)
- snprintf((char*)rbp->bp_file, sizeof(rbp->bp_file), "%s", bootp_filename);
-
- dprintf("offered addr=%s\n", sock_address_to_string(&daddr));
-
- sock_address_init_inet( &saddr, special_addr_ip | CTL_ALIAS,
- BOOTP_SERVER );
-
- rbp->bp_op = BOOTP_REPLY;
- rbp->bp_xid = bp->bp_xid;
- rbp->bp_htype = 1;
- rbp->bp_hlen = 6;
- memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);
-
- rbp->bp_yiaddr = htonl(sock_address_get_ip(&daddr)); /* Client IP address */
- rbp->bp_siaddr = htonl(sock_address_get_ip(&saddr)); /* Server IP address */
-
- q = rbp->bp_vend;
- memcpy(q, rfc1533_cookie, 4);
- q += 4;
-
- if (dhcp_msg_type == DHCPDISCOVER) {
- *q++ = RFC2132_MSG_TYPE;
- *q++ = 1;
- *q++ = DHCPOFFER;
- } else if (dhcp_msg_type == DHCPREQUEST) {
- *q++ = RFC2132_MSG_TYPE;
- *q++ = 1;
- *q++ = DHCPACK;
- }
-
- if (dhcp_msg_type == DHCPDISCOVER ||
- dhcp_msg_type == DHCPREQUEST) {
- uint32_t saddr_ip = htonl(sock_address_get_ip(&saddr));
- *q++ = RFC2132_SRV_ID;
- *q++ = 4;
- memcpy(q, &saddr_ip, 4);
- q += 4;
-
- *q++ = RFC1533_NETMASK;
- *q++ = 4;
- *q++ = 0xff;
- *q++ = 0xff;
- *q++ = 0xff;
- *q++ = 0x00;
-
- *q++ = RFC1533_GATEWAY;
- *q++ = 4;
- memcpy(q, &saddr_ip, 4);
- q += 4;
-
- *q++ = RFC1533_DNS;
- *q++ = 4;
- dns_addr = htonl(special_addr_ip | CTL_DNS);
- memcpy(q, &dns_addr, 4);
- q += 4;
-
- *q++ = RFC2132_LEASE_TIME;
- *q++ = 4;
- val = htonl(LEASE_TIME);
- memcpy(q, &val, 4);
- q += 4;
-
- if (*slirp_hostname) {
- val = strlen(slirp_hostname);
- *q++ = RFC1533_HOSTNAME;
- *q++ = val;
- memcpy(q, slirp_hostname, val);
- q += val;
- }
- }
- *q++ = RFC1533_END;
-
- m->m_len = sizeof(struct bootp_t) -
- sizeof(struct ip) - sizeof(struct udphdr);
-
- udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-}
-
-void bootp_input(MBuf m)
-{
- struct bootp_t *bp = MBUF_TO(m, struct bootp_t *);
-
- if (bp->bp_op == BOOTP_REQUEST) {
- bootp_reply(bp);
- }
-}
diff --git a/slirp2/bootp.h b/slirp2/bootp.h
deleted file mode 100644
index fbc96ac..0000000
--- a/slirp2/bootp.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* bootp/dhcp defines */
-
-#define BOOTP_SERVER 67
-#define BOOTP_CLIENT 68
-
-#define BOOTP_REQUEST 1
-#define BOOTP_REPLY 2
-
-#define RFC1533_COOKIE 99, 130, 83, 99
-#define RFC1533_PAD 0
-#define RFC1533_NETMASK 1
-#define RFC1533_TIMEOFFSET 2
-#define RFC1533_GATEWAY 3
-#define RFC1533_TIMESERVER 4
-#define RFC1533_IEN116NS 5
-#define RFC1533_DNS 6
-#define RFC1533_LOGSERVER 7
-#define RFC1533_COOKIESERVER 8
-#define RFC1533_LPRSERVER 9
-#define RFC1533_IMPRESSSERVER 10
-#define RFC1533_RESOURCESERVER 11
-#define RFC1533_HOSTNAME 12
-#define RFC1533_BOOTFILESIZE 13
-#define RFC1533_MERITDUMPFILE 14
-#define RFC1533_DOMAINNAME 15
-#define RFC1533_SWAPSERVER 16
-#define RFC1533_ROOTPATH 17
-#define RFC1533_EXTENSIONPATH 18
-#define RFC1533_IPFORWARDING 19
-#define RFC1533_IPSOURCEROUTING 20
-#define RFC1533_IPPOLICYFILTER 21
-#define RFC1533_IPMAXREASSEMBLY 22
-#define RFC1533_IPTTL 23
-#define RFC1533_IPMTU 24
-#define RFC1533_IPMTUPLATEAU 25
-#define RFC1533_INTMTU 26
-#define RFC1533_INTLOCALSUBNETS 27
-#define RFC1533_INTBROADCAST 28
-#define RFC1533_INTICMPDISCOVER 29
-#define RFC1533_INTICMPRESPOND 30
-#define RFC1533_INTROUTEDISCOVER 31
-#define RFC1533_INTROUTESOLICIT 32
-#define RFC1533_INTSTATICROUTES 33
-#define RFC1533_LLTRAILERENCAP 34
-#define RFC1533_LLARPCACHETMO 35
-#define RFC1533_LLETHERNETENCAP 36
-#define RFC1533_TCPTTL 37
-#define RFC1533_TCPKEEPALIVETMO 38
-#define RFC1533_TCPKEEPALIVEGB 39
-#define RFC1533_NISDOMAIN 40
-#define RFC1533_NISSERVER 41
-#define RFC1533_NTPSERVER 42
-#define RFC1533_VENDOR 43
-#define RFC1533_NBNS 44
-#define RFC1533_NBDD 45
-#define RFC1533_NBNT 46
-#define RFC1533_NBSCOPE 47
-#define RFC1533_XFS 48
-#define RFC1533_XDM 49
-
-#define RFC2132_REQ_ADDR 50
-#define RFC2132_LEASE_TIME 51
-#define RFC2132_MSG_TYPE 53
-#define RFC2132_SRV_ID 54
-#define RFC2132_PARAM_LIST 55
-#define RFC2132_MAX_SIZE 57
-#define RFC2132_RENEWAL_TIME 58
-#define RFC2132_REBIND_TIME 59
-
-#define DHCPDISCOVER 1
-#define DHCPOFFER 2
-#define DHCPREQUEST 3
-#define DHCPACK 5
-
-#define RFC1533_VENDOR_MAJOR 0
-#define RFC1533_VENDOR_MINOR 0
-
-#define RFC1533_VENDOR_MAGIC 128
-#define RFC1533_VENDOR_ADDPARM 129
-#define RFC1533_VENDOR_ETHDEV 130
-#define RFC1533_VENDOR_HOWTO 132
-#define RFC1533_VENDOR_MNUOPTS 160
-#define RFC1533_VENDOR_SELECTION 176
-#define RFC1533_VENDOR_MOTD 184
-#define RFC1533_VENDOR_NUMOFMOTD 8
-#define RFC1533_VENDOR_IMG 192
-#define RFC1533_VENDOR_NUMOFIMG 16
-
-#define RFC1533_END 255
-#define BOOTP_VENDOR_LEN 64
-#define DHCP_OPT_LEN 312
-
-struct bootp_t {
- struct ip ip;
- struct udphdr udp;
- uint8_t bp_op;
- uint8_t bp_htype;
- uint8_t bp_hlen;
- uint8_t bp_hops;
- uint32_t bp_xid;
- uint16_t bp_secs;
- uint16_t unused;
- uint32_t bp_ciaddr;
- uint32_t bp_yiaddr;
- uint32_t bp_siaddr;
- uint32_t bp_giaddr;
- uint8_t bp_hwaddr[16];
- uint8_t bp_sname[64];
- uint8_t bp_file[128];
- uint8_t bp_vend[DHCP_OPT_LEN];
-};
-
-void bootp_input(MBuf m);
diff --git a/slirp2/cksum.c b/slirp2/cksum.c
deleted file mode 100644
index 9474b9e..0000000
--- a/slirp2/cksum.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 1988, 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
- * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
- */
-
-#include <slirp.h>
-
-/*
- * Checksum routine for Internet Protocol family headers (Portable Version).
- *
- * This routine is very heavily used in the network
- * code and should be modified for each CPU to be as fast as possible.
- *
- * XXX Since we will never span more than 1 mbuf, we can optimise this
- */
-
-#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
-#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
-
-int cksum(MBuf m, int len)
-{
- register u_int16_t *w;
- register int sum = 0;
- register int mlen = 0;
- int byte_swapped = 0;
-
- union {
- u_int8_t c[2];
- u_int16_t s;
- } s_util;
- union {
- u_int16_t s[2];
- u_int32_t l;
- } l_util;
-
- if (m->m_len == 0)
- goto cont;
- w = MBUF_TO(m, u_int16_t *);
-
- mlen = m->m_len;
-
- if (len < mlen)
- mlen = len;
- len -= mlen;
- /*
- * Force to even boundary.
- */
- if ((1 & (long) w) && (mlen > 0)) {
- REDUCE;
- sum <<= 8;
- s_util.c[0] = *(u_int8_t *)w;
- w = (u_int16_t *)((int8_t *)w + 1);
- mlen--;
- byte_swapped = 1;
- }
- /*
- * Unroll the loop to make overhead from
- * branches &c small.
- */
- while ((mlen -= 32) >= 0) {
- sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
- sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
- sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
- sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
- w += 16;
- }
- mlen += 32;
- while ((mlen -= 8) >= 0) {
- sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
- w += 4;
- }
- mlen += 8;
- if (mlen == 0 && byte_swapped == 0)
- goto cont;
- REDUCE;
- while ((mlen -= 2) >= 0) {
- sum += *w++;
- }
-
- if (byte_swapped) {
- REDUCE;
- sum <<= 8;
- byte_swapped = 0;
- if (mlen == -1) {
- s_util.c[1] = *(u_int8_t *)w;
- sum += s_util.s;
- mlen = 0;
- } else
-
- mlen = -1;
- } else if (mlen == -1)
- s_util.c[0] = *(u_int8_t *)w;
-
-cont:
-#ifdef DEBUG
- if (len) {
- DEBUG_ERROR((dfd, "cksum: out of data\n"));
- DEBUG_ERROR((dfd, " len = %d\n", len));
- }
-#endif
- if (mlen == -1) {
- /* The last mbuf has odd # of bytes. Follow the
- standard (the odd byte may be shifted left by 8 bits
- or not as determined by endian-ness of the machine) */
- s_util.c[1] = 0;
- sum += s_util.s;
- }
- REDUCE;
- return (~sum & 0xffff);
-}
diff --git a/slirp2/ctl.h b/slirp2/ctl.h
deleted file mode 100644
index 854ae9a..0000000
--- a/slirp2/ctl.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#define CTL_CMD 0
-#define CTL_EXEC 1
-#define CTL_ALIAS 2
-#define CTL_DNS 3
-/* NOTE: DNS_ADDR_MAX addresses, starting from CTL_DNS, are reserved */
-
-#define CTL_IS_DNS(x) ((unsigned)((x)-CTL_DNS) < (unsigned)dns_addr_count)
-
-#define CTL_SPECIAL "10.0.2.0"
-#define CTL_LOCAL "10.0.2.15"
diff --git a/slirp2/debug.c b/slirp2/debug.c
deleted file mode 100644
index f3a424d..0000000
--- a/slirp2/debug.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- * Portions copyright (c) 2000 Kelly Price.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-FILE *dfd = NULL;
-#ifdef DEBUG
-int dostats = 1;
-#else
-int dostats = 0;
-#endif
-int slirp_debug = 0;
-
-extern char *strerror _P((int));
-
-/* Carry over one item from main.c so that the tty's restored.
- * Only done when the tty being used is /dev/tty --RedWolf */
-extern struct termios slirp_tty_settings;
-extern int slirp_tty_restore;
-
-
-void
-debug_init(file, dbg)
- char *file;
- int dbg;
-{
- /* Close the old debugging file */
- if (dfd)
- fclose(dfd);
-
- dfd = fopen(file,"w");
- if (dfd != NULL) {
-#if 0
- fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION);
-#endif
- fprintf(dfd,"Debugging Started level %i.\r\n",dbg);
- fflush(dfd);
- slirp_debug = dbg;
- } else {
- fprintf(stderr, "Error: Debugging file \"%s\" could not be opened: %s\r\n",
- file, strerror(errno));
- }
-}
-
-/*
- * Dump a packet in the same format as tcpdump -x
- */
-#ifdef DEBUG
-void
-dump_packet(dat, n)
- void *dat;
- int n;
-{
- u_char *pptr = (u_char *)dat;
- int j,k;
-
- n /= 16;
- n++;
- DEBUG_MISC((dfd, "PACKET DUMPED: \n"));
- for(j = 0; j < n; j++) {
- for(k = 0; k < 6; k++)
- DEBUG_MISC((dfd, "%02x ", *pptr++));
- DEBUG_MISC((dfd, "\n"));
- fflush(dfd);
- }
-}
-#endif
-
-#if 0
-/*
- * Statistic routines
- *
- * These will print statistics to the screen, the debug file (dfd), or
- * a buffer, depending on "type", so that the stats can be sent over
- * the link as well.
- */
-
-void
-ttystats(ttyp)
- struct ttys *ttyp;
-{
- struct slirp_ifstats *is = &ttyp->ifstats;
- char buff[512];
-
- lprint(" \r\n");
-
- if (if_comp & IF_COMPRESS)
- strcpy(buff, "on");
- else if (if_comp & IF_NOCOMPRESS)
- strcpy(buff, "off");
- else
- strcpy(buff, "off (for now)");
- lprint("Unit %d:\r\n", ttyp->unit);
- lprint(" using %s encapsulation (VJ compression is %s)\r\n", (
-#ifdef USE_PPP
- ttyp->proto==PROTO_PPP?"PPP":
-#endif
- "SLIP"), buff);
- lprint(" %d baudrate\r\n", ttyp->baud);
- lprint(" interface is %s\r\n", ttyp->up?"up":"down");
- lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid);
-#ifndef FULL_BOLT
- lprint(" towrite is %d bytes\r\n", ttyp->towrite);
-#endif
- if (ttyp->zeros)
- lprint(" %d zeros have been typed\r\n", ttyp->zeros);
- else if (ttyp->ones)
- lprint(" %d ones have been typed\r\n", ttyp->ones);
- lprint("Interface stats:\r\n");
- lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes);
- lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes);
- lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes);
- lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes);
- lprint(" %6d bad input packets\r\n", is->in_mbad);
-}
-
-void
-allttystats()
-{
- struct ttys *ttyp;
-
- for (ttyp = ttys; ttyp; ttyp = ttyp->next)
- ttystats(ttyp);
-}
-#endif
-
-void
-ipstats()
-{
- lprint(" \r\n");
-
- lprint("IP stats:\r\n");
- lprint(" %6d total packets received (%d were unaligned)\r\n",
- ipstat.ips_total, ipstat.ips_unaligned);
- lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers);
- lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum);
- lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort);
- lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall);
- lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen);
- lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen);
- lprint(" %6d fragments received\r\n", ipstat.ips_fragments);
- lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped);
- lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout);
- lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled);
- lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented);
- lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments);
- lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto);
- lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered);
-}
-
-#if 0
-void
-vjstats()
-{
- lprint(" \r\n");
-
- lprint("VJ compression stats:\r\n");
-
- lprint(" %6d outbound packets (%d compressed)\r\n",
- comp_s.sls_packets, comp_s.sls_compressed);
- lprint(" %6d searches for connection stats (%d misses)\r\n",
- comp_s.sls_searches, comp_s.sls_misses);
- lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin);
- lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin);
- lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin);
- lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed);
-}
-#endif
-
-void
-tcpstats()
-{
- lprint(" \r\n");
-
- lprint("TCP stats:\r\n");
-
- lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal);
- lprint(" %6d data packets (%d bytes)\r\n",
- tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte);
- lprint(" %6d data packets retransmitted (%d bytes)\r\n",
- tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte);
- lprint(" %6d ack-only packets (%d delayed)\r\n",
- tcpstat.tcps_sndacks, tcpstat.tcps_delack);
- lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg);
- lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe);
- lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup);
- lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl);
- lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin);
-
- lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal);
- lprint(" %6d acks (for %d bytes)\r\n",
- tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte);
- lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack);
- lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch);
- lprint(" %6d packets received in sequence (%d bytes)\r\n",
- tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte);
- lprint(" %6d completely duplicate packets (%d bytes)\r\n",
- tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte);
-
- lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n",
- tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte);
- lprint(" %6d out-of-order packets (%d bytes)\r\n",
- tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte);
- lprint(" %6d packets of data after window (%d bytes)\r\n",
- tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin);
- lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe);
- lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd);
- lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose);
- lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum);
- lprint(" %6d discarded for bad header offset fields\r\n",
- tcpstat.tcps_rcvbadoff);
-
- lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt);
- lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts);
- lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects);
- lprint(" %6d connections closed (including %d drop)\r\n",
- tcpstat.tcps_closed, tcpstat.tcps_drops);
- lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops);
- lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n",
- tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated);
- lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo);
- lprint(" %6d connections dropped by rxmt timeout\r\n",
- tcpstat.tcps_timeoutdrop);
- lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo);
- lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo);
- lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe);
- lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops);
- lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack);
- lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat);
- lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss);
-
-
-/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */
-/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */
-
-}
-
-void
-udpstats()
-{
- lprint(" \r\n");
-
- lprint("UDP stats:\r\n");
- lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets);
- lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops);
- lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum);
- lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen);
- lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss);
- lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets);
-}
-
-void
-icmpstats()
-{
- lprint(" \r\n");
- lprint("ICMP stats:\r\n");
- lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received);
- lprint(" %6d were too short\r\n", icmpstat.icps_tooshort);
- lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum);
- lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp);
- lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype);
- lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
-}
-
-void
-sockstats()
-{
- char buff[256];
- int n;
- struct socket *so;
-
- lprint(" \r\n");
-
- lprint(
- "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n");
-
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
-
- n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");
- while (n < 17)
- buff[n++] = ' ';
- buff[17] = 0;
- lprint("%s %3d %15s %5d ",
- buff, so->s,
- inet_iptostr(so->so_laddr_ip), so->so_laddr_port);
- lprint("%15s %5d %5d %5d\r\n",
- inet_iptostr(so->so_faddr_ip), so->so_faddr_port,
- so->so_rcv.sb_cc, so->so_snd.sb_cc);
- }
-
- for (so = udb.so_next; so != &udb; so = so->so_next) {
-
- n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);
- while (n < 17)
- buff[n++] = ' ';
- buff[17] = 0;
- lprint("%s %3d %15s %5d ",
- buff, so->s,
- inet_iptostr(so->so_laddr_ip), so->so_laddr_port);
- lprint("%15s %5d %5d %5d\r\n",
- inet_iptostr(so->so_faddr_ip), so->so_faddr_port,
- so->so_rcv.sb_cc, so->so_snd.sb_cc);
- }
-}
-
-#if 0
-void
-slirp_exit(exit_status)
- int exit_status;
-{
- struct ttys *ttyp;
-
- DEBUG_CALL("slirp_exit");
- DEBUG_ARG("exit_status = %d", exit_status);
-
- if (dostats) {
- lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf;
- if (!dfd)
- debug_init("slirp_stats", 0xf);
- lprint_arg = (char **)&dfd;
-
- ipstats();
- tcpstats();
- udpstats();
- icmpstats();
- mbufstats();
- sockstats();
- allttystats();
- vjstats();
- }
-
- for (ttyp = ttys; ttyp; ttyp = ttyp->next)
- tty_detached(ttyp, 1);
-
- if (slirp_forked) {
- /* Menendez time */
- if (kill(getppid(), SIGQUIT) < 0)
- lprint("Couldn't kill parent process %ld!\n",
- (long) getppid());
- }
-
- /* Restore the terminal if we gotta */
- if(slirp_tty_restore)
- tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */
- exit(exit_status);
-}
-#endif
diff --git a/slirp2/debug.h b/slirp2/debug.h
deleted file mode 100644
index 6e8444d..0000000
--- a/slirp2/debug.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define PRN_STDERR 1
-#define PRN_SPRINTF 2
-
-extern FILE *dfd;
-extern FILE *lfd;
-extern int dostats;
-extern int slirp_debug;
-
-#define DBG_CALL 0x1
-#define DBG_MISC 0x2
-#define DBG_ERROR 0x4
-#define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR
-
-#ifdef DEBUG
-#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); }
-#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); }
-#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); }
-#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); }
-#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); }
-
-
-#else
-
-#define DEBUG_CALL(x)
-#define DEBUG_ARG(x, y)
-#define DEBUG_ARGS(x)
-#define DEBUG_MISC(x)
-#define DEBUG_ERROR(x)
-
-#endif
-
-void debug_init _P((char *, int));
-//void ttystats _P((struct ttys *));
-void allttystats _P((void));
-void ipstats _P((void));
-void vjstats _P((void));
-void tcpstats _P((void));
-void udpstats _P((void));
-void icmpstats _P((void));
-void mbufstats _P((void));
-void sockstats _P((void));
-void slirp_exit _P((int));
-
diff --git a/slirp2/helper.h b/slirp2/helper.h
deleted file mode 100644
index e247f46..0000000
--- a/slirp2/helper.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2009 The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef _SLIRP_HELPER_H
-#define _SLIRP_HELPER_H
-
-typedef union {
- u_int32_t addr;
- u_int8_t data[4];
-} ipaddr_t;
-
-/* return ip address in network order */
-static __inline__ uint32_t
-ip_getn( ipaddr_t ip )
-{
- return ip.addr;
-}
-
-/* return ip address in host order */
-static __inline__ uint32_t
-ip_geth( ipaddr_t ip )
-{
- return ntohl(ip.addr);
-}
-
-/* set ip address in network order */
-static __inline__ ipaddr_t
-ip_setn( uint32_t val )
-{
- ipaddr_t ip;
- ip.addr = val;
- return ip;
-}
-
-/* set ip address in host order */
-static __inline__ ipaddr_t
-ip_seth( uint32_t val )
-{
- ipaddr_t ip;
- ip.addr = htonl(val);
- return ip;
-}
-
-static __inline__ int
-ip_equal( ipaddr_t ip1, ipaddr_t ip2 )
-{
- return ip1.addr == ip2.addr;
-}
-
-typedef union {
- u_int16_t port;
- u_int8_t data[2];
-} port_t;
-
-static __inline__ uint16_t
-port_getn( port_t p )
-{
- return p.port;
-}
-
-static __inline__ uint16_t
-port_geth( port_t p )
-{
- return ntohs(p.port);
-}
-
-static __inline__ port_t
-port_setn( uint16_t val )
-{
- port_t p;
- p.port = val;
- return p;
-}
-
-static __inline__ port_t
-port_seth( uint16_t val )
-{
- port_t p;
- p.port = htons(val);
- return p;
-}
-
-#endif /* _SLIRP_HELPER_H */
diff --git a/slirp2/icmp_var.h b/slirp2/icmp_var.h
deleted file mode 100644
index 03fc8c3..0000000
--- a/slirp2/icmp_var.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93
- * icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp
- */
-
-#ifndef _NETINET_ICMP_VAR_H_
-#define _NETINET_ICMP_VAR_H_
-
-/*
- * Variables related to this implementation
- * of the internet control message protocol.
- */
-struct icmpstat {
-/* statistics related to input messages processed */
- u_long icps_received; /* #ICMP packets received */
- u_long icps_tooshort; /* packet < ICMP_MINLEN */
- u_long icps_checksum; /* bad checksum */
- u_long icps_notsupp; /* #ICMP packets not supported */
- u_long icps_badtype; /* #with bad type feild */
- u_long icps_reflect; /* number of responses */
-};
-
-/*
- * Names for ICMP sysctl objects
- */
-#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */
-#define ICMPCTL_STATS 2 /* statistics (read-only) */
-#define ICMPCTL_MAXID 3
-
-#define ICMPCTL_NAMES { \
- { 0, 0 }, \
- { "maskrepl", CTLTYPE_INT }, \
- { "stats", CTLTYPE_STRUCT }, \
-}
-
-extern struct icmpstat icmpstat;
-
-#endif
diff --git a/slirp2/if.c b/slirp2/if.c
deleted file mode 100644
index cd96e65..0000000
--- a/slirp2/if.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-int if_mtu, if_mru;
-int if_comp;
-int if_maxlinkhdr;
-int if_queued = 0; /* Number of packets queued so far */
-int if_thresh = 10; /* Number of packets queued before we start sending
- * (to prevent allocing too many mbufs) */
-
-struct mbuf if_fastq; /* fast queue (for interactive data) */
-struct mbuf if_batchq; /* queue for non-interactive data */
-struct mbuf *next_m; /* Pointer to next mbuf to output */
-
-#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
-
-void
-ifs_insque(ifm, ifmhead)
- MBuf ifm, ifmhead;
-{
- ifm->ifs_next = ifmhead->ifs_next;
- ifmhead->ifs_next = ifm;
- ifm->ifs_prev = ifmhead;
- ifm->ifs_next->ifs_prev = ifm;
-}
-
-void
-ifs_remque(ifm)
- MBuf ifm;
-{
- ifm->ifs_prev->ifs_next = ifm->ifs_next;
- ifm->ifs_next->ifs_prev = ifm->ifs_prev;
-}
-
-void
-if_init()
-{
-#if 0
- /*
- * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP,
- * and 8 bytes for PPP, but need to have it on an 8byte boundary
- */
-#ifdef USE_PPP
- if_maxlinkhdr = 48;
-#else
- if_maxlinkhdr = 40;
-#endif
-#else
- /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
- if_maxlinkhdr = 2 + 14 + 40;
-#endif
- if_mtu = 1500;
- if_mru = 1500;
- if_comp = IF_AUTOCOMP;
- if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
- if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
- // sl_compress_init(&comp_s);
- next_m = &if_batchq;
-}
-
-#if 0
-/*
- * This shouldn't be needed since the modem is blocking and
- * we don't expect any signals, but what the hell..
- */
-inline int
-writen(fd, bptr, n)
- int fd;
- char *bptr;
- int n;
-{
- int ret;
- int total;
-
- /* This should succeed most of the time */
- ret = socket_send(fd, bptr, n);
- if (ret == n || ret <= 0)
- return ret;
-
- /* Didn't write everything, go into the loop */
- total = ret;
- while (n > total) {
- ret = socket_send(fd, bptr+total, n-total);
- if (ret <= 0)
- return ret;
- total += ret;
- }
- return total;
-}
-
-/*
- * if_input - read() the tty, do "top level" processing (ie: check for any escapes),
- * and pass onto (*ttyp->if_input)
- *
- * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet.
- */
-#define INBUFF_SIZE 2048 /* XXX */
-void
-if_input(ttyp)
- struct ttys *ttyp;
-{
- u_char if_inbuff[INBUFF_SIZE];
- int if_n;
-
- DEBUG_CALL("if_input");
- DEBUG_ARG("ttyp = %lx", (long)ttyp);
-
- if_n = socket_recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE);
-
- DEBUG_MISC((dfd, " read %d bytes\n", if_n));
-
- if (if_n <= 0) {
- if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) {
- if (ttyp->up)
- link_up--;
- tty_detached(ttyp, 0);
- }
- return;
- }
- if (if_n == 1) {
- if (*if_inbuff == '0') {
- ttyp->ones = 0;
- if (++ttyp->zeros >= 5)
- slirp_exit(0);
- return;
- }
- if (*if_inbuff == '1') {
- ttyp->zeros = 0;
- if (++ttyp->ones >= 5)
- tty_detached(ttyp, 0);
- return;
- }
- }
- ttyp->ones = ttyp->zeros = 0;
-
- (*ttyp->if_input)(ttyp, if_inbuff, if_n);
-}
-#endif
-
-/*
- * if_output: Queue packet into an output queue.
- * There are 2 output queue's, if_fastq and if_batchq.
- * Each output queue is a doubly linked list of double linked lists
- * of mbufs, each list belonging to one "session" (socket). This
- * way, we can output packets fairly by sending one packet from each
- * session, instead of all the packets from one session, then all packets
- * from the next session, etc. Packets on the if_fastq get absolute
- * priority, but if one session hogs the link, it gets "downgraded"
- * to the batchq until it runs out of packets, then it'll return
- * to the fastq (eg. if the user does an ls -alR in a telnet session,
- * it'll temporarily get downgraded to the batchq)
- */
-void
-if_output(so, ifm)
- struct socket *so;
- MBuf ifm;
-{
- MBuf ifq;
- int on_fastq = 1;
-
- DEBUG_CALL("if_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("ifm = %lx", (long)ifm);
-
- /*
- * First remove the mbuf from m_usedlist,
- * since we're gonna use m_next and m_prev ourselves
- * XXX Shouldn't need this, gotta change dtom() etc.
- */
- if (ifm->m_flags & M_USEDLIST) {
- remque(ifm);
- ifm->m_flags &= ~M_USEDLIST;
- }
-
- /*
- * See if there's already a batchq list for this session.
- * This can include an interactive session, which should go on fastq,
- * but gets too greedy... hence it'll be downgraded from fastq to batchq.
- * We mustn't put this packet back on the fastq (or we'll send it out of order)
- * XXX add cache here?
- */
- for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) {
- if (so == ifq->ifq_so) {
- /* A match! */
- ifm->ifq_so = so;
- ifs_insque(ifm, ifq->ifs_prev);
- goto diddit;
- }
- }
-
- /* No match, check which queue to put it on */
- if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
- ifq = if_fastq.ifq_prev;
- on_fastq = 1;
- /*
- * Check if this packet is a part of the last
- * packet's session
- */
- if (ifq->ifq_so == so) {
- ifm->ifq_so = so;
- ifs_insque(ifm, ifq->ifs_prev);
- goto diddit;
- }
- } else
- ifq = if_batchq.ifq_prev;
-
- /* Create a new doubly linked list for this session */
- ifm->ifq_so = so;
- ifs_init(ifm);
- insque(ifm, ifq);
-
-diddit:
- ++if_queued;
-
- if (so) {
- /* Update *_queued */
- so->so_queued++;
- so->so_nqueued++;
- /*
- * Check if the interactive session should be downgraded to
- * the batchq. A session is downgraded if it has queued 6
- * packets without pausing, and at least 3 of those packets
- * have been sent over the link
- * (XXX These are arbitrary numbers, probably not optimal..)
- */
- if (on_fastq && ((so->so_nqueued >= 6) &&
- (so->so_nqueued - so->so_queued) >= 3)) {
-
- /* Remove from current queue... */
- remque(ifm->ifs_next);
-
- /* ...And insert in the new. That'll teach ya! */
- insque(ifm->ifs_next, &if_batchq);
- }
- }
-
-#ifndef FULL_BOLT
- /*
- * This prevents us from malloc()ing too many mbufs
- */
- if (link_up) {
- /* if_start will check towrite */
- if_start();
- }
-#endif
-}
-
-/*
- * Send a packet
- * We choose a packet based on it's position in the output queues;
- * If there are packets on the fastq, they are sent FIFO, before
- * everything else. Otherwise we choose the first packet from the
- * batchq and send it. the next packet chosen will be from the session
- * after this one, then the session after that one, and so on.. So,
- * for example, if there are 3 ftp session's fighting for bandwidth,
- * one packet will be sent from the first session, then one packet
- * from the second session, then one packet from the third, then back
- * to the first, etc. etc.
- */
-void
-if_start(void)
-{
- MBuf ifm, ifqt;
-
- DEBUG_CALL("if_start");
-
- if (if_queued == 0)
- return; /* Nothing to do */
-
- again:
- /* check if we can really output */
- if (!slirp_can_output())
- return;
-
- /*
- * See which queue to get next packet from
- * If there's something in the fastq, select it immediately
- */
- if (if_fastq.ifq_next != &if_fastq) {
- ifm = if_fastq.ifq_next;
- } else {
- /* Nothing on fastq, see if next_m is valid */
- if (next_m != &if_batchq)
- ifm = next_m;
- else
- ifm = if_batchq.ifq_next;
-
- /* Set which packet to send on next iteration */
- next_m = ifm->ifq_next;
- }
- /* Remove it from the queue */
- ifqt = ifm->ifq_prev;
- remque(ifm);
- --if_queued;
-
- /* If there are more packets for this session, re-queue them */
- if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
- insque(ifm->ifs_next, ifqt);
- ifs_remque(ifm);
- }
-
- /* Update so_queued */
- if (ifm->ifq_so) {
- if (--ifm->ifq_so->so_queued == 0)
- /* If there's no more queued, reset nqueued */
- ifm->ifq_so->so_nqueued = 0;
- }
-
- /* Encapsulate the packet for sending */
- if_encap(ifm->m_data, ifm->m_len);
-
- mbuf_free(ifm);
-
- if (if_queued)
- goto again;
-}
diff --git a/slirp2/if.h b/slirp2/if.h
deleted file mode 100644
index f22f161..0000000
--- a/slirp2/if.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifndef _IF_H_
-#define _IF_H_
-
-#define IF_COMPRESS 0x01 /* We want compression */
-#define IF_NOCOMPRESS 0x02 /* Do not do compression */
-#define IF_AUTOCOMP 0x04 /* Autodetect (default) */
-#define IF_NOCIDCOMP 0x08 /* CID compression */
-
-/* Needed for FreeBSD */
-#undef if_mtu
-extern int if_mtu;
-extern int if_mru; /* MTU and MRU */
-extern int if_comp; /* Flags for compression */
-extern int if_maxlinkhdr;
-extern int if_queued; /* Number of packets queued so far */
-extern int if_thresh; /* Number of packets queued before we start sending
- * (to prevent allocing too many mbufs) */
-
-extern struct mbuf if_fastq; /* fast queue (for interactive data) */
-extern struct mbuf if_batchq; /* queue for non-interactive data */
-extern MBuf next_m;
-
-#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
-
-/* Interface statistics */
-struct slirp_ifstats {
- u_int out_pkts; /* Output packets */
- u_int out_bytes; /* Output bytes */
- u_int out_errpkts; /* Output Error Packets */
- u_int out_errbytes; /* Output Error Bytes */
- u_int in_pkts; /* Input packets */
- u_int in_bytes; /* Input bytes */
- u_int in_errpkts; /* Input Error Packets */
- u_int in_errbytes; /* Input Error Bytes */
-
- u_int bytes_saved; /* Number of bytes that compression "saved" */
- /* ie: number of bytes that didn't need to be sent over the link
- * because of compression */
-
- u_int in_mbad; /* Bad incoming packets */
-};
-
-#endif
diff --git a/slirp2/ip.h b/slirp2/ip.h
deleted file mode 100644
index 8cdb735..0000000
--- a/slirp2/ip.h
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip.h 8.1 (Berkeley) 6/10/93
- * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp
- */
-
-#ifndef _IP_H_
-#define _IP_H_
-
-#include "helper.h"
-
-#ifdef WORDS_BIGENDIAN
-# ifndef NTOHL
-# define NTOHL(d)
-# endif
-# ifndef NTOHS
-# define NTOHS(d)
-# endif
-# ifndef HTONL
-# define HTONL(d)
-# endif
-# ifndef HTONS
-# define HTONS(d)
-# endif
-#else
-# ifndef NTOHL
-# define NTOHL(d) ((d) = ntohl((d)))
-# endif
-# ifndef NTOHS
-# define NTOHS(d) ((d) = ntohs((u_int16_t)(d)))
-# endif
-# ifndef HTONL
-# define HTONL(d) ((d) = htonl((d)))
-# endif
-# ifndef HTONS
-# define HTONS(d) ((d) = htons((u_int16_t)(d)))
-# endif
-#endif
-
-typedef u_int32_t n_long; /* long as received from the net */
-
-/*
- * Definitions for internet protocol version 4.
- * Per RFC 791, September 1981.
- */
-#define IPVERSION 4
-
-/*
- * Structure of an internet header, naked of options.
- */
-struct ip {
-#ifdef WORDS_BIGENDIAN
- u_int ip_v:4; /* version */
- u_int ip_hl:4; /* header length */
-#else
- u_int ip_hl:4; /* header length */
- u_int ip_v:4; /* version */
-#endif
- u_int8_t ip_tos; /* type of service */
- u_int16_t ip_len; /* total length */
- u_int16_t ip_id; /* identification */
- u_int16_t ip_off; /* fragment offset field */
-#define IP_DF 0x4000 /* don't fragment flag */
-#define IP_MF 0x2000 /* more fragments flag */
-#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
- u_int8_t ip_ttl; /* time to live */
- u_int8_t ip_p; /* protocol */
- u_int16_t ip_sum; /* checksum */
- ipaddr_t ip_src, ip_dst; /* source and dest address */
-};
-
-#define IP_MAXPACKET 65535 /* maximum packet size */
-
-/*
- * Definitions for IP type of service (ip_tos)
- */
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-
-/*
- * Definitions for options.
- */
-#define IPOPT_COPIED(o) ((o)&0x80)
-#define IPOPT_CLASS(o) ((o)&0x60)
-#define IPOPT_NUMBER(o) ((o)&0x1f)
-
-#define IPOPT_CONTROL 0x00
-#define IPOPT_RESERVED1 0x20
-#define IPOPT_DEBMEAS 0x40
-#define IPOPT_RESERVED2 0x60
-
-#define IPOPT_EOL 0 /* end of option list */
-#define IPOPT_NOP 1 /* no operation */
-
-#define IPOPT_RR 7 /* record packet route */
-#define IPOPT_TS 68 /* timestamp */
-#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
-#define IPOPT_LSRR 131 /* loose source route */
-#define IPOPT_SATID 136 /* satnet id */
-#define IPOPT_SSRR 137 /* strict source route */
-
-/*
- * Offsets to fields in options other than EOL and NOP.
- */
-#define IPOPT_OPTVAL 0 /* option ID */
-#define IPOPT_OLEN 1 /* option length */
-#define IPOPT_OFFSET 2 /* offset within option */
-#define IPOPT_MINOFF 4 /* min value of above */
-
-/*
- * Time stamp option structure.
- */
-struct ip_timestamp {
- u_int8_t ipt_code; /* IPOPT_TS */
- u_int8_t ipt_len; /* size of structure (variable) */
- u_int8_t ipt_ptr; /* index of current entry */
-#ifdef WORDS_BIGENDIAN
- u_int ipt_oflw:4, /* overflow counter */
- ipt_flg:4; /* flags, see below */
-#else
- u_int ipt_flg:4, /* flags, see below */
- ipt_oflw:4; /* overflow counter */
-#endif
- union ipt_timestamp {
- n_long ipt_time[1];
- struct ipt_ta {
- ipaddr_t ipt_addr;
- n_long ipt_time;
- } ipt_ta[1];
- } ipt_timestamp;
-};
-
-/* flag bits for ipt_flg */
-#define IPOPT_TS_TSONLY 0 /* timestamps only */
-#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
-#define IPOPT_TS_PRESPEC 3 /* specified modules only */
-
-/* bits for security (not byte swapped) */
-#define IPOPT_SECUR_UNCLASS 0x0000
-#define IPOPT_SECUR_CONFID 0xf135
-#define IPOPT_SECUR_EFTO 0x789a
-#define IPOPT_SECUR_MMMM 0xbc4d
-#define IPOPT_SECUR_RESTR 0xaf13
-#define IPOPT_SECUR_SECRET 0xd788
-#define IPOPT_SECUR_TOPSECRET 0x6bc5
-
-/*
- * Internet implementation parameters.
- */
-#define MAXTTL 255 /* maximum time to live (seconds) */
-#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
-#define IPFRAGTTL 60 /* time to live for frags, slowhz */
-#define IPTTLDEC 1 /* subtracted when forwarding */
-
-#define IP_MSS 576 /* default maximum segment size */
-
-#if SIZEOF_CHAR_P == 4
-struct mbuf_ptr {
- struct mbuf *mptr;
- uint32_t dummy;
-};
-#else
-struct mbuf_ptr {
- struct mbuf *mptr;
-};
-#endif
-struct qlink {
- void* next, *prev;
-};
-
-/*
- * Overlay for ip header used by other protocols (tcp, udp).
- */
-struct ipovly {
- struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */
- u_int8_t ih_x1; /* (unused) */
- u_int8_t ih_pr; /* protocol */
- u_int16_t ih_len; /* protocol length */
- ipaddr_t ih_src; /* source internet address */
- ipaddr_t ih_dst; /* destination internet address */
-} __attribute__((packed));
-
-/*
- * Ip reassembly queue structure. Each fragment
- * being reassembled is attached to one of these structures.
- * They are timed out after ipq_ttl drops to 0, and may also
- * be reclaimed if memory becomes tight.
- * size 28 bytes
- */
-struct ipq {
- struct qlink frag_link; /* to ip headers of fragments */
- struct qlink ip_link; /* to other reass headers */
- u_int8_t ipq_ttl; /* time for reass q to live */
- u_int8_t ipq_p; /* protocol of this fragment */
- u_int16_t ipq_id; /* sequence id for reassembly */
- ipaddr_t ipq_src,ipq_dst;
-};
-
-/*
- * Ip header, when holding a fragment.
- *
- * Note: ipf_next must be at same offset as frag_link above
- */
-struct ipasfrag {
- struct qlink ipf_link;
- struct ip ipf_ip;
-};
-
-#define ipf_off ipf_ip.ip_off
-#define ipf_tos ipf_ip.ip_tos
-#define ipf_len ipf_ip.ip_len
-#define ipf_next ipf_link.next
-#define ipf_prev ipf_link.prev
-
-/*
- * Structure stored in mbuf in inpcb.ip_options
- * and passed to ip_output when ip options are in use.
- * The actual length of the options (including ipopt_dst)
- * is in m_len.
- */
-#define MAX_IPOPTLEN 40
-
-struct ipoption {
- u_int32_t ipopt_dst; /* first-hop dst if source routed */
- int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
-};
-
-/*
- * Structure attached to inpcb.ip_moptions and
- * passed to ip_output when IP multicast options are in use.
- */
-
-struct ipstat {
- u_long ips_total; /* total packets received */
- u_long ips_badsum; /* checksum bad */
- u_long ips_tooshort; /* packet too short */
- u_long ips_toosmall; /* not enough data */
- u_long ips_badhlen; /* ip header length < data size */
- u_long ips_badlen; /* ip length < ip header length */
- u_long ips_fragments; /* fragments received */
- u_long ips_fragdropped; /* frags dropped (dups, out of space) */
- u_long ips_fragtimeout; /* fragments timed out */
- u_long ips_forward; /* packets forwarded */
- u_long ips_cantforward; /* packets rcvd for unreachable dest */
- u_long ips_redirectsent; /* packets forwarded on same net */
- u_long ips_noproto; /* unknown or unsupported protocol */
- u_long ips_delivered; /* datagrams delivered to upper level*/
- u_long ips_localout; /* total ip packets generated here */
- u_long ips_odropped; /* lost packets due to nobufs, etc. */
- u_long ips_reassembled; /* total packets reassembled ok */
- u_long ips_fragmented; /* datagrams successfully fragmented */
- u_long ips_ofragments; /* output fragments created */
- u_long ips_cantfrag; /* don't fragment flag was set, etc. */
- u_long ips_badoptions; /* error in option processing */
- u_long ips_noroute; /* packets discarded due to no route */
- u_long ips_badvers; /* ip version != 4 */
- u_long ips_rawout; /* total raw ip packets generated */
- u_long ips_unaligned; /* times the ip packet was not aligned */
-};
-
-extern struct ipstat ipstat;
-extern struct ipq ipq; /* ip reass. queue */
-extern u_int16_t ip_id; /* ip packet ctr, for ids */
-extern int ip_defttl; /* default IP ttl */
-
-#endif
diff --git a/slirp2/ip_icmp.c b/slirp2/ip_icmp.c
deleted file mode 100644
index 6594ec4..0000000
--- a/slirp2/ip_icmp.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
- * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
- */
-
-#include "slirp.h"
-#include "ip_icmp.h"
-#include "sockets.h"
-
-struct icmpstat icmpstat;
-
-/* The message sent when emulating PING */
-/* Be nice and tell them it's just a psuedo-ping packet */
-char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n";
-
-/* list of actions for icmp_error() on RX of an icmp message */
-static int icmp_flush[19] = {
-/* ECHO REPLY (0) */ 0,
- 1,
- 1,
-/* DEST UNREACH (3) */ 1,
-/* SOURCE QUENCH (4)*/ 1,
-/* REDIRECT (5) */ 1,
- 1,
- 1,
-/* ECHO (8) */ 0,
-/* ROUTERADVERT (9) */ 1,
-/* ROUTERSOLICIT (10) */ 1,
-/* TIME EXCEEDED (11) */ 1,
-/* PARAMETER PROBLEM (12) */ 1,
-/* TIMESTAMP (13) */ 0,
-/* TIMESTAMP REPLY (14) */ 0,
-/* INFO (15) */ 0,
-/* INFO REPLY (16) */ 0,
-/* ADDR MASK (17) */ 0,
-/* ADDR MASK REPLY (18) */ 0
-};
-
-/*
- * Process a received ICMP message.
- */
-void
-icmp_input(m, hlen)
- MBuf m;
- int hlen;
-{
- register struct icmp *icp;
- register struct ip *ip=MBUF_TO(m, struct ip *);
- int icmplen=ip->ip_len;
- /* int code; */
-
- DEBUG_CALL("icmp_input");
- DEBUG_ARG("m = %lx", (long )m);
- DEBUG_ARG("m_len = %d", m->m_len);
-
- icmpstat.icps_received++;
-
- /*
- * Locate icmp structure in mbuf, and check
- * that its not corrupted and of at least minimum length.
- */
- if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */
- icmpstat.icps_tooshort++;
- freeit:
- mbuf_free(m);
- goto end_error;
- }
-
- m->m_len -= hlen;
- m->m_data += hlen;
- icp = MBUF_TO(m, struct icmp *);
- if (cksum(m, icmplen)) {
- icmpstat.icps_checksum++;
- goto freeit;
- }
- m->m_len += hlen;
- m->m_data -= hlen;
-
- /* icmpstat.icps_inhist[icp->icmp_type]++; */
- /* code = icp->icmp_code; */
-
- DEBUG_ARG("icmp_type = %d", icp->icmp_type);
- switch (icp->icmp_type) {
- case ICMP_ECHO:
- icp->icmp_type = ICMP_ECHOREPLY;
- ip->ip_len += hlen; /* since ip_input subtracts this */
- if (ip_geth(ip->ip_dst) == alias_addr_ip) {
- icmp_reflect(m);
- } else {
- struct socket *so;
- SockAddress addr;
- uint32_t addr_ip;
- uint16_t addr_port;
-
- if ((so = socreate()) == NULL) goto freeit;
- if(udp_attach(so) == -1) {
- DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
- errno,errno_str));
- sofree(so);
- mbuf_free(m);
- goto end_error;
- }
- so->so_m = m;
- so->so_faddr_ip = ip_geth(ip->ip_dst);
- so->so_faddr_port = 7;
- so->so_laddr_ip = ip_geth(ip->ip_src);
- so->so_laddr_port = 9;
- so->so_iptos = ip->ip_tos;
- so->so_type = IPPROTO_ICMP;
- so->so_state = SS_ISFCONNECTED;
-
- /* Send the packet */
- if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
- /* It's an alias */
- int low = so->so_faddr_ip & 0xff;
-
- if (low >= CTL_DNS && low < CTL_DNS + dns_addr_count)
- addr_ip = dns_addr[low - CTL_DNS];
- else
- addr_ip = loopback_addr_ip;
- } else {
- addr_ip = so->so_faddr_ip;
- }
- addr_port = so->so_faddr_port;
-
- sock_address_init_inet( &addr, addr_ip, addr_port );
-
- if(socket_sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), &addr) < 0) {
- DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
- errno,errno_str));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,errno_str);
- udp_detach(so);
- }
- } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
- break;
- case ICMP_UNREACH:
- /* XXX? report error? close socket? */
- case ICMP_TIMXCEED:
- case ICMP_PARAMPROB:
- case ICMP_SOURCEQUENCH:
- case ICMP_TSTAMP:
- case ICMP_MASKREQ:
- case ICMP_REDIRECT:
- icmpstat.icps_notsupp++;
- mbuf_free(m);
- break;
-
- default:
- icmpstat.icps_badtype++;
- mbuf_free(m);
- } /* swith */
-
-end_error:
- /* m is mbuf_free()'d xor put in a socket xor or given to ip_send */
- return;
-}
-
-
-/*
- * Send an ICMP message in response to a situation
- *
- * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we do).
- * MUST NOT change this header information.
- * MUST NOT reply to a multicast/broadcast IP address.
- * MUST NOT reply to a multicast/broadcast MAC address.
- * MUST reply to only the first fragment.
- */
-/*
- * Send ICMP_UNREACH back to the source regarding msrc.
- * mbuf *msrc is used as a template, but is NOT mbuf_free()'d.
- * It is reported as the bad ip packet. The header should
- * be fully correct and in host byte order.
- * ICMP fragmentation is illegal. All machines must accept 576 bytes in one
- * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548
- */
-
-#define ICMP_MAXDATALEN (IP_MSS-28)
-void
-icmp_error(msrc, type, code, minsize, message)
- MBuf msrc;
- u_char type;
- u_char code;
- int minsize;
- const char *message;
-{
- unsigned hlen, shlen, s_ip_len;
- register struct ip *ip;
- register struct icmp *icp;
- register MBuf m;
-
- DEBUG_CALL("icmp_error");
- DEBUG_ARG("msrc = %lx", (long )msrc);
- DEBUG_ARG("msrc_len = %d", msrc->m_len);
-
- if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error;
-
- /* check msrc */
- if(!msrc) goto end_error;
- ip = MBUF_TO(msrc, struct ip *);
-#if DEBUG
- { char bufa[20], bufb[20];
- strcpy(bufa, inet_iptostr(ip_geth(ip->ip_src)));
- strcpy(bufb, inet_iptostr(ip_geth(ip->ip_dst)));
- DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb));
- }
-#endif
- if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */
-
- shlen=ip->ip_hl << 2;
- s_ip_len=ip->ip_len;
- if(ip->ip_p == IPPROTO_ICMP) {
- icp = (struct icmp *)((char *)ip + shlen);
- /*
- * Assume any unknown ICMP type is an error. This isn't
- * specified by the RFC, but think about it..
- */
- if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error;
- }
-
- /* make a copy */
- if(!(m=mbuf_alloc())) goto end_error; /* get mbuf */
- { int new_m_size;
- new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN;
- if(new_m_size>m->m_size) mbuf_ensure(m, new_m_size);
- }
- memcpy(m->m_data, msrc->m_data, msrc->m_len);
- m->m_len = msrc->m_len; /* copy msrc to m */
-
- /* make the header of the reply packet */
- ip = MBUF_TO(m, struct ip *);
- hlen= sizeof(struct ip ); /* no options in reply */
-
- /* fill in icmp */
- m->m_data += hlen;
- m->m_len -= hlen;
-
- icp = MBUF_TO(m, struct icmp *);
-
- if(minsize) s_ip_len=shlen+ICMP_MINLEN; /* return header+8b only */
- else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */
- s_ip_len=ICMP_MAXDATALEN;
-
- m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */
-
- /* min. size = 8+sizeof(struct ip)+8 */
-
- icp->icmp_type = type;
- icp->icmp_code = code;
- icp->icmp_id = 0;
- icp->icmp_seq = 0;
-
- memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */
- HTONS(icp->icmp_ip.ip_len);
- HTONS(icp->icmp_ip.ip_id);
- HTONS(icp->icmp_ip.ip_off);
-
-#if DEBUG
- if(message) { /* DEBUG : append message to ICMP packet */
- int message_len;
- char *cpnt;
- message_len=strlen(message);
- if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN;
- cpnt=(char *)m->m_data+m->m_len;
- memcpy(cpnt, message, message_len);
- m->m_len+=message_len;
- }
-#endif
-
- icp->icmp_cksum = 0;
- icp->icmp_cksum = cksum(m, m->m_len);
-
- m->m_data -= hlen;
- m->m_len += hlen;
-
- /* fill in ip */
- ip->ip_hl = hlen >> 2;
- ip->ip_len = m->m_len;
-
- ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */
-
- ip->ip_ttl = MAXTTL;
- ip->ip_p = IPPROTO_ICMP;
- ip->ip_dst = ip->ip_src; /* ip adresses */
- ip->ip_src = ip_setn(alias_addr_ip);
-
- (void ) ip_output((struct socket *)NULL, m);
-
- icmpstat.icps_reflect++;
-
-end_error:
- return;
-}
-#undef ICMP_MAXDATALEN
-
-/*
- * Reflect the ip packet back to the source
- */
-void
-icmp_reflect(m)
- MBuf m;
-{
- register struct ip *ip = MBUF_TO(m, struct ip *);
- int hlen = ip->ip_hl << 2;
- int optlen = hlen - sizeof(struct ip );
- register struct icmp *icp;
-
- /*
- * Send an icmp packet back to the ip level,
- * after supplying a checksum.
- */
- m->m_data += hlen;
- m->m_len -= hlen;
- icp = MBUF_TO(m, struct icmp *);
-
- icp->icmp_cksum = 0;
- icp->icmp_cksum = cksum(m, ip->ip_len - hlen);
-
- m->m_data -= hlen;
- m->m_len += hlen;
-
- /* fill in ip */
- if (optlen > 0) {
- /*
- * Strip out original options by copying rest of first
- * mbuf's data back, and adjust the IP length.
- */
- memmove((caddr_t)(ip + 1), (caddr_t)ip + hlen,
- (unsigned )(m->m_len - hlen));
- hlen -= optlen;
- ip->ip_hl = hlen >> 2;
- ip->ip_len -= optlen;
- m->m_len -= optlen;
- }
-
- ip->ip_ttl = MAXTTL;
- { /* swap */
- ipaddr_t icmp_dst;
- icmp_dst = ip->ip_dst;
- ip->ip_dst = ip->ip_src;
- ip->ip_src = icmp_dst;
- }
-
- (void ) ip_output((struct socket *)NULL, m);
-
- icmpstat.icps_reflect++;
-}
diff --git a/slirp2/ip_icmp.h b/slirp2/ip_icmp.h
deleted file mode 100644
index bc0be51..0000000
--- a/slirp2/ip_icmp.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
- * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp
- */
-
-#ifndef _NETINET_IP_ICMP_H_
-#define _NETINET_IP_ICMP_H_
-
-#include "helper.h"
-
-/*
- * Interface Control Message Protocol Definitions.
- * Per RFC 792, September 1981.
- */
-
-typedef u_int32_t n_time;
-
-/*
- * Structure of an icmp header.
- */
-struct icmp {
- u_char icmp_type; /* type of message, see below */
- u_char icmp_code; /* type sub code */
- u_short icmp_cksum; /* ones complement cksum of struct */
- union {
- u_char ih_pptr; /* ICMP_PARAMPROB */
- ipaddr_t ih_gwaddr; /* ICMP_REDIRECT */
- struct ih_idseq {
- u_short icd_id;
- u_short icd_seq;
- } ih_idseq;
- int ih_void;
-
- /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
- struct ih_pmtu {
- u_short ipm_void;
- u_short ipm_nextmtu;
- } ih_pmtu;
- } icmp_hun;
-#define icmp_pptr icmp_hun.ih_pptr
-#define icmp_gwaddr icmp_hun.ih_gwaddr
-#define icmp_id icmp_hun.ih_idseq.icd_id
-#define icmp_seq icmp_hun.ih_idseq.icd_seq
-#define icmp_void icmp_hun.ih_void
-#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
-#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
- union {
- struct id_ts {
- n_time its_otime;
- n_time its_rtime;
- n_time its_ttime;
- } id_ts;
- struct id_ip {
- struct ip idi_ip;
- /* options and then 64 bits of data */
- } id_ip;
- uint32_t id_mask;
- char id_data[1];
- } icmp_dun;
-#define icmp_otime icmp_dun.id_ts.its_otime
-#define icmp_rtime icmp_dun.id_ts.its_rtime
-#define icmp_ttime icmp_dun.id_ts.its_ttime
-#define icmp_ip icmp_dun.id_ip.idi_ip
-#define icmp_mask icmp_dun.id_mask
-#define icmp_data icmp_dun.id_data
-};
-
-/*
- * Lower bounds on packet lengths for various types.
- * For the error advice packets must first insure that the
- * packet is large enought to contain the returned ip header.
- * Only then can we do the check to see if 64 bits of packet
- * data have been returned, since we need to check the returned
- * ip header length.
- */
-#define ICMP_MINLEN 8 /* abs minimum */
-#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
-#define ICMP_MASKLEN 12 /* address mask */
-#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
-#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
- /* N.B.: must separately check that ip_hl >= 5 */
-
-/*
- * Definition of type and code field values.
- */
-#define ICMP_ECHOREPLY 0 /* echo reply */
-#define ICMP_UNREACH 3 /* dest unreachable, codes: */
-#define ICMP_UNREACH_NET 0 /* bad net */
-#define ICMP_UNREACH_HOST 1 /* bad host */
-#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
-#define ICMP_UNREACH_PORT 3 /* bad port */
-#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
-#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
-#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
-#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
-#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
-#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
-#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
-#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
-#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
-#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
-#define ICMP_REDIRECT 5 /* shorter route, codes: */
-#define ICMP_REDIRECT_NET 0 /* for network */
-#define ICMP_REDIRECT_HOST 1 /* for host */
-#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
-#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
-#define ICMP_ECHO 8 /* echo service */
-#define ICMP_ROUTERADVERT 9 /* router advertisement */
-#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
-#define ICMP_TIMXCEED 11 /* time exceeded, code: */
-#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
-#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
-#define ICMP_PARAMPROB 12 /* ip header bad */
-#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
-#define ICMP_TSTAMP 13 /* timestamp request */
-#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
-#define ICMP_IREQ 15 /* information request */
-#define ICMP_IREQREPLY 16 /* information reply */
-#define ICMP_MASKREQ 17 /* address mask request */
-#define ICMP_MASKREPLY 18 /* address mask reply */
-
-#define ICMP_MAXTYPE 18
-
-#define ICMP_INFOTYPE(type) \
- ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
- (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
- (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
- (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
- (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
-
-void icmp_input _P((MBuf , int));
-void icmp_error _P((MBuf , u_char, u_char, int, const char *));
-void icmp_reflect _P((MBuf ));
-
-#endif
diff --git a/slirp2/ip_input.c b/slirp2/ip_input.c
deleted file mode 100644
index fa99a5d..0000000
--- a/slirp2/ip_input.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
- * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp
- */
-
-/*
- * Changes and additions relating to SLiRP are
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#include <osdep.h>
-#include "ip_icmp.h"
-
-int ip_defttl;
-struct ipstat ipstat;
-struct ipq ipq;
-
-/*
- * IP initialization: fill in IP protocol switch table.
- * All protocols not implemented in kernel go to raw IP protocol handler.
- */
-void
-ip_init()
-{
- ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
- ip_id = tt.tv_sec & 0xffff;
- udp_init();
- tcp_init();
- ip_defttl = IPDEFTTL;
-}
-
-/*
- * Ip input routine. Checksum and byte swap header. If fragmented
- * try to reassemble. Process options. Pass to next level.
- */
-void
-ip_input(m)
- MBuf m;
-{
- register struct ip *ip;
- int hlen;
-
- DEBUG_CALL("ip_input");
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("m_len = %d", m->m_len);
-
- ipstat.ips_total++;
-
- if (m->m_len < sizeof (struct ip)) {
- ipstat.ips_toosmall++;
- return;
- }
-
- ip = MBUF_TO(m, struct ip *);
-
- if (ip->ip_v != IPVERSION) {
- ipstat.ips_badvers++;
- goto bad;
- }
-
- hlen = ip->ip_hl << 2;
- if (hlen<sizeof(struct ip ) || hlen>m->m_len) {/* min header length */
- ipstat.ips_badhlen++; /* or packet too short */
- goto bad;
- }
-
- /* keep ip header intact for ICMP reply
- * ip->ip_sum = cksum(m, hlen);
- * if (ip->ip_sum) {
- */
- if(cksum(m,hlen)) {
- ipstat.ips_badsum++;
- goto bad;
- }
-
- /*
- * Convert fields to host representation.
- */
- NTOHS(ip->ip_len);
- if (ip->ip_len < hlen) {
- ipstat.ips_badlen++;
- goto bad;
- }
- NTOHS(ip->ip_id);
- NTOHS(ip->ip_off);
-
- /*
- * Check that the amount of data in the buffers
- * is as at least much as the IP header would have us expect.
- * Trim mbufs if longer than we expect.
- * Drop packet if shorter than we expect.
- */
- if (m->m_len < ip->ip_len) {
- ipstat.ips_tooshort++;
- goto bad;
- }
- /* Should drop packet if mbuf too long? hmmm... */
- if (m->m_len > ip->ip_len)
- mbuf_trim(m, ip->ip_len - m->m_len);
-
- /* check ip_ttl for a correct ICMP reply */
- if(ip->ip_ttl==0 || ip->ip_ttl==1) {
- icmp_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl");
- goto bad;
- }
-
- /*
- * Process options and, if not destined for us,
- * ship it on. ip_dooptions returns 1 when an
- * error was detected (causing an icmp message
- * to be sent and the original packet to be freed).
- */
-/* We do no IP options */
-/* if (hlen > sizeof (struct ip) && ip_dooptions(m))
- * goto next;
- */
- /*
- * If offset or IP_MF are set, must reassemble.
- * Otherwise, nothing need be done.
- * (We could look in the reassembly queue to see
- * if the packet was previously fragmented,
- * but it's not worth the time; just let them time out.)
- *
- * XXX This should fail, don't fragment yet
- */
- if (ip->ip_off &~ IP_DF) {
- register struct ipq *fp;
- struct qlink *l;
- /*
- * Look for queue of fragments
- * of this datagram.
- */
- for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
- fp = container_of(l, struct ipq, ip_link);
- if (ip->ip_id == fp->ipq_id &&
- ip_equal(ip->ip_src, fp->ipq_src) &&
- ip_equal(ip->ip_dst, fp->ipq_dst) &&
- ip->ip_p == fp->ipq_p)
- goto found;
- }
- fp = NULL;
- found:
-
- /*
- * Adjust ip_len to not reflect header,
- * set ip_mff if more fragments are expected,
- * convert offset of this to bytes.
- */
- ip->ip_len -= hlen;
- if (ip->ip_off & IP_MF)
- ip->ip_tos |= 1;
- else
- ip->ip_tos &= ~1;
-
- ip->ip_off <<= 3;
-
- /*
- * If datagram marked as having more fragments
- * or if this is not the first fragment,
- * attempt reassembly; if it succeeds, proceed.
- */
- if (ip->ip_tos & 1 || ip->ip_off) {
- ipstat.ips_fragments++;
- ip = ip_reass(ip, fp);
- if (ip == 0)
- return;
- ipstat.ips_reassembled++;
- m = MBUF_FROM(ip);
- } else
- if (fp)
- ip_freef(fp);
-
- } else
- ip->ip_len -= hlen;
-
- /*
- * Switch out to protocol's input routine.
- */
- ipstat.ips_delivered++;
- switch (ip->ip_p) {
- case IPPROTO_TCP:
- tcp_input(m, hlen, (struct socket *)NULL);
- break;
- case IPPROTO_UDP:
- udp_input(m, hlen);
- break;
- case IPPROTO_ICMP:
- icmp_input(m, hlen);
- break;
- default:
- ipstat.ips_noproto++;
- mbuf_free(m);
- }
- return;
-bad:
- mbuf_free(m);
- return;
-}
-
-#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink)))
-#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink)))
-
-/*
- * Take incoming datagram fragment and try to
- * reassemble it into whole datagram. If a chain for
- * reassembly of this datagram already exists, then it
- * is given as fp; otherwise have to make a chain.
- */
-struct ip *
-ip_reass(ip, fp)
- register struct ip *ip;
- register struct ipq *fp;
-{
- register MBuf m = MBUF_FROM(ip);
- register struct ipasfrag *q;
- int hlen = ip->ip_hl << 2;
- int i, next;
-
- DEBUG_CALL("ip_reass");
- DEBUG_ARG("ip = %lx", (long)ip);
- DEBUG_ARG("fp = %lx", (long)fp);
- DEBUG_ARG("m = %lx", (long)m);
-
- /*
- * Presence of header sizes in mbufs
- * would confuse code below.
- * Fragment m_data is concatenated.
- */
- m->m_data += hlen;
- m->m_len -= hlen;
-
- /*
- * If first fragment to arrive, create a reassembly queue.
- */
- if (fp == 0) {
- MBuf t;
- if ((t = mbuf_alloc()) == NULL) goto dropfrag;
- fp = MBUF_TO(t, struct ipq *);
- insque(&fp->ip_link, &ipq.ip_link);
- fp->ipq_ttl = IPFRAGTTL;
- fp->ipq_p = ip->ip_p;
- fp->ipq_id = ip->ip_id;
- fp->frag_link.next = fp->frag_link.prev = &fp->frag_link;
- fp->ipq_src = ip->ip_src;
- fp->ipq_dst = ip->ip_src;
- q = (struct ipasfrag *)fp;
- goto insert;
- }
-
- /*
- * Find a segment which begins after this one does.
- */
- for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
- q = q->ipf_next)
- if (q->ipf_off > ip->ip_off)
- break;
- /*
- * If there is a preceding segment, it may provide some of
- * our data already. If so, drop the data from the incoming
- * segment. If it provides all of our data, drop us.
- */
- if (q->ipf_prev != &fp->frag_link) {
- struct ipasfrag *pq = q->ipf_prev;
- i = pq->ipf_off + pq->ipf_len - ip->ip_off;
- if (i > 0) {
- if (i >= ip->ip_len)
- goto dropfrag;
- mbuf_trim(MBUF_FROM(ip), i);
- ip->ip_off += i;
- ip->ip_len -= i;
- }
- }
-
- /*
- * While we overlap succeeding segments trim them or,
- * if they are completely covered, dequeue them.
- */
- while (q != (struct ipasfrag *)&fp->frag_link &&
- ip->ip_off + ip->ip_len > q->ipf_off) {
- i = (ip->ip_off + ip->ip_len) - q->ipf_off;
- if (i < q->ipf_len) {
- q->ipf_len -= i;
- q->ipf_off += i;
- mbuf_trim(MBUF_FROM(q), i);
- break;
- }
- q = q->ipf_next;
- mbuf_free(MBUF_FROM(q->ipf_prev));
- ip_deq(q->ipf_prev);
- }
-
-insert:
- /*
- * Stick new segment in its place;
- * check for complete reassembly.
- */
- ip_enq(iptofrag(ip), q->ipf_prev);
- next = 0;
- for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
- q = q->ipf_next)
- {
- if (q->ipf_off != next)
- return (0);
-
- next += q->ipf_len;
- }
- if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1)
- return (0);
-
- /*
- * Reassembly is complete; concatenate fragments.
- */
- q = fp->frag_link.next;
- m = MBUF_FROM(q);
-
- q = (struct ipasfrag *) q->ipf_next;
- while (q != (struct ipasfrag *)&fp->frag_link) {
- MBuf t = MBUF_FROM(q);
- q = (struct ipasfrag *) q->ipf_next;
- mbuf_append(m, t);
- }
-
- /*
- * Create header for new ip packet by
- * modifying header of first packet;
- * dequeue and discard fragment reassembly header.
- * Make header visible.
- */
- q = fp->frag_link.next;
-
- /*
- * If the fragments concatenated to an mbuf that's
- * bigger than the total size of the fragment, then and
- * m_ext buffer was alloced. But fp->ipq_next points to
- * the old buffer (in the mbuf), so we must point ip
- * into the new buffer.
- */
- if (m->m_flags & M_EXT) {
- int delta = (char *)q - m->m_dat;
- q = (struct ipasfrag *)(m->m_ext + delta);
- }
-
- /* DEBUG_ARG("ip = %lx", (long)ip);
- * ip=(struct ipasfrag *)m->m_data; */
-
- ip = fragtoip(q);
- ip->ip_len = next;
- ip->ip_tos &= ~1;
- ip->ip_src = fp->ipq_src;
- ip->ip_dst = fp->ipq_dst;
- remque(&fp->ip_link);
- (void) mbuf_free(MBUF_FROM(fp));
- m->m_len += (ip->ip_hl << 2);
- m->m_data -= (ip->ip_hl << 2);
-
- return ip;
-
-dropfrag:
- ipstat.ips_fragdropped++;
- mbuf_free(m);
- return (0);
-}
-
-/*
- * Free a fragment reassembly header and all
- * associated datagrams.
- */
-void
-ip_freef(fp)
- struct ipq *fp;
-{
- register struct ipasfrag *q, *p;
-
- for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; q = p) {
- p = q->ipf_next;
- ip_deq(q);
- mbuf_free(MBUF_FROM(q));
- }
- remque(&fp->ip_link);
- (void) mbuf_free(MBUF_FROM(fp));
-}
-
-/*
- * Put an ip fragment on a reassembly chain.
- * Like insque, but pointers in middle of structure.
- */
-void
-ip_enq(p, prev)
- register struct ipasfrag *p, *prev;
-{
- DEBUG_CALL("ip_enq");
- DEBUG_ARG("prev = %lx", (long)prev);
- p->ipf_prev = prev;
- p->ipf_next = prev->ipf_next;
- ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p;
- prev->ipf_next = p;
-}
-
-/*
- * To ip_enq as remque is to insque.
- */
-void
-ip_deq(p)
- register struct ipasfrag *p;
-{
- ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next;
- ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev;
-}
-
-/*
- * IP timer processing;
- * if a timer expires on a reassembly
- * queue, discard it.
- */
-void
-ip_slowtimo()
-{
- struct qlink *l;
-
- DEBUG_CALL("ip_slowtimo");
-
- l = ipq.ip_link.next;
- if (l == 0)
- return;
-
- while (l != &ipq.ip_link) {
- struct ipq *fp = container_of(l, struct ipq, ip_link);
- l = l->next;
- if (--fp->ipq_ttl == 0) {
- ipstat.ips_fragtimeout++;
- ip_freef(fp);
- }
- }
-}
-
-/*
- * Do option processing on a datagram,
- * possibly discarding it if bad options are encountered,
- * or forwarding it if source-routed.
- * Returns 1 if packet has been forwarded/freed,
- * 0 if the packet should be processed further.
- */
-
-#ifdef notdef
-
-int
-ip_dooptions(m)
- MBuf m;
-{
- register struct ip *ip = MBUF_TO(m, struct ip *);
- register u_char *cp;
- register struct ip_timestamp *ipt;
- register struct in_ifaddr *ia;
-/* int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; */
- int opt, optlen, cnt, off, code, type, forward = 0;
- ipaddr_t *sin, dst;
-typedef u_int32_t n_time;
- n_time ntime;
-
- dst = ip->ip_dst;
- cp = (u_char *)(ip + 1);
- cnt = (ip->ip_hl << 2) - sizeof (struct ip);
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[IPOPT_OPTVAL];
- if (opt == IPOPT_EOL)
- break;
- if (opt == IPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[IPOPT_OLEN];
- if (optlen <= 0 || optlen > cnt) {
- code = &cp[IPOPT_OLEN] - (u_char *)ip;
- goto bad;
- }
- }
- switch (opt) {
-
- default:
- break;
-
- /*
- * Source routing with record.
- * Find interface with current destination address.
- * If none on this machine then drop if strictly routed,
- * or do nothing if loosely routed.
- * Record interface address and bring up next address
- * component. If strictly routed make sure next
- * address is on directly accessible net.
- */
- case IPOPT_LSRR:
- case IPOPT_SSRR:
- if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
- code = &cp[IPOPT_OFFSET] - (u_char *)ip;
- goto bad;
- }
- ipaddr.sin_addr = ip->ip_dst;
- ia = (struct in_ifaddr *)
- ifa_ifwithaddr((struct sockaddr *)&ipaddr);
- if (ia == 0) {
- if (opt == IPOPT_SSRR) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_SRCFAIL;
- goto bad;
- }
- /*
- * Loose routing, and not at next destination
- * yet; nothing to do except forward.
- */
- break;
- }
- off--; / * 0 origin * /
- if (off > optlen - sizeof(struct in_addr)) {
- /*
- * End of source route. Should be for us.
- */
- save_rte(cp, ip->ip_src);
- break;
- }
- /*
- * locate outgoing interface
- */
- bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
- sizeof(ipaddr.sin_addr));
- if (opt == IPOPT_SSRR) {
-#define INA struct in_ifaddr *
-#define SA struct sockaddr *
- if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
- ia = (INA)ifa_ifwithnet((SA)&ipaddr);
- } else
- ia = ip_rtaddr(ipaddr.sin_addr);
- if (ia == 0) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_SRCFAIL;
- goto bad;
- }
- ip->ip_dst = ipaddr.sin_addr;
- bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
- (caddr_t)(cp + off), sizeof(struct in_addr));
- cp[IPOPT_OFFSET] += sizeof(struct in_addr);
- /*
- * Let ip_intr's mcast routing check handle mcast pkts
- */
- forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));
- break;
-
- case IPOPT_RR:
- if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
- code = &cp[IPOPT_OFFSET] - (u_char *)ip;
- goto bad;
- }
- /*
- * If no space remains, ignore.
- */
- off--; * 0 origin *
- if (off > optlen - sizeof(struct in_addr))
- break;
- bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
- sizeof(ipaddr.sin_addr));
- /*
- * locate outgoing interface; if we're the destination,
- * use the incoming interface (should be same).
- */
- if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
- (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
- type = ICMP_UNREACH;
- code = ICMP_UNREACH_HOST;
- goto bad;
- }
- bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
- (caddr_t)(cp + off), sizeof(struct in_addr));
- cp[IPOPT_OFFSET] += sizeof(struct in_addr);
- break;
-
- case IPOPT_TS:
- code = cp - (u_char *)ip;
- ipt = (struct ip_timestamp *)cp;
- if (ipt->ipt_len < 5)
- goto bad;
- if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) {
- if (++ipt->ipt_oflw == 0)
- goto bad;
- break;
- }
- sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
- switch (ipt->ipt_flg) {
-
- case IPOPT_TS_TSONLY:
- break;
-
- case IPOPT_TS_TSANDADDR:
- if (ipt->ipt_ptr + sizeof(n_time) +
- sizeof(struct in_addr) > ipt->ipt_len)
- goto bad;
- ipaddr.sin_addr = dst;
- ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr,
- m->m_pkthdr.rcvif);
- if (ia == 0)
- continue;
- bcopy((caddr_t)&IA_SIN(ia)->sin_addr,
- (caddr_t)sin, sizeof(struct in_addr));
- ipt->ipt_ptr += sizeof(struct in_addr);
- break;
-
- case IPOPT_TS_PRESPEC:
- if (ipt->ipt_ptr + sizeof(n_time) +
- sizeof(struct in_addr) > ipt->ipt_len)
- goto bad;
- bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
- sizeof(struct in_addr));
- if (ifa_ifwithaddr((SA)&ipaddr) == 0)
- continue;
- ipt->ipt_ptr += sizeof(struct in_addr);
- break;
-
- default:
- goto bad;
- }
- ntime = iptime();
- bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
- sizeof(n_time));
- ipt->ipt_ptr += sizeof(n_time);
- }
- }
- if (forward) {
- ip_forward(m, 1);
- return (1);
- }
- }
- }
- return (0);
-bad:
- /* ip->ip_len -= ip->ip_hl << 2; XXX icmp_error adds in hdr length */
-
-/* Not yet */
- icmp_error(m, type, code, 0, 0);
-
- ipstat.ips_badoptions++;
- return (1);
-}
-
-#endif /* notdef */
-
-/*
- * Strip out IP options, at higher
- * level protocol in the kernel.
- * Second argument is buffer to which options
- * will be moved, and return value is their length.
- * (XXX) should be deleted; last arg currently ignored.
- */
-void
-ip_stripoptions(m, mopt)
- register MBuf m;
- MBuf mopt;
-{
- register int i;
- struct ip *ip = MBUF_TO(m, struct ip *);
- register caddr_t opts;
- int olen;
-
- olen = (ip->ip_hl<<2) - sizeof (struct ip);
- opts = (caddr_t)(ip + 1);
- i = m->m_len - (sizeof (struct ip) + olen);
- memcpy(opts, opts + olen, (unsigned)i);
- m->m_len -= olen;
-
- ip->ip_hl = sizeof(struct ip) >> 2;
-}
diff --git a/slirp2/ip_output.c b/slirp2/ip_output.c
deleted file mode 100644
index 42d789c..0000000
--- a/slirp2/ip_output.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
- * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp
- */
-
-/*
- * Changes and additions relating to SLiRP are
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-u_int16_t ip_id;
-
-/*
- * IP output. The packet in mbuf chain m contains a skeletal IP
- * header (with len, off, ttl, proto, tos, src, dst).
- * The mbuf chain containing the packet will be freed.
- * The mbuf opt, if present, will not be freed.
- */
-int
-ip_output(so, m0)
- struct socket *so;
- MBuf m0;
-{
- register struct ip *ip;
- register MBuf m = m0;
- register int hlen = sizeof(struct ip );
- int len, off, error = 0;
-
- DEBUG_CALL("ip_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m0 = %lx", (long)m0);
-
- /* We do no options */
-/* if (opt) {
- * m = ip_insertoptions(m, opt, &len);
- * hlen = len;
- * }
- */
- ip = MBUF_TO(m, struct ip *);
- /*
- * Fill in IP header.
- */
- ip->ip_v = IPVERSION;
- ip->ip_off &= IP_DF;
- ip->ip_id = htons(ip_id++);
- ip->ip_hl = hlen >> 2;
- ipstat.ips_localout++;
-
- /*
- * Verify that we have any chance at all of being able to queue
- * the packet or packet fragments
- */
- /* XXX Hmmm... */
-/* if (if_queued > if_thresh && towrite <= 0) {
- * error = ENOBUFS;
- * goto bad;
- * }
- */
-
- /*
- * If small enough for interface, can just send directly.
- */
- if ((u_int16_t)ip->ip_len <= if_mtu) {
- ip->ip_len = htons((u_int16_t)ip->ip_len);
- ip->ip_off = htons((u_int16_t)ip->ip_off);
- ip->ip_sum = 0;
- ip->ip_sum = cksum(m, hlen);
-
- if_output(so, m);
- goto done;
- }
-
- /*
- * Too large for interface; fragment if possible.
- * Must be able to put at least 8 bytes per fragment.
- */
- if (ip->ip_off & IP_DF) {
- error = -1;
- ipstat.ips_cantfrag++;
- goto bad;
- }
-
- len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */
- if (len < 8) {
- error = -1;
- goto bad;
- }
-
- {
- int mhlen, firstlen = len;
- MBuf *mnext = &m->m_nextpkt;
-
- /*
- * Loop through length of segment after first fragment,
- * make new header and copy data of each part and link onto chain.
- */
- m0 = m;
- mhlen = sizeof (struct ip);
- for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) {
- register struct ip *mhip;
- m = mbuf_alloc();
- if (m == 0) {
- error = -1;
- ipstat.ips_odropped++;
- goto sendorfree;
- }
- m->m_data += if_maxlinkhdr;
- mhip = MBUF_TO(m, struct ip *);
- *mhip = *ip;
-
- /* No options */
-/* if (hlen > sizeof (struct ip)) {
- * mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
- * mhip->ip_hl = mhlen >> 2;
- * }
- */
- m->m_len = mhlen;
- mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
- if (ip->ip_off & IP_MF)
- mhip->ip_off |= IP_MF;
- if (off + len >= (u_int16_t)ip->ip_len)
- len = (u_int16_t)ip->ip_len - off;
- else
- mhip->ip_off |= IP_MF;
- mhip->ip_len = htons((u_int16_t)(len + mhlen));
-
- if (mbuf_copy(m, m0, off, len) < 0) {
- error = -1;
- goto sendorfree;
- }
-
- mhip->ip_off = htons((u_int16_t)mhip->ip_off);
- mhip->ip_sum = 0;
- mhip->ip_sum = cksum(m, mhlen);
- *mnext = m;
- mnext = &m->m_nextpkt;
- ipstat.ips_ofragments++;
- }
- /*
- * Update first fragment by trimming what's been copied out
- * and updating header, then send each fragment (in order).
- */
- m = m0;
- mbuf_trim(m, hlen + firstlen - (u_int16_t)ip->ip_len);
- ip->ip_len = htons((u_int16_t)m->m_len);
- ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF));
- ip->ip_sum = 0;
- ip->ip_sum = cksum(m, hlen);
-sendorfree:
- for (m = m0; m; m = m0) {
- m0 = m->m_nextpkt;
- m->m_nextpkt = 0;
- if (error == 0)
- if_output(so, m);
- else
- mbuf_free(m);
- }
-
- if (error == 0)
- ipstat.ips_fragmented++;
- }
-
-done:
- return (error);
-
-bad:
- mbuf_free(m0);
- goto done;
-}
diff --git a/slirp2/libslirp.h b/slirp2/libslirp.h
deleted file mode 100644
index e74e71e..0000000
--- a/slirp2/libslirp.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _LIBSLIRP_H
-#define _LIBSLIRP_H
-
-#include <stdint.h>
-#include "sockets.h"
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# define socket_close winsock2_socket_close3
-# include <winsock2.h>
-# undef socket_close
-#else
-# include <sys/select.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int inet_strtoip(const char* str, uint32_t *ip);
-char* inet_iptostr(uint32_t ip);
-
-void slirp_init(void);
-
-void slirp_select_fill(int *pnfds,
- fd_set *readfds, fd_set *writefds, fd_set *xfds);
-
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds);
-
-void slirp_input(const uint8_t *pkt, int pkt_len);
-
-/* you must provide the following functions: */
-int slirp_can_output(void);
-void slirp_output(const uint8_t *pkt, int pkt_len);
-
-int slirp_redir(int is_udp, int host_port,
- uint32_t guest_addr, int guest_port);
-
-int slirp_unredir(int is_udp, int host_port);
-
-int slirp_add_dns_server(const SockAddress* dns_addr);
-int slirp_get_system_dns_servers(void);
-
-extern const char *tftp_prefix;
-extern char slirp_hostname[33];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/slirp2/main.h b/slirp2/main.h
deleted file mode 100644
index 159e5f4..0000000
--- a/slirp2/main.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#define TOWRITEMAX 512
-
-extern struct timeval tt;
-extern int link_up;
-extern int slirp_socket;
-extern int slirp_socket_unit;
-extern int slirp_socket_port;
-extern u_int32_t slirp_socket_addr;
-extern char *slirp_socket_passwd;
-extern int ctty_closed;
-
-/*
- * Get the difference in 2 times from updtim()
- * Allow for wraparound times, "just in case"
- * x is the greater of the 2 (current time) and y is
- * what it's being compared against.
- */
-#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y)
-
-#define DNS_ADDR_MAX 4
-
-extern char *slirp_tty;
-extern char *exec_shell;
-extern u_int curtime;
-extern fd_set *global_readfds, *global_writefds, *global_xfds;
-extern uint32_t ctl_addr_ip;
-extern uint32_t special_addr_ip;
-extern uint32_t alias_addr_ip;
-extern uint32_t our_addr_ip;
-extern uint32_t loopback_addr_ip;
-extern uint32_t dns_addr[DNS_ADDR_MAX];
-extern int dns_addr_count;
-extern char *username;
-extern char *socket_path;
-extern int towrite_max;
-extern int ppp_exit;
-extern int so_options;
-extern int tcp_keepintvl;
-extern uint8_t client_ethaddr[6];
-
-#define PROTO_SLIP 0x1
-#ifdef USE_PPP
-#define PROTO_PPP 0x2
-#endif
-
-void if_encap(const uint8_t *ip_data, int ip_data_len);
diff --git a/slirp2/mbuf.c b/slirp2/mbuf.c
deleted file mode 100644
index efc8141..0000000
--- a/slirp2/mbuf.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-/*
- * mbuf's in SLiRP are much simpler than the real mbufs in
- * FreeBSD. They are fixed size, determined by the MTU,
- * so that one whole packet can fit. Mbuf's cannot be
- * chained together. If there's more data than the mbuf
- * could hold, an external malloced buffer is pointed to
- * by m_ext (and the data pointers) and M_EXT is set in
- * the flags
- */
-
-#include <slirp.h>
-
-static int mbuf_alloced = 0;
-static MBufRec m_freelist, m_usedlist;
-static int mbuf_thresh = 30;
-static int mbuf_max = 0;
-static int msize;
-
-/*
- * How much room is in the mbuf, from m_data to the end of the mbuf
- */
-#define M_ROOM(m) ((m->m_flags & M_EXT)? \
- (((m)->m_ext + (m)->m_size) - (m)->m_data) \
- : \
- (((m)->m_dat + (m)->m_size) - (m)->m_data))
-
-/*
- * How much free room there is
- */
-#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len)
-
-
-void
-mbuf_init()
-{
- m_freelist.m_next = m_freelist.m_prev = &m_freelist;
- m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
- msize_init();
-}
-
-void
-msize_init()
-{
- /*
- * Find a nice value for msize
- * XXX if_maxlinkhdr already in mtu
- */
- msize = (if_mtu > if_mru ? if_mtu : if_mru) +
- if_maxlinkhdr + sizeof(struct m_hdr ) + 6;
-}
-
-static void
-mbuf_insque(MBuf m, MBuf head)
-{
- m->m_next = head->m_next;
- m->m_prev = head;
- head->m_next = m;
- m->m_next->m_prev = m;
-}
-
-static void
-mbuf_remque(MBuf m)
-{
- m->m_prev->m_next = m->m_next;
- m->m_next->m_prev = m->m_prev;
- m->m_next = m->m_prev = m;
-}
-
-/*
- * Get an mbuf from the free list, if there are none
- * malloc one
- *
- * Because fragmentation can occur if we alloc new mbufs and
- * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE,
- * which tells m_free to actually free() it
- */
-MBuf
-mbuf_alloc(void)
-{
- register MBuf m;
- int flags = 0;
-
- DEBUG_CALL("mbuf_alloc");
-
- if (m_freelist.m_next == &m_freelist) {
- m = (MBuf) malloc(msize);
- if (m == NULL) goto end_error;
- mbuf_alloced++;
- if (mbuf_alloced > mbuf_thresh)
- flags = M_DOFREE;
- if (mbuf_alloced > mbuf_max)
- mbuf_max = mbuf_alloced;
- } else {
- m = m_freelist.m_next;
- mbuf_remque(m);
- }
-
- /* Insert it in the used list */
- mbuf_insque(m,&m_usedlist);
- m->m_flags = (flags | M_USEDLIST);
-
- /* Initialise it */
- m->m_size = msize - sizeof(struct m_hdr);
- m->m_data = m->m_dat;
- m->m_len = 0;
- m->m_next2 = NULL;
- m->m_prev2 = NULL;
-end_error:
- DEBUG_ARG("m = %lx", (long )m);
- return m;
-}
-
-void
-mbuf_free(MBuf m)
-{
-
- DEBUG_CALL("mbuf_free");
- DEBUG_ARG("m = %lx", (long )m);
-
- if(m) {
- /* Remove from m_usedlist */
- if (m->m_flags & M_USEDLIST)
- mbuf_remque(m);
-
- /* If it's M_EXT, free() it */
- if (m->m_flags & M_EXT)
- free(m->m_ext);
-
- /*
- * Either free() it or put it on the free list
- */
- if (m->m_flags & M_DOFREE) {
- free(m);
- mbuf_alloced--;
- } else if ((m->m_flags & M_FREELIST) == 0) {
- mbuf_insque(m,&m_freelist);
- m->m_flags = M_FREELIST; /* Clobber other flags */
- }
- } /* if(m) */
-}
-
-/*
- * Copy data from one mbuf to the end of
- * the other.. if result is too big for one mbuf, malloc()
- * an M_EXT data segment
- */
-void
-mbuf_append(MBuf m, MBuf n)
-{
- /*
- * If there's no room, realloc
- */
- if (M_FREEROOM(m) < n->m_len)
- mbuf_ensure(m, m->m_size+MINCSIZE);
-
- memcpy(m->m_data+m->m_len, n->m_data, n->m_len);
- m->m_len += n->m_len;
-
- mbuf_free(n);
-}
-
-
-/* make m size bytes large */
-void
-mbuf_ensure(MBuf m, int size)
-{
- int datasize;
-
- /* some compiles throw up on gotos. This one we can fake. */
- if(m->m_size > size) return;
-
- if (m->m_flags & M_EXT) {
- datasize = m->m_data - m->m_ext;
- m->m_ext = (char *)realloc(m->m_ext,size);
- m->m_data = m->m_ext + datasize;
- } else {
- char *dat;
- datasize = m->m_data - m->m_dat;
- dat = (char *)malloc(size);
- memcpy(dat, m->m_dat, m->m_size);
-
- m->m_ext = dat;
- m->m_data = m->m_ext + datasize;
- m->m_flags |= M_EXT;
- }
-
- m->m_size = size;
-}
-
-
-
-void
-mbuf_trim(MBuf m, int len)
-{
- if (m == NULL)
- return;
- if (len >= 0) {
- /* Trim from head */
- m->m_data += len;
- m->m_len -= len;
- } else {
- /* Trim from tail */
- len = -len;
- m->m_len -= len;
- }
-}
-
-
-/*
- * Copy len bytes from m, starting off bytes into n
- */
-int
-mbuf_copy(MBuf n, MBuf m, int off, int len)
-{
- if (len > M_FREEROOM(n))
- return -1;
-
- memcpy((n->m_data + n->m_len), (m->m_data + off), len);
- n->m_len += len;
- return 0;
-}
-
-int
-mbuf_freeroom( MBuf m )
-{
- return M_FREEROOM(m);
-}
-
-/*
- * Given a pointer into an mbuf, return the mbuf
- * XXX This is a kludge, I should eliminate the need for it
- * Fortunately, it's not used often
- */
-MBuf
-mbuf_from(void* dat)
-{
- MBuf m;
-
- DEBUG_CALL("mbuf_from");
- DEBUG_ARG("dat = %lx", (long )dat);
-
- /* bug corrected for M_EXT buffers */
- for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
- if (m->m_flags & M_EXT) {
- if( (unsigned)((char*)dat - m->m_ext) < (unsigned)m->m_size )
- goto Exit;
- } else {
- if( (unsigned)((char *)dat - m->m_dat) < (unsigned)m->m_size )
- goto Exit;
- }
- }
- m = NULL;
- DEBUG_ERROR((dfd, "mbuf_from failed"));
-Exit:
- return m;
-}
-
-void
-mbufstats()
-{
- MBuf m;
- int i;
-
- lprint(" \r\n");
-
- lprint("Mbuf stats:\r\n");
-
- lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max);
-
- i = 0;
- for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next)
- i++;
- lprint(" %6d mbufs on free list\r\n", i);
-
- i = 0;
- for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
- i++;
- lprint(" %6d mbufs on used list\r\n", i);
- lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
-}
diff --git a/slirp2/mbuf.h b/slirp2/mbuf.h
deleted file mode 100644
index ed83372..0000000
--- a/slirp2/mbuf.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)mbuf.h 8.3 (Berkeley) 1/21/94
- * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp
- */
-
-#ifndef _MBUF_H_
-#define _MBUF_H_
-
-#define MINCSIZE 4096 /* Amount to increase mbuf if too small */
-
-/* flags for the mh_flags field */
-#define M_EXT 0x01 /* m_ext points to more (malloced) data */
-#define M_FREELIST 0x02 /* mbuf is on free list */
-#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */
-#define M_DOFREE 0x08 /* when mbuf_free is called on the mbuf, free()
- * it rather than putting it on the free list */
-
-
-/* XXX About mbufs for slirp:
- * Only one mbuf is ever used in a chain, for each "cell" of data.
- * m_nextpkt points to the next packet, if fragmented.
- * If the data is too large, the M_EXT is used, and a larger block
- * is alloced. Therefore, mbuf_free[m] must check for M_EXT and if set
- * free the m_ext. This is inefficient memory-wise, but who cares.
- */
-
-/* XXX should union some of these! */
-/* header at beginning of each mbuf: */
-
-/**
- * m_next, m_prev :: used to place the MBuf in free/used linked lists
- * m_next2, m_prev2 :: used to place the same MBuf in other linked lists
- * m_flags :: bit flags describing this MBuf
- * m_size :: total size of MBuf buffer
- * m_so :: socket this MBuf is attached to
- * m_data :: pointer to current cursor in MBuf buffer
- * m_len :: amount of data recorded in this MBuf
- */
-#define MBUF_HEADER \
- struct mbuf* m_next; \
- struct mbuf* m_prev; \
- struct mbuf* m_next2; \
- struct mbuf* m_prev2; \
- int m_flags; \
- int m_size; \
- struct socket* m_so; \
- caddr_t m_data; \
- int m_len;
-
-struct m_hdr {
- MBUF_HEADER
-};
-
-typedef struct mbuf {
- MBUF_HEADER
- union M_dat {
- char m_dat_[1]; /* ANSI doesn't like 0 sized arrays */
- char* m_ext_;
- } M_dat;
-} MBufRec, *MBuf;
-
-#define m_nextpkt m_next2
-#define m_prevpkt m_prev2
-#define m_dat M_dat.m_dat_
-#define m_ext M_dat.m_ext_
-
-#define ifq_prev m_prev
-#define ifq_next m_next
-
-#define ifs_prev m_prev2
-#define ifs_next m_next2
-
-#define ifq_so m_so
-
-void mbuf_init (void);
-void msize_init (void);
-MBuf mbuf_alloc (void);
-void mbuf_free (MBuf m);
-void mbuf_append(MBuf m1, MBuf m2);
-void mbuf_ensure(MBuf m, int size);
-void mbuf_trim (MBuf m, int len);
-int mbuf_copy (MBuf m, MBuf n, int n_offset, int n_length);
-
-#define MBUF_TO(m,t) ((t)(m)->m_data)
-#define MBUF_FROM(d) mbuf_from(d)
-MBuf mbuf_from (void *);
-
-int mbuf_freeroom( MBuf m );
-
-#endif
diff --git a/slirp2/misc.c b/slirp2/misc.c
deleted file mode 100644
index 9a2699a..0000000
--- a/slirp2/misc.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define WANT_SYS_IOCTL_H
-#include <slirp.h>
-
-u_int curtime, time_fasttimo, last_slowtimo, detach_time;
-u_int detach_wait = 600000; /* 10 minutes */
-struct emu_t *tcpemu;
-
-int
-inet_strtoip(const char* str, uint32_t *ip)
-{
- int comp[4];
-
- if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4)
- return -1;
-
- if ((unsigned)comp[0] >= 256 ||
- (unsigned)comp[1] >= 256 ||
- (unsigned)comp[2] >= 256 ||
- (unsigned)comp[3] >= 256)
- return -1;
-
- *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) |
- (comp[2] << 8) | comp[3]);
- return 0;
-}
-
-char* inet_iptostr(uint32_t ip)
-{
- static char buff[32];
-
- snprintf(buff, sizeof(buff), "%d.%d.%d.%d",
- (ip >> 24) & 255,
- (ip >> 16) & 255,
- (ip >> 8) & 255,
- ip & 255);
- return buff;
-}
-
-/*
- * Get our IP address and put it in our_addr
- */
-void
-getouraddr()
-{
- char* hostname = host_name();
- SockAddress hostaddr;
-
- our_addr_ip = loopback_addr_ip;
-
- if (sock_address_init_resolve( &hostaddr, hostname, 0, 0 ) < 0)
- return;
-
- our_addr_ip = sock_address_get_ip(&hostaddr);
- if (our_addr_ip == (uint32_t)-1)
- our_addr_ip = loopback_addr_ip;
-}
-
-struct quehead {
- struct quehead *qh_link;
- struct quehead *qh_rlink;
-};
-
-inline void
-insque(void* a, void* b)
-{
- register struct quehead *element = (struct quehead *) a;
- register struct quehead *head = (struct quehead *) b;
- element->qh_link = head->qh_link;
- head->qh_link = (struct quehead *)element;
- element->qh_rlink = (struct quehead *)head;
- ((struct quehead *)(element->qh_link))->qh_rlink
- = (struct quehead *)element;
-}
-
-inline void
-remque(void* a)
-{
- register struct quehead *element = (struct quehead *) a;
- ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
- ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
- element->qh_rlink = NULL;
- /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */
-}
-
-/* #endif */
-
-
-#ifndef HAVE_STRERROR
-
-/*
- * For systems with no strerror
- */
-
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-char *
-strerror(int error)
-{
- if (error < sys_nerr)
- return sys_errlist[error];
- else
- return "Unknown error.";
-}
-
-#endif
-
-
-
-#ifndef HAVE_STRDUP
-char *
-strdup(const char* str)
-{
- char *bptr;
- int len = strlen(str);
-
- bptr = (char *)malloc(len+1);
- memcpy(bptr, str, len+1);
-
- return bptr;
-}
-#endif
-
-
-int (*lprint_print) _P((void *, const char *, va_list));
-char *lprint_ptr, *lprint_ptr2, **lprint_arg;
-
-void
-lprint(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- if (lprint_print)
- lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
-
- /* Check if they want output to be logged to file as well */
- if (lfd) {
- /*
- * Remove \r's
- * otherwise you'll get ^M all over the file
- */
- int len = strlen(format);
- char *bptr1, *bptr2;
-
- bptr1 = bptr2 = strdup(format);
-
- while (len--) {
- if (*bptr1 == '\r')
- memcpy(bptr1, bptr1+1, len+1);
- else
- bptr1++;
- }
- vfprintf(lfd, bptr2, args);
- free(bptr2);
- }
- va_end(args);
-}
-
-void
-add_emu(char* buff)
-{
- u_int lport, fport;
- u_int8_t tos = 0, emu = 0;
- char buff1[256], buff2[256], buff4[128];
- char *buff3 = buff4;
- struct emu_t *emup;
- struct socket *so;
-
- if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
- lprint("Error: Bad arguments\r\n");
- return;
- }
-
- if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
- lport = 0;
- if (sscanf(buff1, "%d", &fport) != 1) {
- lprint("Error: Bad first argument\r\n");
- return;
- }
- }
-
- if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
- buff3 = 0;
- if (sscanf(buff2, "%256s", buff1) != 1) {
- lprint("Error: Bad second argument\r\n");
- return;
- }
- }
-
- if (buff3) {
- if (strcmp(buff3, "lowdelay") == 0)
- tos = IPTOS_LOWDELAY;
- else if (strcmp(buff3, "throughput") == 0)
- tos = IPTOS_THROUGHPUT;
- else {
- lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
- return;
- }
- }
-
- if (strcmp(buff1, "ftp") == 0)
- emu = EMU_FTP;
- else if (strcmp(buff1, "irc") == 0)
- emu = EMU_IRC;
- else if (strcmp(buff1, "none") == 0)
- emu = EMU_NONE; /* ie: no emulation */
- else {
- lprint("Error: Unknown service\r\n");
- return;
- }
-
- /* First, check that it isn't already emulated */
- for (emup = tcpemu; emup; emup = emup->next) {
- if (emup->lport == lport && emup->fport == fport) {
- lprint("Error: port already emulated\r\n");
- return;
- }
- }
-
- /* link it */
- emup = (struct emu_t *)malloc(sizeof (struct emu_t));
- emup->lport = (u_int16_t)lport;
- emup->fport = (u_int16_t)fport;
- emup->tos = tos;
- emup->emu = emu;
- emup->next = tcpemu;
- tcpemu = emup;
-
- /* And finally, mark all current sessions, if any, as being emulated */
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
- if ((lport && lport == so->so_laddr_port) ||
- (fport && fport == so->so_faddr_port)) {
- if (emu)
- so->so_emu = emu;
- if (tos)
- so->so_iptos = tos;
- }
- }
-
- lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
-}
-
-#ifdef BAD_SPRINTF
-
-#undef vsprintf
-#undef sprintf
-
-/*
- * Some BSD-derived systems have a sprintf which returns char *
- */
-
-int
-vsprintf_len(char* string, const char* format, va_list args)
-{
- vsprintf(string, format, args);
- return strlen(string);
-}
-
-int
-sprintf_len(char *string, const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- vsprintf(string, format, args);
- return strlen(string);
-}
-
-#endif
-
diff --git a/slirp2/misc.h b/slirp2/misc.h
deleted file mode 100644
index aa4a0ce..0000000
--- a/slirp2/misc.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifndef _MISC_H_
-#define _MISC_H_
-
-extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait;
-
-extern int (*lprint_print) _P((void *, const char *, va_list));
-extern char *lprint_ptr, *lprint_ptr2, **lprint_arg;
-//extern SBuf lprint_sb;
-
-#ifndef HAVE_STRDUP
-char *strdup _P((const char *));
-#endif
-
-void do_wait _P((int));
-
-#define EMU_NONE 0x0
-
-/* TCP emulations */
-#define EMU_CTL 0x1
-#define EMU_FTP 0x2
-#define EMU_KSH 0x3
-#define EMU_IRC 0x4
-#define EMU_REALAUDIO 0x5
-#define EMU_RLOGIN 0x6
-#define EMU_IDENT 0x7
-#define EMU_RSH 0x8
-
-#define EMU_NOCONNECT 0x10 /* Don't connect */
-
-/* UDP emulations */
-#define EMU_TALK 0x1
-#define EMU_NTALK 0x2
-#define EMU_CUSEEME 0x3
-
-struct tos_t {
- u_int16_t lport;
- u_int16_t fport;
- u_int8_t tos;
- u_int8_t emu;
-};
-
-struct emu_t {
- u_int16_t lport;
- u_int16_t fport;
- u_int8_t tos;
- u_int8_t emu;
- struct emu_t *next;
-};
-
-extern struct emu_t *tcpemu;
-
-void getouraddr _P((void));
-inline void slirp_insque _P((void *, void *));
-inline void slirp_remque _P((void *));
-void add_emu _P((char *));
-
-#endif
diff --git a/slirp2/sbuf.c b/slirp2/sbuf.c
deleted file mode 100644
index abececa..0000000
--- a/slirp2/sbuf.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-void
-sbuf_free(SBuf sb)
-{
- free(sb->sb_data);
-}
-
-void
-sbuf_drop(SBuf sb, int num)
-{
- /*
- * We can only drop how much we have
- * This should never succeed
- */
- if(num > sb->sb_cc)
- num = sb->sb_cc;
- sb->sb_cc -= num;
- sb->sb_rptr += num;
- if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
- sb->sb_rptr -= sb->sb_datalen;
-
-}
-
-void
-sbuf_reserve(SBuf sb, int size)
-{
- if (sb->sb_datalen == size)
- return;
-
- sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
- sb->sb_cc = 0;
- if (sb->sb_wptr)
- sb->sb_datalen = size;
- else
- sb->sb_datalen = 0;
-}
-
-/*
- * Try and write() to the socket, whatever doesn't get written
- * append to the buffer... for a host with a fast net connection,
- * this prevents an unnecessary copy of the data
- * (the socket is non-blocking, so we won't hang)
- */
-void
-sbuf_append(struct socket *so, MBuf m)
-{
- int ret = 0;
-
- DEBUG_CALL("sbuf_append");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("m->m_len = %d", m->m_len);
-
- /* Shouldn't happen, but... e.g. foreign host closes connection */
- if (m->m_len <= 0) {
- mbuf_free(m);
- return;
- }
-
- /*
- * If there is urgent data, call sosendoob
- * if not all was sent, sowrite will take care of the rest
- * (The rest of this function is just an optimisation)
- */
- if (so->so_urgc) {
- sbuf_appendsb(&so->so_rcv, m);
- mbuf_free(m);
- sosendoob(so);
- return;
- }
-
- /*
- * We only write if there's nothing in the buffer,
- * ottherwise it'll arrive out of order, and hence corrupt
- */
- if (!so->so_rcv.sb_cc) {
- ret = socket_send(so->s, m->m_data, m->m_len);
- }
-
- if (ret <= 0) {
- /*
- * Nothing was written
- * It's possible that the socket has closed, but
- * we don't need to check because if it has closed,
- * it will be detected in the normal way by soread()
- */
- sbuf_appendsb(&so->so_rcv, m);
- } else if (ret != m->m_len) {
- /*
- * Something was written, but not everything..
- * sbuf_appendsb the rest
- */
- m->m_len -= ret;
- m->m_data += ret;
- sbuf_appendsb(&so->so_rcv, m);
- } /* else */
- /* Whatever happened, we free the mbuf */
- mbuf_free(m);
-}
-
-/*
- * Copy the data from m into sb
- * The caller is responsible to make sure there's enough room
- */
-void
-sbuf_appendsb(SBuf sb, MBuf m)
-{
- int len, n, nn;
-
- len = m->m_len;
-
- if (sb->sb_wptr < sb->sb_rptr) {
- n = sb->sb_rptr - sb->sb_wptr;
- if (n > len) n = len;
- memcpy(sb->sb_wptr, m->m_data, n);
- } else {
- /* Do the right edge first */
- n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
- if (n > len) n = len;
- memcpy(sb->sb_wptr, m->m_data, n);
- len -= n;
- if (len) {
- /* Now the left edge */
- nn = sb->sb_rptr - sb->sb_data;
- if (nn > len) nn = len;
- memcpy(sb->sb_data,m->m_data+n,nn);
- n += nn;
- }
- }
-
- sb->sb_cc += n;
- sb->sb_wptr += n;
- if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
- sb->sb_wptr -= sb->sb_datalen;
-}
-
-/*
- * Copy data from sbuf to a normal, straight buffer
- * Don't update the sbuf rptr, this will be
- * done in sbdrop when the data is acked
- */
-void
-sbuf_copy(SBuf sb, int off, int len, char* to)
-{
- char *from;
-
- from = sb->sb_rptr + off;
- if (from >= sb->sb_data + sb->sb_datalen)
- from -= sb->sb_datalen;
-
- if (from < sb->sb_wptr) {
- if (len > sb->sb_cc) len = sb->sb_cc;
- memcpy(to,from,len);
- } else {
- /* re-use off */
- off = (sb->sb_data + sb->sb_datalen) - from;
- if (off > len) off = len;
- memcpy(to,from,off);
- len -= off;
- if (len)
- memcpy(to+off,sb->sb_data,len);
- }
-}
-
diff --git a/slirp2/sbuf.h b/slirp2/sbuf.h
deleted file mode 100644
index 05fa01a..0000000
--- a/slirp2/sbuf.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#ifndef _SBUF_H_
-#define _SBUF_H_
-
-#include "mbuf.h"
-#include <stddef.h>
-
-/* a SBuf is a simple circular buffer used to hold RX and TX data in a struct socket
- */
-
-typedef struct sbuf {
- unsigned sb_cc; /* actual chars in buffer */
- unsigned sb_datalen; /* Length of data */
- char* sb_wptr; /* write pointer. points to where the next
- * bytes should be written in the sbuf */
- char* sb_rptr; /* read pointer. points to where the next
- * byte should be read from the sbuf */
- char* sb_data; /* Actual data */
-} SBufRec, *SBuf;
-
-void sbuf_free (SBuf sb);
-void sbuf_drop (SBuf sb, int num);
-void sbuf_reserve (SBuf sb, int count);
-void sbuf_append (struct socket *so, MBuf m);
-void sbuf_appendsb(SBuf sb, MBuf m);
-void sbuf_copy (SBuf sb, int offset, int length, char *to);
-
-#define sbuf_flush(sb) sbuf_drop((sb),(sb)->sb_cc)
-#define sbuf_space(sb) ((sb)->sb_datalen - (sb)->sb_cc)
-
-#endif
diff --git a/slirp2/slirp.c b/slirp2/slirp.c
deleted file mode 100644
index 23a3e3c..0000000
--- a/slirp2/slirp.c
+++ /dev/null
@@ -1,762 +0,0 @@
-#include "slirp.h"
-#include "proxy_common.h"
-#include "android/utils/debug.h" /* for dprint */
-#include "android/utils/bufprint.h"
-#include "android/android.h"
-#include "sockets.h"
-
-#define D(...) VERBOSE_PRINT(slirp,__VA_ARGS__)
-#define DN(...) do { if (VERBOSE_CHECK(slirp)) dprintn(__VA_ARGS__); } while (0)
-
-/* host address */
-uint32_t our_addr_ip;
-/* host dns address */
-uint32_t dns_addr[DNS_ADDR_MAX];
-int dns_addr_count;
-
-/* host loopback address */
-uint32_t loopback_addr_ip;
-
-/* address for slirp virtual addresses */
-uint32_t special_addr_ip;
-
-/* virtual address alias for host */
-uint32_t alias_addr_ip;
-
-const uint8_t special_ethaddr[6] = {
- 0x52, 0x54, 0x00, 0x12, 0x35, 0x00
-};
-
-uint8_t client_ethaddr[6] = {
- 0x52, 0x54, 0x00, 0x12, 0x34, 0x56
-};
-
-int do_slowtimo;
-int link_up;
-struct timeval tt;
-FILE *lfd;
-
-/* XXX: suppress those select globals */
-fd_set *global_readfds, *global_writefds, *global_xfds;
-
-char slirp_hostname[33];
-
-int slirp_add_dns_server(const SockAddress* new_dns_addr)
-{
- int dns_ip;
-
- if (dns_addr_count >= DNS_ADDR_MAX)
- return -1;
-
- dns_ip = sock_address_get_ip(new_dns_addr);
- if (dns_ip < 0)
- return -1;
-
- dns_addr[dns_addr_count++] = dns_ip;
- return 0;
-}
-
-
-#ifdef _WIN32
-
-int slirp_get_system_dns_servers()
-{
- FIXED_INFO *FixedInfo=NULL;
- ULONG BufLen;
- DWORD ret;
- IP_ADDR_STRING *pIPAddr;
-
- if (dns_addr_count > 0)
- return dns_addr_count;
-
- FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
- BufLen = sizeof(FIXED_INFO);
-
- if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
- if (FixedInfo) {
- GlobalFree(FixedInfo);
- FixedInfo = NULL;
- }
- FixedInfo = GlobalAlloc(GPTR, BufLen);
- }
-
- if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
- printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
- if (FixedInfo) {
- GlobalFree(FixedInfo);
- FixedInfo = NULL;
- }
- return -1;
- }
-
- D( "DNS Servers:");
- pIPAddr = &(FixedInfo->DnsServerList);
- while (pIPAddr && dns_addr_count < DNS_ADDR_MAX) {
- uint32_t ip;
- D( " %s", pIPAddr->IpAddress.String );
- if (inet_strtoip(pIPAddr->IpAddress.String, &ip) == 0) {
- if (ip == loopback_addr_ip)
- ip = our_addr_ip;
- if (dns_addr_count < DNS_ADDR_MAX)
- dns_addr[dns_addr_count++] = ip;
- }
- pIPAddr = pIPAddr->Next;
- }
-
- if (FixedInfo) {
- GlobalFree(FixedInfo);
- FixedInfo = NULL;
- }
- if (dns_addr_count <= 0)
- return -1;
-
- return dns_addr_count;
-}
-
-#else
-
-int slirp_get_system_dns_servers(void)
-{
- char buff[512];
- char buff2[256];
- FILE *f;
-
- if (dns_addr_count > 0)
- return dns_addr_count;
-
-#ifdef CONFIG_DARWIN
- /* on Darwin /etc/resolv.conf is a symlink to /private/var/run/resolv.conf
- * in some siutations, the symlink can be destroyed and the system will not
- * re-create it. Darwin-aware applications will continue to run, but "legacy"
- * Unix ones will not.
- */
- f = fopen("/private/var/run/resolv.conf", "r");
- if (!f)
- f = fopen("/etc/resolv.conf", "r"); /* desperate attempt to sanity */
-#else
- f = fopen("/etc/resolv.conf", "r");
-#endif
- if (!f)
- return -1;
-
- DN("emulator: IP address of your DNS(s): ");
- while (fgets(buff, 512, f) != NULL) {
- if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
- uint32_t tmp_ip;
-
- if (inet_strtoip(buff2, &tmp_ip) < 0)
- continue;
- if (tmp_ip == loopback_addr_ip)
- tmp_ip = our_addr_ip;
- if (dns_addr_count < DNS_ADDR_MAX) {
- dns_addr[dns_addr_count++] = tmp_ip;
- if (dns_addr_count > 1)
- DN(", ");
- DN("%s", inet_iptostr(tmp_ip));
- } else {
- DN("(more)");
- break;
- }
- }
- }
- DN("\n");
- fclose(f);
-
- if (!dns_addr_count)
- return -1;
-
- return dns_addr_count;
-}
-
-#endif
-
-extern void slirp_init_shapers();
-
-void slirp_init(void)
-{
-#if DEBUG
- int slirp_logmask = 0;
- char slirp_logfile[512];
- {
- const char* env = getenv( "ANDROID_SLIRP_LOGMASK" );
- if (env != NULL)
- slirp_logmask = atoi(env);
- else if (VERBOSE_CHECK(slirp))
- slirp_logmask = DEBUG_DEFAULT;
- }
-
- {
- char* p = slirp_logfile;
- char* end = p + sizeof(slirp_logfile);
-
- p = bufprint_temp_file( p, end, "slirp.log" );
- if (p >= end) {
- dprint( "cannot create slirp log file in temporary directory" );
- slirp_logmask = 0;
- }
- }
- if (slirp_logmask) {
- dprint( "sending slirp logs with mask %x to %s", slirp_logmask, slirp_logfile );
- debug_init( slirp_logfile, slirp_logmask );
- }
-#endif
-
- link_up = 1;
-
- if_init();
- ip_init();
-
- /* Initialise mbufs *after* setting the MTU */
- mbuf_init();
-
- /* set default addresses */
- inet_strtoip("127.0.0.1", &loopback_addr_ip);
-
- if (dns_addr_count == 0) {
- if (slirp_get_system_dns_servers() < 0) {
- dns_addr[0] = loopback_addr_ip;
- dns_addr_count = 1;
- fprintf (stderr, "Warning: No DNS servers found\n");
- }
- }
-
- inet_strtoip(CTL_SPECIAL, &special_addr_ip);
-
- alias_addr_ip = special_addr_ip | CTL_ALIAS;
- getouraddr();
-
- slirp_init_shapers();
-}
-
-#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
-
-/*
- * curtime kept to an accuracy of 1ms
- */
-#ifdef _WIN32
-static void updtime(void)
-{
- struct _timeb tb;
-
- _ftime(&tb);
- curtime = (u_int)tb.time * (u_int)1000;
- curtime += (u_int)tb.millitm;
-}
-#else
-static void updtime(void)
-{
- gettimeofday(&tt, 0);
-
- curtime = (u_int)tt.tv_sec * (u_int)1000;
- curtime += (u_int)tt.tv_usec / (u_int)1000;
-
- if ((tt.tv_usec % 1000) >= 500)
- curtime++;
-}
-#endif
-
-void slirp_select_fill(int *pnfds,
- fd_set *readfds, fd_set *writefds, fd_set *xfds)
-{
- struct socket *so, *so_next;
- struct timeval timeout;
- int nfds;
- int tmp_time;
-
- /* fail safe */
- global_readfds = NULL;
- global_writefds = NULL;
- global_xfds = NULL;
-
- nfds = *pnfds;
- /*
- * First, TCP sockets
- */
- do_slowtimo = 0;
- if (link_up) {
- /*
- * *_slowtimo needs calling if there are IP fragments
- * in the fragment queue, or there are TCP connections active
- */
- do_slowtimo = ((tcb.so_next != &tcb) ||
- (&ipq.ip_link != ipq.ip_link.next));
-
- for (so = tcb.so_next; so != &tcb; so = so_next) {
- so_next = so->so_next;
-
- /*
- * See if we need a tcp_fasttimo
- */
- if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
- time_fasttimo = curtime; /* Flag when we want a fasttimo */
-
- /*
- * NOFDREF can include still connecting to local-host,
- * newly socreated() sockets etc. Don't want to select these.
- */
- if (so->so_state & SS_NOFDREF || so->s == -1)
- continue;
-
- /*
- * don't register proxified socked connections here
- */
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- /*
- * Set for reading sockets which are accepting
- */
- if (so->so_state & SS_FACCEPTCONN) {
- FD_SET(so->s, readfds);
- UPD_NFDS(so->s);
- continue;
- }
-
- /*
- * Set for writing sockets which are connecting
- */
- if (so->so_state & SS_ISFCONNECTING) {
- FD_SET(so->s, writefds);
- UPD_NFDS(so->s);
- continue;
- }
-
- /*
- * Set for writing if we are connected, can send more, and
- * we have something to send
- */
- if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
- FD_SET(so->s, writefds);
- UPD_NFDS(so->s);
- }
-
- /*
- * Set for reading (and urgent data) if we are connected, can
- * receive more, and we have room for it XXX /2 ?
- */
- if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
- FD_SET(so->s, readfds);
- FD_SET(so->s, xfds);
- UPD_NFDS(so->s);
- }
- }
-
- /*
- * UDP sockets
- */
- for (so = udb.so_next; so != &udb; so = so_next) {
- so_next = so->so_next;
-
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- /*
- * See if it's timed out
- */
- if (so->so_expire) {
- if (so->so_expire <= curtime) {
- udp_detach(so);
- continue;
- } else
- do_slowtimo = 1; /* Let socket expire */
- }
-
- /*
- * When UDP packets are received from over the
- * link, they're sendto()'d straight away, so
- * no need for setting for writing
- * Limit the number of packets queued by this session
- * to 4. Note that even though we try and limit this
- * to 4 packets, the session could have more queued
- * if the packets needed to be fragmented
- * (XXX <= 4 ?)
- */
- if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
- FD_SET(so->s, readfds);
- UPD_NFDS(so->s);
- }
- }
- }
-
- /*
- * Setup timeout to use minimum CPU usage, especially when idle
- */
-
- /*
- * First, see the timeout needed by *timo
- */
- timeout.tv_sec = 0;
- timeout.tv_usec = -1;
- /*
- * If a slowtimo is needed, set timeout to 500ms from the last
- * slow timeout. If a fast timeout is needed, set timeout within
- * 200ms of when it was requested.
- */
- if (do_slowtimo) {
- /* XXX + 10000 because some select()'s aren't that accurate */
- timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
- if (timeout.tv_usec < 0)
- timeout.tv_usec = 0;
- else if (timeout.tv_usec > 510000)
- timeout.tv_usec = 510000;
-
- /* Can only fasttimo if we also slowtimo */
- if (time_fasttimo) {
- tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
- if (tmp_time < 0)
- tmp_time = 0;
-
- /* Choose the smallest of the 2 */
- if (tmp_time < timeout.tv_usec)
- timeout.tv_usec = (u_int)tmp_time;
- }
- }
-
- /*
- * now, the proxified sockets
- */
- proxy_manager_select_fill(&nfds, readfds, writefds, xfds);
-
- *pnfds = nfds;
-}
-
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
-{
- struct socket *so, *so_next;
- int ret;
-
- global_readfds = readfds;
- global_writefds = writefds;
- global_xfds = xfds;
-
- /* Update time */
- updtime();
-
- /*
- * See if anything has timed out
- */
- if (link_up) {
- if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
- tcp_fasttimo();
- time_fasttimo = 0;
- }
- if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
- ip_slowtimo();
- tcp_slowtimo();
- last_slowtimo = curtime;
- }
- }
-
- /*
- * Check sockets
- */
- if (link_up) {
- /*
- * Check TCP sockets
- */
- for (so = tcb.so_next; so != &tcb; so = so_next) {
- so_next = so->so_next;
-
- /*
- * FD_ISSET is meaningless on these sockets
- * (and they can crash the program)
- */
- if (so->so_state & SS_NOFDREF || so->s == -1)
- continue;
-
- /*
- * proxified sockets are polled later in this
- * function.
- */
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- /*
- * Check for URG data
- * This will soread as well, so no need to
- * test for readfds below if this succeeds
- */
- if (FD_ISSET(so->s, xfds))
- sorecvoob(so);
- /*
- * Check sockets for reading
- */
- else if (FD_ISSET(so->s, readfds)) {
- /*
- * Check for incoming connections
- */
- if (so->so_state & SS_FACCEPTCONN) {
- tcp_connect(so);
- continue;
- } /* else */
- ret = soread(so);
-
- /* Output it if we read something */
- if (ret > 0)
- tcp_output(sototcpcb(so));
- }
-
- /*
- * Check sockets for writing
- */
- if (FD_ISSET(so->s, writefds)) {
- /*
- * Check for non-blocking, still-connecting sockets
- */
- if (so->so_state & SS_ISFCONNECTING) {
- /* Connected */
- so->so_state &= ~SS_ISFCONNECTING;
-
- ret = socket_send(so->s, (char*)&ret, 0);
- if (ret < 0) {
- /* XXXXX Must fix, zero bytes is a NOP */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN)
- continue;
-
- /* else failed */
- so->so_state = SS_NOFDREF;
- }
- /* else so->so_state &= ~SS_ISFCONNECTING; */
-
- /*
- * Continue tcp_input
- */
- tcp_input((MBuf )NULL, sizeof(struct ip), so);
- /* continue; */
- } else
- ret = sowrite(so);
- /*
- * XXXXX If we wrote something (a lot), there
- * could be a need for a window update.
- * In the worst case, the remote will send
- * a window probe to get things going again
- */
- }
-
- /*
- * Probe a still-connecting, non-blocking socket
- * to check if it's still alive
- */
-#ifdef PROBE_CONN
- if (so->so_state & SS_ISFCONNECTING) {
- ret = socket_recv(so->s, (char *)&ret, 0);
-
- if (ret < 0) {
- /* XXX */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN)
- continue; /* Still connecting, continue */
-
- /* else failed */
- so->so_state = SS_NOFDREF;
-
- /* tcp_input will take care of it */
- } else {
- ret = socket_send(so->s, &ret, 0,0);
- if (ret < 0) {
- /* XXX */
- if (errno == EAGAIN || errno == EWOULDBLOCK ||
- errno == EINPROGRESS || errno == ENOTCONN)
- continue;
- /* else failed */
- so->so_state = SS_NOFDREF;
- } else
- so->so_state &= ~SS_ISFCONNECTING;
-
- }
- tcp_input((MBuf )NULL, sizeof(struct ip),so);
- } /* SS_ISFCONNECTING */
-#endif
- }
-
- /*
- * Now UDP sockets.
- * Incoming packets are sent straight away, they're not buffered.
- * Incoming UDP data isn't buffered either.
- */
- for (so = udb.so_next; so != &udb; so = so_next) {
- so_next = so->so_next;
-
- if ((so->so_state & SS_PROXIFIED) != 0)
- continue;
-
- if (so->s != -1 && FD_ISSET(so->s, readfds)) {
- sorecvfrom(so);
- }
- }
- }
-
- /*
- * Now the proxified sockets
- */
- proxy_manager_poll(readfds, writefds, xfds);
-
- /*
- * See if we can start outputting
- */
- if (if_queued && link_up)
- if_start();
-
- /* clear global file descriptor sets.
- * these reside on the stack in vl.c
- * so they're unusable if we're not in
- * slirp_select_fill or slirp_select_poll.
- */
- global_readfds = NULL;
- global_writefds = NULL;
- global_xfds = NULL;
-}
-
-#define ETH_ALEN 6
-#define ETH_HLEN 14
-
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
-
-#define ARPOP_REQUEST 1 /* ARP request */
-#define ARPOP_REPLY 2 /* ARP reply */
-
-struct ethhdr
-{
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
-};
-
-struct arphdr
-{
- unsigned short ar_hrd; /* format of hardware address */
- unsigned short ar_pro; /* format of protocol address */
- unsigned char ar_hln; /* length of hardware address */
- unsigned char ar_pln; /* length of protocol address */
- unsigned short ar_op; /* ARP opcode (command) */
-
- /*
- * Ethernet looks like this : This bit is variable sized however...
- */
- unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
- unsigned char ar_sip[4]; /* sender IP address */
- unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
- unsigned char ar_tip[4]; /* target IP address */
-};
-
-void arp_input(const uint8_t *pkt, int pkt_len)
-{
- struct ethhdr *eh = (struct ethhdr *)pkt;
- struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
- uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
- struct ethhdr *reh = (struct ethhdr *)arp_reply;
- struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
- int ar_op;
-
- ar_op = ntohs(ah->ar_op);
- switch(ar_op) {
- uint32_t ar_tip_ip;
- case ARPOP_REQUEST:
- ar_tip_ip = (ah->ar_tip[0] << 24) | (ah->ar_tip[1] << 16) | (ah->ar_tip[2] << 8);
- if (ar_tip_ip == special_addr_ip) {
- if ( CTL_IS_DNS(ah->ar_tip[3]) || ah->ar_tip[3] == CTL_ALIAS)
- goto arp_ok;
- return;
- arp_ok:
- /* XXX: make an ARP request to have the client address */
- memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
-
- /* ARP request for alias/dns mac address */
- memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
- memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
- reh->h_source[5] = ah->ar_tip[3];
- reh->h_proto = htons(ETH_P_ARP);
-
- rah->ar_hrd = htons(1);
- rah->ar_pro = htons(ETH_P_IP);
- rah->ar_hln = ETH_ALEN;
- rah->ar_pln = 4;
- rah->ar_op = htons(ARPOP_REPLY);
- memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
- memcpy(rah->ar_sip, ah->ar_tip, 4);
- memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
- memcpy(rah->ar_tip, ah->ar_sip, 4);
- slirp_output(arp_reply, sizeof(arp_reply));
- }
- break;
- default:
- break;
- }
-}
-
-void slirp_input(const uint8_t *pkt, int pkt_len)
-{
- MBuf m;
- int proto;
-
- if (pkt_len < ETH_HLEN)
- return;
-
- proto = ntohs(*(uint16_t *)(pkt + 12));
- switch(proto) {
- case ETH_P_ARP:
- arp_input(pkt, pkt_len);
- break;
- case ETH_P_IP:
- m = mbuf_alloc();
- if (!m)
- return;
- /* Note: we add to align the IP header */
- m->m_len = pkt_len + 2;
- memcpy(m->m_data + 2, pkt, pkt_len);
-
- m->m_data += 2 + ETH_HLEN;
- m->m_len -= 2 + ETH_HLEN;
-
- ip_input(m);
- break;
- default:
- break;
- }
-}
-
-/* output the IP packet to the ethernet device */
-void if_encap(const uint8_t *ip_data, int ip_data_len)
-{
- uint8_t buf[1600];
- struct ethhdr *eh = (struct ethhdr *)buf;
-
- if (ip_data_len + ETH_HLEN > sizeof(buf))
- return;
-
- memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
- memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
- /* XXX: not correct */
- eh->h_source[5] = CTL_ALIAS;
- eh->h_proto = htons(ETH_P_IP);
- memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
- slirp_output(buf, ip_data_len + ETH_HLEN);
-}
-
-int slirp_redir(int is_udp, int host_port,
- uint32_t guest_ip, int guest_port)
-{
- if (is_udp) {
- if (!udp_listen(host_port,
- guest_ip,
- guest_port, 0))
- return -1;
- } else {
- if (!solisten(host_port, guest_ip, guest_port, 0))
- return -1;
- }
- return 0;
-}
-
-int slirp_unredir(int is_udp, int host_port)
-{
- if (is_udp)
- return udp_unlisten( host_port );
- else
- return sounlisten( host_port );
-}
-
diff --git a/slirp2/slirp.h b/slirp2/slirp.h
deleted file mode 100644
index e69940b..0000000
--- a/slirp2/slirp.h
+++ /dev/null
@@ -1,276 +0,0 @@
-#ifndef __COMMON_H__
-#define __COMMON_H__
-
-#define CONFIG_QEMU
-
-#define DEBUG 1
-
-#ifndef CONFIG_QEMU
-#include "version.h"
-#endif
-#include "config.h"
-#include "slirp_config.h"
-
-#include <stddef.h>
-#include "sockets.h"
-
-#ifdef _WIN32
-# include <inttypes.h>
-
-typedef uint8_t u_int8_t;
-typedef uint16_t u_int16_t;
-typedef uint32_t u_int32_t;
-typedef uint64_t u_int64_t;
-typedef char *caddr_t;
-
-# include <windows.h>
-# include <sys/timeb.h>
-# include <iphlpapi.h>
-#else
-# define O_BINARY 0
-#endif
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_BITYPES_H
-# include <sys/bitypes.h>
-#endif
-
-#include <sys/time.h>
-
-#ifdef NEED_TYPEDEFS
-typedef char int8_t;
-typedef unsigned char u_int8_t;
-
-# if SIZEOF_SHORT == 2
- typedef short int16_t;
- typedef unsigned short u_int16_t;
-# else
-# if SIZEOF_INT == 2
- typedef int int16_t;
- typedef unsigned int u_int16_t;
-# else
- #error Cannot find a type with sizeof() == 2
-# endif
-# endif
-
-# if SIZEOF_SHORT == 4
- typedef short int32_t;
- typedef unsigned short u_int32_t;
-# else
-# if SIZEOF_INT == 4
- typedef int int32_t;
- typedef unsigned int u_int32_t;
-# else
- #error Cannot find a type with sizeof() == 4
-# endif
-# endif
-#endif /* NEED_TYPEDEFS */
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef HAVE_MEMMOVE
-#define memmove(x, y, z) bcopy(y, x, z)
-#endif
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/uio.h>
-#endif
-
-#ifndef _P
-#ifndef NO_PROTOTYPES
-# define _P(x) x
-#else
-# define _P(x) ()
-#endif
-#endif
-
-#ifndef _WIN32
-#include <arpa/inet.h>
-#endif
-
-#ifdef GETTIMEOFDAY_ONE_ARG
-#define gettimeofday(x, y) gettimeofday(x)
-#endif
-
-/* Systems lacking strdup() definition in <string.h>. */
-#if defined(ultrix)
-char *strdup _P((const char *));
-#endif
-
-/* Systems lacking malloc() definition in <stdlib.h>. */
-#if defined(ultrix) || defined(hcx)
-void *malloc _P((size_t arg));
-void free _P((void *ptr));
-#endif
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-/* Avoid conflicting with the libc insque() and remque(), which
- have different prototypes. */
-#define insque slirp_insque
-#define remque slirp_remque
-
-#ifdef HAVE_SYS_STROPTS_H
-#include <sys/stropts.h>
-#endif
-
-#include "debug.h"
-
-#include "ip.h"
-#include "tcp.h"
-#include "tcp_timer.h"
-#include "tcp_var.h"
-#include "tcpip.h"
-#include "udp.h"
-#include "icmp_var.h"
-#include "mbuf.h"
-#include "sbuf.h"
-#include "socket.h"
-#include "if.h"
-#include "main.h"
-#include "misc.h"
-#include "ctl.h"
-#ifdef USE_PPP
-#include "ppp/pppd.h"
-#include "ppp/ppp.h"
-#endif
-
-#include "bootp.h"
-#include "tftp.h"
-#include "libslirp.h"
-
-extern struct ttys *ttys_unit[MAX_INTERFACES];
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-#ifndef FULL_BOLT
-void if_start _P((void));
-#else
-void if_start _P((struct ttys *));
-#endif
-
-#ifdef BAD_SPRINTF
-# define vsprintf vsprintf_len
-# define sprintf sprintf_len
- extern int vsprintf_len _P((char *, const char *, va_list));
- extern int sprintf_len _P((char *, const char *, ...));
-#endif
-
-#ifdef DECLARE_SPRINTF
-# ifndef BAD_SPRINTF
- extern int vsprintf _P((char *, const char *, va_list));
-# endif
- extern int vfprintf _P((FILE *, const char *, va_list));
-#endif
-
-#ifndef HAVE_STRERROR
- extern char *strerror _P((int error));
-#endif
-
-#ifndef HAVE_INDEX
- char *index _P((const char *, int));
-#endif
-
-#ifndef HAVE_GETHOSTID
- long gethostid _P((void));
-#endif
-
-void lprint _P((const char *, ...));
-
-extern int do_echo;
-
-#define DEFAULT_BAUD 115200
-
-/* cksum.c */
-int cksum(MBuf m, int len);
-
-/* if.c */
-void if_init _P((void));
-void if_output _P((struct socket *, MBuf ));
-
-/* ip_input.c */
-void ip_init _P((void));
-void ip_input _P((MBuf ));
-struct ip * ip_reass _P((register struct ip*, register struct ipq *));
-void ip_freef _P((struct ipq *));
-void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *));
-void ip_deq _P((register struct ipasfrag *));
-void ip_slowtimo _P((void));
-void ip_stripoptions _P((register MBuf , MBuf ));
-
-/* ip_output.c */
-int ip_output _P((struct socket *, MBuf ));
-
-/* tcp_input.c */
-int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, MBuf ));
-void tcp_input _P((register MBuf , int, struct socket *));
-void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *));
-void tcp_xmit_timer _P((register struct tcpcb *, int));
-int tcp_mss _P((register struct tcpcb *, u_int));
-
-/* tcp_output.c */
-int tcp_output _P((register struct tcpcb *));
-void tcp_setpersist _P((register struct tcpcb *));
-
-/* tcp_subr.c */
-void tcp_init _P((void));
-void tcp_template _P((struct tcpcb *));
-void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register MBuf , tcp_seq, tcp_seq, int));
-struct tcpcb * tcp_newtcpcb _P((struct socket *));
-struct tcpcb * tcp_close _P((register struct tcpcb *));
-void tcp_drain _P((void));
-void tcp_sockclosed _P((struct tcpcb *));
-int tcp_fconnect _P((struct socket *));
-void tcp_connect _P((struct socket *));
-int tcp_attach _P((struct socket *));
-u_int8_t tcp_tos _P((struct socket *));
-int tcp_emu _P((struct socket *, MBuf ));
-int tcp_ctl _P((struct socket *));
-struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
-
-#ifdef USE_PPP
-#define MIN_MRU MINMRU
-#define MAX_MRU MAXMRU
-#else
-#define MIN_MRU 128
-#define MAX_MRU 16384
-#endif
-
-#ifndef _WIN32
-#define min(x,y) ((x) < (y) ? (x) : (y))
-#define max(x,y) ((x) > (y) ? (x) : (y))
-#endif
-
-#endif
diff --git a/slirp2/slirp_config.h b/slirp2/slirp_config.h
deleted file mode 100644
index 030d2ff..0000000
--- a/slirp2/slirp_config.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * User definable configuration options
- */
-
-/* Undefine if you don't want talk emulation */
-#undef EMULATE_TALK
-
-/* Define if you want the connection to be probed */
-/* XXX Not working yet, so ignore this for now */
-#undef PROBE_CONN
-
-/* Define to 1 if you want KEEPALIVE timers */
-#define DO_KEEPALIVE 0
-
-/* Define to MAX interfaces you expect to use at once */
-/* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */
-/* MAX_PPP_INTERFACES determines max. number of PPP interfaces */
-#define MAX_INTERFACES 1
-#define MAX_PPP_INTERFACES 1
-
-/* Define if you want slirp's socket in /tmp */
-/* XXXXXX Do this in ./configure */
-#undef USE_TMPSOCKET
-
-/* Define if you want slirp to use cfsetXspeed() on the terminal */
-#undef DO_CFSETSPEED
-
-/* Define this if you want slirp to write to the tty as fast as it can */
-/* This should only be set if you are using load-balancing, slirp does a */
-/* pretty good job on single modems already, and seting this will make */
-/* interactive sessions less responsive */
-/* XXXXX Talk about having fast modem as unit 0 */
-#undef FULL_BOLT
-
-/*
- * Define if you want slirp to use less CPU
- * You will notice a small lag in interactive sessions, but it's not that bad
- * Things like Netscape/ftp/etc. are completely unaffected
- * This is mainly for sysadmins who have many slirp users
- */
-#undef USE_LOWCPU
-
-/* Define this if your compiler doesn't like prototypes */
-#ifndef __STDC__
-#define NO_PROTOTYPES
-#endif
-
-/*********************************************************/
-/*
- * Autoconf defined configuration options
- * You shouldn't need to touch any of these
- */
-
-/* Ignore this */
-#undef DUMMY_PPP
-
-/* Define if you have unistd.h */
-#define HAVE_UNISTD_H
-
-/* Define if you have stdlib.h */
-#define HAVE_STDLIB_H
-
-/* Define if you have sys/ioctl.h */
-#undef HAVE_SYS_IOCTL_H
-#ifndef _WIN32
-#define HAVE_SYS_IOCTL_H
-#endif
-
-/* Define if you have sys/filio.h */
-#undef HAVE_SYS_FILIO_H
-#ifdef __APPLE__
-#define HAVE_SYS_FILIO_H
-#endif
-
-/* Define if you have strerror */
-#define HAVE_STRERROR
-
-/* Define if you have strdup() */
-#define HAVE_STRDUP
-
-/* Define according to how time.h should be included */
-#define TIME_WITH_SYS_TIME 0
-#undef HAVE_SYS_TIME_H
-
-/* Define if you have sys/bitypes.h */
-#undef HAVE_SYS_BITYPES_H
-
-/* Define if the machine is big endian */
-//#undef WORDS_BIGENDIAN
-
-/* Define if your sprintf returns char * instead of int */
-#undef BAD_SPRINTF
-
-/* Define if you have readv */
-#undef HAVE_READV
-
-/* Define if iovec needs to be declared */
-#undef DECLARE_IOVEC
-#ifdef _WIN32
-#define DECLARE_IOVEC
-#endif
-
-/* Define if a declaration of sprintf/fprintf is needed */
-#undef DECLARE_SPRINTF
-
-/* Define if you have a POSIX.1 sys/wait.h */
-#undef HAVE_SYS_WAIT_H
-
-/* Define if you have sys/select.h */
-#undef HAVE_SYS_SELECT_H
-#ifndef _WIN32
-#define HAVE_SYS_SELECT_H
-#endif
-
-/* Define if you have strings.h */
-#define HAVE_STRING_H
-
-/* Define if you have arpa/inet.h */
-#undef HAVE_ARPA_INET_H
-#ifndef _WIN32
-#define HAVE_ARPA_INET_H
-#endif
-
-/* Define if you have sys/signal.h */
-#undef HAVE_SYS_SIGNAL_H
-
-/* Define if you have sys/stropts.h */
-#undef HAVE_SYS_STROPTS_H
-
-/* Define to whatever your compiler thinks inline should be */
-#define inline inline
-
-/* Define to whatever your compiler thinks const should be */
-#define const const
-
-/* Define if your compiler doesn't like prototypes */
-#undef NO_PROTOTYPES
-
-/* Define if you don't have u_int32_t etc. typedef'd */
-#undef NEED_TYPEDEFS
-#ifdef __sun__
-#define NEED_TYPEDEFS
-#endif
-
-/* Define to sizeof(char) */
-#define SIZEOF_CHAR 1
-
-/* Define to sizeof(short) */
-#define SIZEOF_SHORT 2
-
-/* Define to sizeof(int) */
-#define SIZEOF_INT 4
-
-/* Define to sizeof(char *) */
-#define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
-
-/* Define if you have random() */
-#undef HAVE_RANDOM
-
-/* Define if you have srandom() */
-#undef HAVE_SRANDOM
-
-/* Define if you have setenv */
-#undef HAVE_SETENV
-
-/* Define if you have index() */
-#undef HAVE_INDEX
-
-/* Define if you have bcmp() */
-#undef HAVE_BCMP
-
-/* Define if you have drand48 */
-#undef HAVE_DRAND48
-
-/* Define if you have memmove */
-#define HAVE_MEMMOVE
-
-/* Define if you have gethostid */
-#undef HAVE_GETHOSTID
-
-/* Define if you DON'T have unix-domain sockets */
-#undef NO_UNIX_SOCKETS
-#ifdef _WIN32
-#define NO_UNIX_SOCKETS
-#endif
-
-/* Define if gettimeofday only takes one argument */
-#undef GETTIMEOFDAY_ONE_ARG
-
-/* Define if you have revoke() */
-#undef HAVE_REVOKE
-
-/* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */
-#undef HAVE_GRANTPT
-
-/* Define if you have fchmod */
-#undef HAVE_FCHMOD
-
-/* Define if you have <sys/type32.h> */
-#undef HAVE_SYS_TYPES32_H
diff --git a/slirp2/socket.c b/slirp2/socket.c
deleted file mode 100644
index 05fb4b7..0000000
--- a/slirp2/socket.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define WANT_SYS_IOCTL_H
-#include <slirp.h>
-#include "ip_icmp.h"
-#include "main.h"
-#ifdef __sun__
-#include <sys/filio.h>
-#endif
-#define SLIRP_COMPILATION 1
-#include "sockets.h"
-#include "proxy_common.h"
-
-void
-so_init()
-{
- /* Nothing yet */
-}
-
-
-struct socket *
-solookup(head, laddr, lport, faddr, fport)
- struct socket *head;
- uint32_t laddr;
- u_int lport;
- uint32_t faddr;
- u_int fport;
-{
- struct socket *so;
-
- for (so = head->so_next; so != head; so = so->so_next) {
- if (so->so_laddr_port == lport &&
- so->so_laddr_ip == laddr &&
- so->so_faddr_ip == faddr &&
- so->so_faddr_port == fport)
- break;
- }
-
- if (so == head)
- return (struct socket *)NULL;
- return so;
-
-}
-
-/*
- * Create a new socket, initialise the fields
- * It is the responsibility of the caller to
- * insque() it into the correct linked-list
- */
-struct socket *
-socreate()
-{
- struct socket *so;
-
- so = (struct socket *)malloc(sizeof(struct socket));
- if(so) {
- memset(so, 0, sizeof(struct socket));
- so->so_state = SS_NOFDREF;
- so->s = -1;
- }
- return(so);
-}
-
-/*
- * remque and free a socket, clobber cache
- */
-void
-sofree(so)
- struct socket *so;
-{
- if (so->so_state & SS_PROXIFIED)
- proxy_manager_del(so);
-
- if (so->extra) {
- sofree(so->extra);
- so->extra=NULL;
- }
- if (so == tcp_last_so)
- tcp_last_so = &tcb;
- else if (so == udp_last_so)
- udp_last_so = &udb;
-
- mbuf_free(so->so_m);
-
- if(so->so_next && so->so_prev)
- remque(so); /* crashes if so is not in a queue */
-
- free(so);
-}
-
-/*
- * Read from so's socket into sb_snd, updating all relevant sbuf fields
- * NOTE: This will only be called if it is select()ed for reading, so
- * a read() of 0 (or less) means it's disconnected
- */
-int
-soread(so)
- struct socket *so;
-{
- int n, nn, lss, total;
- SBuf sb = &so->so_snd;
- int len = sb->sb_datalen - sb->sb_cc;
- struct iovec iov[2];
- int mss = so->so_tcpcb->t_maxseg;
-
- DEBUG_CALL("soread");
- DEBUG_ARG("so = %lx", (long )so);
-
- /*
- * No need to check if there's enough room to read.
- * soread wouldn't have been called if there weren't
- */
-
- len = sb->sb_datalen - sb->sb_cc;
-
- iov[0].iov_base = sb->sb_wptr;
- if (sb->sb_wptr < sb->sb_rptr) {
- iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
- /* Should never succeed, but... */
- if (iov[0].iov_len > len)
- iov[0].iov_len = len;
- if (iov[0].iov_len > mss)
- iov[0].iov_len -= iov[0].iov_len%mss;
- n = 1;
- } else {
- iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
- /* Should never succeed, but... */
- if (iov[0].iov_len > len) iov[0].iov_len = len;
- len -= iov[0].iov_len;
- if (len) {
- iov[1].iov_base = sb->sb_data;
- iov[1].iov_len = sb->sb_rptr - sb->sb_data;
- if(iov[1].iov_len > len)
- iov[1].iov_len = len;
- total = iov[0].iov_len + iov[1].iov_len;
- if (total > mss) {
- lss = total%mss;
- if (iov[1].iov_len > lss) {
- iov[1].iov_len -= lss;
- n = 2;
- } else {
- lss -= iov[1].iov_len;
- iov[0].iov_len -= lss;
- n = 1;
- }
- } else
- n = 2;
- } else {
- if (iov[0].iov_len > mss)
- iov[0].iov_len -= iov[0].iov_len%mss;
- n = 1;
- }
- }
-
-#ifdef HAVE_READV
- nn = readv(so->s, (struct iovec *)iov, n);
- DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#else
- nn = socket_recv(so->s, iov[0].iov_base, iov[0].iov_len);
-#endif
- if (nn <= 0) {
- if (nn < 0 && (errno == EINTR || errno == EAGAIN))
- return 0;
- else {
- DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,errno_str));
- sofcantrcvmore(so);
- tcp_sockclosed(sototcpcb(so));
- return -1;
- }
- }
-
-#ifndef HAVE_READV
- /*
- * If there was no error, try and read the second time round
- * We read again if n = 2 (ie, there's another part of the buffer)
- * and we read as much as we could in the first read
- * We don't test for <= 0 this time, because there legitimately
- * might not be any more data (since the socket is non-blocking),
- * a close will be detected on next iteration.
- * A return of -1 wont (shouldn't) happen, since it didn't happen above
- */
- if (n == 2 && nn == iov[0].iov_len) {
- int ret;
- ret = socket_recv(so->s, iov[1].iov_base, iov[1].iov_len);
- if (ret > 0)
- nn += ret;
- }
-
- DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#endif
-
- /* Update fields */
- sb->sb_cc += nn;
- sb->sb_wptr += nn;
- if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
- sb->sb_wptr -= sb->sb_datalen;
- return nn;
-}
-
-/*
- * Get urgent data
- *
- * When the socket is created, we set it SO_OOBINLINE,
- * so when OOB data arrives, we soread() it and everything
- * in the send buffer is sent as urgent data
- */
-void
-sorecvoob(so)
- struct socket *so;
-{
- struct tcpcb *tp = sototcpcb(so);
-
- DEBUG_CALL("sorecvoob");
- DEBUG_ARG("so = %lx", (long)so);
-
- /*
- * We take a guess at how much urgent data has arrived.
- * In most situations, when urgent data arrives, the next
- * read() should get all the urgent data. This guess will
- * be wrong however if more data arrives just after the
- * urgent data, or the read() doesn't return all the
- * urgent data.
- */
- soread(so);
- tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
- tp->t_force = 1;
- tcp_output(tp);
- tp->t_force = 0;
-}
-
-/*
- * Send urgent data
- * There's a lot duplicated code here, but...
- */
-int
-sosendoob(so)
- struct socket *so;
-{
- SBuf sb = &so->so_rcv;
- char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
- int n, len;
-
- DEBUG_CALL("sosendoob");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
-
- if (so->so_urgc > 2048)
- so->so_urgc = 2048; /* XXXX */
-
- if (sb->sb_rptr < sb->sb_wptr) {
- /* We can send it directly */
- n = socket_send_oob(so->s, sb->sb_rptr, so->so_urgc); /* |MSG_DONTWAIT)); */
- so->so_urgc -= n;
-
- DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
- } else {
- /*
- * Since there's no sendv or sendtov like writev,
- * we must copy all data to a linear buffer then
- * send it all
- */
- len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
- if (len > so->so_urgc) len = so->so_urgc;
- memcpy(buff, sb->sb_rptr, len);
- so->so_urgc -= len;
- if (so->so_urgc) {
- n = sb->sb_wptr - sb->sb_data;
- if (n > so->so_urgc) n = so->so_urgc;
- memcpy((buff + len), sb->sb_data, n);
- so->so_urgc -= n;
- len += n;
- }
- n = socket_send_oob(so->s, buff, len); /* |MSG_DONTWAIT)); */
-#ifdef DEBUG
- if (n != len)
- DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
-#endif
- DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
- }
-
- sb->sb_cc -= n;
- sb->sb_rptr += n;
- if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
- sb->sb_rptr -= sb->sb_datalen;
-
- return n;
-}
-
-/*
- * Write data from so_rcv to so's socket,
- * updating all sbuf field as necessary
- */
-int
-sowrite(so)
- struct socket *so;
-{
- int n,nn;
- SBuf sb = &so->so_rcv;
- int len = sb->sb_cc;
- struct iovec iov[2];
-
- DEBUG_CALL("sowrite");
- DEBUG_ARG("so = %lx", (long)so);
-
- if (so->so_urgc) {
- sosendoob(so);
- if (sb->sb_cc == 0)
- return 0;
- }
-
- /*
- * No need to check if there's something to write,
- * sowrite wouldn't have been called otherwise
- */
-
- len = sb->sb_cc;
-
- iov[0].iov_base = sb->sb_rptr;
- if (sb->sb_rptr < sb->sb_wptr) {
- iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
- /* Should never succeed, but... */
- if (iov[0].iov_len > len) iov[0].iov_len = len;
- n = 1;
- } else {
- iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
- if (iov[0].iov_len > len) iov[0].iov_len = len;
- len -= iov[0].iov_len;
- if (len) {
- iov[1].iov_base = sb->sb_data;
- iov[1].iov_len = sb->sb_wptr - sb->sb_data;
- if (iov[1].iov_len > len) iov[1].iov_len = len;
- n = 2;
- } else
- n = 1;
- }
- /* Check if there's urgent data to send, and if so, send it */
-
-#ifdef HAVE_READV
- nn = writev(so->s, (const struct iovec *)iov, n);
-
- DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
-#else
- nn = socket_send(so->s, iov[0].iov_base, iov[0].iov_len);
-#endif
- /* This should never happen, but people tell me it does *shrug* */
- if (nn < 0 && (errno == EAGAIN || errno == EINTR))
- return 0;
-
- if (nn <= 0) {
- DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
- so->so_state, errno));
- sofcantsendmore(so);
- tcp_sockclosed(sototcpcb(so));
- return -1;
- }
-
-#ifndef HAVE_READV
- if (n == 2 && nn == iov[0].iov_len) {
- int ret;
- ret = socket_send(so->s, iov[1].iov_base, iov[1].iov_len);
- if (ret > 0)
- nn += ret;
- }
- DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
-#endif
-
- /* Update sbuf */
- sb->sb_cc -= nn;
- sb->sb_rptr += nn;
- if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
- sb->sb_rptr -= sb->sb_datalen;
-
- /*
- * If in DRAIN mode, and there's no more data, set
- * it CANTSENDMORE
- */
- if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
- sofcantsendmore(so);
-
- return nn;
-}
-
-/*
- * recvfrom() a UDP socket
- */
-void
-sorecvfrom(so)
- struct socket *so;
-{
- SockAddress addr;
-
- DEBUG_CALL("sorecvfrom");
- DEBUG_ARG("so = %lx", (long)so);
-
- if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
- char buff[256];
- int len;
-
- len = socket_recvfrom(so->s, buff, 256, &addr);
- /* XXX Check if reply is "correct"? */
-
- if(len == -1 || len == 0) {
- u_char code=ICMP_UNREACH_PORT;
-
- if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
- else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
-
- DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
- errno,errno_str));
- icmp_error(so->so_m, ICMP_UNREACH,code, 0,errno_str);
- } else {
- icmp_reflect(so->so_m);
- so->so_m = 0; /* Don't mbuf_free() it again! */
- }
- /* No need for this socket anymore, udp_detach it */
- udp_detach(so);
- } else { /* A "normal" UDP packet */
- MBuf m;
- int len, n;
-
- if (!(m = mbuf_alloc())) return;
- m->m_data += if_maxlinkhdr;
-
- /*
- * XXX Shouldn't FIONREAD packets destined for port 53,
- * but I don't know the max packet size for DNS lookups
- */
- len = mbuf_freeroom(m);
- /* if (so->so_fport != htons(53)) { */
- n = socket_can_read(so->s);
-
- if (n > len) {
- n = (m->m_data - m->m_dat) + m->m_len + n + 1;
- mbuf_ensure(m, n);
- len = mbuf_freeroom(m);
- }
- /* } */
-
- m->m_len = socket_recvfrom(so->s, m->m_data, len, &addr);
- DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
- m->m_len, errno,errno_str));
- if(m->m_len<0) {
- u_char code=ICMP_UNREACH_PORT;
-
- if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
- else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
-
- DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
- icmp_error(so->so_m, ICMP_UNREACH,code, 0,errno_str);
- mbuf_free(m);
- } else {
- /*
- * Hack: domain name lookup will be used the most for UDP,
- * and since they'll only be used once there's no need
- * for the 4 minute (or whatever) timeout... So we time them
- * out much quicker (10 seconds for now...)
- */
- if (so->so_expire) {
- if (so->so_faddr_port == 53)
- so->so_expire = curtime + SO_EXPIREFAST;
- else
- so->so_expire = curtime + SO_EXPIRE;
- }
-
- /* if (m->m_len == len) {
- * mbuf_ensure(m, MINCSIZE);
- * m->m_len = 0;
- * }
- */
-
- /*
- * If this packet was destined for CTL_ADDR,
- * make it look like that's where it came from, done by udp_output
- */
- udp_output_(so, m, &addr);
- } /* rx error */
- } /* if ping packet */
-}
-
-/*
- * sendto() a socket
- */
-int
-sosendto(so, m)
- struct socket *so;
- MBuf m;
-{
- SockAddress addr;
- uint32_t addr_ip;
- uint16_t addr_port;
- int ret;
-
- DEBUG_CALL("sosendto");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
-
- if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
- /* It's an alias */
- int low = so->so_faddr_ip & 0xff;
-
- if ( CTL_IS_DNS(low) )
- addr_ip = dns_addr[low - CTL_DNS];
- else
- addr_ip = loopback_addr_ip;
- } else
- addr_ip = so->so_faddr_ip;
-
- addr_port = so->so_faddr_port;
-
- sock_address_init_inet(&addr, addr_ip, addr_port);
-
- DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%08x\n", addr_port, addr_ip));
-
- /* Don't care what port we get */
- ret = socket_sendto(so->s, m->m_data, m->m_len,&addr);
- if (ret < 0)
- return -1;
-
- /*
- * Kill the socket if there's no reply in 4 minutes,
- * but only if it's an expirable socket
- */
- if (so->so_expire)
- so->so_expire = curtime + SO_EXPIRE;
- so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
- return 0;
-}
-
-/*
- * XXX This should really be tcp_listen
- */
-struct socket *
-solisten(port, laddr, lport, flags)
- u_int port;
- u_int32_t laddr;
- u_int lport;
- int flags;
-{
- SockAddress addr;
- uint32_t addr_ip;
- struct socket *so;
- int s;
-
- DEBUG_CALL("solisten");
- DEBUG_ARG("port = %d", port);
- DEBUG_ARG("laddr = %x", laddr);
- DEBUG_ARG("lport = %d", lport);
- DEBUG_ARG("flags = %x", flags);
-
- if ((so = socreate()) == NULL) {
- /* free(so); Not sofree() ??? free(NULL) == NOP */
- return NULL;
- }
-
- /* Don't tcp_attach... we don't need so_snd nor so_rcv */
- if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
- free(so);
- return NULL;
- }
- insque(so,&tcb);
-
- /*
- * SS_FACCEPTONCE sockets must time out.
- */
- if (flags & SS_FACCEPTONCE)
- so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
-
- so->so_state = (SS_FACCEPTCONN|flags);
- so->so_laddr_port = lport; /* Kept in host format */
- so->so_laddr_ip = laddr; /* Ditto */
- so->so_haddr_port = port;
-
- s = socket_loopback_server( port, SOCKET_STREAM );
- if (s < 0)
- return NULL;
-
- socket_get_address(s, &addr);
-
- so->so_faddr_port = sock_address_get_port(&addr);
-
- addr_ip = (uint32_t) sock_address_get_ip(&addr);
-
- if (addr_ip == 0 || addr_ip == loopback_addr_ip)
- so->so_faddr_ip = alias_addr_ip;
- else
- so->so_faddr_ip = addr_ip;
-
- so->s = s;
- return so;
-}
-
-
-int
-sounlisten(u_int port)
-{
- struct socket *so;
-
- for (so = tcb.so_next; so != &tcb; so = so->so_next) {
- if (so->so_haddr_port == port) {
- break;
- }
- }
-
- if (so == &tcb) {
- return -1;
- }
-
- sofcantrcvmore( so );
- sofcantsendmore( so );
- close( so->s );
- so->s = -1;
- sofree( so );
- return 0;
-}
-
-
-/*
- * Data is available in so_rcv
- * Just write() the data to the socket
- * XXX not yet...
- */
-void
-sorwakeup(so)
- struct socket *so;
-{
-/* sowrite(so); */
-/* FD_CLR(so->s,&writefds); */
-}
-
-/*
- * Data has been freed in so_snd
- * We have room for a read() if we want to
- * For now, don't read, it'll be done in the main loop
- */
-void
-sowwakeup(so)
- struct socket *so;
-{
- /* Nothing, yet */
-}
-
-/*
- * Various session state calls
- * XXX Should be #define's
- * The socket state stuff needs work, these often get call 2 or 3
- * times each when only 1 was needed
- */
-void
-soisfconnecting(so)
- register struct socket *so;
-{
- so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
- SS_FCANTSENDMORE|SS_FWDRAIN);
- so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
-}
-
-void
-soisfconnected(so)
- register struct socket *so;
-{
- so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
- so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
-}
-
-void
-sofcantrcvmore(so)
- struct socket *so;
-{
- if ((so->so_state & SS_NOFDREF) == 0) {
- shutdown(so->s,0);
- if(global_writefds) {
- FD_CLR(so->s,global_writefds);
- }
- }
- so->so_state &= ~(SS_ISFCONNECTING);
- if (so->so_state & SS_FCANTSENDMORE)
- so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */
- else
- so->so_state |= SS_FCANTRCVMORE;
-}
-
-void
-sofcantsendmore(so)
- struct socket *so;
-{
- if ((so->so_state & SS_NOFDREF) == 0) {
- shutdown(so->s,1); /* send FIN to fhost */
- if (global_readfds) {
- FD_CLR(so->s,global_readfds);
- }
- if (global_xfds) {
- FD_CLR(so->s,global_xfds);
- }
- }
- so->so_state &= ~(SS_ISFCONNECTING);
- if (so->so_state & SS_FCANTRCVMORE)
- so->so_state = SS_NOFDREF; /* as above */
- else
- so->so_state |= SS_FCANTSENDMORE;
-}
-
-void
-soisfdisconnected(so)
- struct socket *so;
-{
-/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */
-/* close(so->s); */
-/* so->so_state = SS_ISFDISCONNECTED; */
- /*
- * XXX Do nothing ... ?
- */
-}
-
-/*
- * Set write drain mode
- * Set CANTSENDMORE once all data has been write()n
- */
-void
-sofwdrain(so)
- struct socket *so;
-{
- if (so->so_rcv.sb_cc)
- so->so_state |= SS_FWDRAIN;
- else
- sofcantsendmore(so);
-}
-
diff --git a/slirp2/socket.h b/slirp2/socket.h
deleted file mode 100644
index 5b71d45..0000000
--- a/slirp2/socket.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-/* MINE */
-
-#ifndef _SLIRP_SOCKET_H_
-#define _SLIRP_SOCKET_H_
-
-#define SO_EXPIRE 240000
-#define SO_EXPIREFAST 10000
-
-/*
- * Our socket structure
- */
-
-struct socket {
- struct socket *so_next,*so_prev; /* For a linked list of sockets */
-
- int s; /* The actual socket */
-
- /* XXX union these with not-yet-used sbuf params */
- MBuf so_m; /* Pointer to the original SYN packet,
- * for non-blocking connect()'s, and
- * PING reply's */
- struct tcpiphdr *so_ti; /* Pointer to the original ti within
- * so_mconn, for non-blocking connections */
- int so_urgc;
- uint32_t so_faddr_ip;
- uint32_t so_laddr_ip;
- uint16_t so_faddr_port;
- uint16_t so_laddr_port;
- uint16_t so_haddr_port;
-
- u_int8_t so_iptos; /* Type of service */
- u_int8_t so_emu; /* Is the socket emulated? */
-
- u_char so_type; /* Type of socket, UDP or TCP */
- int so_state; /* internal state flags SS_*, below */
-
- struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */
- u_int so_expire; /* When the socket will expire */
-
- int so_queued; /* Number of packets queued from this socket */
- int so_nqueued; /* Number of packets queued in a row
- * Used to determine when to "downgrade" a session
- * from fastq to batchq */
-
- SBufRec so_rcv; /* Receive buffer */
- SBufRec so_snd; /* Send buffer */
- void * extra; /* Extra pointer */
-};
-
-
-/*
- * Socket state bits. (peer means the host on the Internet,
- * local host means the host on the other end of the modem)
- */
-#define SS_NOFDREF 0x001 /* No fd reference */
-
-#define SS_ISFCONNECTING 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */
-#define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */
-#define SS_FCANTRCVMORE 0x008 /* Socket can't receive more from peer (for half-closes) */
-#define SS_FCANTSENDMORE 0x010 /* Socket can't send more to peer (for half-closes) */
-/* #define SS_ISFDISCONNECTED 0x020*/ /* Socket has disconnected from peer, in 2MSL state */
-#define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */
-
-#define SS_CTL 0x080
-#define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */
-#define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */
-#define SS_PROXIFIED 0x400 /* Socket is trying to connect through a proxy, only makes sense
- when SS_ISFCONNECTING is also set */
-extern struct socket tcb;
-
-
-#if defined(DECLARE_IOVEC) && !defined(HAVE_READV)
-struct iovec {
- char *iov_base;
- size_t iov_len;
-};
-#endif
-
-void so_init _P((void));
-struct socket * solookup _P((struct socket *, uint32_t, u_int, uint32_t, u_int));
-struct socket * socreate _P((void));
-void sofree _P((struct socket *));
-int soread _P((struct socket *));
-void sorecvoob _P((struct socket *));
-int sosendoob _P((struct socket *));
-int sowrite _P((struct socket *));
-void sorecvfrom _P((struct socket *));
-int sosendto _P((struct socket *, MBuf ));
-struct socket * solisten _P((u_int, u_int32_t, u_int, int));
-int sounlisten _P((u_int port));
-void sorwakeup _P((struct socket *));
-void sowwakeup _P((struct socket *));
-void soisfconnecting _P((register struct socket *));
-void soisfconnected _P((register struct socket *));
-void sofcantrcvmore _P((struct socket *));
-void sofcantsendmore _P((struct socket *));
-void soisfdisconnected _P((struct socket *));
-void sofwdrain _P((struct socket *));
-
-#endif /* _SOCKET_H_ */
diff --git a/slirp2/tcp.h b/slirp2/tcp.h
deleted file mode 100644
index 3cddb77..0000000
--- a/slirp2/tcp.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp.h 8.1 (Berkeley) 6/10/93
- * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp
- */
-
-#ifndef _TCP_H_
-#define _TCP_H_
-
-#include "helper.h"
-
-typedef u_int32_t tcp_seq;
-
-#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */
-#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */
-
-extern int tcp_rcvspace;
-extern int tcp_sndspace;
-extern struct socket *tcp_last_so;
-
-#define TCP_SNDSPACE 8192
-#define TCP_RCVSPACE 8192
-
-/*
- * TCP header.
- * Per RFC 793, September, 1981.
- */
-struct tcphdr {
- port_t th_sport; /* source port */
- port_t th_dport; /* destination port */
- tcp_seq th_seq; /* sequence number */
- tcp_seq th_ack; /* acknowledgement number */
-#ifdef WORDS_BIGENDIAN
- u_int th_off:4, /* data offset */
- th_x2:4; /* (unused) */
-#else
- u_int th_x2:4, /* (unused) */
- th_off:4; /* data offset */
-#endif
- u_int8_t th_flags;
-#define TH_FIN 0x01
-#define TH_SYN 0x02
-#define TH_RST 0x04
-#define TH_PUSH 0x08
-#define TH_ACK 0x10
-#define TH_URG 0x20
- u_int16_t th_win; /* window */
- u_int16_t th_sum; /* checksum */
- u_int16_t th_urp; /* urgent pointer */
-};
-
-#include "tcp_var.h"
-
-#define TCPOPT_EOL 0
-#define TCPOPT_NOP 1
-#define TCPOPT_MAXSEG 2
-#define TCPOLEN_MAXSEG 4
-#define TCPOPT_WINDOW 3
-#define TCPOLEN_WINDOW 3
-#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
-#define TCPOLEN_SACK_PERMITTED 2
-#define TCPOPT_SACK 5 /* Experimental */
-#define TCPOPT_TIMESTAMP 8
-#define TCPOLEN_TIMESTAMP 10
-#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
-
-#define TCPOPT_TSTAMP_HDR \
- (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
-
-/*
- * Default maximum segment size for TCP.
- * With an IP MSS of 576, this is 536,
- * but 512 is probably more convenient.
- * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
- *
- * We make this 1460 because we only care about Ethernet in the qemu context.
- */
-#define TCP_MSS 1460
-
-#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
-
-#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
-
-/*
- * User-settable options (used with setsockopt).
- */
-#undef TCP_NODELAY
-#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
-#undef TCP_MAXSEG
-/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */
-
-/*
- * TCP FSM state definitions.
- * Per RFC793, September, 1981.
- */
-
-#define TCP_NSTATES 11
-
-#define TCPS_CLOSED 0 /* closed */
-#define TCPS_LISTEN 1 /* listening for connection */
-#define TCPS_SYN_SENT 2 /* active, have sent syn */
-#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
-/* states < TCPS_ESTABLISHED are those where connections not established */
-#define TCPS_ESTABLISHED 4 /* established */
-#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
-/* states > TCPS_CLOSE_WAIT are those where user has closed */
-#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
-#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
-#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
-/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
-#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
-#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
-
-#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED)
-#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED)
-#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT)
-
-/*
- * TCP sequence numbers are 32 bit integers operated
- * on with modular arithmetic. These macros can be
- * used to compare such integers.
- */
-#define SEQ_LT(a,b) ((int)((a)-(b)) < 0)
-#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
-#define SEQ_GT(a,b) ((int)((a)-(b)) > 0)
-#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0)
-
-/*
- * Macros to initialize tcp sequence numbers for
- * send and receive from initial send and receive
- * sequence numbers.
- */
-#define tcp_rcvseqinit(tp) \
- (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1
-
-#define tcp_sendseqinit(tp) \
- (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss
-
-#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */
-
-extern tcp_seq tcp_iss; /* tcp initial send seq # */
-
-extern char *tcpstates[];
-
-#endif
diff --git a/slirp2/tcp_input.c b/slirp2/tcp_input.c
deleted file mode 100644
index c3196d3..0000000
--- a/slirp2/tcp_input.c
+++ /dev/null
@@ -1,1714 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94
- * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#include "ip_icmp.h"
-
-struct socket tcb;
-
-int tcprexmtthresh = 3;
-struct socket *tcp_last_so = &tcb;
-
-tcp_seq tcp_iss; /* tcp initial send seq # */
-
-#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)
-
-/* for modulo comparisons of timestamps */
-#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0)
-#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0)
-
-/*
- * Insert segment ti into reassembly queue of tcp with
- * control block tp. Return TH_FIN if reassembly now includes
- * a segment with FIN. The macro form does the common case inline
- * (segment is the next to be received on an established connection,
- * and the queue is empty), avoiding linkage into and removal
- * from the queue and repetition of various conversions.
- * Set DELACK for segments received in order, but ack immediately
- * when segments are out of order (so fast retransmit can work).
- */
-#ifdef TCP_ACK_HACK
-#define TCP_REASS(tp, ti, m, so, flags) {\
- if ((ti)->ti_seq == (tp)->rcv_nxt && \
- tcpfrag_list_empty(tp) && \
- (tp)->t_state == TCPS_ESTABLISHED) {\
- if (ti->ti_flags & TH_PUSH) \
- tp->t_flags |= TF_ACKNOW; \
- else \
- tp->t_flags |= TF_DELACK; \
- (tp)->rcv_nxt += (ti)->ti_len; \
- flags = (ti)->ti_flags & TH_FIN; \
- tcpstat.tcps_rcvpack++;\
- tcpstat.tcps_rcvbyte += (ti)->ti_len;\
- if (so->so_emu) { \
- if (tcp_emu((so),(m))) sbuf_append((so), (m)); \
- } else \
- sbuf_append((so), (m)); \
-/* sorwakeup(so); */ \
- } else {\
- (flags) = tcp_reass((tp), (ti), (m)); \
- tp->t_flags |= TF_ACKNOW; \
- } \
-}
-#else
-#define TCP_REASS(tp, ti, m, so, flags) { \
- if ((ti)->ti_seq == (tp)->rcv_nxt && \
- tcpfrag_list_empty(tp) && \
- (tp)->t_state == TCPS_ESTABLISHED) { \
- tp->t_flags |= TF_DELACK; \
- (tp)->rcv_nxt += (ti)->ti_len; \
- flags = (ti)->ti_flags & TH_FIN; \
- tcpstat.tcps_rcvpack++;\
- tcpstat.tcps_rcvbyte += (ti)->ti_len;\
- if (so->so_emu) { \
- if (tcp_emu((so),(m))) sbuf_append(so, (m)); \
- } else \
- sbuf_append((so), (m)); \
-/* sorwakeup(so); */ \
- } else { \
- (flags) = tcp_reass((tp), (ti), (m)); \
- tp->t_flags |= TF_ACKNOW; \
- } \
-}
-#endif
-
-int
-tcp_reass(tp, ti, m)
- register struct tcpcb *tp;
- register struct tcpiphdr *ti;
- MBuf m;
-{
- register struct tcpiphdr *q;
- struct socket *so = tp->t_socket;
- int flags;
-
- /*
- * Call with ti==0 after become established to
- * force pre-ESTABLISHED data up to user socket.
- */
- if (ti == 0)
- goto present;
-
- /*
- * Find a segment which begins after this one does.
- */
- for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp);
- q = tcpiphdr_next(q))
- if (SEQ_GT(q->ti_seq, ti->ti_seq))
- break;
-
- /*
- * If there is a preceding segment, it may provide some of
- * our data already. If so, drop the data from the incoming
- * segment. If it provides all of our data, drop us.
- */
- if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) {
- register int i;
- q = tcpiphdr_prev(q);
- /* conversion to int (in i) handles seq wraparound */
- i = q->ti_seq + q->ti_len - ti->ti_seq;
- if (i > 0) {
- if (i >= ti->ti_len) {
- tcpstat.tcps_rcvduppack++;
- tcpstat.tcps_rcvdupbyte += ti->ti_len;
- mbuf_free(m);
- /*
- * Try to present any queued data
- * at the left window edge to the user.
- * This is needed after the 3-WHS
- * completes.
- */
- goto present; /* ??? */
- }
- mbuf_trim(m, i);
- ti->ti_len -= i;
- ti->ti_seq += i;
- }
- q = tcpiphdr_next(q);
- }
- tcpstat.tcps_rcvoopack++;
- tcpstat.tcps_rcvoobyte += ti->ti_len;
- ti->ti_mbuf = m;
-
- /*
- * While we overlap succeeding segments trim them or,
- * if they are completely covered, dequeue them.
- */
- while (!tcpfrag_list_end(q, tp)) {
- register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
- if (i <= 0)
- break;
- if (i < q->ti_len) {
- q->ti_seq += i;
- q->ti_len -= i;
- mbuf_trim(q->ti_mbuf, i);
- break;
- }
- q = tcpiphdr_next(q);
- m = tcpiphdr_prev(q)->ti_mbuf;
- remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
- mbuf_free(m);
- }
-
- /*
- * Stick new segment in its place.
- */
- insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q)));
-
-present:
- /*
- * Present data to user, advancing rcv_nxt through
- * completed sequence space.
- */
- if (!TCPS_HAVEESTABLISHED(tp->t_state))
- return (0);
- ti = tcpfrag_list_first(tp);
- if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
- return (0);
- if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
- return (0);
- do {
- tp->rcv_nxt += ti->ti_len;
- flags = ti->ti_flags & TH_FIN;
- remque(tcpiphdr2qlink(ti));
- m = ti->ti_mbuf;
- ti = tcpiphdr_next(ti);
-/* if (so->so_state & SS_FCANTRCVMORE) */
- if (so->so_state & SS_FCANTSENDMORE)
- mbuf_free(m);
- else {
- if (so->so_emu) {
- if (tcp_emu(so,m)) sbuf_append(so, m);
- } else
- sbuf_append(so, m);
- }
- } while (!tcpfrag_list_end(ti, tp) && ti->ti_seq == tp->rcv_nxt);
-/* sorwakeup(so); */
- return (flags);
-}
-
-/*
- * TCP input routine, follows pages 65-76 of the
- * protocol specification dated September, 1981 very closely.
- */
-void
-tcp_input(m, iphlen, inso)
- register MBuf m;
- int iphlen;
- struct socket *inso;
-{
- struct ip save_ip, *ip;
- register struct tcpiphdr *ti;
- caddr_t optp = NULL;
- int optlen = 0;
- int len, tlen, off;
- register struct tcpcb *tp = 0;
- register int tiflags;
- struct socket *so = 0;
- int todrop, acked, ourfinisacked, needoutput = 0;
-/* int dropsocket = 0; */
- int iss = 0;
- u_long tiwin;
- int ret;
-/* int ts_present = 0; */
-
- DEBUG_CALL("tcp_input");
- DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n",
- (long )m, iphlen, (long )inso ));
-
- /*
- * If called with m == 0, then we're continuing the connect
- */
- if (m == NULL) {
- so = inso;
-
- /* Re-set a few variables */
- tp = sototcpcb(so);
- m = so->so_m;
- so->so_m = 0;
- ti = so->so_ti;
- tiwin = ti->ti_win;
- tiflags = ti->ti_flags;
-
- goto cont_conn;
- }
-
-
- tcpstat.tcps_rcvtotal++;
- /*
- * Get IP and TCP header together in first mbuf.
- * Note: IP leaves IP header in first mbuf.
- */
- ti = MBUF_TO(m, struct tcpiphdr *);
- if (iphlen > sizeof(struct ip )) {
- ip_stripoptions(m, (MBuf )0);
- iphlen=sizeof(struct ip );
- }
- /* XXX Check if too short */
-
-
- /*
- * Save a copy of the IP header in case we want restore it
- * for sending an ICMP error message in response.
- */
- ip=MBUF_TO(m, struct ip *);
- save_ip = *ip;
- save_ip.ip_len+= iphlen;
-
- /*
- * Checksum extended TCP header and data.
- */
- tlen = ((struct ip *)ti)->ip_len;
- tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0;
- memset(&ti->ti_i.ih_mbuf, 0, sizeof(struct mbuf_ptr));
- ti->ti_x1 = 0;
- ti->ti_len = htons((u_int16_t)tlen);
- len = sizeof(struct ip ) + tlen;
- /* keep checksum for ICMP reply
- * ti->ti_sum = cksum(m, len);
- * if (ti->ti_sum) { */
- if(cksum(m, len)) {
- tcpstat.tcps_rcvbadsum++;
- goto drop;
- }
-
- /*
- * Check that TCP offset makes sense,
- * pull out TCP options and adjust length. XXX
- */
- off = ti->ti_off << 2;
- if (off < sizeof (struct tcphdr) || off > tlen) {
- tcpstat.tcps_rcvbadoff++;
- goto drop;
- }
- tlen -= off;
- ti->ti_len = tlen;
- if (off > sizeof (struct tcphdr)) {
- optlen = off - sizeof (struct tcphdr);
- optp = MBUF_TO(m, caddr_t) + sizeof (struct tcpiphdr);
-
- /*
- * Do quick retrieval of timestamp options ("options
- * prediction?"). If timestamp is the only option and it's
- * formatted as recommended in RFC 1323 appendix A, we
- * quickly get the values now and not bother calling
- * tcp_dooptions(), etc.
- */
-/* if ((optlen == TCPOLEN_TSTAMP_APPA ||
- * (optlen > TCPOLEN_TSTAMP_APPA &&
- * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
- * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
- * (ti->ti_flags & TH_SYN) == 0) {
- * ts_present = 1;
- * ts_val = ntohl(*(u_int32_t *)(optp + 4));
- * ts_ecr = ntohl(*(u_int32_t *)(optp + 8));
- * optp = NULL; / * we've parsed the options * /
- * }
- */
- }
- tiflags = ti->ti_flags;
-
- /*
- * Convert TCP protocol specific fields to host format.
- */
- NTOHL(ti->ti_seq);
- NTOHL(ti->ti_ack);
- NTOHS(ti->ti_win);
- NTOHS(ti->ti_urp);
-
- /*
- * Drop TCP, IP headers and TCP options.
- */
- m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
-
- /*
- * Locate pcb for segment.
- */
-findso:
- so = tcp_last_so;
- {
- uint32_t srcip = ip_geth(ti->ti_src);
- uint32_t dstip = ip_geth(ti->ti_dst);
- uint16_t dstport = port_geth(ti->ti_dport);
- uint16_t srcport = port_geth(ti->ti_sport);
-
- if (so->so_faddr_port != dstport ||
- so->so_laddr_port != srcport ||
- so->so_laddr_ip != srcip ||
- so->so_faddr_ip != dstip) {
- so = solookup(&tcb, srcip, srcport, dstip, dstport);
- if (so)
- tcp_last_so = so;
- ++tcpstat.tcps_socachemiss;
- }
- }
-
- /*
- * If the state is CLOSED (i.e., TCB does not exist) then
- * all data in the incoming segment is discarded.
- * If the TCB exists but is in CLOSED state, it is embryonic,
- * but should either do a listen or a connect soon.
- *
- * state == CLOSED means we've done socreate() but haven't
- * attached it to a protocol yet...
- *
- * XXX If a TCB does not exist, and the TH_SYN flag is
- * the only flag set, then create a session, mark it
- * as if it was LISTENING, and continue...
- */
- if (so == 0) {
- if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN)
- goto dropwithreset;
-
- if ((so = socreate()) == NULL)
- goto dropwithreset;
- if (tcp_attach(so) < 0) {
- free(so); /* Not sofree (if it failed, it's not insqued) */
- goto dropwithreset;
- }
-
- sbuf_reserve(&so->so_snd, tcp_sndspace);
- sbuf_reserve(&so->so_rcv, tcp_rcvspace);
-
- /* tcp_last_so = so; */ /* XXX ? */
- /* tp = sototcpcb(so); */
-
- so->so_laddr_ip = ip_geth(ti->ti_src);
- so->so_laddr_port = port_geth(ti->ti_sport);
- so->so_faddr_ip = ip_geth(ti->ti_dst);
- so->so_faddr_port = port_geth(ti->ti_dport);
-
- if ((so->so_iptos = tcp_tos(so)) == 0)
- so->so_iptos = ((struct ip *)ti)->ip_tos;
-
- tp = sototcpcb(so);
- tp->t_state = TCPS_LISTEN;
- }
-
- /*
- * If this is a still-connecting socket, this probably
- * a retransmit of the SYN. Whether it's a retransmit SYN
- * or something else, we nuke it.
- */
- if (so->so_state & SS_ISFCONNECTING)
- goto drop;
-
- tp = sototcpcb(so);
-
- /* XXX Should never fail */
- if (tp == 0)
- goto dropwithreset;
- if (tp->t_state == TCPS_CLOSED)
- goto drop;
-
- /* Unscale the window into a 32-bit value. */
-/* if ((tiflags & TH_SYN) == 0)
- * tiwin = ti->ti_win << tp->snd_scale;
- * else
- */
- tiwin = ti->ti_win;
-
- /*
- * Segment received on connection.
- * Reset idle time and keep-alive timer.
- */
- tp->t_idle = 0;
- if (so_options)
- tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
- else
- tp->t_timer[TCPT_KEEP] = tcp_keepidle;
-
- /*
- * Process options if not in LISTEN state,
- * else do it below (after getting remote address).
- */
- if (optp && tp->t_state != TCPS_LISTEN)
- tcp_dooptions(tp, (u_char *)optp, optlen, ti);
-/* , */
-/* &ts_present, &ts_val, &ts_ecr); */
-
- /*
- * Header prediction: check for the two common cases
- * of a uni-directional data xfer. If the packet has
- * no control flags, is in-sequence, the window didn't
- * change and we're not retransmitting, it's a
- * candidate. If the length is zero and the ack moved
- * forward, we're the sender side of the xfer. Just
- * free the data acked & wake any higher level process
- * that was blocked waiting for space. If the length
- * is non-zero and the ack didn't move, we're the
- * receiver side. If we're getting packets in-order
- * (the reassembly queue is empty), add the data to
- * the socket buffer and note that we need a delayed ack.
- *
- * XXX Some of these tests are not needed
- * eg: the tiwin == tp->snd_wnd prevents many more
- * predictions.. with no *real* advantage..
- */
- if (tp->t_state == TCPS_ESTABLISHED &&
- (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK &&
-/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */
- ti->ti_seq == tp->rcv_nxt &&
- tiwin && tiwin == tp->snd_wnd &&
- tp->snd_nxt == tp->snd_max) {
- /*
- * If last ACK falls within this segment's sequence numbers,
- * record the timestamp.
- */
-/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) &&
- * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) {
- * tp->ts_recent_age = tcp_now;
- * tp->ts_recent = ts_val;
- * }
- */
- if (ti->ti_len == 0) {
- if (SEQ_GT(ti->ti_ack, tp->snd_una) &&
- SEQ_LEQ(ti->ti_ack, tp->snd_max) &&
- tp->snd_cwnd >= tp->snd_wnd) {
- /*
- * this is a pure ack for outstanding data.
- */
- ++tcpstat.tcps_predack;
-/* if (ts_present)
- * tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
- * else
- */ if (tp->t_rtt &&
- SEQ_GT(ti->ti_ack, tp->t_rtseq))
- tcp_xmit_timer(tp, tp->t_rtt);
- acked = ti->ti_ack - tp->snd_una;
- tcpstat.tcps_rcvackpack++;
- tcpstat.tcps_rcvackbyte += acked;
- sbuf_drop(&so->so_snd, acked);
- tp->snd_una = ti->ti_ack;
- mbuf_free(m);
-
- /*
- * If all outstanding data are acked, stop
- * retransmit timer, otherwise restart timer
- * using current (possibly backed-off) value.
- * If process is waiting for space,
- * wakeup/selwakeup/signal. If data
- * are ready to send, let tcp_output
- * decide between more output or persist.
- */
- if (tp->snd_una == tp->snd_max)
- tp->t_timer[TCPT_REXMT] = 0;
- else if (tp->t_timer[TCPT_PERSIST] == 0)
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
-
- /*
- * There's room in so_snd, sowwakup will read()
- * from the socket if we can
- */
-/* if (so->so_snd.sb_flags & SB_NOTIFY)
- * sowwakeup(so);
- */
- /*
- * This is called because sowwakeup might have
- * put data into so_snd. Since we don't so sowwakeup,
- * we don't need this.. XXX???
- */
- if (so->so_snd.sb_cc)
- (void) tcp_output(tp);
-
- return;
- }
- } else if (ti->ti_ack == tp->snd_una &&
- tcpfrag_list_empty(tp) &&
- ti->ti_len <= sbuf_space(&so->so_rcv)) {
- /*
- * this is a pure, in-sequence data packet
- * with nothing on the reassembly queue and
- * we have enough buffer space to take it.
- */
- ++tcpstat.tcps_preddat;
- tp->rcv_nxt += ti->ti_len;
- tcpstat.tcps_rcvpack++;
- tcpstat.tcps_rcvbyte += ti->ti_len;
- /*
- * Add data to socket buffer.
- */
- if (so->so_emu) {
- if (tcp_emu(so,m)) sbuf_append(so, m);
- } else
- sbuf_append(so, m);
-
- /*
- * XXX This is called when data arrives. Later, check
- * if we can actually write() to the socket
- * XXX Need to check? It's be NON_BLOCKING
- */
-/* sorwakeup(so); */
-
- /*
- * If this is a short packet, then ACK now - with Nagel
- * congestion avoidance sender won't send more until
- * he gets an ACK.
- *
- * It is better to not delay acks at all to maximize
- * TCP throughput. See RFC 2581.
- */
- tp->t_flags |= TF_ACKNOW;
- tcp_output(tp);
- return;
- }
- } /* header prediction */
- /*
- * Calculate amount of space in receive window,
- * and then do TCP input processing.
- * Receive window is amount of space in rcv queue,
- * but not less than advertised window.
- */
- { int win;
- win = sbuf_space(&so->so_rcv);
- if (win < 0)
- win = 0;
- tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt));
- }
-
- switch (tp->t_state) {
-
- /*
- * If the state is LISTEN then ignore segment if it contains an RST.
- * If the segment contains an ACK then it is bad and send a RST.
- * If it does not contain a SYN then it is not interesting; drop it.
- * Don't bother responding if the destination was a broadcast.
- * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
- * tp->iss, and send a segment:
- * <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
- * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
- * Fill in remote peer address fields if not previously specified.
- * Enter SYN_RECEIVED state, and process any other fields of this
- * segment in this state.
- */
- case TCPS_LISTEN: {
-
- if (tiflags & TH_RST)
- goto drop;
- if (tiflags & TH_ACK)
- goto dropwithreset;
- if ((tiflags & TH_SYN) == 0)
- goto drop;
-
- /*
- * This has way too many gotos...
- * But a bit of spaghetti code never hurt anybody :)
- */
-
- /*
- * If this is destined for the control address, then flag to
- * tcp_ctl once connected, otherwise connect
- */
- if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
- //int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff;
- /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */
- }
-
- if (so->so_emu & EMU_NOCONNECT) {
- so->so_emu &= ~EMU_NOCONNECT;
- goto cont_input;
- }
-
- if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
- u_char code=ICMP_UNREACH_NET;
- DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n",
- errno,errno_str));
- if(errno == ECONNREFUSED) {
- /* ACK the SYN, send RST to refuse the connection */
- tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0,
- TH_RST|TH_ACK);
- } else {
- if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
- HTONL(ti->ti_seq); /* restore tcp header */
- HTONL(ti->ti_ack);
- HTONS(ti->ti_win);
- HTONS(ti->ti_urp);
- m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- *ip=save_ip;
- icmp_error(m, ICMP_UNREACH,code, 0,errno_str);
- }
- tp = tcp_close(tp);
- mbuf_free(m);
- } else {
- /*
- * Haven't connected yet, save the current mbuf
- * and ti, and return
- * XXX Some OS's don't tell us whether the connect()
- * succeeded or not. So we must time it out.
- */
- so->so_m = m;
- so->so_ti = ti;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->t_state = TCPS_SYN_RECEIVED;
- }
- return;
-
- cont_conn:
- /* m==NULL
- * Check if the connect succeeded
- */
- if (so->so_state & SS_NOFDREF) {
- DEBUG_MISC((dfd, " tcp_input closing connecting socket %lx\n", (long)so));
- tp = tcp_close(tp);
- goto dropwithreset;
- }
- cont_input:
- tcp_template(tp);
-
- if (optp)
- tcp_dooptions(tp, (u_char *)optp, optlen, ti);
- /* , */
- /* &ts_present, &ts_val, &ts_ecr); */
-
- if (iss)
- tp->iss = iss;
- else
- tp->iss = tcp_iss;
- tcp_iss += TCP_ISSINCR/2;
- tp->irs = ti->ti_seq;
- tcp_sendseqinit(tp);
- tcp_rcvseqinit(tp);
- tp->t_flags |= TF_ACKNOW;
- tp->t_state = TCPS_SYN_RECEIVED;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tcpstat.tcps_accepts++;
- DEBUG_MISC((dfd, " tcp_input accept connected socket %lx\n", (long)so));
- goto trimthenstep6;
- } /* case TCPS_LISTEN */
-
- /*
- * If the state is SYN_SENT:
- * if seg contains an ACK, but not for our SYN, drop the input.
- * if seg contains a RST, then drop the connection.
- * if seg does not contain SYN, then drop it.
- * Otherwise this is an acceptable SYN segment
- * initialize tp->rcv_nxt and tp->irs
- * if seg contains ack then advance tp->snd_una
- * if SYN has been acked change to ESTABLISHED else SYN_RCVD state
- * arrange for segment to be acked (eventually)
- * continue processing rest of data/controls, beginning with URG
- */
- case TCPS_SYN_SENT:
- if ((tiflags & TH_ACK) &&
- (SEQ_LEQ(ti->ti_ack, tp->iss) ||
- SEQ_GT(ti->ti_ack, tp->snd_max)))
- goto dropwithreset;
-
- if (tiflags & TH_RST) {
- if (tiflags & TH_ACK)
- tp = tcp_drop(tp,0); /* XXX Check t_softerror! */
- goto drop;
- }
-
- if ((tiflags & TH_SYN) == 0)
- goto drop;
- if (tiflags & TH_ACK) {
- tp->snd_una = ti->ti_ack;
- if (SEQ_LT(tp->snd_nxt, tp->snd_una))
- tp->snd_nxt = tp->snd_una;
- }
-
- tp->t_timer[TCPT_REXMT] = 0;
- tp->irs = ti->ti_seq;
- tcp_rcvseqinit(tp);
- tp->t_flags |= TF_ACKNOW;
- if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
- tcpstat.tcps_connects++;
- soisfconnected(so);
- tp->t_state = TCPS_ESTABLISHED;
-
- /* Do window scaling on this connection? */
-/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
- * (TF_RCVD_SCALE|TF_REQ_SCALE)) {
- * tp->snd_scale = tp->requested_s_scale;
- * tp->rcv_scale = tp->request_r_scale;
- * }
- */
- (void) tcp_reass(tp, (struct tcpiphdr *)0,
- (MBuf )0);
- /*
- * if we didn't have to retransmit the SYN,
- * use its rtt as our initial srtt & rtt var.
- */
- if (tp->t_rtt)
- tcp_xmit_timer(tp, tp->t_rtt);
- } else
- tp->t_state = TCPS_SYN_RECEIVED;
-
-trimthenstep6:
- /*
- * Advance ti->ti_seq to correspond to first data byte.
- * If data, trim to stay within window,
- * dropping FIN if necessary.
- */
- ti->ti_seq++;
- if (ti->ti_len > tp->rcv_wnd) {
- todrop = ti->ti_len - tp->rcv_wnd;
- mbuf_trim(m, -todrop);
- ti->ti_len = tp->rcv_wnd;
- tiflags &= ~TH_FIN;
- tcpstat.tcps_rcvpackafterwin++;
- tcpstat.tcps_rcvbyteafterwin += todrop;
- }
- tp->snd_wl1 = ti->ti_seq - 1;
- tp->rcv_up = ti->ti_seq;
- goto step6;
- } /* switch tp->t_state */
- /*
- * States other than LISTEN or SYN_SENT.
- * First check timestamp, if present.
- * Then check that at least some bytes of segment are within
- * receive window. If segment begins before rcv_nxt,
- * drop leading data (and SYN); if nothing left, just ack.
- *
- * RFC 1323 PAWS: If we have a timestamp reply on this segment
- * and it's less than ts_recent, drop it.
- */
-/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent &&
- * TSTMP_LT(ts_val, tp->ts_recent)) {
- *
- */ /* Check to see if ts_recent is over 24 days old. */
-/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) {
- */ /*
- * * Invalidate ts_recent. If this segment updates
- * * ts_recent, the age will be reset later and ts_recent
- * * will get a valid value. If it does not, setting
- * * ts_recent to zero will at least satisfy the
- * * requirement that zero be placed in the timestamp
- * * echo reply when ts_recent isn't valid. The
- * * age isn't reset until we get a valid ts_recent
- * * because we don't want out-of-order segments to be
- * * dropped when ts_recent is old.
- * */
-/* tp->ts_recent = 0;
- * } else {
- * tcpstat.tcps_rcvduppack++;
- * tcpstat.tcps_rcvdupbyte += ti->ti_len;
- * tcpstat.tcps_pawsdrop++;
- * goto dropafterack;
- * }
- * }
- */
-
- todrop = tp->rcv_nxt - ti->ti_seq;
- if (todrop > 0) {
- if (tiflags & TH_SYN) {
- tiflags &= ~TH_SYN;
- ti->ti_seq++;
- if (ti->ti_urp > 1)
- ti->ti_urp--;
- else
- tiflags &= ~TH_URG;
- todrop--;
- }
- /*
- * Following if statement from Stevens, vol. 2, p. 960.
- */
- if (todrop > ti->ti_len
- || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) {
- /*
- * Any valid FIN must be to the left of the window.
- * At this point the FIN must be a duplicate or out
- * of sequence; drop it.
- */
- tiflags &= ~TH_FIN;
-
- /*
- * Send an ACK to resynchronize and drop any data.
- * But keep on processing for RST or ACK.
- */
- tp->t_flags |= TF_ACKNOW;
- todrop = ti->ti_len;
- tcpstat.tcps_rcvduppack++;
- tcpstat.tcps_rcvdupbyte += todrop;
- } else {
- tcpstat.tcps_rcvpartduppack++;
- tcpstat.tcps_rcvpartdupbyte += todrop;
- }
- mbuf_trim(m, todrop);
- ti->ti_seq += todrop;
- ti->ti_len -= todrop;
- if (ti->ti_urp > todrop)
- ti->ti_urp -= todrop;
- else {
- tiflags &= ~TH_URG;
- ti->ti_urp = 0;
- }
- }
- /*
- * If new data are received on a connection after the
- * user processes are gone, then RST the other end.
- */
- if ((so->so_state & SS_NOFDREF) &&
- tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
- tp = tcp_close(tp);
- tcpstat.tcps_rcvafterclose++;
- goto dropwithreset;
- }
-
- /*
- * If segment ends after window, drop trailing data
- * (and PUSH and FIN); if nothing left, just ACK.
- */
- todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
- if (todrop > 0) {
- tcpstat.tcps_rcvpackafterwin++;
- if (todrop >= ti->ti_len) {
- tcpstat.tcps_rcvbyteafterwin += ti->ti_len;
- /*
- * If a new connection request is received
- * while in TIME_WAIT, drop the old connection
- * and start over if the sequence numbers
- * are above the previous ones.
- */
- if (tiflags & TH_SYN &&
- tp->t_state == TCPS_TIME_WAIT &&
- SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
- iss = tp->rcv_nxt + TCP_ISSINCR;
- tp = tcp_close(tp);
- goto findso;
- }
- /*
- * If window is closed can only take segments at
- * window edge, and have to drop data and PUSH from
- * incoming segments. Continue processing, but
- * remember to ack. Otherwise, drop segment
- * and ack.
- */
- if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
- tp->t_flags |= TF_ACKNOW;
- tcpstat.tcps_rcvwinprobe++;
- } else
- goto dropafterack;
- } else
- tcpstat.tcps_rcvbyteafterwin += todrop;
- mbuf_trim(m, -todrop);
- ti->ti_len -= todrop;
- tiflags &= ~(TH_PUSH|TH_FIN);
- }
-
- /*
- * If last ACK falls within this segment's sequence numbers,
- * record its timestamp.
- */
-/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) &&
- * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len +
- * ((tiflags & (TH_SYN|TH_FIN)) != 0))) {
- * tp->ts_recent_age = tcp_now;
- * tp->ts_recent = ts_val;
- * }
- */
-
- /*
- * If the RST bit is set examine the state:
- * SYN_RECEIVED STATE:
- * If passive open, return to LISTEN state.
- * If active open, inform user that connection was refused.
- * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
- * Inform user that connection was reset, and close tcb.
- * CLOSING, LAST_ACK, TIME_WAIT STATES
- * Close the tcb.
- */
- if (tiflags&TH_RST) switch (tp->t_state) {
-
- case TCPS_SYN_RECEIVED:
-/* so->so_error = ECONNREFUSED; */
- goto close;
-
- case TCPS_ESTABLISHED:
- case TCPS_FIN_WAIT_1:
- case TCPS_FIN_WAIT_2:
- case TCPS_CLOSE_WAIT:
-/* so->so_error = ECONNRESET; */
- close:
- tp->t_state = TCPS_CLOSED;
- tcpstat.tcps_drops++;
- tp = tcp_close(tp);
- goto drop;
-
- case TCPS_CLOSING:
- case TCPS_LAST_ACK:
- case TCPS_TIME_WAIT:
- tp = tcp_close(tp);
- goto drop;
- }
-
- /*
- * If a SYN is in the window, then this is an
- * error and we send an RST and drop the connection.
- */
- if (tiflags & TH_SYN) {
- tp = tcp_drop(tp,0);
- goto dropwithreset;
- }
-
- /*
- * If the ACK bit is off we drop the segment and return.
- */
- if ((tiflags & TH_ACK) == 0) goto drop;
-
- /*
- * Ack processing.
- */
- switch (tp->t_state) {
- /*
- * In SYN_RECEIVED state if the ack ACKs our SYN then enter
- * ESTABLISHED state and continue processing, otherwise
- * send an RST. una<=ack<=max
- */
- case TCPS_SYN_RECEIVED:
-
- if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
- SEQ_GT(ti->ti_ack, tp->snd_max))
- goto dropwithreset;
- tcpstat.tcps_connects++;
- tp->t_state = TCPS_ESTABLISHED;
- /*
- * The sent SYN is ack'ed with our sequence number +1
- * The first data byte already in the buffer will get
- * lost if no correction is made. This is only needed for
- * SS_CTL since the buffer is empty otherwise.
- * tp->snd_una++; or:
- */
- tp->snd_una=ti->ti_ack;
- if (so->so_state & SS_CTL) {
- /* So tcp_ctl reports the right state */
- ret = tcp_ctl(so);
- if (ret == 1) {
- soisfconnected(so);
- so->so_state &= ~SS_CTL; /* success XXX */
- } else if (ret == 2) {
- so->so_state = SS_NOFDREF; /* CTL_CMD */
- } else {
- needoutput = 1;
- tp->t_state = TCPS_FIN_WAIT_1;
- }
- } else {
- soisfconnected(so);
- }
-
- /* Do window scaling? */
-/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) ==
- * (TF_RCVD_SCALE|TF_REQ_SCALE)) {
- * tp->snd_scale = tp->requested_s_scale;
- * tp->rcv_scale = tp->request_r_scale;
- * }
- */
- (void) tcp_reass(tp, (struct tcpiphdr *)0, (MBuf )0);
- tp->snd_wl1 = ti->ti_seq - 1;
- /* Avoid ack processing; snd_una==ti_ack => dup ack */
- goto synrx_to_est;
- /* fall into ... */
-
- /*
- * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
- * ACKs. If the ack is in the range
- * tp->snd_una < ti->ti_ack <= tp->snd_max
- * then advance tp->snd_una to ti->ti_ack and drop
- * data from the retransmission queue. If this ACK reflects
- * more up to date window information we update our window information.
- */
- case TCPS_ESTABLISHED:
- case TCPS_FIN_WAIT_1:
- case TCPS_FIN_WAIT_2:
- case TCPS_CLOSE_WAIT:
- case TCPS_CLOSING:
- case TCPS_LAST_ACK:
- case TCPS_TIME_WAIT:
-
- if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
- if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
- tcpstat.tcps_rcvdupack++;
- DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n",
- (long )m, (long )so));
- /*
- * If we have outstanding data (other than
- * a window probe), this is a completely
- * duplicate ack (ie, window info didn't
- * change), the ack is the biggest we've
- * seen and we've seen exactly our rexmt
- * threshold of them, assume a packet
- * has been dropped and retransmit it.
- * Kludge snd_nxt & the congestion
- * window so we send only this one
- * packet.
- *
- * We know we're losing at the current
- * window size so do congestion avoidance
- * (set ssthresh to half the current window
- * and pull our congestion window back to
- * the new ssthresh).
- *
- * Dup acks mean that packets have left the
- * network (they're now cached at the receiver)
- * so bump cwnd by the amount in the receiver
- * to keep a constant cwnd packets in the
- * network.
- */
- if (tp->t_timer[TCPT_REXMT] == 0 ||
- ti->ti_ack != tp->snd_una)
- tp->t_dupacks = 0;
- else if (++tp->t_dupacks == tcprexmtthresh) {
- tcp_seq onxt = tp->snd_nxt;
- u_int win =
- min(tp->snd_wnd, tp->snd_cwnd) / 2 /
- tp->t_maxseg;
-
- if (win < 2)
- win = 2;
- tp->snd_ssthresh = win * tp->t_maxseg;
- tp->t_timer[TCPT_REXMT] = 0;
- tp->t_rtt = 0;
- tp->snd_nxt = ti->ti_ack;
- tp->snd_cwnd = tp->t_maxseg;
- (void) tcp_output(tp);
- tp->snd_cwnd = tp->snd_ssthresh +
- tp->t_maxseg * tp->t_dupacks;
- if (SEQ_GT(onxt, tp->snd_nxt))
- tp->snd_nxt = onxt;
- goto drop;
- } else if (tp->t_dupacks > tcprexmtthresh) {
- tp->snd_cwnd += tp->t_maxseg;
- (void) tcp_output(tp);
- goto drop;
- }
- } else
- tp->t_dupacks = 0;
- break;
- }
- synrx_to_est:
- /*
- * If the congestion window was inflated to account
- * for the other side's cached packets, retract it.
- */
- if (tp->t_dupacks > tcprexmtthresh &&
- tp->snd_cwnd > tp->snd_ssthresh)
- tp->snd_cwnd = tp->snd_ssthresh;
- tp->t_dupacks = 0;
- if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
- tcpstat.tcps_rcvacktoomuch++;
- goto dropafterack;
- }
- acked = ti->ti_ack - tp->snd_una;
- tcpstat.tcps_rcvackpack++;
- tcpstat.tcps_rcvackbyte += acked;
-
- /*
- * If we have a timestamp reply, update smoothed
- * round trip time. If no timestamp is present but
- * transmit timer is running and timed sequence
- * number was acked, update smoothed round trip time.
- * Since we now have an rtt measurement, cancel the
- * timer backoff (cf., Phil Karn's retransmit alg.).
- * Recompute the initial retransmit timer.
- */
-/* if (ts_present)
- * tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
- * else
- */
- if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
- tcp_xmit_timer(tp,tp->t_rtt);
-
- /*
- * If all outstanding data is acked, stop retransmit
- * timer and remember to restart (more output or persist).
- * If there is more data to be acked, restart retransmit
- * timer, using current (possibly backed-off) value.
- */
- if (ti->ti_ack == tp->snd_max) {
- tp->t_timer[TCPT_REXMT] = 0;
- needoutput = 1;
- } else if (tp->t_timer[TCPT_PERSIST] == 0)
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- /*
- * When new data is acked, open the congestion window.
- * If the window gives us less than ssthresh packets
- * in flight, open exponentially (maxseg per packet).
- * Otherwise open linearly: maxseg per window
- * (maxseg^2 / cwnd per packet).
- */
- {
- register u_int cw = tp->snd_cwnd;
- register u_int incr = tp->t_maxseg;
-
- if (cw > tp->snd_ssthresh)
- incr = incr * incr / cw;
- tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale);
- }
- if (acked > so->so_snd.sb_cc) {
- tp->snd_wnd -= so->so_snd.sb_cc;
- sbuf_drop(&so->so_snd, (int )so->so_snd.sb_cc);
- ourfinisacked = 1;
- } else {
- sbuf_drop(&so->so_snd, acked);
- tp->snd_wnd -= acked;
- ourfinisacked = 0;
- }
- /*
- * XXX sowwakup is called when data is acked and there's room for
- * for more data... it should read() the socket
- */
-/* if (so->so_snd.sb_flags & SB_NOTIFY)
- * sowwakeup(so);
- */
- tp->snd_una = ti->ti_ack;
- if (SEQ_LT(tp->snd_nxt, tp->snd_una))
- tp->snd_nxt = tp->snd_una;
-
- switch (tp->t_state) {
-
- /*
- * In FIN_WAIT_1 STATE in addition to the processing
- * for the ESTABLISHED state if our FIN is now acknowledged
- * then enter FIN_WAIT_2.
- */
- case TCPS_FIN_WAIT_1:
- if (ourfinisacked) {
- /*
- * If we can't receive any more
- * data, then closing user can proceed.
- * Starting the timer is contrary to the
- * specification, but if we don't get a FIN
- * we'll hang forever.
- */
- if (so->so_state & SS_FCANTRCVMORE) {
- soisfdisconnected(so);
- tp->t_timer[TCPT_2MSL] = tcp_maxidle;
- }
- tp->t_state = TCPS_FIN_WAIT_2;
- }
- break;
-
- /*
- * In CLOSING STATE in addition to the processing for
- * the ESTABLISHED state if the ACK acknowledges our FIN
- * then enter the TIME-WAIT state, otherwise ignore
- * the segment.
- */
- case TCPS_CLOSING:
- if (ourfinisacked) {
- tp->t_state = TCPS_TIME_WAIT;
- tcp_canceltimers(tp);
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- soisfdisconnected(so);
- }
- break;
-
- /*
- * In LAST_ACK, we may still be waiting for data to drain
- * and/or to be acked, as well as for the ack of our FIN.
- * If our FIN is now acknowledged, delete the TCB,
- * enter the closed state and return.
- */
- case TCPS_LAST_ACK:
- if (ourfinisacked) {
- tp = tcp_close(tp);
- goto drop;
- }
- break;
-
- /*
- * In TIME_WAIT state the only thing that should arrive
- * is a retransmission of the remote FIN. Acknowledge
- * it and restart the finack timer.
- */
- case TCPS_TIME_WAIT:
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- goto dropafterack;
- }
- } /* switch(tp->t_state) */
-
-step6:
- /*
- * Update window information.
- * Don't look at window if no ACK: TAC's send garbage on first SYN.
- */
- if ((tiflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
- (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
- (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) {
- /* keep track of pure window updates */
- if (ti->ti_len == 0 &&
- tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)
- tcpstat.tcps_rcvwinupd++;
- tp->snd_wnd = tiwin;
- tp->snd_wl1 = ti->ti_seq;
- tp->snd_wl2 = ti->ti_ack;
- if (tp->snd_wnd > tp->max_sndwnd)
- tp->max_sndwnd = tp->snd_wnd;
- needoutput = 1;
- }
-
- /*
- * Process segments with URG.
- */
- if ((tiflags & TH_URG) && ti->ti_urp &&
- TCPS_HAVERCVDFIN(tp->t_state) == 0) {
- /*
- * This is a kludge, but if we receive and accept
- * random urgent pointers, we'll crash in
- * soreceive. It's hard to imagine someone
- * actually wanting to send this much urgent data.
- */
- if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) {
- ti->ti_urp = 0;
- tiflags &= ~TH_URG;
- goto dodata;
- }
- /*
- * If this segment advances the known urgent pointer,
- * then mark the data stream. This should not happen
- * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
- * a FIN has been received from the remote side.
- * In these states we ignore the URG.
- *
- * According to RFC961 (Assigned Protocols),
- * the urgent pointer points to the last octet
- * of urgent data. We continue, however,
- * to consider it to indicate the first octet
- * of data past the urgent section as the original
- * spec states (in one of two places).
- */
- if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) {
- tp->rcv_up = ti->ti_seq + ti->ti_urp;
- so->so_urgc = so->so_rcv.sb_cc +
- (tp->rcv_up - tp->rcv_nxt); /* -1; */
- tp->rcv_up = ti->ti_seq + ti->ti_urp;
-
- }
- } else
- /*
- * If no out of band data is expected,
- * pull receive urgent pointer along
- * with the receive window.
- */
- if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
- tp->rcv_up = tp->rcv_nxt;
-dodata:
-
- /*
- * Process the segment text, merging it into the TCP sequencing queue,
- * and arranging for acknowledgment of receipt if necessary.
- * This process logically involves adjusting tp->rcv_wnd as data
- * is presented to the user (this happens in tcp_usrreq.c,
- * case PRU_RCVD). If a FIN has already been received on this
- * connection then we just ignore the text.
- */
- if ((ti->ti_len || (tiflags&TH_FIN)) &&
- TCPS_HAVERCVDFIN(tp->t_state) == 0) {
- TCP_REASS(tp, ti, m, so, tiflags);
- /*
- * Note the amount of data that peer has sent into
- * our window, in order to estimate the sender's
- * buffer size.
- */
- len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt);
- } else {
- mbuf_free(m);
- tiflags &= ~TH_FIN;
- }
-
- /*
- * If FIN is received ACK the FIN and let the user know
- * that the connection is closing.
- */
- if (tiflags & TH_FIN) {
- if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
- /*
- * If we receive a FIN we can't send more data,
- * set it SS_FDRAIN
- * Shutdown the socket if there is no rx data in the
- * buffer.
- * soread() is called on completion of shutdown() and
- * will got to TCPS_LAST_ACK, and use tcp_output()
- * to send the FIN.
- */
-/* sofcantrcvmore(so); */
- sofwdrain(so);
-
- tp->t_flags |= TF_ACKNOW;
- tp->rcv_nxt++;
- }
- switch (tp->t_state) {
-
- /*
- * In SYN_RECEIVED and ESTABLISHED STATES
- * enter the CLOSE_WAIT state.
- */
- case TCPS_SYN_RECEIVED:
- case TCPS_ESTABLISHED:
- if(so->so_emu == EMU_CTL) /* no shutdown on socket */
- tp->t_state = TCPS_LAST_ACK;
- else
- tp->t_state = TCPS_CLOSE_WAIT;
- break;
-
- /*
- * If still in FIN_WAIT_1 STATE FIN has not been acked so
- * enter the CLOSING state.
- */
- case TCPS_FIN_WAIT_1:
- tp->t_state = TCPS_CLOSING;
- break;
-
- /*
- * In FIN_WAIT_2 state enter the TIME_WAIT state,
- * starting the time-wait timer, turning off the other
- * standard timers.
- */
- case TCPS_FIN_WAIT_2:
- tp->t_state = TCPS_TIME_WAIT;
- tcp_canceltimers(tp);
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- soisfdisconnected(so);
- break;
-
- /*
- * In TIME_WAIT state restart the 2 MSL time_wait timer.
- */
- case TCPS_TIME_WAIT:
- tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
- break;
- }
- }
-
- /*
- * If this is a small packet, then ACK now - with Nagel
- * congestion avoidance sender won't send more until
- * he gets an ACK.
- *
- * See above.
- */
-/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) {
- */
-/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg &&
- * (so->so_iptos & IPTOS_LOWDELAY) == 0) ||
- * ((so->so_iptos & IPTOS_LOWDELAY) &&
- * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) {
- */
- if (ti->ti_len && (unsigned)ti->ti_len <= 5 &&
- ((struct tcpiphdr_2 *)ti)->first_char == (char)27) {
- tp->t_flags |= TF_ACKNOW;
- }
-
- /*
- * Return any desired output.
- */
- if (needoutput || (tp->t_flags & TF_ACKNOW)) {
- (void) tcp_output(tp);
- }
- return;
-
-dropafterack:
- /*
- * Generate an ACK dropping incoming segment if it occupies
- * sequence space, where the ACK reflects our state.
- */
- if (tiflags & TH_RST)
- goto drop;
- mbuf_free(m);
- tp->t_flags |= TF_ACKNOW;
- (void) tcp_output(tp);
- return;
-
-dropwithreset:
- /* reuses m if m!=NULL, mbuf_free() unnecessary */
- if (tiflags & TH_ACK)
- tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
- else {
- if (tiflags & TH_SYN) ti->ti_len++;
- tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
- TH_RST|TH_ACK);
- }
-
- return;
-
-drop:
- /*
- * Drop space held by incoming segment and return.
- */
- mbuf_free(m);
-
- return;
-}
-
- /* , ts_present, ts_val, ts_ecr) */
-/* int *ts_present;
- * u_int32_t *ts_val, *ts_ecr;
- */
-void
-tcp_dooptions(tp, cp, cnt, ti)
- struct tcpcb *tp;
- u_char *cp;
- int cnt;
- struct tcpiphdr *ti;
-{
- u_int16_t mss;
- int opt, optlen;
-
- DEBUG_CALL("tcp_dooptions");
- DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt));
-
- for (; cnt > 0; cnt -= optlen, cp += optlen) {
- opt = cp[0];
- if (opt == TCPOPT_EOL)
- break;
- if (opt == TCPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[1];
- if (optlen <= 0)
- break;
- }
- switch (opt) {
-
- default:
- continue;
-
- case TCPOPT_MAXSEG:
- if (optlen != TCPOLEN_MAXSEG)
- continue;
- if (!(ti->ti_flags & TH_SYN))
- continue;
- memcpy((char *) &mss, (char *) cp + 2, sizeof(mss));
- NTOHS(mss);
- (void) tcp_mss(tp, mss); /* sets t_maxseg */
- break;
-
-/* case TCPOPT_WINDOW:
- * if (optlen != TCPOLEN_WINDOW)
- * continue;
- * if (!(ti->ti_flags & TH_SYN))
- * continue;
- * tp->t_flags |= TF_RCVD_SCALE;
- * tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT);
- * break;
- */
-/* case TCPOPT_TIMESTAMP:
- * if (optlen != TCPOLEN_TIMESTAMP)
- * continue;
- * *ts_present = 1;
- * memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val));
- * NTOHL(*ts_val);
- * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr));
- * NTOHL(*ts_ecr);
- *
- */ /*
- * * A timestamp received in a SYN makes
- * * it ok to send timestamp requests and replies.
- * */
-/* if (ti->ti_flags & TH_SYN) {
- * tp->t_flags |= TF_RCVD_TSTMP;
- * tp->ts_recent = *ts_val;
- * tp->ts_recent_age = tcp_now;
- * }
- */ break;
- }
- }
-}
-
-
-/*
- * Pull out of band byte out of a segment so
- * it doesn't appear in the user's data queue.
- * It is still reflected in the segment length for
- * sequencing purposes.
- */
-
-#ifdef notdef
-
-void
-tcp_pulloutofband(so, ti, m)
- struct socket *so;
- struct tcpiphdr *ti;
- register MBuf m;
-{
- int cnt = ti->ti_urp - 1;
-
- while (cnt >= 0) {
- if (m->m_len > cnt) {
- char *cp = MBUF_TO(m, caddr_t) + cnt;
- struct tcpcb *tp = sototcpcb(so);
-
- tp->t_iobc = *cp;
- tp->t_oobflags |= TCPOOB_HAVEDATA;
- memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1));
- m->m_len--;
- return;
- }
- cnt -= m->m_len;
- m = m->m_next; /* XXX WRONG! Fix it! */
- if (m == 0)
- break;
- }
- panic("tcp_pulloutofband");
-}
-
-#endif /* notdef */
-
-/*
- * Collect new round-trip time estimate
- * and update averages and current timeout.
- */
-
-void
-tcp_xmit_timer(tp, rtt)
- register struct tcpcb *tp;
- int rtt;
-{
- register short delta;
-
- DEBUG_CALL("tcp_xmit_timer");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("rtt = %d", rtt);
-
- tcpstat.tcps_rttupdated++;
- if (tp->t_srtt != 0) {
- /*
- * srtt is stored as fixed point with 3 bits after the
- * binary point (i.e., scaled by 8). The following magic
- * is equivalent to the smoothing algorithm in rfc793 with
- * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed
- * point). Adjust rtt to origin 0.
- */
- delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT);
- if ((tp->t_srtt += delta) <= 0)
- tp->t_srtt = 1;
- /*
- * We accumulate a smoothed rtt variance (actually, a
- * smoothed mean difference), then set the retransmit
- * timer to smoothed rtt + 4 times the smoothed variance.
- * rttvar is stored as fixed point with 2 bits after the
- * binary point (scaled by 4). The following is
- * equivalent to rfc793 smoothing with an alpha of .75
- * (rttvar = rttvar*3/4 + |delta| / 4). This replaces
- * rfc793's wired-in beta.
- */
- if (delta < 0)
- delta = -delta;
- delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT);
- if ((tp->t_rttvar += delta) <= 0)
- tp->t_rttvar = 1;
- } else {
- /*
- * No rtt measurement yet - use the unsmoothed rtt.
- * Set the variance to half the rtt (so our first
- * retransmit happens at 3*rtt).
- */
- tp->t_srtt = rtt << TCP_RTT_SHIFT;
- tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1);
- }
- tp->t_rtt = 0;
- tp->t_rxtshift = 0;
-
- /*
- * the retransmit should happen at rtt + 4 * rttvar.
- * Because of the way we do the smoothing, srtt and rttvar
- * will each average +1/2 tick of bias. When we compute
- * the retransmit timer, we want 1/2 tick of rounding and
- * 1 extra tick because of +-1/2 tick uncertainty in the
- * firing of the timer. The bias will give us exactly the
- * 1.5 tick we need. But, because the bias is
- * statistical, we have to test that we don't drop below
- * the minimum feasible timer (which is 2 ticks).
- */
- TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp),
- (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
-
- /*
- * We received an ack for a packet that wasn't retransmitted;
- * it is probably safe to discard any error indications we've
- * received recently. This isn't quite right, but close enough
- * for now (a route might have failed after we sent a segment,
- * and the return path might not be symmetrical).
- */
- tp->t_softerror = 0;
-}
-
-/*
- * Determine a reasonable value for maxseg size.
- * If the route is known, check route for mtu.
- * If none, use an mss that can be handled on the outgoing
- * interface without forcing IP to fragment; if bigger than
- * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES
- * to utilize large mbufs. If no route is found, route has no mtu,
- * or the destination isn't local, use a default, hopefully conservative
- * size (usually 512 or the default IP max size, but no more than the mtu
- * of the interface), as we can't discover anything about intervening
- * gateways or networks. We also initialize the congestion/slow start
- * window to be a single segment if the destination isn't local.
- * While looking at the routing entry, we also initialize other path-dependent
- * parameters from pre-set or cached values in the routing entry.
- */
-
-int
-tcp_mss(tp, offer)
- register struct tcpcb *tp;
- u_int offer;
-{
- struct socket *so = tp->t_socket;
- int mss;
-
- DEBUG_CALL("tcp_mss");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("offer = %d", offer);
-
- mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr);
- if (offer)
- mss = min(mss, offer);
- mss = max(mss, 32);
- if (mss < tp->t_maxseg || offer != 0)
- tp->t_maxseg = mss;
-
- tp->snd_cwnd = mss;
-
- sbuf_reserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0));
- sbuf_reserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0));
-
- DEBUG_MISC((dfd, " returning mss = %d\n", mss));
-
- return mss;
-}
diff --git a/slirp2/tcp_output.c b/slirp2/tcp_output.c
deleted file mode 100644
index 95246aa..0000000
--- a/slirp2/tcp_output.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93
- * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-
-/*
- * Since this is only used in "stats socket", we give meaning
- * names instead of the REAL names
- */
-char *tcpstates[] = {
-/* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */
- "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD",
- "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING",
- "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",
-};
-
-u_char tcp_outflags[TCP_NSTATES] = {
- TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
- TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
- TH_FIN|TH_ACK, TH_ACK, TH_ACK,
-};
-
-
-#define MAX_TCPOPTLEN 32 /* max # bytes that go in options */
-
-/*
- * Tcp output routine: figure out what should be sent and send it.
- */
-int
-tcp_output(tp)
- register struct tcpcb *tp;
-{
- register struct socket *so = tp->t_socket;
- register long len, win;
- int off, flags, error;
- register MBuf m;
- register struct tcpiphdr *ti;
- u_char opt[MAX_TCPOPTLEN];
- unsigned optlen, hdrlen;
- int idle, sendalot;
-
- DEBUG_CALL("tcp_output");
- DEBUG_ARG("tp = %lx", (long )tp);
-
- /*
- * Determine length of data that should be transmitted,
- * and flags that will be used.
- * If there is some data or critical controls (SYN, RST)
- * to send, then transmit; otherwise, investigate further.
- */
- idle = (tp->snd_max == tp->snd_una);
- if (idle && tp->t_idle >= tp->t_rxtcur)
- /*
- * We have been idle for "a while" and no acks are
- * expected to clock out any data we send --
- * slow start to get ack "clock" running again.
- */
- tp->snd_cwnd = tp->t_maxseg;
-again:
- sendalot = 0;
- off = tp->snd_nxt - tp->snd_una;
- win = min(tp->snd_wnd, tp->snd_cwnd);
-
- flags = tcp_outflags[tp->t_state];
-
- DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags));
-
- /*
- * If in persist timeout with window of 0, send 1 byte.
- * Otherwise, if window is small but nonzero
- * and timer expired, we will send what we can
- * and go to transmit state.
- */
- if (tp->t_force) {
- if (win == 0) {
- /*
- * If we still have some data to send, then
- * clear the FIN bit. Usually this would
- * happen below when it realizes that we
- * aren't sending all the data. However,
- * if we have exactly 1 byte of unset data,
- * then it won't clear the FIN bit below,
- * and if we are in persist state, we wind
- * up sending the packet without recording
- * that we sent the FIN bit.
- *
- * We can't just blindly clear the FIN bit,
- * because if we don't have any more data
- * to send then the probe will be the FIN
- * itself.
- */
- if (off < so->so_snd.sb_cc)
- flags &= ~TH_FIN;
- win = 1;
- } else {
- tp->t_timer[TCPT_PERSIST] = 0;
- tp->t_rxtshift = 0;
- }
- }
-
- len = min(so->so_snd.sb_cc, win) - off;
-
- if (len < 0) {
- /*
- * If FIN has been sent but not acked,
- * but we haven't been called to retransmit,
- * len will be -1. Otherwise, window shrank
- * after we sent into it. If window shrank to 0,
- * cancel pending retransmit and pull snd_nxt
- * back to (closed) window. We will enter persist
- * state below. If the window didn't close completely,
- * just wait for an ACK.
- */
- len = 0;
- if (win == 0) {
- tp->t_timer[TCPT_REXMT] = 0;
- tp->snd_nxt = tp->snd_una;
- }
- }
-
- if (len > tp->t_maxseg) {
- len = tp->t_maxseg;
- sendalot = 1;
- }
- if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
- flags &= ~TH_FIN;
-
- win = sbuf_space(&so->so_rcv);
-
- /*
- * Sender silly window avoidance. If connection is idle
- * and can send all data, a maximum segment,
- * at least a maximum default-size segment do it,
- * or are forced, do it; otherwise don't bother.
- * If peer's buffer is tiny, then send
- * when window is at least half open.
- * If retransmitting (possibly after persist timer forced us
- * to send into a small window), then must resend.
- */
- if (len) {
- if (len == tp->t_maxseg)
- goto send;
- if ((1 || idle || tp->t_flags & TF_NODELAY) &&
- len + off >= so->so_snd.sb_cc)
- goto send;
- if (tp->t_force)
- goto send;
- if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
- goto send;
- if (SEQ_LT(tp->snd_nxt, tp->snd_max))
- goto send;
- }
-
- /*
- * Compare available window to amount of window
- * known to peer (as advertised window less
- * next expected input). If the difference is at least two
- * max size segments, or at least 50% of the maximum possible
- * window, then want to send a window update to peer.
- */
- if (win > 0) {
- /*
- * "adv" is the amount we can increase the window,
- * taking into account that we are limited by
- * TCP_MAXWIN << tp->rcv_scale.
- */
- long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) -
- (tp->rcv_adv - tp->rcv_nxt);
-
- if (adv >= (long) (2 * tp->t_maxseg))
- goto send;
- if (2 * adv >= (long) so->so_rcv.sb_datalen)
- goto send;
- }
-
- /*
- * Send if we owe peer an ACK.
- */
- if (tp->t_flags & TF_ACKNOW)
- goto send;
- if (flags & (TH_SYN|TH_RST))
- goto send;
- if (SEQ_GT(tp->snd_up, tp->snd_una))
- goto send;
- /*
- * If our state indicates that FIN should be sent
- * and we have not yet done so, or we're retransmitting the FIN,
- * then we need to send.
- */
- if (flags & TH_FIN &&
- ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
- goto send;
-
- /*
- * TCP window updates are not reliable, rather a polling protocol
- * using ``persist'' packets is used to insure receipt of window
- * updates. The three ``states'' for the output side are:
- * idle not doing retransmits or persists
- * persisting to move a small or zero window
- * (re)transmitting and thereby not persisting
- *
- * tp->t_timer[TCPT_PERSIST]
- * is set when we are in persist state.
- * tp->t_force
- * is set when we are called to send a persist packet.
- * tp->t_timer[TCPT_REXMT]
- * is set when we are retransmitting
- * The output side is idle when both timers are zero.
- *
- * If send window is too small, there is data to transmit, and no
- * retransmit or persist is pending, then go to persist state.
- * If nothing happens soon, send when timer expires:
- * if window is nonzero, transmit what we can,
- * otherwise force out a byte.
- */
- if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
- tp->t_timer[TCPT_PERSIST] == 0) {
- tp->t_rxtshift = 0;
- tcp_setpersist(tp);
- }
-
- /*
- * No reason to send a segment, just return.
- */
- tcpstat.tcps_didnuttin++;
-
- return (0);
-
-send:
- /*
- * Before ESTABLISHED, force sending of initial options
- * unless TCP set not to do any options.
- * NOTE: we assume that the IP/TCP header plus TCP options
- * always fit in a single mbuf, leaving room for a maximum
- * link header, i.e.
- * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN
- */
- optlen = 0;
- hdrlen = sizeof (struct tcpiphdr);
- if (flags & TH_SYN) {
- tp->snd_nxt = tp->iss;
- if ((tp->t_flags & TF_NOOPT) == 0) {
- u_int16_t mss;
-
- opt[0] = TCPOPT_MAXSEG;
- opt[1] = 4;
- mss = htons((u_int16_t) tcp_mss(tp, 0));
- memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss));
- optlen = 4;
-
-/* if ((tp->t_flags & TF_REQ_SCALE) &&
- * ((flags & TH_ACK) == 0 ||
- * (tp->t_flags & TF_RCVD_SCALE))) {
- * *((u_int32_t *) (opt + optlen)) = htonl(
- * TCPOPT_NOP << 24 |
- * TCPOPT_WINDOW << 16 |
- * TCPOLEN_WINDOW << 8 |
- * tp->request_r_scale);
- * optlen += 4;
- * }
- */
- }
- }
-
- /*
- * Send a timestamp and echo-reply if this is a SYN and our side
- * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
- * and our peer have sent timestamps in our SYN's.
- */
-/* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
- * (flags & TH_RST) == 0 &&
- * ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
- * (tp->t_flags & TF_RCVD_TSTMP))) {
- * u_int32_t *lp = (u_int32_t *)(opt + optlen);
- *
- * / * Form timestamp option as shown in appendix A of RFC 1323. * /
- * *lp++ = htonl(TCPOPT_TSTAMP_HDR);
- * *lp++ = htonl(tcp_now);
- * *lp = htonl(tp->ts_recent);
- * optlen += TCPOLEN_TSTAMP_APPA;
- * }
- */
- hdrlen += optlen;
-
- /*
- * Adjust data length if insertion of options will
- * bump the packet length beyond the t_maxseg length.
- */
- if (len > tp->t_maxseg - optlen) {
- len = tp->t_maxseg - optlen;
- sendalot = 1;
- }
-
- /*
- * Grab a header mbuf, attaching a copy of data to
- * be transmitted, and initialize the header from
- * the template for sends on this connection.
- */
- if (len) {
- if (tp->t_force && len == 1)
- tcpstat.tcps_sndprobe++;
- else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
- tcpstat.tcps_sndrexmitpack++;
- tcpstat.tcps_sndrexmitbyte += len;
- } else {
- tcpstat.tcps_sndpack++;
- tcpstat.tcps_sndbyte += len;
- }
-
- m = mbuf_alloc();
- if (m == NULL) {
-/* error = ENOBUFS; */
- error = 1;
- goto out;
- }
- m->m_data += if_maxlinkhdr;
- m->m_len = hdrlen;
-
- /*
- * This will always succeed, since we make sure our mbufs
- * are big enough to hold one MSS packet + header + ... etc.
- */
-/* if (len <= MHLEN - hdrlen - max_linkhdr) { */
-
- sbuf_copy(&so->so_snd, off, (int) len, MBUF_TO(m, caddr_t) + hdrlen);
- m->m_len += len;
-
-/* } else {
- * m->m_next = mbuf_copy(so->so_snd.sb_mb, off, (int) len);
- * if (m->m_next == 0)
- * len = 0;
- * }
- */
- /*
- * If we're sending everything we've got, set PUSH.
- * (This will keep happy those implementations which only
- * give data to the user when a buffer fills or
- * a PUSH comes in.)
- */
- if (off + len == so->so_snd.sb_cc)
- flags |= TH_PUSH;
- } else {
- if (tp->t_flags & TF_ACKNOW)
- tcpstat.tcps_sndacks++;
- else if (flags & (TH_SYN|TH_FIN|TH_RST))
- tcpstat.tcps_sndctrl++;
- else if (SEQ_GT(tp->snd_up, tp->snd_una))
- tcpstat.tcps_sndurg++;
- else
- tcpstat.tcps_sndwinup++;
-
- m = mbuf_alloc();
- if (m == NULL) {
-/* error = ENOBUFS; */
- error = 1;
- goto out;
- }
- m->m_data += if_maxlinkhdr;
- m->m_len = hdrlen;
- }
-
- ti = MBUF_TO(m, struct tcpiphdr *);
-
- memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr));
-
- /*
- * Fill in fields, remembering maximum advertised
- * window for use in delaying messages about window sizes.
- * If resending a FIN, be sure not to use a new sequence number.
- */
- if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
- tp->snd_nxt == tp->snd_max)
- tp->snd_nxt--;
- /*
- * If we are doing retransmissions, then snd_nxt will
- * not reflect the first unsent octet. For ACK only
- * packets, we do not want the sequence number of the
- * retransmitted packet, we want the sequence number
- * of the next unsent octet. So, if there is no data
- * (and no SYN or FIN), use snd_max instead of snd_nxt
- * when filling in ti_seq. But if we are in persist
- * state, snd_max might reflect one byte beyond the
- * right edge of the window, so use snd_nxt in that
- * case, since we know we aren't doing a retransmission.
- * (retransmit and persist are mutually exclusive...)
- */
- if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
- ti->ti_seq = htonl(tp->snd_nxt);
- else
- ti->ti_seq = htonl(tp->snd_max);
- ti->ti_ack = htonl(tp->rcv_nxt);
- if (optlen) {
- memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen);
- ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
- }
- ti->ti_flags = flags;
- /*
- * Calculate receive window. Don't shrink window,
- * but avoid silly window syndrome.
- */
- if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg)
- win = 0;
- if (win > (long)TCP_MAXWIN << tp->rcv_scale)
- win = (long)TCP_MAXWIN << tp->rcv_scale;
- if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
- win = (long)(tp->rcv_adv - tp->rcv_nxt);
- ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale));
-
- if (SEQ_GT(tp->snd_up, tp->snd_una)) {
- ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq)));
-#ifdef notdef
- if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
- ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt));
-#endif
- ti->ti_flags |= TH_URG;
- } else
- /*
- * If no urgent pointer to send, then we pull
- * the urgent pointer to the left edge of the send window
- * so that it doesn't drift into the send window on sequence
- * number wraparound.
- */
- tp->snd_up = tp->snd_una; /* drag it along */
-
- /*
- * Put TCP length in extended header, and then
- * checksum extended header and data.
- */
- if (len + optlen)
- ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) +
- optlen + len));
- ti->ti_sum = cksum(m, (int)(hdrlen + len));
-
- /*
- * In transmit state, time the transmission and arrange for
- * the retransmit. In persist state, just set snd_max.
- */
- if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
- tcp_seq startseq = tp->snd_nxt;
-
- /*
- * Advance snd_nxt over sequence space of this segment.
- */
- if (flags & (TH_SYN|TH_FIN)) {
- if (flags & TH_SYN)
- tp->snd_nxt++;
- if (flags & TH_FIN) {
- tp->snd_nxt++;
- tp->t_flags |= TF_SENTFIN;
- }
- }
- tp->snd_nxt += len;
- if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
- tp->snd_max = tp->snd_nxt;
- /*
- * Time this transmission if not a retransmission and
- * not currently timing anything.
- */
- if (tp->t_rtt == 0) {
- tp->t_rtt = 1;
- tp->t_rtseq = startseq;
- tcpstat.tcps_segstimed++;
- }
- }
-
- /*
- * Set retransmit timer if not currently set,
- * and not doing an ack or a keep-alive probe.
- * Initial value for retransmit timer is smoothed
- * round-trip time + 2 * round-trip time variance.
- * Initialize shift counter which is used for backoff
- * of retransmit time.
- */
- if (tp->t_timer[TCPT_REXMT] == 0 &&
- tp->snd_nxt != tp->snd_una) {
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- if (tp->t_timer[TCPT_PERSIST]) {
- tp->t_timer[TCPT_PERSIST] = 0;
- tp->t_rxtshift = 0;
- }
- }
- } else
- if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
- tp->snd_max = tp->snd_nxt + len;
-
- /*
- * Fill in IP length and desired time to live and
- * send to IP level. There should be a better way
- * to handle ttl and tos; we could keep them in
- * the template, but need a way to checksum without them.
- */
- m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
-
- {
-
- ((struct ip *)ti)->ip_len = m->m_len;
-
- ((struct ip *)ti)->ip_ttl = ip_defttl;
- ((struct ip *)ti)->ip_tos = so->so_iptos;
-
-/* #if BSD >= 43 */
- /* Don't do IP options... */
-/* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
- * so->so_options & SO_DONTROUTE, 0);
- */
- error = ip_output(so, m);
-
-/* #else
- * error = ip_output(m, (MBuf )0, &tp->t_inpcb->inp_route,
- * so->so_options & SO_DONTROUTE);
- * #endif
- */
- }
- if (error) {
-out:
-/* if (error == ENOBUFS) {
- * tcp_quench(tp->t_inpcb, 0);
- * return (0);
- * }
- */
-/* if ((error == EHOSTUNREACH || error == ENETDOWN)
- * && TCPS_HAVERCVDSYN(tp->t_state)) {
- * tp->t_softerror = error;
- * return (0);
- * }
- */
- return (error);
- }
- tcpstat.tcps_sndtotal++;
-
- /*
- * Data sent (as far as we can tell).
- * If this advertises a larger window than any other segment,
- * then remember the size of the advertised window.
- * Any pending ACK has now been sent.
- */
- if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
- tp->rcv_adv = tp->rcv_nxt + win;
- tp->last_ack_sent = tp->rcv_nxt;
- tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
- if (sendalot)
- goto again;
-
- return (0);
-}
-
-void
-tcp_setpersist(tp)
- register struct tcpcb *tp;
-{
- int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
-
-/* if (tp->t_timer[TCPT_REXMT])
- * panic("tcp_output REXMT");
- */
- /*
- * Start/restart persistence timer.
- */
- TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
- t * tcp_backoff[tp->t_rxtshift],
- TCPTV_PERSMIN, TCPTV_PERSMAX);
- if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
- tp->t_rxtshift++;
-}
diff --git a/slirp2/tcp_subr.c b/slirp2/tcp_subr.c
deleted file mode 100644
index e453877..0000000
--- a/slirp2/tcp_subr.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93
- * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#define WANT_SYS_IOCTL_H
-#include <slirp.h>
-#include "proxy_common.h"
-
-/* patchable/settable parameters for tcp */
-int tcp_mssdflt = TCP_MSS;
-int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
-int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */
-int tcp_rcvspace; /* You may want to change this */
-int tcp_sndspace; /* Keep small if you have an error prone link */
-
-/*
- * Tcp initialization
- */
-void
-tcp_init()
-{
- tcp_iss = 1; /* wrong */
- tcb.so_next = tcb.so_prev = &tcb;
-
- /* tcp_rcvspace = our Window we advertise to the remote */
- tcp_rcvspace = TCP_RCVSPACE;
- tcp_sndspace = TCP_SNDSPACE;
-
- /* Make sure tcp_sndspace is at least 2*MSS */
- if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)))
- tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr));
-}
-
-/*
- * Create template to be used to send tcp packets on a connection.
- * Call after host entry created, fills
- * in a skeletal tcp/ip header, minimizing the amount of work
- * necessary when the connection is used.
- */
-/* struct tcpiphdr * */
-void
-tcp_template(tp)
- struct tcpcb *tp;
-{
- struct socket *so = tp->t_socket;
- register struct tcpiphdr *n = &tp->t_template;
-
- n->ti_mbuf = NULL;
- n->ti_x1 = 0;
- n->ti_pr = IPPROTO_TCP;
- n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
- n->ti_src = ip_seth(so->so_faddr_ip);
- n->ti_dst = ip_seth(so->so_laddr_ip);
- n->ti_sport = port_seth(so->so_faddr_port);
- n->ti_dport = port_seth(so->so_laddr_port);
-
- n->ti_seq = 0;
- n->ti_ack = 0;
- n->ti_x2 = 0;
- n->ti_off = 5;
- n->ti_flags = 0;
- n->ti_win = 0;
- n->ti_sum = 0;
- n->ti_urp = 0;
-}
-
-/*
- * Send a single message to the TCP at address specified by
- * the given TCP/IP header. If m == 0, then we make a copy
- * of the tcpiphdr at ti and send directly to the addressed host.
- * This is used to force keep alive messages out using the TCP
- * template for a connection tp->t_template. If flags are given
- * then we send a message back to the TCP which originated the
- * segment ti, and discard the mbuf containing it and any other
- * attached mbufs.
- *
- * In any case the ack and sequence number of the transmitted
- * segment are as specified by the parameters.
- */
-void
-tcp_respond(tp, ti, m, ack, seq, flags)
- struct tcpcb *tp;
- register struct tcpiphdr *ti;
- register MBuf m;
- tcp_seq ack, seq;
- int flags;
-{
- register int tlen;
- int win = 0;
-
- DEBUG_CALL("tcp_respond");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("ti = %lx", (long)ti);
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("ack = %u", ack);
- DEBUG_ARG("seq = %u", seq);
- DEBUG_ARG("flags = %x", flags);
-
- if (tp)
- win = sbuf_space(&tp->t_socket->so_rcv);
- if (m == 0) {
- if ((m = mbuf_alloc()) == NULL)
- return;
-#ifdef TCP_COMPAT_42
- tlen = 1;
-#else
- tlen = 0;
-#endif
- m->m_data += if_maxlinkhdr;
- *MBUF_TO(m, struct tcpiphdr *) = *ti;
- ti = MBUF_TO(m, struct tcpiphdr *);
- flags = TH_ACK;
- } else {
- /*
- * ti points into m so the next line is just making
- * the mbuf point to ti
- */
- m->m_data = (caddr_t)ti;
-
- m->m_len = sizeof (struct tcpiphdr);
- tlen = 0;
-#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
- xchg(ti->ti_dst, ti->ti_src, ipaddr_t);
- xchg(ti->ti_dport, ti->ti_sport, port_t);
-#undef xchg
- }
- ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
- tlen += sizeof (struct tcpiphdr);
- m->m_len = tlen;
-
- ti->ti_mbuf = 0;
- ti->ti_x1 = 0;
- ti->ti_seq = htonl(seq);
- ti->ti_ack = htonl(ack);
- ti->ti_x2 = 0;
- ti->ti_off = sizeof (struct tcphdr) >> 2;
- ti->ti_flags = flags;
- if (tp)
- ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale));
- else
- ti->ti_win = htons((u_int16_t)win);
- ti->ti_urp = 0;
- ti->ti_sum = 0;
- ti->ti_sum = cksum(m, tlen);
- ((struct ip *)ti)->ip_len = tlen;
-
- if(flags & TH_RST)
- ((struct ip *)ti)->ip_ttl = MAXTTL;
- else
- ((struct ip *)ti)->ip_ttl = ip_defttl;
-
- (void) ip_output((struct socket *)0, m);
-}
-
-/*
- * Create a new TCP control block, making an
- * empty reassembly queue and hooking it to the argument
- * protocol control block.
- */
-struct tcpcb *
-tcp_newtcpcb(so)
- struct socket *so;
-{
- register struct tcpcb *tp;
-
- tp = (struct tcpcb *)malloc(sizeof(*tp));
- if (tp == NULL)
- return ((struct tcpcb *)0);
-
- memset((char *) tp, 0, sizeof(struct tcpcb));
- tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
- tp->t_maxseg = tcp_mssdflt;
-
- tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
- tp->t_socket = so;
-
- /*
- * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
- * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives
- * reasonable initial retransmit time.
- */
- tp->t_srtt = TCPTV_SRTTBASE;
- tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
- tp->t_rttmin = TCPTV_MIN;
-
- TCPT_RANGESET(tp->t_rxtcur,
- ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1,
- TCPTV_MIN, TCPTV_REXMTMAX);
-
- tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
- tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
- tp->t_state = TCPS_CLOSED;
-
- so->so_tcpcb = tp;
-
- return (tp);
-}
-
-/*
- * Drop a TCP connection, reporting
- * the specified error. If connection is synchronized,
- * then send a RST to peer.
- */
-struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
-{
-/* tcp_drop(tp, errno)
- register struct tcpcb *tp;
- int errno;
-{
-*/
-
- DEBUG_CALL("tcp_drop");
- DEBUG_ARG("tp = %lx", (long)tp);
- DEBUG_ARG("errno = %d", errno);
-
- if (TCPS_HAVERCVDSYN(tp->t_state)) {
- tp->t_state = TCPS_CLOSED;
- (void) tcp_output(tp);
- tcpstat.tcps_drops++;
- } else
- tcpstat.tcps_conndrops++;
-/* if (errno == ETIMEDOUT && tp->t_softerror)
- * errno = tp->t_softerror;
- */
-/* so->so_error = errno; */
- return (tcp_close(tp));
-}
-
-/*
- * Close a TCP control block:
- * discard all space held by the tcp
- * discard internet protocol block
- * wake up any sleepers
- */
-struct tcpcb *
-tcp_close(tp)
- register struct tcpcb *tp;
-{
- register struct tcpiphdr *t;
- struct socket *so = tp->t_socket;
- register MBuf m;
-
- DEBUG_CALL("tcp_close");
- DEBUG_ARG("tp = %lx", (long )tp);
-
- /* free the reassembly queue, if any */
- t = tcpfrag_list_first(tp);
- while (!tcpfrag_list_end(t, tp)) {
- t = tcpiphdr_next(t);
- m = tcpiphdr_prev(t)->ti_mbuf;
- remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
- mbuf_free(m);
- }
- /* It's static */
-/* if (tp->t_template)
- * (void) mbuf_free(MBUF_FROM(tp->t_template));
- */
-/* free(tp, M_PCB); */
- free(tp);
- so->so_tcpcb = 0;
- soisfdisconnected(so);
- /* clobber input socket cache if we're closing the cached connection */
- if (so == tcp_last_so)
- tcp_last_so = &tcb;
- socket_close(so->s);
- sbuf_free(&so->so_rcv);
- sbuf_free(&so->so_snd);
- sofree(so);
- tcpstat.tcps_closed++;
- return ((struct tcpcb *)0);
-}
-
-void
-tcp_drain()
-{
- /* XXX */
-}
-
-/*
- * When a source quench is received, close congestion window
- * to one segment. We will gradually open it again as we proceed.
- */
-
-#ifdef notdef
-
-void
-tcp_quench(i, errno)
-
- int errno;
-{
- struct tcpcb *tp = intotcpcb(inp);
-
- if (tp)
- tp->snd_cwnd = tp->t_maxseg;
-}
-
-#endif /* notdef */
-
-/*
- * TCP protocol interface to socket abstraction.
- */
-
-/*
- * User issued close, and wish to trail through shutdown states:
- * if never received SYN, just forget it. If got a SYN from peer,
- * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
- * If already got a FIN from peer, then almost done; go to LAST_ACK
- * state. In all other cases, have already sent FIN to peer (e.g.
- * after PRU_SHUTDOWN), and just have to play tedious game waiting
- * for peer to send FIN or not respond to keep-alives, etc.
- * We can let the user exit from the close as soon as the FIN is acked.
- */
-void
-tcp_sockclosed(tp)
- struct tcpcb *tp;
-{
-
- DEBUG_CALL("tcp_sockclosed");
- DEBUG_ARG("tp = %lx", (long)tp);
-
- switch (tp->t_state) {
-
- case TCPS_CLOSED:
- case TCPS_LISTEN:
- case TCPS_SYN_SENT:
- tp->t_state = TCPS_CLOSED;
- tp = tcp_close(tp);
- break;
-
- case TCPS_SYN_RECEIVED:
- case TCPS_ESTABLISHED:
- tp->t_state = TCPS_FIN_WAIT_1;
- break;
-
- case TCPS_CLOSE_WAIT:
- tp->t_state = TCPS_LAST_ACK;
- break;
- }
-/* soisfdisconnecting(tp->t_socket); */
- if (tp && tp->t_state >= TCPS_FIN_WAIT_2)
- soisfdisconnected(tp->t_socket);
- if (tp)
- tcp_output(tp);
-}
-
-static void
-tcp_proxy_event( struct socket* so,
- int s,
- ProxyEvent event )
-{
- so->so_state &= ~SS_PROXIFIED;
-
- if (event == PROXY_EVENT_CONNECTED) {
- so->s = s;
- so->so_state &= ~(SS_ISFCONNECTING);
- }
- else {
- so->so_state = SS_NOFDREF;
- }
-
- /* continue the connect */
- tcp_input(NULL, sizeof(struct ip), so);
-}
-
-/*
- * Connect to a host on the Internet
- * Called by tcp_input
- * Only do a connect, the tcp fields will be set in tcp_input
- * return 0 if there's a result of the connect,
- * else return -1 means we're still connecting
- * The return value is almost always -1 since the socket is
- * nonblocking. Connect returns after the SYN is sent, and does
- * not wait for ACK+SYN.
- */
-int tcp_fconnect(so)
- struct socket *so;
-{
- int ret=0;
- int try_proxy = 1;
- SockAddress sockaddr;
- uint32_t sock_ip;
- uint16_t sock_port;
-
- DEBUG_CALL("tcp_fconnect");
- DEBUG_ARG("so = %lx", (long )so);
-
- sock_ip = so->so_faddr_ip;
- sock_port = so->so_faddr_port;
-
- if ((sock_ip & 0xffffff00) == special_addr_ip) {
- /* It's an alias */
- int last_byte = sock_ip & 0xff;
-
- if (CTL_IS_DNS(last_byte))
- sock_ip = dns_addr[last_byte - CTL_DNS];
- else
- sock_ip = loopback_addr_ip;
- try_proxy = 0;
- }
-
- sock_address_init_inet( &sockaddr, sock_ip, sock_port );
-
- DEBUG_MISC((dfd, " connect()ing, addr=%s, proxy=%d\n",
- sock_address_to_string(&sockaddr), try_proxy));
-
- if (try_proxy) {
- if (!proxy_manager_add(&sockaddr, SOCKET_STREAM, (ProxyEventFunc) tcp_proxy_event, so)) {
- soisfconnecting(so);
- so->s = -1;
- so->so_state |= SS_PROXIFIED;
- return 0;
- }
- }
-
- if ((ret=so->s=socket_create_inet(SOCKET_STREAM)) >= 0)
- {
- int s = so->s;
-
- socket_set_nonblock(s);
- socket_set_xreuseaddr(s);
- socket_set_oobinline(s);
-
- /* We don't care what port we get */
- socket_connect(s, &sockaddr);
-
- /*
- * If it's not in progress, it failed, so we just return 0,
- * without clearing SS_NOFDREF
- */
- soisfconnecting(so);
- }
-
- return(ret);
-}
-
-/*
- * Accept the socket and connect to the local-host
- *
- * We have a problem. The correct thing to do would be
- * to first connect to the local-host, and only if the
- * connection is accepted, then do an accept() here.
- * But, a) we need to know who's trying to connect
- * to the socket to be able to SYN the local-host, and
- * b) we are already connected to the foreign host by
- * the time it gets to accept(), so... We simply accept
- * here and SYN the local-host.
- */
-void
-tcp_connect(inso)
- struct socket *inso;
-{
- struct socket *so;
- SockAddress addr;
- uint32_t addr_ip;
- struct tcpcb *tp;
- int s;
-
- DEBUG_CALL("tcp_connect");
- DEBUG_ARG("inso = %lx", (long)inso);
-
- /*
- * If it's an SS_ACCEPTONCE socket, no need to socreate()
- * another socket, just use the accept() socket.
- */
- if (inso->so_state & SS_FACCEPTONCE) {
- /* FACCEPTONCE already have a tcpcb */
- so = inso;
- } else {
- if ((so = socreate()) == NULL) {
- /* If it failed, get rid of the pending connection */
- socket_close(socket_accept(inso->s, NULL));
- return;
- }
- if (tcp_attach(so) < 0) {
- free(so); /* NOT sofree */
- return;
- }
- so->so_laddr_ip = inso->so_laddr_ip;
- so->so_laddr_port = inso->so_laddr_port;
- }
-
- (void) tcp_mss(sototcpcb(so), 0);
-
- if ((s = socket_accept(inso->s, &addr)) < 0) {
- tcp_close(sototcpcb(so)); /* This will sofree() as well */
- return;
- }
- socket_set_nonblock(s);
- socket_set_xreuseaddr(s);
- socket_set_oobinline(s);
- socket_set_nodelay(s);
-
- so->so_faddr_port = sock_address_get_port(&addr);
-
- addr_ip = sock_address_get_ip(&addr);
-
- so->so_faddr_ip = addr_ip;
- /* Translate connections from localhost to the real hostname */
- if (addr_ip == 0 || addr_ip == loopback_addr_ip)
- so->so_faddr_ip = alias_addr_ip;
-
- /* Close the accept() socket, set right state */
- if (inso->so_state & SS_FACCEPTONCE) {
- socket_close(so->s); /* If we only accept once, close the accept() socket */
- so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */
- /* if it's not FACCEPTONCE, it's already NOFDREF */
- }
- so->s = s;
-
- so->so_iptos = tcp_tos(so);
- tp = sototcpcb(so);
-
- tcp_template(tp);
-
- /* Compute window scaling to request. */
-/* while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
- * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
- * tp->request_r_scale++;
- */
-
-/* soisconnecting(so); */ /* NOFDREF used instead */
- tcpstat.tcps_connattempt++;
-
- tp->t_state = TCPS_SYN_SENT;
- tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
- tp->iss = tcp_iss;
- tcp_iss += TCP_ISSINCR/2;
- tcp_sendseqinit(tp);
- tcp_output(tp);
-}
-
-/*
- * Attach a TCPCB to a socket.
- */
-int
-tcp_attach(so)
- struct socket *so;
-{
- if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
- return -1;
-
- insque(so, &tcb);
-
- return 0;
-}
-
-/*
- * Set the socket's type of service field
- */
-struct tos_t tcptos[] = {
- {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */
- {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */
- {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */
- {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */
- {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */
- {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */
- {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */
- {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */
- {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */
- {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */
- {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */
- {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */
- {0, 0, 0, 0}
-};
-
-
-/*
- * Return TOS according to the above table
- */
-u_int8_t
-tcp_tos(so)
- struct socket *so;
-{
- int i = 0;
-
- while(tcptos[i].tos) {
- if ((tcptos[i].fport && so->so_faddr_port == tcptos[i].fport) ||
- (tcptos[i].lport && so->so_laddr_port == tcptos[i].lport)) {
- so->so_emu = tcptos[i].emu;
- return tcptos[i].tos;
- }
- i++;
- }
-
- return 0;
-}
-
-int do_echo = -1;
-
-/*
- * Emulate programs that try and connect to us
- * This includes ftp (the data connection is
- * initiated by the server) and IRC (DCC CHAT and
- * DCC SEND) for now
- *
- * NOTE: It's possible to crash SLiRP by sending it
- * unstandard strings to emulate... if this is a problem,
- * more checks are needed here
- *
- * XXX Assumes the whole command came in one packet
- *
- * XXX Some ftp clients will have their TOS set to
- * LOWDELAY and so Nagel will kick in. Because of this,
- * we'll get the first letter, followed by the rest, so
- * we simply scan for ORT instead of PORT...
- * DCC doesn't have this problem because there's other stuff
- * in the packet before the DCC command.
- *
- * Return 1 if the mbuf m is still valid and should be
- * sbuf_append()ed
- *
- * NOTE: if you return 0 you MUST mbuf_free() the mbuf!
- */
-int
-tcp_emu(so, m)
- struct socket *so;
- MBuf m;
-{
- u_int n1, n2, n3, n4, n5, n6;
- char buff[256];
- u_int32_t laddr;
- u_int lport;
- char *bptr;
-
- DEBUG_CALL("tcp_emu");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
-
- switch(so->so_emu) {
- int x, i;
-
- case EMU_IDENT:
- /*
- * Identification protocol as per rfc-1413
- */
-
- {
- struct socket *tmpso;
- SockAddress addr;
- SBuf so_rcv = &so->so_rcv;
-
- memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
- so_rcv->sb_wptr += m->m_len;
- so_rcv->sb_rptr += m->m_len;
- m->m_data[m->m_len] = 0; /* NULL terminate */
- if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) {
- if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) {
- /* n2 is the one on our host */
- for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
- if (tmpso->so_laddr_ip == so->so_laddr_ip &&
- tmpso->so_laddr_port == n2 &&
- tmpso->so_faddr_ip == so->so_faddr_ip &&
- tmpso->so_faddr_port == n1) {
- if (socket_get_address(tmpso->s, &addr) == 0)
- n2 = sock_address_get_port(&addr);
- break;
- }
- }
- }
- so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2);
- so_rcv->sb_rptr = so_rcv->sb_data;
- so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;
- }
- mbuf_free(m);
- return 0;
- }
-
- case EMU_FTP: /* ftp */
- *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */
- if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
- /*
- * Need to emulate the PORT command
- */
- x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
- &n1, &n2, &n3, &n4, &n5, &n6, buff);
- if (x < 6)
- return 1;
-
- laddr = (n1 << 24) | (n2 << 16) | (n3 << 8) | (n4);
- lport = (n5 << 8) | (n6);
-
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- n6 = so->so_faddr_port;
-
- n5 = (n6 >> 8) & 0xff;
- n6 &= 0xff;
-
- laddr = so->so_faddr_ip;
-
- n1 = ((laddr >> 24) & 0xff);
- n2 = ((laddr >> 16) & 0xff);
- n3 = ((laddr >> 8) & 0xff);
- n4 = (laddr & 0xff);
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
- n1, n2, n3, n4, n5, n6, x==7?buff:"");
- return 1;
- } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
- /*
- * Need to emulate the PASV response
- */
- x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]",
- &n1, &n2, &n3, &n4, &n5, &n6, buff);
- if (x < 6)
- return 1;
-
- laddr = (n1 << 24) | (n2 << 16) | (n3 << 8) | (n4);
- lport = (n5 << 8) | (n6);
-
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- n6 = so->so_faddr_port;
-
- n5 = (n6 >> 8) & 0xff;
- n6 &= 0xff;
-
- laddr = so->so_faddr_ip;
-
- n1 = ((laddr >> 24) & 0xff);
- n2 = ((laddr >> 16) & 0xff);
- n3 = ((laddr >> 8) & 0xff);
- n4 = (laddr & 0xff);
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
- n1, n2, n3, n4, n5, n6, x==7?buff:"");
-
- return 1;
- }
-
- return 1;
-
- case EMU_KSH:
- /*
- * The kshell (Kerberos rsh) and shell services both pass
- * a local port port number to carry signals to the server
- * and stderr to the client. It is passed at the beginning
- * of the connection as a NUL-terminated decimal ASCII string.
- */
- so->so_emu = 0;
- for (lport = 0, i = 0; i < m->m_len-1; ++i) {
- if (m->m_data[i] < '0' || m->m_data[i] > '9')
- return 1; /* invalid number */
- lport *= 10;
- lport += m->m_data[i] - '0';
- }
- if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
- (so = solisten(0, so->so_laddr_ip, lport, SS_FACCEPTONCE)) != NULL)
- m->m_len = sprintf(m->m_data, "%d", so->so_faddr_port)+1;
- return 1;
-
- case EMU_IRC:
- /*
- * Need to emulate DCC CHAT, DCC SEND and DCC MOVE
- */
- *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */
- if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)
- return 1;
-
- /* The %256s is for the broken mIRC */
- if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",
- (unsigned long) so->so_faddr_ip,
- so->so_faddr_port, 1);
- } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
- buff, (unsigned long)so->so_faddr_ip,
- so->so_faddr_port, n1, 1);
- } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
- if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
- return 1;
-
- m->m_len = bptr - m->m_data; /* Adjust length */
- m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",
- buff, (unsigned long)so->so_faddr_ip,
- so->so_faddr_port, n1, 1);
- }
- return 1;
-
- case EMU_REALAUDIO:
- /*
- * RealAudio emulation - JP. We must try to parse the incoming
- * data and try to find the two characters that contain the
- * port number. Then we redirect an udp port and replace the
- * number with the real port we got.
- *
- * The 1.0 beta versions of the player are not supported
- * any more.
- *
- * A typical packet for player version 1.0 (release version):
- *
- * 0000:50 4E 41 00 05
- * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....�..g�l�c..P
- * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH
- * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v
- * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB
- *
- * Now the port number 0x1BD7 is found at offset 0x04 of the
- * Now the port number 0x1BD7 is found at offset 0x04 of the
- * second packet. This time we received five bytes first and
- * then the rest. You never know how many bytes you get.
- *
- * A typical packet for player version 2.0 (beta):
- *
- * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........�.
- * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux�c..Win2.0.0
- * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/
- * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas
- * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B
- *
- * Port number 0x1BC1 is found at offset 0x0d.
- *
- * This is just a horrible switch statement. Variable ra tells
- * us where we're going.
- */
-
- bptr = m->m_data;
- while (bptr < m->m_data + m->m_len) {
- u_short p;
- static int ra = 0;
- char ra_tbl[4];
-
- ra_tbl[0] = 0x50;
- ra_tbl[1] = 0x4e;
- ra_tbl[2] = 0x41;
- ra_tbl[3] = 0;
-
- switch (ra) {
- case 0:
- case 2:
- case 3:
- if (*bptr++ != ra_tbl[ra]) {
- ra = 0;
- continue;
- }
- break;
-
- case 1:
- /*
- * We may get 0x50 several times, ignore them
- */
- if (*bptr == 0x50) {
- ra = 1;
- bptr++;
- continue;
- } else if (*bptr++ != ra_tbl[ra]) {
- ra = 0;
- continue;
- }
- break;
-
- case 4:
- /*
- * skip version number
- */
- bptr++;
- break;
-
- case 5:
- /*
- * The difference between versions 1.0 and
- * 2.0 is here. For future versions of
- * the player this may need to be modified.
- */
- if (*(bptr + 1) == 0x02)
- bptr += 8;
- else
- bptr += 4;
- break;
-
- case 6:
- /* This is the field containing the port
- * number that RA-player is listening to.
- */
- lport = (((u_char*)bptr)[0] << 8)
- + ((u_char *)bptr)[1];
- if (lport < 6970)
- lport += 256; /* don't know why */
- if (lport < 6970 || lport > 7170)
- return 1; /* failed */
-
- /* try to get udp port between 6970 - 7170 */
- for (p = 6970; p < 7071; p++) {
- if (udp_listen( p,
- so->so_laddr_ip,
- lport,
- SS_FACCEPTONCE)) {
- break;
- }
- }
- if (p == 7071)
- p = 0;
- *(u_char *)bptr++ = (p >> 8) & 0xff;
- *(u_char *)bptr++ = p & 0xff;
- ra = 0;
- return 1; /* port redirected, we're done */
- break;
-
- default:
- ra = 0;
- }
- ra++;
- }
- return 1;
-
- default:
- /* Ooops, not emulated, won't call tcp_emu again */
- so->so_emu = 0;
- return 1;
- }
-}
-
-/*
- * Do misc. config of SLiRP while its running.
- * Return 0 if this connections is to be closed, 1 otherwise,
- * return 2 if this is a command-line connection
- */
-int
-tcp_ctl(so)
- struct socket *so;
-{
- SBuf sb = &so->so_snd;
- int command;
-#if 0
- struct ex_list *ex_ptr;
- int do_pty;
-#endif
- // struct socket *tmpso;
-
- DEBUG_CALL("tcp_ctl");
- DEBUG_ARG("so = %lx", (long )so);
-
-#if 0
- /*
- * Check if they're authorised
- */
- if (ctl_addr_ip && (ctl_addr_ip == -1 || (so->so_laddr_ip != ctl_addr_ip))) {
- sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n");
- sb->sb_wptr += sb->sb_cc;
- return 0;
- }
-#endif
- command = (so->so_faddr_ip & 0xff);
-
- switch(command) {
- default:
- /*
- * Nothing bound..
- */
- /* tcp_fconnect(so); */
-
- case CTL_ALIAS:
- sb->sb_cc = sprintf(sb->sb_wptr,
- "Error: No application configured.\r\n");
- sb->sb_wptr += sb->sb_cc;
- return(0);
- }
-}
diff --git a/slirp2/tcp_timer.c b/slirp2/tcp_timer.c
deleted file mode 100644
index ad03098..0000000
--- a/slirp2/tcp_timer.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93
- * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp
- */
-
-#include <slirp.h>
-
-int tcp_keepidle = TCPTV_KEEP_IDLE;
-int tcp_keepintvl = TCPTV_KEEPINTVL;
-int tcp_maxidle;
-int so_options = DO_KEEPALIVE;
-
-struct tcpstat tcpstat; /* tcp statistics */
-u_int32_t tcp_now; /* for RFC 1323 timestamps */
-
-/*
- * Fast timeout routine for processing delayed acks
- */
-void
-tcp_fasttimo()
-{
- register struct socket *so;
- register struct tcpcb *tp;
-
- DEBUG_CALL("tcp_fasttimo");
-
- so = tcb.so_next;
- if (so)
- for (; so != &tcb; so = so->so_next)
- if ((tp = (struct tcpcb *)so->so_tcpcb) &&
- (tp->t_flags & TF_DELACK)) {
- tp->t_flags &= ~TF_DELACK;
- tp->t_flags |= TF_ACKNOW;
- tcpstat.tcps_delack++;
- (void) tcp_output(tp);
- }
-}
-
-/*
- * Tcp protocol timeout routine called every 500 ms.
- * Updates the timers in all active tcb's and
- * causes finite state machine actions if timers expire.
- */
-void
-tcp_slowtimo()
-{
- register struct socket *ip, *ipnxt;
- register struct tcpcb *tp;
- register int i;
-
- DEBUG_CALL("tcp_slowtimo");
-
- tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl;
- /*
- * Search through tcb's and update active timers.
- */
- ip = tcb.so_next;
- if (ip == 0)
- return;
- for (; ip != &tcb; ip = ipnxt) {
- ipnxt = ip->so_next;
- tp = sototcpcb(ip);
- if (tp == 0)
- continue;
- for (i = 0; i < TCPT_NTIMERS; i++) {
- if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
- tcp_timers(tp,i);
- if (ipnxt->so_prev != ip)
- goto tpgone;
- }
- }
- tp->t_idle++;
- if (tp->t_rtt)
- tp->t_rtt++;
-tpgone:
- ;
- }
- tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */
-#ifdef TCP_COMPAT_42
- if ((int)tcp_iss < 0)
- tcp_iss = 0; /* XXX */
-#endif
- tcp_now++; /* for timestamps */
-}
-
-/*
- * Cancel all timers for TCP tp.
- */
-void
-tcp_canceltimers(tp)
- struct tcpcb *tp;
-{
- register int i;
-
- for (i = 0; i < TCPT_NTIMERS; i++)
- tp->t_timer[i] = 0;
-}
-
-int tcp_backoff[TCP_MAXRXTSHIFT + 1] =
- { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 };
-
-/*
- * TCP timer processing.
- */
-struct tcpcb *
-tcp_timers(tp, timer)
- register struct tcpcb *tp;
- int timer;
-{
- register int rexmt;
-
- DEBUG_CALL("tcp_timers");
-
- switch (timer) {
-
- /*
- * 2 MSL timeout in shutdown went off. If we're closed but
- * still waiting for peer to close and connection has been idle
- * too long, or if 2MSL time is up from TIME_WAIT, delete connection
- * control block. Otherwise, check again in a bit.
- */
- case TCPT_2MSL:
- if (tp->t_state != TCPS_TIME_WAIT &&
- tp->t_idle <= tcp_maxidle)
- tp->t_timer[TCPT_2MSL] = tcp_keepintvl;
- else
- tp = tcp_close(tp);
- break;
-
- /*
- * Retransmission timer went off. Message has not
- * been acked within retransmit interval. Back off
- * to a longer retransmit interval and retransmit one segment.
- */
- case TCPT_REXMT:
-
- /*
- * XXXXX If a packet has timed out, then remove all the queued
- * packets for that session.
- */
-
- if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
- /*
- * This is a hack to suit our terminal server here at the uni of canberra
- * since they have trouble with zeroes... It usually lets them through
- * unharmed, but under some conditions, it'll eat the zeros. If we
- * keep retransmitting it, it'll keep eating the zeroes, so we keep
- * retransmitting, and eventually the connection dies...
- * (this only happens on incoming data)
- *
- * So, if we were gonna drop the connection from too many retransmits,
- * don't... instead halve the t_maxseg, which might break up the NULLs and
- * let them through
- *
- * *sigh*
- */
-
- tp->t_maxseg >>= 1;
- if (tp->t_maxseg < 32) {
- /*
- * We tried our best, now the connection must die!
- */
- tp->t_rxtshift = TCP_MAXRXTSHIFT;
- tcpstat.tcps_timeoutdrop++;
- tp = tcp_drop(tp, tp->t_softerror);
- /* tp->t_softerror : ETIMEDOUT); */ /* XXX */
- return (tp); /* XXX */
- }
-
- /*
- * Set rxtshift to 6, which is still at the maximum
- * backoff time
- */
- tp->t_rxtshift = 6;
- }
- tcpstat.tcps_rexmttimeo++;
- rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
- TCPT_RANGESET(tp->t_rxtcur, rexmt,
- (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
- tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
- /*
- * If losing, let the lower level know and try for
- * a better route. Also, if we backed off this far,
- * our srtt estimate is probably bogus. Clobber it
- * so we'll take the next rtt measurement as our srtt;
- * move the current srtt into rttvar to keep the current
- * retransmit times until then.
- */
- if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
-/* in_losing(tp->t_inpcb); */
- tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
- tp->t_srtt = 0;
- }
- tp->snd_nxt = tp->snd_una;
- /*
- * If timing a segment in this window, stop the timer.
- */
- tp->t_rtt = 0;
- /*
- * Close the congestion window down to one segment
- * (we'll open it by one segment for each ack we get).
- * Since we probably have a window's worth of unacked
- * data accumulated, this "slow start" keeps us from
- * dumping all that data as back-to-back packets (which
- * might overwhelm an intermediate gateway).
- *
- * There are two phases to the opening: Initially we
- * open by one mss on each ack. This makes the window
- * size increase exponentially with time. If the
- * window is larger than the path can handle, this
- * exponential growth results in dropped packet(s)
- * almost immediately. To get more time between
- * drops but still "push" the network to take advantage
- * of improving conditions, we switch from exponential
- * to linear window opening at some threshold size.
- * For a threshold, we use half the current window
- * size, truncated to a multiple of the mss.
- *
- * (the minimum cwnd that will give us exponential
- * growth is 2 mss. We don't allow the threshold
- * to go below this.)
- */
- {
- u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
- if (win < 2)
- win = 2;
- tp->snd_cwnd = tp->t_maxseg;
- tp->snd_ssthresh = win * tp->t_maxseg;
- tp->t_dupacks = 0;
- }
- (void) tcp_output(tp);
- break;
-
- /*
- * Persistence timer into zero window.
- * Force a byte to be output, if possible.
- */
- case TCPT_PERSIST:
- tcpstat.tcps_persisttimeo++;
- tcp_setpersist(tp);
- tp->t_force = 1;
- (void) tcp_output(tp);
- tp->t_force = 0;
- break;
-
- /*
- * Keep-alive timer went off; send something
- * or drop connection if idle for too long.
- */
- case TCPT_KEEP:
- tcpstat.tcps_keeptimeo++;
- if (tp->t_state < TCPS_ESTABLISHED)
- goto dropit;
-
-/* if (tp->t_socket->so_options & SO_KEEPALIVE && */
- if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) {
- if (tp->t_idle >= tcp_keepidle + tcp_maxidle)
- goto dropit;
- /*
- * Send a packet designed to force a response
- * if the peer is up and reachable:
- * either an ACK if the connection is still alive,
- * or an RST if the peer has closed the connection
- * due to timeout or reboot.
- * Using sequence number tp->snd_una-1
- * causes the transmitted zero-length segment
- * to lie outside the receive window;
- * by the protocol spec, this requires the
- * correspondent TCP to respond.
- */
- tcpstat.tcps_keepprobe++;
-#ifdef TCP_COMPAT_42
- /*
- * The keepalive packet must have nonzero length
- * to get a 4.2 host to respond.
- */
- tcp_respond(tp, &tp->t_template, (MBuf )NULL,
- tp->rcv_nxt - 1, tp->snd_una - 1, 0);
-#else
- tcp_respond(tp, &tp->t_template, (MBuf )NULL,
- tp->rcv_nxt, tp->snd_una - 1, 0);
-#endif
- tp->t_timer[TCPT_KEEP] = tcp_keepintvl;
- } else
- tp->t_timer[TCPT_KEEP] = tcp_keepidle;
- break;
-
- dropit:
- tcpstat.tcps_keepdrops++;
- tp = tcp_drop(tp, 0); /* ETIMEDOUT); */
- break;
- }
-
- return (tp);
-}
diff --git a/slirp2/tcp_timer.h b/slirp2/tcp_timer.h
deleted file mode 100644
index 59933bc..0000000
--- a/slirp2/tcp_timer.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93
- * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp
- */
-
-#ifndef _TCP_TIMER_H_
-#define _TCP_TIMER_H_
-
-/*
- * Definitions of the TCP timers. These timers are counted
- * down PR_SLOWHZ times a second.
- */
-#define TCPT_NTIMERS 4
-
-#define TCPT_REXMT 0 /* retransmit */
-#define TCPT_PERSIST 1 /* retransmit persistence */
-#define TCPT_KEEP 2 /* keep alive */
-#define TCPT_2MSL 3 /* 2*msl quiet time timer */
-
-/*
- * The TCPT_REXMT timer is used to force retransmissions.
- * The TCP has the TCPT_REXMT timer set whenever segments
- * have been sent for which ACKs are expected but not yet
- * received. If an ACK is received which advances tp->snd_una,
- * then the retransmit timer is cleared (if there are no more
- * outstanding segments) or reset to the base value (if there
- * are more ACKs expected). Whenever the retransmit timer goes off,
- * we retransmit one unacknowledged segment, and do a backoff
- * on the retransmit timer.
- *
- * The TCPT_PERSIST timer is used to keep window size information
- * flowing even if the window goes shut. If all previous transmissions
- * have been acknowledged (so that there are no retransmissions in progress),
- * and the window is too small to bother sending anything, then we start
- * the TCPT_PERSIST timer. When it expires, if the window is nonzero,
- * we go to transmit state. Otherwise, at intervals send a single byte
- * into the peer's window to force him to update our window information.
- * We do this at most as often as TCPT_PERSMIN time intervals,
- * but no more frequently than the current estimate of round-trip
- * packet time. The TCPT_PERSIST timer is cleared whenever we receive
- * a window update from the peer.
- *
- * The TCPT_KEEP timer is used to keep connections alive. If an
- * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time,
- * but not yet established, then we drop the connection. Once the connection
- * is established, if the connection is idle for TCPTV_KEEP_IDLE time
- * (and keepalives have been enabled on the socket), we begin to probe
- * the connection. We force the peer to send us a segment by sending:
- * <SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
- * This segment is (deliberately) outside the window, and should elicit
- * an ack segment in response from the peer. If, despite the TCPT_KEEP
- * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE
- * amount of time probing, then we drop the connection.
- */
-
-/*
- * Time constants.
- */
-#define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */
-
-#define TCPTV_SRTTBASE 0 /* base roundtrip time;
- if 0, no idea yet */
-#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */
-
-#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */
-#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */
-
-#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */
-#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */
-#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */
-#define TCPTV_KEEPCNT 8 /* max probes before drop */
-
-#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */
-/* #define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) */ /* max allowable REXMT value */
-#define TCPTV_REXMTMAX ( 12*PR_SLOWHZ) /* max allowable REXMT value */
-
-#define TCP_LINGERTIME 120 /* linger at most 2 minutes */
-
-#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
-
-
-#ifdef TCPTIMERS
-char *tcptimers[] =
- { "REXMT", "PERSIST", "KEEP", "2MSL" };
-#endif
-
-/*
- * Force a time value to be in a certain range.
- */
-#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \
- (tv) = (value); \
- if ((tv) < (tvmin)) \
- (tv) = (tvmin); \
- else if ((tv) > (tvmax)) \
- (tv) = (tvmax); \
-}
-
-extern int tcp_keepidle; /* time before keepalive probes begin */
-extern int tcp_keepintvl; /* time between keepalive probes */
-extern int tcp_maxidle; /* time to drop after starting probes */
-extern int tcp_ttl; /* time to live for TCP segs */
-extern int tcp_backoff[];
-
-struct tcpcb;
-
-void tcp_fasttimo _P((void));
-void tcp_slowtimo _P((void));
-void tcp_canceltimers _P((struct tcpcb *));
-struct tcpcb * tcp_timers _P((register struct tcpcb *, int));
-
-#endif
diff --git a/slirp2/tcp_var.h b/slirp2/tcp_var.h
deleted file mode 100644
index 3509ec8..0000000
--- a/slirp2/tcp_var.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94
- * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp
- */
-
-#ifndef _TCP_VAR_H_
-#define _TCP_VAR_H_
-
-#include "mbuf.h"
-#include "tcpip.h"
-#include "tcp_timer.h"
-
-/*
- * Tcp control block, one per tcp; fields:
- */
-struct tcpcb {
- struct tcpiphdr *seg_next; /* sequencing queue */
- struct tcpiphdr *seg_prev;
- short t_state; /* state of this connection */
- short t_timer[TCPT_NTIMERS]; /* tcp timers */
- short t_rxtshift; /* log(2) of rexmt exp. backoff */
- short t_rxtcur; /* current retransmit value */
- short t_dupacks; /* consecutive dup acks recd */
- u_short t_maxseg; /* maximum segment size */
- char t_force; /* 1 if forcing out a byte */
- u_short t_flags;
-#define TF_ACKNOW 0x0001 /* ack peer immediately */
-#define TF_DELACK 0x0002 /* ack, but try to delay it */
-#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */
-#define TF_NOOPT 0x0008 /* don't use tcp options */
-#define TF_SENTFIN 0x0010 /* have sent FIN */
-#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */
-#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */
-#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */
-#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */
-#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */
-
- /* Make it static for now */
-/* struct tcpiphdr *t_template; / * skeletal packet for transmit */
- struct tcpiphdr t_template;
-
- struct socket *t_socket; /* back pointer to socket */
-/*
- * The following fields are used as in the protocol specification.
- * See RFC783, Dec. 1981, page 21.
- */
-/* send sequence variables */
- tcp_seq snd_una; /* send unacknowledged */
- tcp_seq snd_nxt; /* send next */
- tcp_seq snd_up; /* send urgent pointer */
- tcp_seq snd_wl1; /* window update seg seq number */
- tcp_seq snd_wl2; /* window update seg ack number */
- tcp_seq iss; /* initial send sequence number */
- u_int32_t snd_wnd; /* send window */
-/* receive sequence variables */
- u_int32_t rcv_wnd; /* receive window */
- tcp_seq rcv_nxt; /* receive next */
- tcp_seq rcv_up; /* receive urgent pointer */
- tcp_seq irs; /* initial receive sequence number */
-/*
- * Additional variables for this implementation.
- */
-/* receive variables */
- tcp_seq rcv_adv; /* advertised window */
-/* retransmit variables */
- tcp_seq snd_max; /* highest sequence number sent;
- * used to recognize retransmits
- */
-/* congestion control (for slow start, source quench, retransmit after loss) */
- u_int32_t snd_cwnd; /* congestion-controlled window */
- u_int32_t snd_ssthresh; /* snd_cwnd size threshold for
- * for slow start exponential to
- * linear switch
- */
-/*
- * transmit timing stuff. See below for scale of srtt and rttvar.
- * "Variance" is actually smoothed difference.
- */
- short t_idle; /* inactivity time */
- short t_rtt; /* round trip time */
- tcp_seq t_rtseq; /* sequence number being timed */
- short t_srtt; /* smoothed round-trip time */
- short t_rttvar; /* variance in round-trip time */
- u_short t_rttmin; /* minimum rtt allowed */
- u_int32_t max_sndwnd; /* largest window peer has offered */
-
-/* out-of-band data */
- char t_oobflags; /* have some */
- char t_iobc; /* input character */
-#define TCPOOB_HAVEDATA 0x01
-#define TCPOOB_HADDATA 0x02
- short t_softerror; /* possible error not yet reported */
-
-/* RFC 1323 variables */
- u_char snd_scale; /* window scaling for send window */
- u_char rcv_scale; /* window scaling for recv window */
- u_char request_r_scale; /* pending window scaling */
- u_char requested_s_scale;
- u_int32_t ts_recent; /* timestamp echo data */
- u_int32_t ts_recent_age; /* when last updated */
- tcp_seq last_ack_sent;
-
-};
-
-#define sototcpcb(so) ((so)->so_tcpcb)
-
-/*
- * The smoothed round-trip time and estimated variance
- * are stored as fixed point numbers scaled by the values below.
- * For convenience, these scales are also used in smoothing the average
- * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed).
- * With these scales, srtt has 3 bits to the right of the binary point,
- * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the
- * binary point, and is smoothed with an ALPHA of 0.75.
- */
-#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */
-#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */
-#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */
-#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */
-
-/*
- * The initial retransmission should happen at rtt + 4 * rttvar.
- * Because of the way we do the smoothing, srtt and rttvar
- * will each average +1/2 tick of bias. When we compute
- * the retransmit timer, we want 1/2 tick of rounding and
- * 1 extra tick because of +-1/2 tick uncertainty in the
- * firing of the timer. The bias will give us exactly the
- * 1.5 tick we need. But, because the bias is
- * statistical, we have to test that we don't drop below
- * the minimum feasible timer (which is 2 ticks).
- * This macro assumes that the value of TCP_RTTVAR_SCALE
- * is the same as the multiplier for rttvar.
- */
-#define TCP_REXMTVAL(tp) \
- (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
-
-/*
- * TCP statistics.
- * Many of these should be kept per connection,
- * but that's inconvenient at the moment.
- */
-struct tcpstat {
- u_long tcps_connattempt; /* connections initiated */
- u_long tcps_accepts; /* connections accepted */
- u_long tcps_connects; /* connections established */
- u_long tcps_drops; /* connections dropped */
- u_long tcps_conndrops; /* embryonic connections dropped */
- u_long tcps_closed; /* conn. closed (includes drops) */
- u_long tcps_segstimed; /* segs where we tried to get rtt */
- u_long tcps_rttupdated; /* times we succeeded */
- u_long tcps_delack; /* delayed acks sent */
- u_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */
- u_long tcps_rexmttimeo; /* retransmit timeouts */
- u_long tcps_persisttimeo; /* persist timeouts */
- u_long tcps_keeptimeo; /* keepalive timeouts */
- u_long tcps_keepprobe; /* keepalive probes sent */
- u_long tcps_keepdrops; /* connections dropped in keepalive */
-
- u_long tcps_sndtotal; /* total packets sent */
- u_long tcps_sndpack; /* data packets sent */
- u_long tcps_sndbyte; /* data bytes sent */
- u_long tcps_sndrexmitpack; /* data packets retransmitted */
- u_long tcps_sndrexmitbyte; /* data bytes retransmitted */
- u_long tcps_sndacks; /* ack-only packets sent */
- u_long tcps_sndprobe; /* window probes sent */
- u_long tcps_sndurg; /* packets sent with URG only */
- u_long tcps_sndwinup; /* window update-only packets sent */
- u_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */
-
- u_long tcps_rcvtotal; /* total packets received */
- u_long tcps_rcvpack; /* packets received in sequence */
- u_long tcps_rcvbyte; /* bytes received in sequence */
- u_long tcps_rcvbadsum; /* packets received with ccksum errs */
- u_long tcps_rcvbadoff; /* packets received with bad offset */
-/* u_long tcps_rcvshort; */ /* packets received too short */
- u_long tcps_rcvduppack; /* duplicate-only packets received */
- u_long tcps_rcvdupbyte; /* duplicate-only bytes received */
- u_long tcps_rcvpartduppack; /* packets with some duplicate data */
- u_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */
- u_long tcps_rcvoopack; /* out-of-order packets received */
- u_long tcps_rcvoobyte; /* out-of-order bytes received */
- u_long tcps_rcvpackafterwin; /* packets with data after window */
- u_long tcps_rcvbyteafterwin; /* bytes rcvd after window */
- u_long tcps_rcvafterclose; /* packets rcvd after "close" */
- u_long tcps_rcvwinprobe; /* rcvd window probe packets */
- u_long tcps_rcvdupack; /* rcvd duplicate acks */
- u_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */
- u_long tcps_rcvackpack; /* rcvd ack packets */
- u_long tcps_rcvackbyte; /* bytes acked by rcvd acks */
- u_long tcps_rcvwinupd; /* rcvd window update packets */
-/* u_long tcps_pawsdrop; */ /* segments dropped due to PAWS */
- u_long tcps_predack; /* times hdr predict ok for acks */
- u_long tcps_preddat; /* times hdr predict ok for data pkts */
- u_long tcps_socachemiss; /* tcp_last_so misses */
- u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */
-};
-
-extern struct tcpstat tcpstat; /* tcp statistics */
-extern u_int32_t tcp_now; /* for RFC 1323 timestamps */
-
-#endif
diff --git a/slirp2/tcpip.h b/slirp2/tcpip.h
deleted file mode 100644
index 891d699..0000000
--- a/slirp2/tcpip.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tcpip.h 8.1 (Berkeley) 6/10/93
- * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp
- */
-
-#ifndef _TCPIP_H_
-#define _TCPIP_H_
-
-/*
- * Tcp+ip header, after ip options removed.
- */
-struct tcpiphdr {
- struct ipovly ti_i; /* overlaid ip structure */
- struct tcphdr ti_t; /* tcp header */
-};
-#define ti_mbuf ti_i.ih_mbuf.mptr
-#define ti_x1 ti_i.ih_x1
-#define ti_pr ti_i.ih_pr
-#define ti_len ti_i.ih_len
-#define ti_src ti_i.ih_src
-#define ti_dst ti_i.ih_dst
-#define ti_sport ti_t.th_sport
-#define ti_dport ti_t.th_dport
-#define ti_seq ti_t.th_seq
-#define ti_ack ti_t.th_ack
-#define ti_x2 ti_t.th_x2
-#define ti_off ti_t.th_off
-#define ti_flags ti_t.th_flags
-#define ti_win ti_t.th_win
-#define ti_sum ti_t.th_sum
-#define ti_urp ti_t.th_urp
-
-#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink)))
-#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink)))
-#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next)
-#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev)
-#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next)
-#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T))
-#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T))
-
-/*
- * Just a clean way to get to the first byte
- * of the packet
- */
-struct tcpiphdr_2 {
- struct tcpiphdr dummy;
- char first_char;
-};
-
-#endif
diff --git a/slirp2/tftp.c b/slirp2/tftp.c
deleted file mode 100644
index 37933d9..0000000
--- a/slirp2/tftp.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * tftp.c - a simple, read-only tftp server for qemu
- *
- * Copyright (c) 2004 Magnus Damm <damm@opensource.se>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <slirp.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-struct tftp_session {
- int in_use;
- unsigned char filename[TFTP_FILENAME_MAX];
-
- uint32_t client_ip;
- uint16_t client_port;
-
- int timestamp;
-};
-
-struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
-
-const char *tftp_prefix;
-
-static void tftp_session_update(struct tftp_session *spt)
-{
- spt->timestamp = curtime;
- spt->in_use = 1;
-}
-
-static void tftp_session_terminate(struct tftp_session *spt)
-{
- spt->in_use = 0;
-}
-
-static int tftp_session_allocate(struct tftp_t *tp)
-{
- struct tftp_session *spt;
- int k;
-
- for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
- spt = &tftp_sessions[k];
-
- if (!spt->in_use)
- goto found;
-
- /* sessions time out after 5 inactive seconds */
- if ((int)(curtime - spt->timestamp) > 5000)
- goto found;
- }
-
- return -1;
-
- found:
- memset(spt, 0, sizeof(*spt));
- spt->client_ip = ip_geth(tp->ip.ip_src);
- spt->client_port = port_geth(tp->udp.uh_sport);
-
- tftp_session_update(spt);
-
- return k;
-}
-
-static int tftp_session_find(struct tftp_t *tp)
-{
- struct tftp_session *spt;
- int k;
-
- for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
- spt = &tftp_sessions[k];
-
- if (spt->in_use) {
- if (spt->client_ip == ip_geth(tp->ip.ip_src)) {
- if (spt->client_port == port_geth(tp->udp.uh_sport)) {
- return k;
- }
- }
- }
- }
-
- return -1;
-}
-
-static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr,
- u_int8_t *buf, int len)
-{
- int fd;
- int bytes_read = 0;
- char buffer[1024];
- int n;
-
- n = snprintf(buffer, sizeof(buffer), "%s/%s",
- tftp_prefix, spt->filename);
- if (n >= sizeof(buffer))
- return -1;
-
- fd = open(buffer, O_RDONLY | O_BINARY);
-
- if (fd < 0) {
- return -1;
- }
-
- if (len) {
- lseek(fd, block_nr * 512, SEEK_SET);
-
- bytes_read = read(fd, buf, len);
- }
-
- close(fd);
-
- return bytes_read;
-}
-
-static int tftp_send_oack(struct tftp_session *spt,
- const char *key, uint32_t value,
- struct tftp_t *recv_tp)
-{
- SockAddress saddr, daddr;
- MBuf m;
- struct tftp_t *tp;
- int n = 0;
-
- m = mbuf_alloc();
-
- if (!m)
- return -1;
-
- memset(m->m_data, 0, m->m_size);
-
- m->m_data += if_maxlinkhdr;
- tp = (void *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
-
- tp->tp_op = htons(TFTP_OACK);
- n += sprintf((char*)tp->x.tp_buf + n, "%s", key) + 1;
- n += sprintf((char*)tp->x.tp_buf + n, "%u", value) + 1;
-
- sock_address_init_inet( &saddr,
- ip_geth(recv_tp->ip.ip_dst),
- port_geth(recv_tp->udp.uh_dport) );
-
- sock_address_init_inet( &daddr,
- spt->client_ip,
- spt->client_port );
-
- m->m_len = sizeof(struct tftp_t) - 514 + n -
- sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-
- return 0;
-}
-
-
-
-static int tftp_send_error(struct tftp_session *spt,
- u_int16_t errorcode, const char *msg,
- struct tftp_t *recv_tp)
-{
- SockAddress saddr, daddr;
- MBuf m;
- struct tftp_t *tp;
- int nobytes;
-
- m = mbuf_alloc();
-
- if (!m) {
- return -1;
- }
-
- memset(m->m_data, 0, m->m_size);
-
- m->m_data += if_maxlinkhdr;
- tp = (void *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
-
- tp->tp_op = htons(TFTP_ERROR);
- tp->x.tp_error.tp_error_code = htons(errorcode);
- strcpy((char*)tp->x.tp_error.tp_msg, msg);
-
- sock_address_init_inet( &saddr,
- ip_geth(recv_tp->ip.ip_dst),
- port_geth(recv_tp->udp.uh_dport) );
-
- sock_address_init_inet( &daddr,
- spt->client_ip,
- spt->client_port );
-
- nobytes = 2;
-
- m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
- sizeof(struct ip) - sizeof(struct udphdr);
-
- udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-
- tftp_session_terminate(spt);
-
- return 0;
-}
-
-static int tftp_send_data(struct tftp_session *spt,
- u_int16_t block_nr,
- struct tftp_t *recv_tp)
-{
- SockAddress saddr, daddr;
- MBuf m;
- struct tftp_t *tp;
- int nobytes;
-
- if (block_nr < 1) {
- return -1;
- }
-
- m = mbuf_alloc();
-
- if (!m) {
- return -1;
- }
-
- memset(m->m_data, 0, m->m_size);
-
- m->m_data += if_maxlinkhdr;
- tp = (void *)m->m_data;
- m->m_data += sizeof(struct udpiphdr);
-
- tp->tp_op = htons(TFTP_DATA);
- tp->x.tp_data.tp_block_nr = htons(block_nr);
-
- sock_address_init_inet( &saddr,
- ip_geth(recv_tp->ip.ip_dst),
- port_geth(recv_tp->udp.uh_dport) );
-
- sock_address_init_inet( &daddr,
- spt->client_ip,
- spt->client_port );
-
- nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);
-
- if (nobytes < 0) {
- mbuf_free(m);
-
- /* send "file not found" error back */
-
- tftp_send_error(spt, 1, "File not found", tp);
-
- return -1;
- }
-
- m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
- sizeof(struct ip) - sizeof(struct udphdr);
-
- udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
-
- if (nobytes == 512) {
- tftp_session_update(spt);
- }
- else {
- tftp_session_terminate(spt);
- }
-
- return 0;
-}
-
-static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
-{
- struct tftp_session *spt;
- int s, k, n;
- u_int8_t *src, *dst;
-
- s = tftp_session_allocate(tp);
-
- if (s < 0) {
- return;
- }
-
- spt = &tftp_sessions[s];
-
- src = tp->x.tp_buf;
- dst = spt->filename;
- n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);
-
- /* get name */
-
- for (k = 0; k < n; k++) {
- if (k < TFTP_FILENAME_MAX) {
- dst[k] = src[k];
- }
- else {
- return;
- }
-
- if (src[k] == '\0') {
- break;
- }
- }
-
- if (k >= n) {
- return;
- }
-
- k++;
-
- /* check mode */
- if ((n - k) < 6) {
- return;
- }
-
- if (memcmp(&src[k], "octet\0", 6) != 0) {
- tftp_send_error(spt, 4, "Unsupported transfer mode", tp);
- return;
- }
-
- k += 6; /* skipping octet */
-
- /* do sanity checks on the filename */
-
- if ((spt->filename[0] != '/')
- || (spt->filename[strlen((const char*)spt->filename) - 1] == '/')
- || strstr((const char*)spt->filename, "/../")) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- /* only allow exported prefixes */
-
- if (!tftp_prefix) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- /* check if the file exists */
-
- if (tftp_read_data(spt, 0, spt->filename, 0) < 0) {
- tftp_send_error(spt, 1, "File not found", tp);
- return;
- }
-
- if (src[n - 1] != 0) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- while (k < n) {
- const char *key, *value;
-
- key = (const char*)src + k;
- k += strlen(key) + 1;
-
- if (k >= n) {
- tftp_send_error(spt, 2, "Access violation", tp);
- return;
- }
-
- value = (const char*)src + k;
- k += strlen(value) + 1;
-
- if (strcmp(key, "tsize") == 0) {
- int tsize = atoi(value);
- struct stat stat_p;
-
- if (tsize == 0 && tftp_prefix) {
- char buffer[1024];
- int len;
-
- len = snprintf(buffer, sizeof(buffer), "%s/%s",
- tftp_prefix, spt->filename);
-
- if (stat(buffer, &stat_p) == 0)
- tsize = stat_p.st_size;
- else {
- tftp_send_error(spt, 1, "File not found", tp);
- return;
- }
- }
-
- tftp_send_oack(spt, "tsize", tsize, tp);
- }
- }
-
- tftp_send_data(spt, 1, tp);
-}
-
-static void tftp_handle_ack(struct tftp_t *tp, int pktlen)
-{
- int s;
-
- s = tftp_session_find(tp);
-
- if (s < 0) {
- return;
- }
-
- if (tftp_send_data(&tftp_sessions[s],
- ntohs(tp->x.tp_data.tp_block_nr) + 1,
- tp) < 0) {
- return;
- }
-}
-
-void tftp_input(MBuf m)
-{
- struct tftp_t *tp = (struct tftp_t *)m->m_data;
-
- switch(ntohs(tp->tp_op)) {
- case TFTP_RRQ:
- tftp_handle_rrq(tp, m->m_len);
- break;
-
- case TFTP_ACK:
- tftp_handle_ack(tp, m->m_len);
- break;
- }
-}
diff --git a/slirp2/tftp.h b/slirp2/tftp.h
deleted file mode 100644
index 06018a7..0000000
--- a/slirp2/tftp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* tftp defines */
-
-#define TFTP_SESSIONS_MAX 3
-
-#define TFTP_SERVER 69
-
-#define TFTP_RRQ 1
-#define TFTP_WRQ 2
-#define TFTP_DATA 3
-#define TFTP_ACK 4
-#define TFTP_ERROR 5
-#define TFTP_OACK 6
-
-#define TFTP_FILENAME_MAX 512
-
-struct tftp_t {
- struct ip ip;
- struct udphdr udp;
- u_int16_t tp_op;
- union {
- struct {
- u_int16_t tp_block_nr;
- u_int8_t tp_buf[512];
- } tp_data;
- struct {
- u_int16_t tp_error_code;
- u_int8_t tp_msg[512];
- } tp_error;
- u_int8_t tp_buf[512 + 2];
- } x;
-};
-
-void tftp_input(MBuf m);
diff --git a/slirp2/udp.c b/slirp2/udp.c
deleted file mode 100644
index 9305cfd..0000000
--- a/slirp2/udp.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1988, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94
- * udp_usrreq.c,v 1.4 1994/10/02 17:48:45 phk Exp
- */
-
-/*
- * Changes and additions relating to SLiRP
- * Copyright (c) 1995 Danny Gasparovski.
- *
- * Please read the file COPYRIGHT for the
- * terms and conditions of the copyright.
- */
-
-#include <slirp.h>
-#include "ip_icmp.h"
-#define SLIRP_COMPILATION 1
-#include "sockets.h"
-
-struct udpstat udpstat;
-
-struct socket udb;
-
-/*
- * UDP protocol implementation.
- * Per RFC 768, August, 1980.
- */
-#ifndef COMPAT_42
-int udpcksum = 1;
-#else
-int udpcksum = 0; /* XXX */
-#endif
-
-struct socket *udp_last_so = &udb;
-
-void
-udp_init()
-{
- udb.so_next = udb.so_prev = &udb;
-}
-/* m->m_data points at ip packet header
- * m->m_len length ip packet
- * ip->ip_len length data (IPDU)
- */
-void
-udp_input(m, iphlen)
- register MBuf m;
- int iphlen;
-{
- register struct ip *ip;
- register struct udphdr *uh;
-/* MBuf opts = 0;*/
- int len;
- struct ip save_ip;
- struct socket *so;
-
- DEBUG_CALL("udp_input");
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("iphlen = %d", iphlen);
-
- udpstat.udps_ipackets++;
-
- /*
- * Strip IP options, if any; should skip this,
- * make available to user, and use on returned packets,
- * but we don't yet have a way to check the checksum
- * with options still present.
- */
- if(iphlen > sizeof(struct ip)) {
- ip_stripoptions(m, (MBuf )0);
- iphlen = sizeof(struct ip);
- }
-
- /*
- * Get IP and UDP header together in first mbuf.
- */
- ip = MBUF_TO(m, struct ip *);
- uh = (struct udphdr *)((caddr_t)ip + iphlen);
-
- /*
- * Make mbuf data length reflect UDP length.
- * If not enough data to reflect UDP length, drop.
- */
- len = ntohs((u_int16_t)uh->uh_ulen);
-
- if (ip->ip_len != len) {
- if (len > ip->ip_len) {
- udpstat.udps_badlen++;
- goto bad;
- }
- mbuf_trim(m, len - ip->ip_len);
- ip->ip_len = len;
- }
-
- /*
- * Save a copy of the IP header in case we want restore it
- * for sending an ICMP error message in response.
- */
- save_ip = *ip;
- save_ip.ip_len+= iphlen; /* tcp_input subtracts this */
-
- /*
- * Checksum extended UDP header and data.
- */
- if (udpcksum && uh->uh_sum) {
- memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr));
- ((struct ipovly *)ip)->ih_x1 = 0;
- ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
- /* keep uh_sum for ICMP reply
- * uh->uh_sum = cksum(m, len + sizeof (struct ip));
- * if (uh->uh_sum) {
- */
- if(cksum(m, len + sizeof(struct ip))) {
- udpstat.udps_badsum++;
- goto bad;
- }
- }
-
- /*
- * handle DHCP/BOOTP
- */
- if (port_geth(uh->uh_dport) == BOOTP_SERVER) {
- bootp_input(m);
- goto bad;
- }
-
- /*
- * handle TFTP
- */
- if (port_geth(uh->uh_dport) == TFTP_SERVER) {
- tftp_input(m);
- goto bad;
- }
-
- /*
- * Locate pcb for datagram.
- */
- so = udp_last_so;
- if (so->so_laddr_port != port_geth(uh->uh_sport) ||
- so->so_laddr_ip != ip_geth(ip->ip_src)) {
- struct socket *tmp;
-
- for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) {
- if (tmp->so_laddr_port == port_geth(uh->uh_sport) &&
- tmp->so_laddr_ip == ip_geth(ip->ip_src)) {
- tmp->so_faddr_ip = ip_geth(ip->ip_dst);
- tmp->so_faddr_port = port_geth(uh->uh_dport);
- so = tmp;
- break;
- }
- }
- if (tmp == &udb) {
- so = NULL;
- } else {
- udpstat.udpps_pcbcachemiss++;
- udp_last_so = so;
- }
- }
-
- if (so == NULL) {
- /*
- * If there's no socket for this packet,
- * create one
- */
- if ((so = socreate()) == NULL) goto bad;
- if(udp_attach(so) == -1) {
- DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
- errno,errno_str));
- sofree(so);
- goto bad;
- }
-
- /*
- * Setup fields
- */
- /* udp_last_so = so; */
- so->so_laddr_ip = ip_geth(ip->ip_src);
- so->so_laddr_port = port_geth(uh->uh_sport);
-
- if ((so->so_iptos = udp_tos(so)) == 0)
- so->so_iptos = ip->ip_tos;
-
- /*
- * XXXXX Here, check if it's in udpexec_list,
- * and if it is, do the fork_exec() etc.
- */
- }
-
- so->so_faddr_ip = ip_geth(ip->ip_dst); /* XXX */
- so->so_faddr_port = port_geth(uh->uh_dport); /* XXX */
-
- iphlen += sizeof(struct udphdr);
- m->m_len -= iphlen;
- m->m_data += iphlen;
-
- /*
- * Now we sendto() the packet.
- */
- if (so->so_emu)
- udp_emu(so, m);
-
- if(sosendto(so,m) == -1) {
- m->m_len += iphlen;
- m->m_data -= iphlen;
- *ip=save_ip;
- DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno, errno_str));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,errno_str);
- }
-
- mbuf_free(so->so_m); /* used for ICMP if error on sorecvfrom */
-
- /* restore the orig mbuf packet */
- m->m_len += iphlen;
- m->m_data -= iphlen;
- *ip=save_ip;
- so->so_m=m; /* ICMP backup */
-
- return;
-bad:
- mbuf_free(m);
- /* if (opts) mbuf_free(opts); */
- return;
-}
-
-int udp_output2_(struct socket* so, MBuf m,
- const SockAddress* saddr,
- const SockAddress* daddr,
- int iptos)
-{
- register struct udpiphdr *ui;
- uint32_t saddr_ip = sock_address_get_ip(saddr);
- uint32_t daddr_ip = sock_address_get_ip(daddr);
- int saddr_port = sock_address_get_port(saddr);
- int daddr_port = sock_address_get_port(daddr);
- int error = 0;
-
- DEBUG_CALL("udp_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
- DEBUG_ARG("saddr = %lx", (long) saddr_ip);
- DEBUG_ARG("daddr = %lx", (long) daddr_ip);
-
- /*
- * Adjust for header
- */
- m->m_data -= sizeof(struct udpiphdr);
- m->m_len += sizeof(struct udpiphdr);
-
- /*
- * Fill in mbuf with extended UDP header
- * and addresses and length put into network format.
- */
- ui = MBUF_TO(m, struct udpiphdr *);
- memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
- ui->ui_x1 = 0;
- ui->ui_pr = IPPROTO_UDP;
- ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
- /* XXXXX Check for from-one-location sockets, or from-any-location sockets */
- ui->ui_src = ip_seth(saddr_ip);
- ui->ui_dst = ip_seth(daddr_ip);
- ui->ui_sport = port_seth(saddr_port);
- ui->ui_dport = port_seth(daddr_port);
- ui->ui_ulen = ui->ui_len;
-
- /*
- * Stuff checksum and output datagram.
- */
- ui->ui_sum = 0;
- if (udpcksum) {
- if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0)
- ui->ui_sum = 0xffff;
- }
- ((struct ip *)ui)->ip_len = m->m_len;
-
- ((struct ip *)ui)->ip_ttl = ip_defttl;
- ((struct ip *)ui)->ip_tos = iptos;
-
- udpstat.udps_opackets++;
-
- error = ip_output(so, m);
-
- return (error);
-}
-
-int udp_output_(struct socket *so, MBuf m, SockAddress* from)
-{
- SockAddress saddr, daddr;
- uint32_t saddr_ip;
- uint16_t saddr_port;
-
- saddr_ip = sock_address_get_ip(from);
- saddr_port = sock_address_get_port(from);
-
- if ((so->so_faddr_ip & 0xffffff00) == special_addr_ip) {
- saddr_ip = so->so_faddr_ip;
- if ((so->so_faddr_ip & 0x000000ff) == 0xff)
- saddr_ip = alias_addr_ip;
- }
-
- sock_address_init_inet( &saddr, saddr_ip, saddr_port );
- sock_address_init_inet( &daddr, so->so_laddr_ip, so->so_laddr_port );
-
- return udp_output2_(so, m, &saddr, &daddr, so->so_iptos);
-}
-
-int
-udp_attach(so)
- struct socket *so;
-{
- so->s = socket_anyaddr_server( 0, SOCKET_DGRAM );
- if (so->s != -1) {
- /* success, insert in queue */
- so->so_expire = curtime + SO_EXPIRE;
- insque(so,&udb);
- }
- return(so->s);
-}
-
-void
-udp_detach(so)
- struct socket *so;
-{
- socket_close(so->s);
- /* if (so->so_m) mbuf_free(so->so_m); done by sofree */
-
- sofree(so);
-}
-
-struct tos_t udptos[] = {
- {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */
- {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */
- {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */
- {0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME}, /* Cu-Seeme */
- {0, 0, 0, 0}
-};
-
-u_int8_t
-udp_tos(so)
- struct socket *so;
-{
- int i = 0;
-
- while(udptos[i].tos) {
- if ((udptos[i].fport && so->so_faddr_port == udptos[i].fport) ||
- (udptos[i].lport && so->so_laddr_port == udptos[i].lport)) {
- so->so_emu = udptos[i].emu;
- return udptos[i].tos;
- }
- i++;
- }
-
- return 0;
-}
-
-/*
- * Here, talk/ytalk/ntalk requests must be emulated
- */
-void
-udp_emu(so, m)
- struct socket *so;
- MBuf m;
-{
- SockAddress sockaddr;
-
-struct cu_header {
- uint16_t d_family; // destination family
- uint16_t d_port; // destination port
- uint32_t d_addr; // destination address
- uint16_t s_family; // source family
- uint16_t s_port; // source port
- uint32_t so_addr; // source address
- uint32_t seqn; // sequence number
- uint16_t message; // message
- uint16_t data_type; // data type
- uint16_t pkt_len; // packet length
-} *cu_head;
-
- switch(so->so_emu) {
-
- case EMU_CUSEEME:
-
- /*
- * Cu-SeeMe emulation.
- * Hopefully the packet is more that 16 bytes long. We don't
- * do any other tests, just replace the address and port
- * fields.
- */
- if (m->m_len >= sizeof (*cu_head)) {
- if (socket_get_address(so->s, &sockaddr) < 0)
- return;
-
- cu_head = MBUF_TO(m, struct cu_header *);
- cu_head->s_port = htons( sock_address_get_port(&sockaddr));
- cu_head->so_addr = htonl( sock_address_get_ip(&sockaddr));
- }
-
- return;
- }
-}
-
-struct socket *
-udp_listen(port, laddr, lport, flags)
- u_int port;
- u_int32_t laddr;
- u_int lport;
- int flags;
-{
- struct socket *so;
- SockAddress addr;
- uint32_t addr_ip;
-
- if ((so = socreate()) == NULL) {
- free(so);
- return NULL;
- }
- so->s = socket_anyaddr_server( port, SOCKET_DGRAM );
- so->so_expire = curtime + SO_EXPIRE;
- so->so_haddr_port = port;
- insque(so,&udb);
-
- if (so->s < 0) {
- udp_detach(so);
- return NULL;
- }
-
- socket_get_address(so->s, &addr);
-
- so->so_faddr_port = sock_address_get_port(&addr);
- addr_ip = sock_address_get_ip(&addr);
-
- if (addr_ip == 0 || addr_ip == loopback_addr_ip)
- so->so_faddr_ip = alias_addr_ip;
- else
- so->so_faddr_ip = addr_ip;
-
- so->so_laddr_port = lport;
- so->so_laddr_ip = laddr;
- if (flags != SS_FACCEPTONCE)
- so->so_expire = 0;
-
- so->so_state = SS_ISFCONNECTED;
-
- return so;
-}
-
-int udp_unlisten (u_int port)
-{
- struct socket *so;
-
- for (so = udb.so_next; so != &udb; so = so->so_next) {
- if (so->so_haddr_port == port) {
- break;
- }
- }
-
- if (so == &udb)
- return -1;
-
- sofcantrcvmore( so );
- sofcantsendmore( so );
- socket_close( so->s );
- so->s = -1;
- sofree( so );
- return 0;
-}
diff --git a/slirp2/udp.h b/slirp2/udp.h
deleted file mode 100644
index cadd17e..0000000
--- a/slirp2/udp.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)udp.h 8.1 (Berkeley) 6/10/93
- * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp
- */
-
-#ifndef _UDP_H_
-#define _UDP_H_
-
-#include "helper.h"
-
-#define UDP_TTL 0x60
-#define UDP_UDPDATALEN 16192
-
-extern struct socket *udp_last_so;
-
-/*
- * Udp protocol header.
- * Per RFC 768, September, 1981.
- */
-struct udphdr {
- port_t uh_sport; /* source port */
- port_t uh_dport; /* destination port */
- int16_t uh_ulen; /* udp length */
- u_int16_t uh_sum; /* udp checksum */
-};
-
-/*
- * UDP kernel structures and variables.
- */
-struct udpiphdr {
- struct ipovly ui_i; /* overlaid ip structure */
- struct udphdr ui_u; /* udp header */
-};
-#define ui_mbuf ui_i.ih_mbuf.mptr
-#define ui_x1 ui_i.ih_x1
-#define ui_pr ui_i.ih_pr
-#define ui_len ui_i.ih_len
-#define ui_src ui_i.ih_src
-#define ui_dst ui_i.ih_dst
-#define ui_sport ui_u.uh_sport
-#define ui_dport ui_u.uh_dport
-#define ui_ulen ui_u.uh_ulen
-#define ui_sum ui_u.uh_sum
-
-struct udpstat {
- /* input statistics: */
- u_long udps_ipackets; /* total input packets */
- u_long udps_hdrops; /* packet shorter than header */
- u_long udps_badsum; /* checksum error */
- u_long udps_badlen; /* data length larger than packet */
- u_long udps_noport; /* no socket on port */
- u_long udps_noportbcast; /* of above, arrived as broadcast */
- u_long udps_fullsock; /* not delivered, input socket full */
- u_long udpps_pcbcachemiss; /* input packets missing pcb cache */
- /* output statistics: */
- u_long udps_opackets; /* total output packets */
-};
-
-/*
- * Names for UDP sysctl objects
- */
-#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
-#define UDPCTL_MAXID 2
-
-extern struct udpstat udpstat;
-extern struct socket udb;
-struct mbuf;
-
-void udp_init _P((void));
-void udp_input _P((register MBuf , int));
-int udp_attach _P((struct socket *));
-void udp_detach _P((struct socket *));
-u_int8_t udp_tos _P((struct socket *));
-void udp_emu _P((struct socket *, MBuf ));
-struct socket * udp_listen _P((u_int, u_int32_t, u_int, int));
-int udp_unlisten _P((u_int));
-
-int udp_output_(struct socket *, MBuf, SockAddress*);
-
-int udp_output2_(struct socket* so, MBuf m,
- const SockAddress* saddr, const SockAddress* daddr,
- int iptos);
-
-#endif
diff --git a/sockets.c b/sockets.c
deleted file mode 100644
index 62c1ee3..0000000
--- a/sockets.c
+++ /dev/null
@@ -1,1269 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sockets.h"
-#include "qemu-common.h"
-#include <fcntl.h>
-#include <stddef.h>
-#include "qemu_debug.h"
-#include <stdlib.h>
-#include <string.h>
-#include "android/utils/path.h"
-
-#ifdef _WIN32
-# define xxWIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <winsock2.h>
-# include <ws2tcpip.h>
-#else /* !_WIN32 */
-# include <sys/ioctl.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <netinet/tcp.h>
-# include <netdb.h>
-# if HAVE_UNIX_SOCKETS
-# include <sys/un.h>
-# ifndef UNIX_PATH_MAX
-# define UNIX_PATH_MAX (sizeof(((struct sockaddr_un*)0)->sun_path)-1)
-# endif
-# endif
-#endif /* !_WIN32 */
-
-
-
-/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
- * easily in QEMU since we use SIGALRM to implement periodic timers
- */
-#ifdef _WIN32
-# define QSOCKET_CALL(_ret,_cmd) \
- do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
-#else
-# define QSOCKET_CALL(_ret,_cmd) \
- do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR )
-#endif
-
-#ifdef _WIN32
-
-#include <errno.h>
-
-static int winsock_error;
-
-#define WINSOCK_ERRORS_LIST \
- EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
- EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
- EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
- EE(WSAEINTR,EINTR,"interrupted function call") \
- EE(WSAEALREADY,EALREADY,"operation already in progress") \
- EE(WSAEBADF,EBADF,"bad file descriptor") \
- EE(WSAEACCES,EACCES,"permission denied") \
- EE(WSAEFAULT,EFAULT,"bad address") \
- EE(WSAEINVAL,EINVAL,"invalid argument") \
- EE(WSAEMFILE,EMFILE,"too many opened files") \
- EE(WSAEWOULDBLOCK,EAGAIN,"resource temporarily unavailable") \
- EE(WSAEINPROGRESS,EAGAIN,"operation now in progress") \
- EE(WSAEALREADY,EAGAIN,"operation already in progress") \
- EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
- EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
- EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
- EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
- EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
- EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
- EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
- EE(WSAENETDOWN,ENETDOWN,"network is down") \
- EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
- EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
- EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
- EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
- EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
- EE(WSAEISCONN,EISCONN,"socket is already connected") \
- EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
- EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
- EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
- EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
- EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
- EE(WSAELOOP,ELOOP,"cannot translate name") \
- EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
- EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
- EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
-
-typedef struct {
- int winsock;
- int unix;
- const char* string;
-} WinsockError;
-
-static const WinsockError _winsock_errors[] = {
-#define EE(w,u,s) { w, u, s },
- WINSOCK_ERRORS_LIST
-#undef EE
- { -1, -1, NULL }
-};
-
-/* this function reads the latest winsock error code and updates
- * errno to a matching value. It also returns the new value of
- * errno.
- */
-static int
-_fix_errno( void )
-{
- const WinsockError* werr = _winsock_errors;
- int unix = EINVAL; /* generic error code */
-
- for ( ; werr->string != NULL; werr++ ) {
- if (werr->winsock == winsock_error) {
- unix = werr->unix;
- break;
- }
- }
- errno = unix;
- return -1;
-}
-
-static int
-_set_errno( int code )
-{
- winsock_error = -1;
- errno = code;
- return -1;
-}
-
-/* this function returns a string describing the latest Winsock error */
-const char*
-_errno_str(void)
-{
- const WinsockError* werr = _winsock_errors;
- const char* result = "<unknown error>";
-
- for ( ; werr->string; werr++ ) {
- if (werr->winsock == winsock_error) {
- result = werr->string;
- break;
- }
- }
-
- if (result == NULL)
- result = strerror(errno);
-
- return result;
-}
-#else
-static int
-_fix_errno( void )
-{
- return -1;
-}
-
-static int
-_set_errno( int code )
-{
- errno = code;
- return -1;
-}
-#endif
-
-/* socket types */
-
-static int
-socket_family_to_bsd( SocketFamily family )
-{
- switch (family) {
- case SOCKET_INET: return AF_INET;
- case SOCKET_IN6: return AF_INET6;
-#if HAVE_UNIX_SOCKETS
- case SOCKET_UNIX: return AF_LOCAL;
-#endif
- default: return -1;
- }
-}
-
-static int
-socket_type_to_bsd( SocketType type )
-{
- switch (type) {
- case SOCKET_DGRAM: return SOCK_DGRAM;
- case SOCKET_STREAM: return SOCK_STREAM;
- default: return -1;
- }
-}
-
-static SocketType
-socket_type_from_bsd( int type )
-{
- switch (type) {
- case SOCK_DGRAM: return SOCKET_DGRAM;
- case SOCK_STREAM: return SOCKET_STREAM;
- default: return (SocketType) -1;
- }
-}
-
-#if 0
-static int
-socket_type_check( SocketType type )
-{
- return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
-}
-#endif
-
-/* socket addresses */
-
-void
-sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port )
-{
- a->family = SOCKET_INET;
- a->u.inet.port = port;
- a->u.inet.address = ip;
-}
-
-void
-sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port )
-{
- a->family = SOCKET_IN6;
- a->u.in6.port = port;
- memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) );
-}
-
-void
-sock_address_init_unix( SockAddress* a, const char* path )
-{
- a->family = SOCKET_UNIX;
- a->u._unix.path = strdup(path ? path : "");
- a->u._unix.owner = 1;
-}
-
-void sock_address_done( SockAddress* a )
-{
- if (a->family == SOCKET_UNIX && a->u._unix.owner) {
- a->u._unix.owner = 0;
- free((char*)a->u._unix.path);
- }
-}
-
-static char*
-format_char( char* buf, char* end, int c )
-{
- if (buf >= end)
- return buf;
- if (buf+1 == end)
- c = 0;
- *buf++ = (char) c;
- return buf;
-}
-
-static char*
-format_str( char* buf, char* end, const char* str )
-{
- int len = strlen(str);
- int avail = end - buf;
-
- if (len > avail)
- len = avail;
-
- memcpy( buf, str, len );
- buf += len;
-
- if (buf == end)
- buf[-1] = 0;
- else
- buf[0] = 0;
-
- return buf;
-}
-
-static char*
-format_unsigned( char* buf, char* end, unsigned val )
-{
- char temp[16];
- int nn;
-
- for ( nn = 0; val != 0; nn++ ) {
- int rem = val % 10;
- temp[nn] = '0'+rem;
- val /= 10;
- }
-
- if (nn == 0)
- temp[nn++] = '0';
-
- while (nn > 0)
- buf = format_char(buf, end, temp[--nn]);
-
- return buf;
-}
-
-static char*
-format_hex( char* buf, char* end, unsigned val, int ndigits )
-{
- int shift = 4*ndigits;
- static const char hex[16] = "0123456789abcdef";
-
- while (shift >= 0) {
- buf = format_char(buf, end, hex[(val >> shift) & 15]);
- shift -= 4;
- }
- return buf;
-}
-
-static char*
-format_ip4( char* buf, char* end, uint32_t ip )
-{
- buf = format_unsigned( buf, end, (unsigned)(ip >> 24) );
- buf = format_char( buf, end, '.');
- buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255));
- buf = format_char( buf, end, '.');
- buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255));
- buf = format_char( buf, end, '.');
- buf = format_unsigned( buf, end, (unsigned)(ip & 255));
- return buf;
-}
-
-static char*
-format_ip6( char* buf, char* end, const uint8_t* ip6 )
-{
- int nn;
- for (nn = 0; nn < 8; nn++) {
- int val = (ip6[0] << 16) | ip6[1];
- ip6 += 2;
- if (nn > 0)
- buf = format_char(buf, end, ':');
- if (val == 0)
- continue;
- buf = format_hex(buf, end, val, 4);
- }
- return buf;
-}
-
-const char*
-sock_address_to_string( const SockAddress* a )
-{
- static char buf0[MAX_PATH];
- char *buf = buf0, *end = buf + sizeof(buf0);
-
- switch (a->family) {
- case SOCKET_INET:
- buf = format_ip4( buf, end, a->u.inet.address );
- buf = format_char( buf, end, ':' );
- buf = format_unsigned( buf, end, (unsigned) a->u.inet.port );
- break;
-
- case SOCKET_IN6:
- buf = format_ip6( buf, end, a->u.in6.address );
- buf = format_char( buf, end, ':' );
- buf = format_unsigned( buf, end, (unsigned) a->u.in6.port );
- break;
-
- case SOCKET_UNIX:
- buf = format_str( buf, end, a->u._unix.path );
- break;
-
- default:
- return NULL;
- }
-
- return buf0;
-}
-
-int
-sock_address_equal( const SockAddress* a, const SockAddress* b )
-{
- if (a->family != b->family)
- return 0;
-
- switch (a->family) {
- case SOCKET_INET:
- return (a->u.inet.address == b->u.inet.address &&
- a->u.inet.port == b->u.inet.port);
-
- case SOCKET_IN6:
- return (!memcmp(a->u.in6.address, b->u.in6.address, 16) &&
- a->u.in6.port == b->u.in6.port);
-
- case SOCKET_UNIX:
- return (!strcmp(a->u._unix.path, b->u._unix.path));
-
- default:
- return 0;
- }
-}
-
-int
-sock_address_get_port( const SockAddress* a )
-{
- switch (a->family) {
- case SOCKET_INET:
- return a->u.inet.port;
- case SOCKET_IN6:
- return a->u.in6.port;
- default:
- return -1;
- }
-}
-
-void
-sock_address_set_port( SockAddress* a, uint16_t port )
-{
- switch (a->family) {
- case SOCKET_INET:
- a->u.inet.port = port;
- break;
- case SOCKET_IN6:
- a->u.in6.port = port;
- break;
- default:
- ;
- }
-}
-
-const char*
-sock_address_get_path( const SockAddress* a )
-{
- if (a->family == SOCKET_UNIX)
- return a->u._unix.path;
- else
- return NULL;
-}
-
-int
-sock_address_get_ip( const SockAddress* a )
-{
- if (a->family == SOCKET_INET)
- return a->u.inet.address;
-
- return -1;
-}
-
-#if 0
-char*
-bufprint_sock_address( char* p, char* end, const SockAddress* a )
-{
- switch (a->family) {
- case SOCKET_INET:
- {
- uint32_t ip = a->u.inet.address;
-
- return bufprint( p, end, "%d.%d.%d.%d:%d",
- (ip >> 24) & 255, (ip >> 16) & 255,
- (ip >> 8) & 255, ip & 255,
- a->u.inet.port );
- }
- case SOCKET_IN6:
- {
- int nn = 0;
- const char* column = "";
- const uint8_t* tab = a->u.in6.address;
- for (nn = 0; nn < 16; nn += 2) {
- p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]);
- column = ":";
- }
- return bufprint(p, end, ":%d", a->u.in6.port);
- }
- case SOCKET_UNIX:
- {
- return bufprint(p, end, "%s", a->u._unix.path);
- }
- default:
- return p;
- }
-}
-#endif
-
-int
-sock_address_to_bsd( const SockAddress* a, void* paddress, size_t *psize )
-{
- switch (a->family) {
- case SOCKET_INET:
- {
- struct sockaddr_in* dst = (struct sockaddr_in*) paddress;
-
- *psize = sizeof(*dst);
-
- memset( paddress, 0, *psize );
-
- dst->sin_family = AF_INET;
- dst->sin_port = htons(a->u.inet.port);
- dst->sin_addr.s_addr = htonl(a->u.inet.address);
- }
- break;
-
-#if HAVE_IN6_SOCKETS
- case SOCKET_IN6:
- {
- struct sockaddr_in6* dst = (struct sockaddr_in6*) paddress;
-
- *psize = sizeof(*dst);
-
- memset( paddress, 0, *psize );
-
- dst->sin6_family = AF_INET6;
- dst->sin6_port = htons(a->u.in6.port);
- memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 );
- }
- break;
-#endif /* HAVE_IN6_SOCKETS */
-
-#if HAVE_UNIX_SOCKETS
- case SOCKET_UNIX:
- {
- int slen = strlen(a->u._unix.path);
- struct sockaddr_un* dst = (struct sockaddr_un*) paddress;
-
- if (slen >= UNIX_PATH_MAX)
- return -1;
-
- memset( paddress, 0, sizeof(*dst) );
-
- dst->sun_family = AF_LOCAL;
- memcpy( dst->sun_path, a->u._unix.path, slen );
- dst->sun_path[slen] = 0;
-
- *psize = (char*)&dst->sun_path[slen+1] - (char*)dst;
- }
- break;
-#endif /* HAVE_UNIX_SOCKETS */
-
- default:
- return _set_errno(EINVAL);
- }
-
- return 0;
-}
-
-int
-sock_address_to_inet( SockAddress* a, int *paddr_ip, int *paddr_port )
-{
- struct sockaddr addr;
- socklen_t addrlen;
-
- if (a->family != SOCKET_INET) {
- return _set_errno(EINVAL);
- }
-
- if (sock_address_to_bsd(a, &addr, &addrlen) < 0)
- return -1;
-
- *paddr_ip = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
- *paddr_port = ntohs(((struct sockaddr_in*)&addr)->sin_port);
-
- return 0;
-}
-
-int
-sock_address_from_bsd( SockAddress* a, const void* from, size_t fromlen )
-{
- switch (((struct sockaddr*)from)->sa_family) {
- case AF_INET:
- {
- struct sockaddr_in* src = (struct sockaddr_in*) from;
-
- if (fromlen < sizeof(*src))
- return _set_errno(EINVAL);
-
- a->family = SOCKET_INET;
- a->u.inet.port = ntohs(src->sin_port);
- a->u.inet.address = ntohl(src->sin_addr.s_addr);
- }
- break;
-
-#ifdef HAVE_IN6_SOCKETS
- case AF_INET6:
- {
- struct sockaddr_in6* src = (struct sockaddr_in6*) from;
-
- if (fromlen < sizeof(*src))
- return _set_errno(EINVAL);
-
- a->family = SOCKET_IN6;
- a->u.in6.port = ntohs(src->sin6_port);
- memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16);
- }
- break;
-#endif
-
-#ifdef HAVE_UNIX_SOCKETS
- case AF_LOCAL:
- {
- struct sockaddr_un* src = (struct sockaddr_un*) from;
- char* end;
-
- if (fromlen < sizeof(*src))
- return _set_errno(EINVAL);
-
- /* check that the path is zero-terminated */
- end = memchr(src->sun_path, 0, UNIX_PATH_MAX);
- if (end == NULL)
- return _set_errno(EINVAL);
-
- a->family = SOCKET_UNIX;
- a->u._unix.owner = 1;
- a->u._unix.path = strdup(src->sun_path);
- }
- break;
-#endif
-
- default:
- return _set_errno(EINVAL);
- }
- return 0;
-}
-
-
-int
-sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t port, int preferIn6 )
-{
- struct addrinfo hints[1];
- struct addrinfo* res;
- int ret;
-
- memset(hints, 0, sizeof(hints));
- hints->ai_family = preferIn6 ? AF_INET6 : AF_UNSPEC;
-
- if (getaddrinfo(hostname, NULL, hints, &res) < 0) {
- return _fix_errno();
- }
-
- ret = sock_address_from_bsd( a, res->ai_addr, res->ai_addrlen );
- freeaddrinfo(res);
-
- /* need to set the port */
- switch (a->family) {
- case SOCKET_INET: a->u.inet.port = port; break;
- case SOCKET_IN6: a->u.in6.port = port; break;
- default: ;
- }
-
- return ret;
-}
-
-
-int
-socket_create( SocketFamily family, SocketType type )
-{
- int ret;
- int sfamily = socket_family_to_bsd(family);
- int stype = socket_type_to_bsd(type);
-
- if (sfamily < 0 || stype < 0) {
- return _set_errno(EINVAL);
- }
-
- QSOCKET_CALL(ret, socket(sfamily, stype, 0));
- if (ret < 0)
- return _fix_errno();
-
- return ret;
-}
-
-
-int
-socket_create_inet( SocketType type )
-{
- return socket_create( SOCKET_INET, type );
-}
-
-#if HAVE_IN6_SOCKETS
-int
-socket_create_in6 ( SocketType type )
-{
- return socket_create( SOCKET_IN6, type );
-}
-#endif
-
-#if HAVE_UNIX_SOCKETS
-int
-socket_create_unix( SocketType type )
-{
- return socket_create( SOCKET_UNIX, type );
-}
-#endif
-
-int socket_can_read(int fd)
-{
-#ifdef _WIN32
- unsigned long opt;
-
- if (ioctlsocket(fd, FIONREAD, &opt) < 0)
- return 0;
-
- return opt;
-#else
- int opt;
-
- if (ioctl(fd, FIONREAD, &opt) < 0)
- return 0;
-
- return opt;
-#endif
-}
-
-#define SOCKET_CALL(cmd) \
- int ret; \
- QSOCKET_CALL(ret, (cmd)); \
- if (ret < 0) \
- return _fix_errno(); \
- return ret; \
-
-int
-socket_send(int fd, const void* buf, int buflen)
-{
- SOCKET_CALL(send(fd, buf, buflen, 0))
-}
-
-int
-socket_send_oob( int fd, const void* buf, int buflen )
-{
- SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
-}
-
-int
-socket_sendto(int fd, const void* buf, int buflen, const SockAddress* to)
-{
- struct sockaddr sa;
- socklen_t salen;
-
- if (sock_address_to_bsd(to, &sa, &salen) < 0)
- return -1;
-
- SOCKET_CALL(sendto(fd, buf, buflen, 0, &sa, salen));
-}
-
-int
-socket_recv(int fd, void* buf, int len)
-{
- SOCKET_CALL(recv(fd, buf, len, 0));
-}
-
-int
-socket_recvfrom(int fd, void* buf, int len, SockAddress* from)
-{
- struct sockaddr sa;
- socklen_t salen = sizeof(sa);
- int ret;
-
- QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,&sa,&salen));
- if (ret < 0)
- return _fix_errno();
-
- if (sock_address_from_bsd(from, &sa, salen) < 0)
- return -1;
-
- return ret;
-}
-
-int
-socket_connect( int fd, const SockAddress* address )
-{
- struct sockaddr addr;
- socklen_t addrlen;
-
- if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
- return -1;
-
- SOCKET_CALL(connect(fd,&addr,addrlen));
-}
-
-int
-socket_bind( int fd, const SockAddress* address )
-{
- struct sockaddr addr;
- socklen_t addrlen;
-
- if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
- return -1;
-
- SOCKET_CALL(bind(fd, &addr, addrlen));
-}
-
-int
-socket_get_address( int fd, SockAddress* address )
-{
- struct sockaddr addr;
- socklen_t addrlen = sizeof(addr);
- int ret;
-
- QSOCKET_CALL(ret, getsockname(fd, &addr, &addrlen));
- if (ret < 0)
- return _fix_errno();
-
- return sock_address_from_bsd(address, &addr, addrlen);
-}
-
-int
-socket_listen( int fd, int backlog )
-{
- SOCKET_CALL(listen(fd, backlog));
-}
-
-int
-socket_accept( int fd, SockAddress* address )
-{
- struct sockaddr addr;
- socklen_t addrlen = sizeof(addr);
- int ret;
-
- QSOCKET_CALL(ret, accept(fd, &addr, &addrlen));
- if (ret < 0)
- return _fix_errno();
-
- if (address) {
- if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
- socket_close(ret);
- return -1;
- }
- }
- return ret;
-}
-
-SocketType socket_get_type(int fd)
-{
- int opt = -1;
- int optlen = sizeof(opt);
- getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*)&opt, (void*)&optlen );
-
- return socket_type_from_bsd(opt);
-}
-
-int socket_set_nonblock(int fd)
-{
-#ifdef _WIN32
- unsigned long opt = 1;
- return ioctlsocket(fd, FIONBIO, &opt);
-#else
- int flags = fcntl(fd, F_GETFL);
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-#endif
-}
-
-int socket_set_blocking(int fd)
-{
-#ifdef _WIN32
- unsigned long opt = 0;
- return ioctlsocket(fd, FIONBIO, &opt);
-#else
- int flags = fcntl(fd, F_GETFL);
- return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
-#endif
-}
-
-static int
-socket_setoption(int fd, int domain, int option, int _flag)
-{
-#ifdef _WIN32
- DWORD flag = (DWORD) _flag;
-#else
- int flag = _flag;
-#endif
- return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
-}
-
-
-int socket_set_xreuseaddr(int fd)
-{
-#ifdef _WIN32
- /* on Windows, SO_REUSEADDR is used to indicate that several programs can
- * bind to the same port. this is completely different from the Unix
- * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
- * this.
- */
- return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
-#else
- return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
-#endif
-}
-
-
-int socket_set_oobinline(int fd)
-{
- return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
-}
-
-
-int socket_set_nodelay(int fd)
-{
- return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
-}
-
-
-#ifdef _WIN32
-#include <stdlib.h>
-
-static void socket_cleanup(void)
-{
- WSACleanup();
-}
-
-int socket_init(void)
-{
- WSADATA Data;
- int ret, err;
-
- ret = WSAStartup(MAKEWORD(2,2), &Data);
- if (ret != 0) {
- err = WSAGetLastError();
- return -1;
- }
- atexit(socket_cleanup);
- return 0;
-}
-
-#else /* !_WIN32 */
-
-int socket_init(void)
-{
- return 0; /* nothing to do on Unix */
-}
-
-#endif /* !_WIN32 */
-
-#ifdef _WIN32
-
-static void
-socket_close_handler( void* _fd )
-{
- int fd = (int)_fd;
- int ret;
- char buff[64];
-
- /* we want to drain the read side of the socket before closing it */
- do {
- ret = recv( fd, buff, sizeof(buff), 0 );
- } while (ret < 0 && WSAGetLastError() == WSAEINTR);
-
- if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
- return;
-
- qemu_set_fd_handler( fd, NULL, NULL, NULL );
- closesocket( fd );
-}
-
-void
-socket_close( int fd )
-{
- int old_errno = errno;
-
- shutdown( fd, SD_BOTH );
- /* we want to drain the socket before closing it */
- qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
-
- errno = old_errno;
-}
-
-#else /* !_WIN32 */
-
-#include <unistd.h>
-
-void
-socket_close( int fd )
-{
- int old_errno = errno;
-
- shutdown( fd, SHUT_RDWR );
- close( fd );
-
- errno = old_errno;
-}
-
-#endif /* !_WIN32 */
-
-
-static int
-socket_bind_server( int s, const SockAddress* to, SocketType type )
-{
- socket_set_xreuseaddr(s);
-
- if (socket_bind(s, to) < 0) {
- dprint("could not bind server socket address %s: %s",
- sock_address_to_string(to), errno_str);
- goto FAIL;
- }
-
- if (type == SOCKET_STREAM) {
- if (socket_listen(s, 4) < 0) {
- dprint("could not listen server socket %s: %s",
- sock_address_to_string(to), errno_str);
- goto FAIL;
- }
- }
- return s;
-
-FAIL:
- socket_close(s);
- return -1;
-}
-
-
-static int
-socket_connect_client( int s, const SockAddress* to )
-{
- if (socket_connect(s, to) < 0) {
- dprint( "could not connect client socket to %s: %s\n",
- sock_address_to_string(to), errno_str );
- socket_close(s);
- return -1;
- }
-
- socket_set_nonblock( s );
- return s;
-}
-
-
-static int
-socket_in_server( int address, int port, SocketType type )
-{
- SockAddress addr;
- int s;
-
- sock_address_init_inet( &addr, address, port );
- s = socket_create_inet( type );
- if (s < 0)
- return -1;
-
- return socket_bind_server( s, &addr, type );
-}
-
-
-static int
-socket_in_client( SockAddress* to, SocketType type )
-{
- int s;
-
- s = socket_create_inet( type );
- if (s < 0) return -1;
-
- return socket_connect_client( s, to );
-}
-
-
-int
-socket_loopback_server( int port, SocketType type )
-{
- return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
-}
-
-int
-socket_loopback_client( int port, SocketType type )
-{
- SockAddress addr;
-
- sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
- return socket_in_client( &addr, type );
-}
-
-
-int
-socket_network_client( const char* host, int port, SocketType type )
-{
- SockAddress addr;
-
- if (sock_address_init_resolve( &addr, host, port, 0) < 0)
- return -1;
-
- return socket_in_client( &addr, type );
-}
-
-
-int
-socket_anyaddr_server( int port, SocketType type )
-{
- return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
-}
-
-int
-socket_accept_any( int server_fd )
-{
- int fd;
-
- QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
- if (fd < 0) {
- dprint( "could not accept client connection from fd %d: %s",
- server_fd, errno_str );
- return -1;
- }
-
- /* set to non-blocking */
- socket_set_nonblock( fd );
- return fd;
-}
-
-
-#if HAVE_UNIX_SOCKETS
-
-int
-socket_unix_server( const char* name, SocketType type )
-{
- SockAddress addr;
- int s, ret;
-
- s = socket_create_unix( type );
- if (s < 0)
- return -1;
-
- sock_address_init_unix( &addr, name );
-
- do {
- ret = unlink( name );
- } while (ret < 0 && errno == EINTR);
-
- ret = socket_bind_server( s, &addr, type );
-
- sock_address_done( &addr );
- return ret;
-}
-
-int
-socket_unix_client( const char* name, SocketType type )
-{
- SockAddress addr;
- int s, ret;
-
- s = socket_create_unix(type);
- if (s < 0)
- return -1;
-
- sock_address_init_unix( &addr, name );
-
- ret = socket_connect_client( s, &addr );
-
- sock_address_done( &addr );
- return ret;
-}
-
-#endif /* HAVE_UNIX_SOCKETS */
-
-
-
-int
-socket_pair(int *fd1, int *fd2)
-{
-#ifndef _WIN32
- int fds[2];
- int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
-
- if (!ret) {
- socket_set_nonblock(fds[0]);
- socket_set_nonblock(fds[1]);
- *fd1 = fds[0];
- *fd2 = fds[1];
- }
- return ret;
-#else /* _WIN32 */
- /* on Windows, select() only works with network sockets, which
- * means we absolutely cannot use Win32 PIPEs to implement
- * socket pairs with the current event loop implementation.
- * We're going to do like Cygwin: create a random pair
- * of localhost TCP sockets and connect them together
- */
- int s0, s1, s2, port;
- struct sockaddr_in sockin;
- socklen_t len;
-
- /* first, create the 'server' socket.
- * a port number of 0 means 'any port between 1024 and 5000.
- * see Winsock bind() documentation for details */
- s0 = socket_loopback_server( 0, SOCK_STREAM );
- if (s0 < 0)
- return -1;
-
- /* now connect a client socket to it, we first need to
- * extract the server socket's port number */
- len = sizeof sockin;
- if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
- closesocket (s0);
- return -1;
- }
-
- port = ntohs(sockin.sin_port);
- s2 = socket_loopback_client( port, SOCK_STREAM );
- if (s2 < 0) {
- closesocket(s0);
- return -1;
- }
-
- /* we need to accept the connection on the server socket
- * this will create the second socket for the pair
- */
- len = sizeof sockin;
- s1 = accept(s0, (struct sockaddr*) &sockin, &len);
- if (s1 == INVALID_SOCKET) {
- closesocket (s0);
- closesocket (s2);
- return -1;
- }
- socket_set_nonblock(s1);
-
- /* close server socket */
- closesocket(s0);
- *fd1 = s1;
- *fd2 = s2;
- return 0;
-#endif /* _WIN32 */
-}
-
-
-
-int
-socket_mcast_inet_add_membership( int s, uint32_t ip )
-{
- struct ip_mreq imr;
-
- imr.imr_multiaddr.s_addr = htonl(ip);
- imr.imr_interface.s_addr = htonl(INADDR_ANY);
-
- if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (const char *)&imr,
- sizeof(struct ip_mreq)) < 0 )
- {
- return _fix_errno();
- }
- return 0;
-}
-
-int
-socket_mcast_inet_drop_membership( int s, uint32_t ip )
-{
- struct ip_mreq imr;
-
- imr.imr_multiaddr.s_addr = htonl(ip);
- imr.imr_interface.s_addr = htonl(INADDR_ANY);
-
- if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
- (const char *)&imr,
- sizeof(struct ip_mreq)) < 0 )
- {
- return _fix_errno();
- }
- return 0;
-}
-
-int
-socket_mcast_inet_set_loop( int s, int enabled )
-{
- return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
-}
-
-int
-socket_mcast_inet_set_ttl( int s, int ttl )
-{
- return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
-}
-
-
-char*
-host_name( void )
-{
- static char buf[256]; /* 255 is the max host name length supported by DNS */
- int ret;
-
- QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
-
- if (ret < 0)
- return "localhost";
- else
- return buf;
-}
diff --git a/sockets.h b/sockets.h
deleted file mode 100644
index 274cf32..0000000
--- a/sockets.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/* headers to use the BSD sockets */
-#ifndef QEMU_SOCKET_H
-#define QEMU_SOCKET_H
-
-#include <stddef.h>
-#include <stdint.h>
-#include <errno.h>
-
-/* we're going to hide the implementation details of sockets behind
- * a simple wrapper interface declared here.
- *
- * all socket operations set the global 'errno' variable on error.
- * this is unlike Winsock which instead modifies another internal
- * variable accessed through WSAGetLastError() and WSASetLastError()
- */
-
-/* the wrapper will convert any Winsock error message into an errno
- * code for you. There are however a few standard Unix error codes
- * that are not defined by the MS C library headers, so we add them
- * here. We use the official Winsock error codes, which are documented
- * even though we don't want to include the Winsock headers
- */
-#ifdef _WIN32
-# ifndef EINTR
-# define EINTR 10004
-# endif
-# ifndef EWOULDBLOCK
-# define EWOULDBLOCK 10035
-# endif
-# ifndef EINPROGRESS
-# define EINPROGRESS 10036
-# endif
-# ifndef EALREADY
-# define EALREADY 10037
-# endif
-# ifndef EDESTADDRREQ
-# define EDESTADDRREQ 10039
-# endif
-# ifndef EMSGSIZE
-# define EMSGSIZE 10040
-# endif
-# ifndef EPROTOTYPE
-# define EPROTOTYPE 10041
-# endif
-# ifndef ENOPROTOOPT
-# define ENOPROTOOPT 10042
-# endif
-# ifndef EADDRINUSE
-# define EADDRINUSE 10048
-# endif
-# ifndef EADDRNOTAVAIL
-# define EADDRNOTAVAIL 10049
-# endif
-# ifndef ENETDOWN
-# define ENETDOWN 10050
-# endif
-# ifndef ENETUNREACH
-# define ENETUNREACH 10051
-# endif
-# ifndef ENETRESET
-# define ENETRESET 10052
-# endif
-# ifndef ECONNABORTED
-# define ECONNABORTED 10053
-# endif
-# ifndef ECONNRESET
-# define ECONNRESET 10054
-# endif
-# ifndef ENOBUFS
-# define ENOBUFS 10055
-# endif
-# ifndef EISCONN
-# define EISCONN 10056
-# endif
-# ifndef ENOTCONN
-# define ENOTCONN 10057
-# endif
-# ifndef ESHUTDOWN
-# define ESHUTDOWN 10058
-# endif
-# ifndef ETOOMANYREFS
-# define ETOOMANYREFS 10059
-# endif
-# ifndef ETIMEDOUT
-# define ETIMEDOUT 10060
-# endif
-# ifndef ECONNREFUSED
-# define ECONNREFUSED 10061
-# endif
-# ifndef ELOOP
-# define ELOOP 10062
-# endif
-# ifndef EHOSTDOWN
-# define EHOSTDOWN 10064
-# endif
-# ifndef EHOSTUNREACH
-# define EHOSTUNREACH 10065
-# endif
-#endif /* _WIN32 */
-
-/* Define 'errno_str' as a handy macro to return the string
- * corresponding to a given errno code. On Unix, this is
- * equivalent to strerror(errno), but on Windows, this will
- * take care of Winsock-originated errors as well.
- */
-#ifdef _WIN32
- extern const char* _errno_str(void);
-# define errno_str _errno_str()
-#else
-# define errno_str strerror(errno)
-#endif
-
-/* always enable IPv6 sockets for now.
- * the QEMU internal router is not capable of
- * supporting them, but we plan to replace it
- * with something better in the future.
- */
-#define HAVE_IN6_SOCKETS 1
-
-/* Unix sockets are not available on Win32 */
-#ifndef _WIN32
-# define HAVE_UNIX_SOCKETS 1
-#endif
-
-/* initialize the socket sub-system. this must be called before
- * using any of the declarations below.
- */
-int socket_init( void );
-
-/* return the name of the current host */
-char* host_name( void );
-
-/* supported socket types */
-typedef enum {
- SOCKET_DGRAM = 0,
- SOCKET_STREAM
-} SocketType;
-
-/* supported socket families */
-typedef enum {
- SOCKET_UNSPEC,
- SOCKET_INET,
- SOCKET_IN6,
- SOCKET_UNIX
-} SocketFamily;
-
-/* Generic socket address structure. Note that for Unix
- * sockets, the path is stored in a heap-allocated block,
- * unless the 'owner' field is cleared. If this is the case,
- */
-typedef struct {
- SocketFamily family;
- union {
- struct {
- uint16_t port;
- uint32_t address;
- } inet;
- struct {
- uint16_t port;
- uint8_t address[16];
- } in6;
- struct {
- int owner;
- const char* path;
- } _unix;
- } u;
-} SockAddress;
-
-#define SOCK_ADDRESS_INET_ANY 0x00000000
-#define SOCK_ADDRESS_INET_LOOPBACK 0x7f000001
-
-/* initialize a new IPv4 socket address, the IP address and port are
- * in host endianess.
- */
-void sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port );
-
-/* Initialize an IPv6 socket address, the address is in network order
- * and the port in host endianess.
- */
-#if HAVE_IN6_SOCKETS
-void sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port );
-#endif
-
-/* Intialize a Unix socket address, this will copy the 'path' string into the
- * heap. You need to call sock_address_done() to release the copy
- */
-#if HAVE_UNIX_SOCKETS
-void sock_address_init_unix( SockAddress* a, const char* path );
-#endif
-
-/* Finalize a socket address, only needed for now for Unix addresses */
-void sock_address_done( SockAddress* a );
-
-int sock_address_equal( const SockAddress* a, const SockAddress* b );
-
-/* THIS SHOULD DISAPPEAR SOON - TRANSITIONAL HELPER */
-int sock_address_to_bsd( const SockAddress* a, void* sa, size_t* salen );
-int sock_address_from_bsd( SockAddress* a, const void* sa, size_t salen );
-int sock_address_to_inet( SockAddress* a, int *paddr_ip, int *paddr_port );
-
-/* return a static string describing the address */
-const char* sock_address_to_string( const SockAddress* a );
-
-/* return the port number of a given socket address, or -1 if it's a Unix one */
-int sock_address_get_port( const SockAddress* a );
-
-/* set the port number of a given socket address, don't do anything for Unix ones */
-void sock_address_set_port( SockAddress* a, uint16_t port );
-
-/* return the path of a given Unix socket, returns NULL for non-Unix ones */
-const char* sock_address_get_path( const SockAddress* a );
-
-/* return the inet address, or -1 if it's not SOCKET_INET */
-int sock_address_get_ip( const SockAddress* a );
-
-/* bufprint a socket address into a human-readable string */
-char* bufprint_sock_address( char* p, char* end, const SockAddress* a );
-
-/* resolve a hostname or decimal IPv4/IPv6 address into a socket address.
- * returns 0 on success, or -1 on failure */
-int sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t port, int preferIn6 );
-
-/* create a new socket, return the socket number of -1 on failure */
-int socket_create( SocketFamily family, SocketType type );
-
-/* create a new socket intended for IPv4 communication. returns the socket number,
- * or -1 on failure.
- */
-int socket_create_inet( SocketType type );
-
-/* create a new socket intended for IPv6 communication. returns the socket number,
- * or -1 on failure.
- */
-#if HAVE_IN6_SOCKETS
-int socket_create_in6 ( SocketType type );
-#endif
-
-/* create a unix/local domain socket. returns the socket number,
- * or -1 on failure.
- */
-#if HAVE_UNIX_SOCKETS
-int socket_create_unix( SocketType type );
-#endif
-
-/* return the type of a given socket */
-SocketType socket_get_type(int fd);
-
-/* set SO_REUSEADDR on Unix, SO_EXCLUSIVEADDR on Windows */
-int socket_set_xreuseaddr(int fd);
-
-/* set socket in non-blocking mode */
-int socket_set_nonblock(int fd);
-
-/* set socket in blocking mode */
-int socket_set_blocking(int fd);
-
-/* disable the TCP Nagle algorithm for lower latency */
-int socket_set_nodelay(int fd);
-
-/* send OOB data inline for this socket */
-int socket_set_oobinline(int fd);
-
-/* close an opened socket. Note that this is unlike the Unix 'close' because:
- * - it will properly shutdown the socket in the background
- * - it does not modify errno
- */
-void socket_close( int fd );
-
-/* the following functions are equivalent to the BSD sockets ones
- */
-int socket_recv ( int fd, void* buf, int buflen );
-int socket_recvfrom( int fd, void* buf, int buflen, SockAddress* from );
-
-int socket_send ( int fd, const void* buf, int buflen );
-int socket_send_oob( int fd, const void* buf, int buflen );
-int socket_sendto( int fd, const void* buf, int buflen, const SockAddress* to );
-
-int socket_connect( int fd, const SockAddress* address );
-int socket_bind( int fd, const SockAddress* address );
-int socket_get_address( int fd, SockAddress* address );
-int socket_listen( int fd, int backlog );
-int socket_accept( int fd, SockAddress* address );
-
-/* returns the number of bytes that can be read from a socket */
-int socket_can_read( int fd );
-
-/* this call creates a pair of non-blocking sockets connected
- * to each other. this is equivalent to calling the Unix function:
- * socketpair(AF_LOCAL,SOCK_STREAM,0,&fds)
- *
- * on Windows, this will use a pair of TCP loopback sockets instead
- * returns 0 on success, -1 on error.
- */
-int socket_pair(int *fd1, int *fd2);
-
-/* create a server socket listening on the host's loopback interface */
-int socket_loopback_server( int port, SocketType type );
-
-/* connect to a port on the host's loopback interface */
-int socket_loopback_client( int port, SocketType type );
-
-/* create a server socket listening to a Unix domain path */
-#if HAVE_UNIX_SOCKETS
-int socket_unix_server( const char* name, SocketType type );
-#endif
-
-/* create a Unix sockets and connects it to a Unix server */
-#if HAVE_UNIX_SOCKETS
-int socket_unix_client( const char* name, SocketType type );
-#endif
-
-/* create an IPv4 client socket and connect it to a given host */
-int socket_network_client( const char* host, int port, SocketType type );
-
-/* create an IPv4 socket and binds it to a given port of the host's interface */
-int socket_anyaddr_server( int port, SocketType type );
-
-/* accept a connection from the host's any interface, return the new socket
- * descriptor or -1 */
-int socket_accept_any( int server_fd );
-
-
-int socket_mcast_inet_add_membership( int s, uint32_t ip );
-int socket_mcast_inet_drop_membership( int s, uint32_t ip );
-int socket_mcast_inet_set_loop( int s, int enabled );
-int socket_mcast_inet_set_ttl( int s, int ttl );
-
-#endif /* QEMU_SOCKET_H */
diff --git a/softmmu-semi.h b/softmmu-semi.h
deleted file mode 100644
index 8bf96f4..0000000
--- a/softmmu-semi.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Helper routines to provide target memory access for semihosting
- * syscalls in system emulation mode.
- *
- * Copyright (c) 2007 CodeSourcery.
- *
- * This code is licenced under the GPL
- */
-
-static inline uint32_t softmmu_tget32(CPUState *env, uint32_t addr)
-{
- uint32_t val;
-
- cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
- return tswap32(val);
-}
-static inline uint32_t softmmu_tget8(CPUState *env, uint32_t addr)
-{
- uint8_t val;
-
- cpu_memory_rw_debug(env, addr, &val, 1, 0);
- return val;
-}
-
-#define get_user_u32(arg, p) ({ arg = softmmu_tget32(env, p) ; 0; })
-#define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; })
-#define get_user_ual(arg, p) get_user_u32(arg, p)
-
-static inline void softmmu_tput32(CPUState *env, uint32_t addr, uint32_t val)
-{
- val = tswap32(val);
- cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
-}
-#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
-#define put_user_ual(arg, p) put_user_u32(arg, p)
-
-static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,
- int copy)
-{
- char *p;
- /* TODO: Make this something that isn't fixed size. */
- p = malloc(len);
- if (copy)
- cpu_memory_rw_debug(env, addr, p, len, 0);
- return p;
-}
-#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
-static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)
-{
- char *p;
- char *s;
- uint8_t c;
- /* TODO: Make this something that isn't fixed size. */
- s = p = malloc(1024);
- do {
- cpu_memory_rw_debug(env, addr, &c, 1, 0);
- addr++;
- *(p++) = c;
- } while (c);
- return s;
-}
-#define lock_user_string(p) softmmu_lock_user_string(env, p)
-static void softmmu_unlock_user(CPUState *env, void *p, target_ulong addr,
- target_ulong len)
-{
- if (len)
- cpu_memory_rw_debug(env, addr, p, len, 1);
- free(p);
-}
-#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
diff --git a/softmmu_defs.h b/softmmu_defs.h
deleted file mode 100644
index e38bb75..0000000
--- a/softmmu_defs.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef SOFTMMU_DEFS_H
-#define SOFTMMU_DEFS_H
-
-uint8_t REGPARM __ldb_mmu(target_ulong addr, int mmu_idx);
-void REGPARM __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
-uint16_t REGPARM __ldw_mmu(target_ulong addr, int mmu_idx);
-void REGPARM __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx);
-uint32_t REGPARM __ldl_mmu(target_ulong addr, int mmu_idx);
-void REGPARM __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx);
-uint64_t REGPARM __ldq_mmu(target_ulong addr, int mmu_idx);
-void REGPARM __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx);
-
-uint8_t REGPARM __ldb_cmmu(target_ulong addr, int mmu_idx);
-void REGPARM __stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx);
-uint16_t REGPARM __ldw_cmmu(target_ulong addr, int mmu_idx);
-void REGPARM __stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx);
-uint32_t REGPARM __ldl_cmmu(target_ulong addr, int mmu_idx);
-void REGPARM __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
-uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx);
-void REGPARM __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
-
-#endif
diff --git a/softmmu_exec.h b/softmmu_exec.h
deleted file mode 100644
index 9cc4535..0000000
--- a/softmmu_exec.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Common softmmu definitions and inline routines. */
-
-/* XXX: find something cleaner.
- * Furthermore, this is false for 64 bits targets
- */
-#define ldul_user ldl_user
-#define ldul_kernel ldl_kernel
-#define ldul_hypv ldl_hypv
-#define ldul_executive ldl_executive
-#define ldul_supervisor ldl_supervisor
-
-#include "softmmu_defs.h"
-
-#define ACCESS_TYPE 0
-#define MEMSUFFIX MMU_MODE0_SUFFIX
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#define ACCESS_TYPE 1
-#define MEMSUFFIX MMU_MODE1_SUFFIX
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#if (NB_MMU_MODES >= 3)
-
-#define ACCESS_TYPE 2
-#define MEMSUFFIX MMU_MODE2_SUFFIX
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#if (NB_MMU_MODES >= 4)
-
-#define ACCESS_TYPE 3
-#define MEMSUFFIX MMU_MODE3_SUFFIX
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#if (NB_MMU_MODES > 4)
-#error "NB_MMU_MODES > 4 is not supported for now"
-#endif /* (NB_MMU_MODES > 4) */
-#endif /* (NB_MMU_MODES == 4) */
-#endif /* (NB_MMU_MODES >= 3) */
-
-/* these access are slower, they must be as rare as possible */
-#define ACCESS_TYPE (NB_MMU_MODES)
-#define MEMSUFFIX _data
-#define DATA_SIZE 1
-#include "softmmu_header.h"
-
-#define DATA_SIZE 2
-#include "softmmu_header.h"
-
-#define DATA_SIZE 4
-#include "softmmu_header.h"
-
-#define DATA_SIZE 8
-#include "softmmu_header.h"
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-
-#define ldub(p) ldub_data(p)
-#define ldsb(p) ldsb_data(p)
-#define lduw(p) lduw_data(p)
-#define ldsw(p) ldsw_data(p)
-#define ldl(p) ldl_data(p)
-#define ldq(p) ldq_data(p)
-
-#define stb(p, v) stb_data(p, v)
-#define stw(p, v) stw_data(p, v)
-#define stl(p, v) stl_data(p, v)
-#define stq(p, v) stq_data(p, v)
diff --git a/softmmu_header.h b/softmmu_header.h
deleted file mode 100644
index 9649717..0000000
--- a/softmmu_header.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Software MMU support
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#if DATA_SIZE == 8
-#define SUFFIX q
-#define USUFFIX q
-#define DATA_TYPE uint64_t
-#elif DATA_SIZE == 4
-#define SUFFIX l
-#define USUFFIX l
-#define DATA_TYPE uint32_t
-#elif DATA_SIZE == 2
-#define SUFFIX w
-#define USUFFIX uw
-#define DATA_TYPE uint16_t
-#define DATA_STYPE int16_t
-#elif DATA_SIZE == 1
-#define SUFFIX b
-#define USUFFIX ub
-#define DATA_TYPE uint8_t
-#define DATA_STYPE int8_t
-#else
-#error unsupported data size
-#endif
-
-#if ACCESS_TYPE < (NB_MMU_MODES)
-
-#define CPU_MMU_INDEX ACCESS_TYPE
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == (NB_MMU_MODES)
-
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
-#define MMUSUFFIX _mmu
-
-#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
-
-#define CPU_MMU_INDEX (cpu_mmu_index(env))
-#define MMUSUFFIX _cmmu
-
-#else
-#error invalid ACCESS_TYPE
-#endif
-
-#if DATA_SIZE == 8
-#define RES_TYPE uint64_t
-#else
-#define RES_TYPE int
-#endif
-
-#if ACCESS_TYPE == (NB_MMU_MODES + 1)
-#define ADDR_READ addr_code
-#else
-#define ADDR_READ addr_read
-#endif
-
-#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
- (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
-
-static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "movl %6, %%edx\n"
- "call %7\n"
- "movl %%eax, %0\n"
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movzbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movzwl (%%eax), %0\n"
-#elif DATA_SIZE == 4
- "movl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-
-#if DATA_SIZE <= 2
-static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "movl %6, %%edx\n"
- "call %7\n"
-#if DATA_SIZE == 1
- "movsbl %%al, %0\n"
-#elif DATA_SIZE == 2
- "movswl %%ax, %0\n"
-#else
-#error unsupported size
-#endif
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movsbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movswl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-#endif
-
-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-{
- asm volatile ("movl %0, %%edx\n"
- "movl %0, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %0, %%eax\n"
- "je 1f\n"
-#if DATA_SIZE == 1
- "movzbl %b1, %%edx\n"
-#elif DATA_SIZE == 2
- "movzwl %w1, %%edx\n"
-#elif DATA_SIZE == 4
- "movl %1, %%edx\n"
-#else
-#error unsupported size
-#endif
- "movl %6, %%ecx\n"
- "call %7\n"
- "jmp 2f\n"
- "1:\n"
- "addl 8(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movb %b1, (%%eax)\n"
-#elif DATA_SIZE == 2
- "movw %w1, (%%eax)\n"
-#elif DATA_SIZE == 4
- "movl %1, (%%eax)\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- :
- : "r" (ptr),
-#if DATA_SIZE == 1
- "q" (v),
-#else
- "r" (v),
-#endif
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
-}
-
-#else
-
-/* generic load/store macros */
-
-static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int page_index;
- RES_TYPE res;
- target_ulong addr;
- unsigned long physaddr;
- int mmu_idx;
-
- addr = ptr;
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- mmu_idx = CPU_MMU_INDEX;
- if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
- (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
- res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
- } else {
- physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
- }
- return res;
-}
-
-#if DATA_SIZE <= 2
-static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res, page_index;
- target_ulong addr;
- unsigned long physaddr;
- int mmu_idx;
-
- addr = ptr;
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- mmu_idx = CPU_MMU_INDEX;
- if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
- (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
- res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
- } else {
- physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
- res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
- }
- return res;
-}
-#endif
-
-#if ACCESS_TYPE != (NB_MMU_MODES + 1)
-
-/* generic store macro */
-
-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-{
- int page_index;
- target_ulong addr;
- unsigned long physaddr;
- int mmu_idx;
-
- addr = ptr;
- page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- mmu_idx = CPU_MMU_INDEX;
- if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
- (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
- glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
- } else {
- physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
- glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
- }
-}
-
-#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
-
-#endif /* !asm */
-
-#if ACCESS_TYPE != (NB_MMU_MODES + 1)
-
-#if DATA_SIZE == 8
-static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
-{
- union {
- float64 d;
- uint64_t i;
- } u;
- u.i = glue(ldq, MEMSUFFIX)(ptr);
- return u.d;
-}
-
-static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
-{
- union {
- float64 d;
- uint64_t i;
- } u;
- u.d = v;
- glue(stq, MEMSUFFIX)(ptr, u.i);
-}
-#endif /* DATA_SIZE == 8 */
-
-#if DATA_SIZE == 4
-static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.i = glue(ldl, MEMSUFFIX)(ptr);
- return u.f;
-}
-
-static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
-{
- union {
- float32 f;
- uint32_t i;
- } u;
- u.f = v;
- glue(stl, MEMSUFFIX)(ptr, u.i);
-}
-#endif /* DATA_SIZE == 4 */
-
-#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
-
-#undef RES_TYPE
-#undef DATA_TYPE
-#undef DATA_STYPE
-#undef SUFFIX
-#undef USUFFIX
-#undef DATA_SIZE
-#undef CPU_MMU_INDEX
-#undef MMUSUFFIX
-#undef ADDR_READ
diff --git a/softmmu_template.h b/softmmu_template.h
deleted file mode 100644
index 98dd378..0000000
--- a/softmmu_template.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Software MMU support
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#define DATA_SIZE (1 << SHIFT)
-
-#if DATA_SIZE == 8
-#define SUFFIX q
-#define USUFFIX q
-#define DATA_TYPE uint64_t
-#elif DATA_SIZE == 4
-#define SUFFIX l
-#define USUFFIX l
-#define DATA_TYPE uint32_t
-#elif DATA_SIZE == 2
-#define SUFFIX w
-#define USUFFIX uw
-#define DATA_TYPE uint16_t
-#elif DATA_SIZE == 1
-#define SUFFIX b
-#define USUFFIX ub
-#define DATA_TYPE uint8_t
-#else
-#error unsupported data size
-#endif
-
-#ifdef SOFTMMU_CODE_ACCESS
-#define READ_ACCESS_TYPE 2
-#define ADDR_READ addr_code
-#else
-#define READ_ACCESS_TYPE 0
-#define ADDR_READ addr_read
-#endif
-
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int mmu_idx,
- void *retaddr);
-static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
- target_ulong addr,
- void *retaddr)
-{
- DATA_TYPE res;
- int index;
- index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
- env->mem_io_pc = (unsigned long)retaddr;
- if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT)
- && !can_do_io(env)) {
- cpu_io_recompile(env, retaddr);
- }
-
-#if SHIFT <= 2
- res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
-#else
-#ifdef TARGET_WORDS_BIGENDIAN
- res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr) << 32;
- res |= io_mem_read[index][2](io_mem_opaque[index], physaddr + 4);
-#else
- res = io_mem_read[index][2](io_mem_opaque[index], physaddr);
- res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
-#endif
-#endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
- env->last_io_time = cpu_get_time_fast();
-#endif
- return res;
-}
-
-/* handle all cases except unaligned access which span two pages */
-DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int mmu_idx)
-{
- DATA_TYPE res;
- int index;
- target_ulong tlb_addr;
- target_phys_addr_t addend;
- void *retaddr;
-
- /* test if there is match for unaligned or IO access */
- /* XXX: could done more in memory macro in a non portable way */
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- retaddr = GETPC();
- addend = env->iotlb[mmu_idx][index];
- res = glue(io_read, SUFFIX)(addend, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- /* slow unaligned access (it spans two pages or IO) */
- do_unaligned_access:
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
-#endif
- res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
- mmu_idx, retaddr);
- } else {
- /* unaligned/aligned access in the same page */
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0) {
- retaddr = GETPC();
- do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
- }
-#endif
- addend = env->tlb_table[mmu_idx][index].addend;
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
- }
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0)
- do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
-#endif
- tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
- goto redo;
- }
- return res;
-}
-
-/* handle all unaligned cases */
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
- int mmu_idx,
- void *retaddr)
-{
- DATA_TYPE res, res1, res2;
- int index, shift;
- target_phys_addr_t addend;
- target_ulong tlb_addr, addr1, addr2;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- retaddr = GETPC();
- addend = env->iotlb[mmu_idx][index];
- res = glue(io_read, SUFFIX)(addend, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- /* slow unaligned access (it spans two pages) */
- addr1 = addr & ~(DATA_SIZE - 1);
- addr2 = addr1 + DATA_SIZE;
- res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
- mmu_idx, retaddr);
- res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
- mmu_idx, retaddr);
- shift = (addr & (DATA_SIZE - 1)) * 8;
-#ifdef TARGET_WORDS_BIGENDIAN
- res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
-#else
- res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
-#endif
- res = (DATA_TYPE)res;
- } else {
- /* unaligned/aligned access in the same page */
- addend = env->tlb_table[mmu_idx][index].addend;
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
- }
- } else {
- /* the page is not in the TLB : fill it */
- tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
- goto redo;
- }
- return res;
-}
-
-#ifndef SOFTMMU_CODE_ACCESS
-
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
- int mmu_idx,
- void *retaddr);
-
-static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
- DATA_TYPE val,
- target_ulong addr,
- void *retaddr)
-{
- int index;
- index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
- if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT)
- && !can_do_io(env)) {
- cpu_io_recompile(env, retaddr);
- }
-
- env->mem_io_vaddr = addr;
- env->mem_io_pc = (unsigned long)retaddr;
-#if SHIFT <= 2
- io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
-#else
-#ifdef TARGET_WORDS_BIGENDIAN
- io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
- io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
-#else
- io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
- io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
-#endif
-#endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
- int mmu_idx)
-{
- target_phys_addr_t addend;
- target_ulong tlb_addr;
- void *retaddr;
- int index;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- retaddr = GETPC();
- addend = env->iotlb[mmu_idx][index];
- glue(io_write, SUFFIX)(addend, val, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- do_unaligned_access(addr, 1, mmu_idx, retaddr);
-#endif
- glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
- mmu_idx, retaddr);
- } else {
- /* aligned/unaligned access in the same page */
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0) {
- retaddr = GETPC();
- do_unaligned_access(addr, 1, mmu_idx, retaddr);
- }
-#endif
- addend = env->tlb_table[mmu_idx][index].addend;
- glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val);
- }
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0)
- do_unaligned_access(addr, 1, mmu_idx, retaddr);
-#endif
- tlb_fill(addr, 1, mmu_idx, retaddr);
- goto redo;
- }
-}
-
-/* handles all unaligned cases */
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
- DATA_TYPE val,
- int mmu_idx,
- void *retaddr)
-{
- target_phys_addr_t addend;
- target_ulong tlb_addr;
- int index, i;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- addend = env->iotlb[mmu_idx][index];
- glue(io_write, SUFFIX)(addend, val, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- /* XXX: not efficient, but simple */
- /* Note: relies on the fact that tlb_fill() does not remove the
- * previous page from the TLB cache. */
- for(i = DATA_SIZE - 1; i >= 0; i--) {
-#ifdef TARGET_WORDS_BIGENDIAN
- glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
- mmu_idx, retaddr);
-#else
- glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
- mmu_idx, retaddr);
-#endif
- }
- } else {
- /* aligned/unaligned access in the same page */
- addend = env->tlb_table[mmu_idx][index].addend;
- glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val);
- }
- } else {
- /* the page is not in the TLB : fill it */
- tlb_fill(addr, 1, mmu_idx, retaddr);
- goto redo;
- }
-}
-
-#endif /* !defined(SOFTMMU_CODE_ACCESS) */
-
-#undef READ_ACCESS_TYPE
-#undef SHIFT
-#undef DATA_TYPE
-#undef SUFFIX
-#undef USUFFIX
-#undef DATA_SIZE
-#undef ADDR_READ
diff --git a/sparc.ld b/sparc.ld
deleted file mode 100644
index 26ab415..0000000
--- a/sparc.ld
+++ /dev/null
@@ -1,131 +0,0 @@
-OUTPUT_FORMAT("elf32-sparc", "elf32-sparc",
- "elf32-sparc")
-OUTPUT_ARCH(sparc)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata) }
- .tbss : { *(.tbss) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
- /DISCARD/ : { *(.note.GNU-stack) *(.note.ABI-tag) }
-}
diff --git a/sysemu.h b/sysemu.h
deleted file mode 100644
index b12fae0..0000000
--- a/sysemu.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef SYSEMU_H
-#define SYSEMU_H
-/* Misc. things related to the system emulator. */
-
-/* vl.c */
-extern const char *bios_name;
-extern const char *bios_dir;
-
-extern int vm_running;
-extern const char *qemu_name;
-
-typedef struct vm_change_state_entry VMChangeStateEntry;
-typedef void VMChangeStateHandler(void *opaque, int running);
-typedef void VMStopHandler(void *opaque, int reason);
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque);
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque);
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque);
-
-void vm_start(void);
-void vm_stop(int reason);
-
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
-void qemu_system_reset_request(void);
-void qemu_system_shutdown_request(void);
-void qemu_system_powerdown_request(void);
-int qemu_shutdown_requested(void);
-int qemu_reset_requested(void);
-int qemu_powerdown_requested(void);
-#if !defined(TARGET_SPARC) && !defined(TARGET_I386)
-// Please implement a power failure function to signal the OS
-#define qemu_system_powerdown() do{}while(0)
-#else
-void qemu_system_powerdown(void);
-#endif
-void qemu_system_reset(void);
-
-void do_savevm(const char *name);
-void do_loadvm(const char *name);
-void do_delvm(const char *name);
-void do_info_snapshots(void);
-
-void main_loop_wait(int timeout);
-
-/* Polling handling */
-
-/* return TRUE if no sleep should be done afterwards */
-typedef int PollingFunc(void *opaque);
-
-int qemu_add_polling_cb(PollingFunc *func, void *opaque);
-void qemu_del_polling_cb(PollingFunc *func, void *opaque);
-
-#ifdef _WIN32
-/* Wait objects handling */
-typedef void WaitObjectFunc(void *opaque);
-
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-#endif
-
-/* TAP win32 */
-int tap_win32_init(VLANState *vlan, const char *ifname);
-
-/* SLIRP */
-void do_info_slirp(void);
-
-extern int bios_size;
-extern int cirrus_vga_enabled;
-extern int vmsvga_enabled;
-extern int graphic_width;
-extern int graphic_height;
-extern int graphic_depth;
-extern const char *keyboard_layout;
-extern int win2k_install_hack;
-extern int alt_grab;
-extern int usb_enabled;
-extern int smp_cpus;
-extern int cursor_hide;
-extern int graphic_rotate;
-extern int no_quit;
-extern int semihosting_enabled;
-extern int autostart;
-extern int old_param;
-extern const char *bootp_filename;
-
-
-#ifdef USE_KQEMU
-extern int kqemu_allowed;
-#endif
-
-#define MAX_OPTION_ROMS 16
-extern const char *option_rom[MAX_OPTION_ROMS];
-extern int nb_option_roms;
-
-#ifdef TARGET_SPARC
-#define MAX_PROM_ENVS 128
-extern const char *prom_envs[MAX_PROM_ENVS];
-extern unsigned int nb_prom_envs;
-#endif
-
-#if defined (TARGET_PPC)
-#define BIOS_SIZE (1024 * 1024)
-#elif defined (TARGET_SPARC64)
-#define BIOS_SIZE ((512 + 32) * 1024)
-#elif defined(TARGET_MIPS)
-#define BIOS_SIZE (4 * 1024 * 1024)
-#endif
-
-typedef enum {
- IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD
-} BlockInterfaceType;
-
-typedef struct DriveInfo {
- BlockDriverState *bdrv;
- BlockInterfaceType type;
- int bus;
- int unit;
-} DriveInfo;
-
-#define MAX_IDE_DEVS 2
-#define MAX_SCSI_DEVS 7
-#define MAX_DRIVES 32
-
-extern int nb_drives;
-extern DriveInfo drives_table[MAX_DRIVES+1];
-
-extern int drive_get_index(BlockInterfaceType type, int bus, int unit);
-extern int drive_get_max_bus(BlockInterfaceType type);
-
-/* serial ports */
-
-#define MAX_SERIAL_PORTS 4
-
-extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-
-/* parallel ports */
-
-#define MAX_PARALLEL_PORTS 3
-
-extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-
-#ifdef NEED_CPU_H
-/* loader.c */
-int get_image_size(const char *filename);
-int load_image(const char *filename, uint8_t *addr); /* deprecated */
-int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
-int load_elf(const char *filename, int64_t virt_to_phys_addend,
- uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
-int load_aout(const char *filename, target_phys_addr_t addr, int max_sz);
-int load_uboot(const char *filename, target_ulong *ep, int *is_linux);
-
-int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
-int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
-int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes);
-void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
- const char *source);
-#endif
-
-#ifdef HAS_AUDIO
-struct soundhw {
- const char *name;
- const char *descr;
- int enabled;
- int isa;
- union {
- int (*init_isa) (AudioState *s, qemu_irq *pic);
- int (*init_pci) (PCIBus *bus, AudioState *s);
- } init;
-};
-
-extern struct soundhw soundhw[];
-#endif
-
-void do_usb_add(const char *devname);
-void do_usb_del(const char *devname);
-void usb_info(void);
-
-#endif
diff --git a/tap-win32.c b/tap-win32.c
deleted file mode 100644
index b4b61d0..0000000
--- a/tap-win32.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * TAP-Win32 -- A kernel driver to provide virtual tap device functionality
- * on Windows. Originally derived from the CIPE-Win32
- * project by Damion K. Wilson, with extensive modifications by
- * James Yonan.
- *
- * All source code which derives from the CIPE-Win32 project is
- * Copyright (C) Damion K. Wilson, 2003, and is released under the
- * GPL version 2 (see below).
- *
- * All other source code is Copyright (C) James Yonan, 2003-2004,
- * and is released under the GPL version 2 (see below).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdio.h>
-#include <stdint.h>
-#include <windows.h>
-
-/* NOTE: PCIBus is redefined in winddk.h */
-#define PCIBus _PCIBus
-#include <ddk/ntapi.h>
-#include <ddk/winddk.h>
-#include <ddk/ntddk.h>
-#undef PCIBus
-
-//=============
-// TAP IOCTLs
-//=============
-
-#define TAP_CONTROL_CODE(request,method) \
- CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
-
-#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED)
-#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED)
-#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED)
-#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED)
-
-//=================
-// Registry keys
-//=================
-
-#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
-
-//======================
-// Filesystem prefixes
-//======================
-
-#define USERMODEDEVICEDIR "\\\\.\\Global\\"
-#define TAPSUFFIX ".tap"
-
-
-//======================
-// Compile time configuration
-//======================
-
-//#define DEBUG_TAP_WIN32 1
-
-#define TUN_ASYNCHRONOUS_WRITES 1
-
-#define TUN_BUFFER_SIZE 1560
-#define TUN_MAX_BUFFER_COUNT 32
-
-/*
- * The data member "buffer" must be the first element in the tun_buffer
- * structure. See the function, tap_win32_free_buffer.
- */
-typedef struct tun_buffer_s {
- unsigned char buffer [TUN_BUFFER_SIZE];
- unsigned long read_size;
- struct tun_buffer_s* next;
-} tun_buffer_t;
-
-typedef struct tap_win32_overlapped {
- HANDLE handle;
- HANDLE read_event;
- HANDLE write_event;
- HANDLE output_queue_semaphore;
- HANDLE free_list_semaphore;
- CRITICAL_SECTION output_queue_cs;
- CRITICAL_SECTION free_list_cs;
- OVERLAPPED read_overlapped;
- OVERLAPPED write_overlapped;
- tun_buffer_t buffers[TUN_MAX_BUFFER_COUNT];
- tun_buffer_t* free_list;
- tun_buffer_t* output_queue_front;
- tun_buffer_t* output_queue_back;
-} tap_win32_overlapped_t;
-
-static tap_win32_overlapped_t tap_overlapped;
-
-static tun_buffer_t* get_buffer_from_free_list(tap_win32_overlapped_t* const overlapped)
-{
- tun_buffer_t* buffer = NULL;
- WaitForSingleObject(overlapped->free_list_semaphore, INFINITE);
- EnterCriticalSection(&overlapped->free_list_cs);
- buffer = overlapped->free_list;
-// assert(buffer != NULL);
- overlapped->free_list = buffer->next;
- LeaveCriticalSection(&overlapped->free_list_cs);
- buffer->next = NULL;
- return buffer;
-}
-
-static void put_buffer_on_free_list(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer)
-{
- EnterCriticalSection(&overlapped->free_list_cs);
- buffer->next = overlapped->free_list;
- overlapped->free_list = buffer;
- LeaveCriticalSection(&overlapped->free_list_cs);
- ReleaseSemaphore(overlapped->free_list_semaphore, 1, NULL);
-}
-
-static tun_buffer_t* get_buffer_from_output_queue(tap_win32_overlapped_t* const overlapped, const int block)
-{
- tun_buffer_t* buffer = NULL;
- DWORD result, timeout = block ? INFINITE : 0L;
-
- // Non-blocking call
- result = WaitForSingleObject(overlapped->output_queue_semaphore, timeout);
-
- switch (result)
- {
- // The semaphore object was signaled.
- case WAIT_OBJECT_0:
- EnterCriticalSection(&overlapped->output_queue_cs);
-
- buffer = overlapped->output_queue_front;
- overlapped->output_queue_front = buffer->next;
-
- if(overlapped->output_queue_front == NULL) {
- overlapped->output_queue_back = NULL;
- }
-
- LeaveCriticalSection(&overlapped->output_queue_cs);
- break;
-
- // Semaphore was nonsignaled, so a time-out occurred.
- case WAIT_TIMEOUT:
- // Cannot open another window.
- break;
- }
-
- return buffer;
-}
-
-static tun_buffer_t* get_buffer_from_output_queue_immediate (tap_win32_overlapped_t* const overlapped)
-{
- return get_buffer_from_output_queue(overlapped, 0);
-}
-
-static void put_buffer_on_output_queue(tap_win32_overlapped_t* const overlapped, tun_buffer_t* const buffer)
-{
- EnterCriticalSection(&overlapped->output_queue_cs);
-
- if(overlapped->output_queue_front == NULL && overlapped->output_queue_back == NULL) {
- overlapped->output_queue_front = overlapped->output_queue_back = buffer;
- } else {
- buffer->next = NULL;
- overlapped->output_queue_back->next = buffer;
- overlapped->output_queue_back = buffer;
- }
-
- LeaveCriticalSection(&overlapped->output_queue_cs);
-
- ReleaseSemaphore(overlapped->output_queue_semaphore, 1, NULL);
-}
-
-
-static int is_tap_win32_dev(const char *guid)
-{
- HKEY netcard_key;
- LONG status;
- DWORD len;
- int i = 0;
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- ADAPTER_KEY,
- 0,
- KEY_READ,
- &netcard_key);
-
- if (status != ERROR_SUCCESS) {
- return FALSE;
- }
-
- for (;;) {
- char enum_name[256];
- char unit_string[256];
- HKEY unit_key;
- char component_id_string[] = "ComponentId";
- char component_id[256];
- char net_cfg_instance_id_string[] = "NetCfgInstanceId";
- char net_cfg_instance_id[256];
- DWORD data_type;
-
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
- netcard_key,
- i,
- enum_name,
- &len,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS) {
- return FALSE;
- }
-
- snprintf (unit_string, sizeof(unit_string), "%s\\%s",
- ADAPTER_KEY, enum_name);
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- unit_string,
- 0,
- KEY_READ,
- &unit_key);
-
- if (status != ERROR_SUCCESS) {
- return FALSE;
- } else {
- len = sizeof (component_id);
- status = RegQueryValueEx(
- unit_key,
- component_id_string,
- NULL,
- &data_type,
- component_id,
- &len);
-
- if (!(status != ERROR_SUCCESS || data_type != REG_SZ)) {
- len = sizeof (net_cfg_instance_id);
- status = RegQueryValueEx(
- unit_key,
- net_cfg_instance_id_string,
- NULL,
- &data_type,
- net_cfg_instance_id,
- &len);
-
- if (status == ERROR_SUCCESS && data_type == REG_SZ) {
- if (/* !strcmp (component_id, TAP_COMPONENT_ID) &&*/
- !strcmp (net_cfg_instance_id, guid)) {
- RegCloseKey (unit_key);
- RegCloseKey (netcard_key);
- return TRUE;
- }
- }
- }
- RegCloseKey (unit_key);
- }
- ++i;
- }
-
- RegCloseKey (netcard_key);
- return FALSE;
-}
-
-static int get_device_guid(
- char *name,
- int name_size,
- char *actual_name,
- int actual_name_size)
-{
- LONG status;
- HKEY control_net_key;
- DWORD len;
- int i = 0;
- int stop = 0;
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- NETWORK_CONNECTIONS_KEY,
- 0,
- KEY_READ,
- &control_net_key);
-
- if (status != ERROR_SUCCESS) {
- return -1;
- }
-
- while (!stop)
- {
- char enum_name[256];
- char connection_string[256];
- HKEY connection_key;
- char name_data[256];
- DWORD name_type;
- const char name_string[] = "Name";
-
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
- control_net_key,
- i,
- enum_name,
- &len,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS) {
- return -1;
- }
-
- snprintf(connection_string,
- sizeof(connection_string),
- "%s\\%s\\Connection",
- NETWORK_CONNECTIONS_KEY, enum_name);
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- connection_string,
- 0,
- KEY_READ,
- &connection_key);
-
- if (status == ERROR_SUCCESS) {
- len = sizeof (name_data);
- status = RegQueryValueEx(
- connection_key,
- name_string,
- NULL,
- &name_type,
- name_data,
- &len);
-
- if (status != ERROR_SUCCESS || name_type != REG_SZ) {
- return -1;
- }
- else {
- if (is_tap_win32_dev(enum_name)) {
- snprintf(name, name_size, "%s", enum_name);
- if (actual_name) {
- if (strcmp(actual_name, "") != 0) {
- if (strcmp(name_data, actual_name) != 0) {
- RegCloseKey (connection_key);
- ++i;
- continue;
- }
- }
- else {
- snprintf(actual_name, actual_name_size, "%s", name_data);
- }
- }
- stop = 1;
- }
- }
-
- RegCloseKey (connection_key);
- }
- ++i;
- }
-
- RegCloseKey (control_net_key);
-
- if (stop == 0)
- return -1;
-
- return 0;
-}
-
-static int tap_win32_set_status(HANDLE handle, int status)
-{
- unsigned long len = 0;
-
- return DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS,
- &status, sizeof (status),
- &status, sizeof (status), &len, NULL);
-}
-
-static void tap_win32_overlapped_init(tap_win32_overlapped_t* const overlapped, const HANDLE handle)
-{
- overlapped->handle = handle;
-
- overlapped->read_event = CreateEvent(NULL, FALSE, FALSE, NULL);
- overlapped->write_event = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- overlapped->read_overlapped.Offset = 0;
- overlapped->read_overlapped.OffsetHigh = 0;
- overlapped->read_overlapped.hEvent = overlapped->read_event;
-
- overlapped->write_overlapped.Offset = 0;
- overlapped->write_overlapped.OffsetHigh = 0;
- overlapped->write_overlapped.hEvent = overlapped->write_event;
-
- InitializeCriticalSection(&overlapped->output_queue_cs);
- InitializeCriticalSection(&overlapped->free_list_cs);
-
- overlapped->output_queue_semaphore = CreateSemaphore(
- NULL, // default security attributes
- 0, // initial count
- TUN_MAX_BUFFER_COUNT, // maximum count
- NULL); // unnamed semaphore
-
- if(!overlapped->output_queue_semaphore) {
- fprintf(stderr, "error creating output queue semaphore!\n");
- }
-
- overlapped->free_list_semaphore = CreateSemaphore(
- NULL, // default security attributes
- TUN_MAX_BUFFER_COUNT, // initial count
- TUN_MAX_BUFFER_COUNT, // maximum count
- NULL); // unnamed semaphore
-
- if(!overlapped->free_list_semaphore) {
- fprintf(stderr, "error creating free list semaphore!\n");
- }
-
- overlapped->free_list = overlapped->output_queue_front = overlapped->output_queue_back = NULL;
-
- {
- unsigned index;
- for(index = 0; index < TUN_MAX_BUFFER_COUNT; index++) {
- tun_buffer_t* element = &overlapped->buffers[index];
- element->next = overlapped->free_list;
- overlapped->free_list = element;
- }
- }
-}
-
-static int tap_win32_write(tap_win32_overlapped_t *overlapped,
- const void *buffer, unsigned long size)
-{
- unsigned long write_size;
- BOOL result;
- DWORD error;
-
- result = GetOverlappedResult( overlapped->handle, &overlapped->write_overlapped,
- &write_size, FALSE);
-
- if (!result && GetLastError() == ERROR_IO_INCOMPLETE)
- WaitForSingleObject(overlapped->write_event, INFINITE);
-
- result = WriteFile(overlapped->handle, buffer, size,
- &write_size, &overlapped->write_overlapped);
-
- if (!result) {
- switch (error = GetLastError())
- {
- case ERROR_IO_PENDING:
-#ifndef TUN_ASYNCHRONOUS_WRITES
- WaitForSingleObject(overlapped->write_event, INFINITE);
-#endif
- break;
- default:
- return -1;
- }
- }
-
- return 0;
-}
-
-static DWORD WINAPI tap_win32_thread_entry(LPVOID param)
-{
- tap_win32_overlapped_t *overlapped = (tap_win32_overlapped_t*)param;
- unsigned long read_size;
- BOOL result;
- DWORD dwError;
- tun_buffer_t* buffer = get_buffer_from_free_list(overlapped);
-
-
- for (;;) {
- result = ReadFile(overlapped->handle,
- buffer->buffer,
- sizeof(buffer->buffer),
- &read_size,
- &overlapped->read_overlapped);
- if (!result) {
- dwError = GetLastError();
- if (dwError == ERROR_IO_PENDING) {
- WaitForSingleObject(overlapped->read_event, INFINITE);
- result = GetOverlappedResult( overlapped->handle, &overlapped->read_overlapped,
- &read_size, FALSE);
- if (!result) {
-#if DEBUG_TAP_WIN32
- LPVOID lpBuffer;
- dwError = GetLastError();
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) & lpBuffer, 0, NULL );
- fprintf(stderr, "Tap-Win32: Error GetOverlappedResult %d - %s\n", dwError, lpBuffer);
- LocalFree( lpBuffer );
-#endif
- }
- } else {
-#if DEBUG_TAP_WIN32
- LPVOID lpBuffer;
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) & lpBuffer, 0, NULL );
- fprintf(stderr, "Tap-Win32: Error ReadFile %d - %s\n", dwError, lpBuffer);
- LocalFree( lpBuffer );
-#endif
- }
- }
-
- if(read_size > 0) {
- buffer->read_size = read_size;
- put_buffer_on_output_queue(overlapped, buffer);
- buffer = get_buffer_from_free_list(overlapped);
- }
- }
-
- return 0;
-}
-
-static int tap_win32_read(tap_win32_overlapped_t *overlapped,
- uint8_t **pbuf, int max_size)
-{
- int size = 0;
-
- tun_buffer_t* buffer = get_buffer_from_output_queue_immediate(overlapped);
-
- if(buffer != NULL) {
- *pbuf = buffer->buffer;
- size = (int)buffer->read_size;
- if(size > max_size) {
- size = max_size;
- }
- }
-
- return size;
-}
-
-static void tap_win32_free_buffer(tap_win32_overlapped_t *overlapped,
- char* pbuf)
-{
- tun_buffer_t* buffer = (tun_buffer_t*)pbuf;
- put_buffer_on_free_list(overlapped, buffer);
-}
-
-static int tap_win32_open(tap_win32_overlapped_t **phandle,
- const char *prefered_name)
-{
- char device_path[256];
- char device_guid[0x100];
- int rc;
- HANDLE handle;
- BOOL bret;
- char name_buffer[0x100] = {0, };
- struct {
- unsigned long major;
- unsigned long minor;
- unsigned long debug;
- } version;
- LONG version_len;
- DWORD idThread;
- HANDLE hThread;
-
- if (prefered_name != NULL)
- snprintf(name_buffer, sizeof(name_buffer), "%s", prefered_name);
-
- rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
- if (rc)
- return -1;
-
- snprintf (device_path, sizeof(device_path), "%s%s%s",
- USERMODEDEVICEDIR,
- device_guid,
- TAPSUFFIX);
-
- handle = CreateFile (
- device_path,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- 0,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
- 0 );
-
- if (handle == INVALID_HANDLE_VALUE) {
- return -1;
- }
-
- bret = DeviceIoControl(handle, TAP_IOCTL_GET_VERSION,
- &version, sizeof (version),
- &version, sizeof (version), &version_len, NULL);
-
- if (bret == FALSE) {
- CloseHandle(handle);
- return -1;
- }
-
- if (!tap_win32_set_status(handle, TRUE)) {
- return -1;
- }
-
- tap_win32_overlapped_init(&tap_overlapped, handle);
-
- *phandle = &tap_overlapped;
-
- hThread = CreateThread(NULL, 0, tap_win32_thread_entry,
- (LPVOID)&tap_overlapped, 0, &idThread);
- SetThreadPriority(hThread,THREAD_PRIORITY_TIME_CRITICAL);
-
- return 0;
-}
-
-/********************************************/
-
- typedef struct TAPState {
- VLANClientState *vc;
- tap_win32_overlapped_t *handle;
- HANDLE tap_event;
- } TAPState;
-
-static TAPState *tap_win32_state = NULL;
-
-void tap_receive(void *opaque, const uint8_t *buf, int size)
-{
- TAPState *s = opaque;
-
- tap_win32_write(s->handle, buf, size);
-}
-
-/* XXX: horrible, suppress this by using proper thread signaling */
-void tap_win32_poll(void)
-{
- TAPState *s = tap_win32_state;
- uint8_t *buf;
- int max_size = 4096;
- int size;
-
- if (!s)
- return;
-
- size = tap_win32_read(s->handle, &buf, max_size);
- if (size > 0) {
- qemu_send_packet(s->vc, buf, size);
- tap_win32_free_buffer(s->handle, buf);
- SetEvent(s->tap_event);
- }
-}
-
-int tap_win32_init(VLANState *vlan, const char *ifname)
-{
- TAPState *s;
-
- s = qemu_mallocz(sizeof(TAPState));
- if (!s)
- return -1;
- if (tap_win32_open(&s->handle, ifname) < 0) {
- printf("tap: Could not open '%s'\n", ifname);
- return -1;
- }
-
- s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "tap: ifname=%s", ifname);
- tap_win32_state = s;
-
- s->tap_event = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!s->tap_event) {
- fprintf(stderr, "tap-win32: Failed CreateEvent\n");
- }
- qemu_add_wait_object(s->tap_event, NULL, NULL);
- return 0;
-}
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
deleted file mode 100644
index ff765f7..0000000
--- a/target-arm/cpu.h
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * ARM virtual CPU header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_ARM_H
-#define CPU_ARM_H
-
-#define TARGET_LONG_BITS 32
-
-#define ELF_MACHINE EM_ARM
-
-#include "cpu-defs.h"
-
-#include "softfloat.h"
-
-#define TARGET_HAS_ICE 1
-
-#define EXCP_UDEF 1 /* undefined instruction */
-#define EXCP_SWI 2 /* software interrupt */
-#define EXCP_PREFETCH_ABORT 3
-#define EXCP_DATA_ABORT 4
-#define EXCP_IRQ 5
-#define EXCP_FIQ 6
-#define EXCP_BKPT 7
-#define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */
-#define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */
-
-#define ARMV7M_EXCP_RESET 1
-#define ARMV7M_EXCP_NMI 2
-#define ARMV7M_EXCP_HARD 3
-#define ARMV7M_EXCP_MEM 4
-#define ARMV7M_EXCP_BUS 5
-#define ARMV7M_EXCP_USAGE 6
-#define ARMV7M_EXCP_SVC 11
-#define ARMV7M_EXCP_DEBUG 12
-#define ARMV7M_EXCP_PENDSV 14
-#define ARMV7M_EXCP_SYSTICK 15
-
-typedef void ARMWriteCPFunc(void *opaque, int cp_info,
- int srcreg, int operand, uint32_t value);
-typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
- int dstreg, int operand);
-
-struct arm_boot_info;
-
-#define NB_MMU_MODES 2
-
-/* We currently assume float and double are IEEE single and double
- precision respectively.
- Doing runtime conversions is tricky because VFP registers may contain
- integer values (eg. as the result of a FTOSI instruction).
- s<2n> maps to the least significant half of d<n>
- s<2n+1> maps to the most significant half of d<n>
- */
-
-typedef struct CPUARMState {
- /* Regs for current mode. */
- uint32_t regs[16];
- /* Frequently accessed CPSR bits are stored separately for efficiently.
- This contains all the other bits. Use cpsr_{read,write} to access
- the whole CPSR. */
- uint32_t uncached_cpsr;
- uint32_t spsr;
-
- /* Banked registers. */
- uint32_t banked_spsr[6];
- uint32_t banked_r13[6];
- uint32_t banked_r14[6];
-
- /* These hold r8-r12. */
- uint32_t usr_regs[5];
- uint32_t fiq_regs[5];
-
- /* cpsr flag cache for faster execution */
- uint32_t CF; /* 0 or 1 */
- uint32_t VF; /* V is the bit 31. All other bits are undefined */
- uint32_t NF; /* N is bit 31. All other bits are undefined. */
- uint32_t ZF; /* Z set if zero. */
- uint32_t QF; /* 0 or 1 */
- uint32_t GE; /* cpsr[19:16] */
- uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
- uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
-
- /* System control coprocessor (cp15) */
- struct {
- uint32_t c0_cpuid;
- uint32_t c0_cachetype;
- uint32_t c0_c1[8]; /* Feature registers. */
- uint32_t c0_c2[8]; /* Instruction set registers. */
- uint32_t c1_sys; /* System control register. */
- uint32_t c1_coproc; /* Coprocessor access register. */
- uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
- uint32_t c2_base0; /* MMU translation table base 0. */
- uint32_t c2_base1; /* MMU translation table base 1. */
- uint32_t c2_mask; /* MMU translation table base mask. */
- uint32_t c2_data; /* MPU data cachable bits. */
- uint32_t c2_insn; /* MPU instruction cachable bits. */
- uint32_t c3; /* MMU domain access control register
- MPU write buffer control. */
- uint32_t c5_insn; /* Fault status registers. */
- uint32_t c5_data;
- uint32_t c6_region[8]; /* MPU base/size registers. */
- uint32_t c6_insn; /* Fault address registers. */
- uint32_t c6_data;
- uint32_t c9_insn; /* Cache lockdown registers. */
- uint32_t c9_data;
- uint32_t c13_fcse; /* FCSE PID. */
- uint32_t c13_context; /* Context ID. */
- uint32_t c13_tls1; /* User RW Thread register. */
- uint32_t c13_tls2; /* User RO Thread register. */
- uint32_t c13_tls3; /* Privileged Thread register. */
- uint32_t c15_cpar; /* XScale Coprocessor Access Register */
- uint32_t c15_ticonfig; /* TI925T configuration byte. */
- uint32_t c15_i_max; /* Maximum D-cache dirty line index. */
- uint32_t c15_i_min; /* Minimum D-cache dirty line index. */
- uint32_t c15_threadid; /* TI debugger thread-ID. */
- } cp15;
-
- struct {
- uint32_t other_sp;
- uint32_t vecbase;
- uint32_t basepri;
- uint32_t control;
- int current_sp;
- int exception;
- int pending_exception;
- void *nvic;
- } v7m;
-
- /* Coprocessor IO used by peripherals */
- struct {
- ARMReadCPFunc *cp_read;
- ARMWriteCPFunc *cp_write;
- void *opaque;
- } cp[15];
-
- /* Internal CPU feature flags. */
- uint32_t features;
-
- /* Callback for vectored interrupt controller. */
- int (*get_irq_vector)(struct CPUARMState *);
- void *irq_opaque;
-
- /* VFP coprocessor state. */
- struct {
- float64 regs[32];
-
- uint32_t xregs[16];
- /* We store these fpcsr fields separately for convenience. */
- int vec_len;
- int vec_stride;
-
- /* scratch space when Tn are not sufficient. */
- uint32_t scratch[8];
-
- float_status fp_status;
- } vfp;
-#if defined(CONFIG_USER_ONLY)
- struct mmon_state *mmon_entry;
-#else
- uint32_t mmon_addr;
-#endif
-
- /* iwMMXt coprocessor state. */
- struct {
- uint64_t regs[16];
- uint64_t val;
-
- uint32_t cregs[16];
- } iwmmxt;
-
-#if defined(CONFIG_USER_ONLY)
- /* For usermode syscall translation. */
- int eabi;
-#endif
-
- CPU_COMMON
-
- /* These fields after the common ones so they are preserved on reset. */
- struct arm_boot_info *boot_info;
-} CPUARMState;
-
-CPUARMState *cpu_arm_init(const char *cpu_model);
-void arm_translate_init(void);
-int cpu_arm_exec(CPUARMState *s);
-void cpu_arm_close(CPUARMState *s);
-void do_interrupt(CPUARMState *);
-void switch_mode(CPUARMState *, int);
-uint32_t do_arm_semihosting(CPUARMState *env);
-
-/* you can call this signal handler from your SIGBUS and SIGSEGV
- signal handlers to inform the virtual CPU of exceptions. non zero
- is returned if the signal was handled by the virtual CPU. */
-int cpu_arm_signal_handler(int host_signum, void *pinfo,
- void *puc);
-
-void cpu_lock(void);
-void cpu_unlock(void);
-static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
-{
- env->cp15.c13_tls2 = newtls;
-}
-
-#define CPSR_M (0x1f)
-#define CPSR_T (1 << 5)
-#define CPSR_F (1 << 6)
-#define CPSR_I (1 << 7)
-#define CPSR_A (1 << 8)
-#define CPSR_E (1 << 9)
-#define CPSR_IT_2_7 (0xfc00)
-#define CPSR_GE (0xf << 16)
-#define CPSR_RESERVED (0xf << 20)
-#define CPSR_J (1 << 24)
-#define CPSR_IT_0_1 (3 << 25)
-#define CPSR_Q (1 << 27)
-#define CPSR_V (1 << 28)
-#define CPSR_C (1 << 29)
-#define CPSR_Z (1 << 30)
-#define CPSR_N (1 << 31)
-#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
-
-#define CPSR_IT (CPSR_IT_0_1 | CPSR_IT_2_7)
-#define CACHED_CPSR_BITS (CPSR_T | CPSR_GE | CPSR_IT | CPSR_Q | CPSR_NZCV)
-/* Bits writable in user mode. */
-#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE)
-/* Execution state bits. MRS read as zero, MSR writes ignored. */
-#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J)
-
-/* Return the current CPSR value. */
-uint32_t cpsr_read(CPUARMState *env);
-/* Set the CPSR. Note that some bits of mask must be all-set or all-clear. */
-void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask);
-
-/* Return the current xPSR value. */
-static inline uint32_t xpsr_read(CPUARMState *env)
-{
- int ZF;
- ZF = (env->ZF == 0);
- return (env->NF & 0x80000000) | (ZF << 30)
- | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
- | (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
- | ((env->condexec_bits & 0xfc) << 8)
- | env->v7m.exception;
-}
-
-/* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */
-static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
-{
- if (mask & CPSR_NZCV) {
- env->ZF = (~val) & CPSR_Z;
- env->NF = val;
- env->CF = (val >> 29) & 1;
- env->VF = (val << 3) & 0x80000000;
- }
- if (mask & CPSR_Q)
- env->QF = ((val & CPSR_Q) != 0);
- if (mask & (1 << 24))
- env->thumb = ((val & (1 << 24)) != 0);
- if (mask & CPSR_IT_0_1) {
- env->condexec_bits &= ~3;
- env->condexec_bits |= (val >> 25) & 3;
- }
- if (mask & CPSR_IT_2_7) {
- env->condexec_bits &= 3;
- env->condexec_bits |= (val >> 8) & 0xfc;
- }
- if (mask & 0x1ff) {
- env->v7m.exception = val & 0x1ff;
- }
-}
-
-enum arm_cpu_mode {
- ARM_CPU_MODE_USR = 0x10,
- ARM_CPU_MODE_FIQ = 0x11,
- ARM_CPU_MODE_IRQ = 0x12,
- ARM_CPU_MODE_SVC = 0x13,
- ARM_CPU_MODE_ABT = 0x17,
- ARM_CPU_MODE_UND = 0x1b,
- ARM_CPU_MODE_SYS = 0x1f
-};
-
-/* VFP system registers. */
-#define ARM_VFP_FPSID 0
-#define ARM_VFP_FPSCR 1
-#define ARM_VFP_MVFR1 6
-#define ARM_VFP_MVFR0 7
-#define ARM_VFP_FPEXC 8
-#define ARM_VFP_FPINST 9
-#define ARM_VFP_FPINST2 10
-
-/* iwMMXt coprocessor control registers. */
-#define ARM_IWMMXT_wCID 0
-#define ARM_IWMMXT_wCon 1
-#define ARM_IWMMXT_wCSSF 2
-#define ARM_IWMMXT_wCASF 3
-#define ARM_IWMMXT_wCGR0 8
-#define ARM_IWMMXT_wCGR1 9
-#define ARM_IWMMXT_wCGR2 10
-#define ARM_IWMMXT_wCGR3 11
-
-enum arm_features {
- ARM_FEATURE_VFP,
- ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
- ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
- ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */
- ARM_FEATURE_V6,
- ARM_FEATURE_V6K,
- ARM_FEATURE_V7,
- ARM_FEATURE_THUMB2,
- ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */
- ARM_FEATURE_VFP3,
- ARM_FEATURE_NEON,
- ARM_FEATURE_DIV,
- ARM_FEATURE_M, /* Microcontroller profile. */
- ARM_FEATURE_OMAPCP /* OMAP specific CP15 ops handling. */
-};
-
-static inline int arm_feature(CPUARMState *env, int feature)
-{
- return (env->features & (1u << feature)) != 0;
-}
-
-void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
-
-/* Interface between CPU and Interrupt controller. */
-void armv7m_nvic_set_pending(void *opaque, int irq);
-int armv7m_nvic_acknowledge_irq(void *opaque);
-void armv7m_nvic_complete_irq(void *opaque, int irq);
-
-void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
- ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
- void *opaque);
-
-/* Does the core conform to the the "MicroController" profile. e.g. Cortex-M3.
- Note the M in older cores (eg. ARM7TDMI) stands for Multiply. These are
- conventional cores (ie. Application or Realtime profile). */
-
-#define IS_M(env) arm_feature(env, ARM_FEATURE_M)
-#define ARM_CPUID(env) (env->cp15.c0_cpuid)
-
-#define ARM_CPUID_ARM1026 0x4106a262
-#define ARM_CPUID_ARM926 0x41069265
-#define ARM_CPUID_ARM946 0x41059461
-#define ARM_CPUID_TI915T 0x54029152
-#define ARM_CPUID_TI925T 0x54029252
-#define ARM_CPUID_PXA250 0x69052100
-#define ARM_CPUID_PXA255 0x69052d00
-#define ARM_CPUID_PXA260 0x69052903
-#define ARM_CPUID_PXA261 0x69052d05
-#define ARM_CPUID_PXA262 0x69052d06
-#define ARM_CPUID_PXA270 0x69054110
-#define ARM_CPUID_PXA270_A0 0x69054110
-#define ARM_CPUID_PXA270_A1 0x69054111
-#define ARM_CPUID_PXA270_B0 0x69054112
-#define ARM_CPUID_PXA270_B1 0x69054113
-#define ARM_CPUID_PXA270_C0 0x69054114
-#define ARM_CPUID_PXA270_C5 0x69054117
-#define ARM_CPUID_ARM1136 0x4117b363
-#define ARM_CPUID_ARM1136_R2 0x4107b362
-#define ARM_CPUID_ARM11MPCORE 0x410fb022
-#define ARM_CPUID_CORTEXA8 0x410fc080
-#define ARM_CPUID_CORTEXM3 0x410fc231
-#define ARM_CPUID_ANY 0xffffffff
-
-#if defined(CONFIG_USER_ONLY)
-#define TARGET_PAGE_BITS 12
-#else
-/* The ARM MMU allows 1k pages. */
-/* ??? Linux doesn't actually use these, and they're deprecated in recent
- architecture revisions. Maybe a configure option to disable them. */
-#define TARGET_PAGE_BITS 10
-#endif
-
-#define CPUState CPUARMState
-#define cpu_init cpu_arm_init
-#define cpu_exec cpu_arm_exec
-#define cpu_gen_code cpu_arm_gen_code
-#define cpu_signal_handler cpu_arm_signal_handler
-#define cpu_list arm_cpu_list
-
-#define CPU_SAVE_VERSION 1
-
-/* MMU modes definitions */
-#define MMU_MODE0_SUFFIX _kernel
-#define MMU_MODE1_SUFFIX _user
-#define MMU_USER_IDX 1
-static inline int cpu_mmu_index (CPUState *env)
-{
- return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
-}
-
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
-{
- if (newsp)
- env->regs[13] = newsp;
- env->regs[0] = 0;
-}
-#endif
-
-#define CPU_PC_FROM_TB(env, tb) env->regs[15] = tb->pc
-
-#include "cpu-all.h"
-
-#endif
diff --git a/target-arm/exec.h b/target-arm/exec.h
deleted file mode 100644
index c543cf4..0000000
--- a/target-arm/exec.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * ARM execution defines
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#include "dyngen-exec.h"
-
-register struct CPUARMState *env asm(AREG0);
-register uint32_t T0 asm(AREG1);
-register uint32_t T1 asm(AREG2);
-
-#define M0 env->iwmmxt.val
-
-#include "cpu.h"
-#include "exec-all.h"
-
-static inline void env_to_regs(void)
-{
-}
-
-static inline void regs_to_env(void)
-{
-}
-
-int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
- int mmu_idx, int is_softmmu);
-
-static inline int cpu_halted(CPUState *env) {
- if (!env->halted)
- return 0;
- /* An interrupt wakes the CPU even if the I and F CPSR bits are
- set. We use EXITTB to silently wake CPU without causing an
- actual interrupt. */
- if (env->interrupt_request &
- (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-#include "softmmu_exec.h"
-#endif
-
-void cpu_loop_exit(void);
-
-void raise_exception(int);
diff --git a/target-arm/helper.c b/target-arm/helper.c
deleted file mode 100644
index 7cc8b0f..0000000
--- a/target-arm/helper.c
+++ /dev/null
@@ -1,2553 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "gdbstub.h"
-#include "helpers.h"
-#include "qemu-common.h"
-
-static uint32_t cortexa8_cp15_c0_c1[8] =
-{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
-
-static uint32_t cortexa8_cp15_c0_c2[8] =
-{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
-
-static uint32_t mpcore_cp15_c0_c1[8] =
-{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
-
-static uint32_t mpcore_cp15_c0_c2[8] =
-{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
-
-static uint32_t arm1136_cp15_c0_c1[8] =
-{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
-
-static uint32_t arm1136_cp15_c0_c2[8] =
-{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
-
-static uint32_t cpu_arm_find_by_name(const char *name);
-
-static inline void set_feature(CPUARMState *env, int feature)
-{
- env->features |= 1u << feature;
-}
-
-static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
-{
- env->cp15.c0_cpuid = id;
- switch (id) {
- case ARM_CPUID_ARM926:
- set_feature(env, ARM_FEATURE_VFP);
- env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
- env->cp15.c0_cachetype = 0x1dd20d2;
- env->cp15.c1_sys = 0x00090078;
- break;
- case ARM_CPUID_ARM946:
- set_feature(env, ARM_FEATURE_MPU);
- env->cp15.c0_cachetype = 0x0f004006;
- env->cp15.c1_sys = 0x00000078;
- break;
- case ARM_CPUID_ARM1026:
- set_feature(env, ARM_FEATURE_VFP);
- set_feature(env, ARM_FEATURE_AUXCR);
- env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
- env->cp15.c0_cachetype = 0x1dd20d2;
- env->cp15.c1_sys = 0x00090078;
- break;
- case ARM_CPUID_ARM1136_R2:
- case ARM_CPUID_ARM1136:
- set_feature(env, ARM_FEATURE_V6);
- set_feature(env, ARM_FEATURE_VFP);
- set_feature(env, ARM_FEATURE_AUXCR);
- env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
- env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
- env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
- memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
- memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
- env->cp15.c0_cachetype = 0x1dd20d2;
- break;
- case ARM_CPUID_ARM11MPCORE:
- set_feature(env, ARM_FEATURE_V6);
- set_feature(env, ARM_FEATURE_V6K);
- set_feature(env, ARM_FEATURE_VFP);
- set_feature(env, ARM_FEATURE_AUXCR);
- env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
- env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
- env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
- memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
- memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
- env->cp15.c0_cachetype = 0x1dd20d2;
- break;
- case ARM_CPUID_CORTEXA8:
- set_feature(env, ARM_FEATURE_V6);
- set_feature(env, ARM_FEATURE_V6K);
- set_feature(env, ARM_FEATURE_V7);
- set_feature(env, ARM_FEATURE_AUXCR);
- set_feature(env, ARM_FEATURE_THUMB2);
- set_feature(env, ARM_FEATURE_VFP);
- set_feature(env, ARM_FEATURE_VFP3);
- set_feature(env, ARM_FEATURE_NEON);
- env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
- env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
- env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
- memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
- memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
- env->cp15.c0_cachetype = 0x1dd20d2;
- break;
- case ARM_CPUID_CORTEXM3:
- set_feature(env, ARM_FEATURE_V6);
- set_feature(env, ARM_FEATURE_THUMB2);
- set_feature(env, ARM_FEATURE_V7);
- set_feature(env, ARM_FEATURE_M);
- set_feature(env, ARM_FEATURE_DIV);
- break;
- case ARM_CPUID_ANY: /* For userspace emulation. */
- set_feature(env, ARM_FEATURE_V6);
- set_feature(env, ARM_FEATURE_V6K);
- set_feature(env, ARM_FEATURE_V7);
- set_feature(env, ARM_FEATURE_THUMB2);
- set_feature(env, ARM_FEATURE_VFP);
- set_feature(env, ARM_FEATURE_VFP3);
- set_feature(env, ARM_FEATURE_NEON);
- set_feature(env, ARM_FEATURE_DIV);
- break;
- case ARM_CPUID_TI915T:
- case ARM_CPUID_TI925T:
- set_feature(env, ARM_FEATURE_OMAPCP);
- env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */
- env->cp15.c0_cachetype = 0x5109149;
- env->cp15.c1_sys = 0x00000070;
- env->cp15.c15_i_max = 0x000;
- env->cp15.c15_i_min = 0xff0;
- break;
- case ARM_CPUID_PXA250:
- case ARM_CPUID_PXA255:
- case ARM_CPUID_PXA260:
- case ARM_CPUID_PXA261:
- case ARM_CPUID_PXA262:
- set_feature(env, ARM_FEATURE_XSCALE);
- /* JTAG_ID is ((id << 28) | 0x09265013) */
- env->cp15.c0_cachetype = 0xd172172;
- env->cp15.c1_sys = 0x00000078;
- break;
- case ARM_CPUID_PXA270_A0:
- case ARM_CPUID_PXA270_A1:
- case ARM_CPUID_PXA270_B0:
- case ARM_CPUID_PXA270_B1:
- case ARM_CPUID_PXA270_C0:
- case ARM_CPUID_PXA270_C5:
- set_feature(env, ARM_FEATURE_XSCALE);
- /* JTAG_ID is ((id << 28) | 0x09265013) */
- set_feature(env, ARM_FEATURE_IWMMXT);
- env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
- env->cp15.c0_cachetype = 0xd172172;
- env->cp15.c1_sys = 0x00000078;
- break;
- default:
- cpu_abort(env, "Bad CPU ID: %x\n", id);
- break;
- }
-}
-
-void cpu_reset(CPUARMState *env)
-{
- uint32_t id;
- id = env->cp15.c0_cpuid;
- memset(env, 0, offsetof(CPUARMState, breakpoints));
- if (id)
- cpu_reset_model_id(env, id);
-#if defined (CONFIG_USER_ONLY)
- env->uncached_cpsr = ARM_CPU_MODE_USR;
- env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
-#else
- /* SVC mode with interrupts disabled. */
- env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
- /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
- clear at reset. */
- if (IS_M(env))
- env->uncached_cpsr &= ~CPSR_I;
- env->vfp.xregs[ARM_VFP_FPEXC] = 0;
-#endif
- env->regs[15] = 0;
- tlb_flush(env, 1);
-}
-
-CPUARMState *cpu_arm_init(const char *cpu_model)
-{
- CPUARMState *env;
- uint32_t id;
- static int inited = 0;
-
- id = cpu_arm_find_by_name(cpu_model);
- if (id == 0)
- return NULL;
- env = qemu_mallocz(sizeof(CPUARMState));
- if (!env)
- return NULL;
- cpu_exec_init(env);
- if (!inited) {
- inited = 1;
- arm_translate_init();
- }
-
- env->cpu_model_str = cpu_model;
- env->cp15.c0_cpuid = id;
- cpu_reset(env);
- return env;
-}
-
-struct arm_cpu_t {
- uint32_t id;
- const char *name;
-};
-
-static const struct arm_cpu_t arm_cpu_names[] = {
- { ARM_CPUID_ARM926, "arm926"},
- { ARM_CPUID_ARM946, "arm946"},
- { ARM_CPUID_ARM1026, "arm1026"},
- { ARM_CPUID_ARM1136, "arm1136"},
- { ARM_CPUID_ARM1136_R2, "arm1136-r2"},
- { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
- { ARM_CPUID_CORTEXM3, "cortex-m3"},
- { ARM_CPUID_CORTEXA8, "cortex-a8"},
- { ARM_CPUID_TI925T, "ti925t" },
- { ARM_CPUID_PXA250, "pxa250" },
- { ARM_CPUID_PXA255, "pxa255" },
- { ARM_CPUID_PXA260, "pxa260" },
- { ARM_CPUID_PXA261, "pxa261" },
- { ARM_CPUID_PXA262, "pxa262" },
- { ARM_CPUID_PXA270, "pxa270" },
- { ARM_CPUID_PXA270_A0, "pxa270-a0" },
- { ARM_CPUID_PXA270_A1, "pxa270-a1" },
- { ARM_CPUID_PXA270_B0, "pxa270-b0" },
- { ARM_CPUID_PXA270_B1, "pxa270-b1" },
- { ARM_CPUID_PXA270_C0, "pxa270-c0" },
- { ARM_CPUID_PXA270_C5, "pxa270-c5" },
- { ARM_CPUID_ANY, "any"},
- { 0, NULL}
-};
-
-void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
- int i;
-
- (*cpu_fprintf)(f, "Available CPUs:\n");
- for (i = 0; arm_cpu_names[i].name; i++) {
- (*cpu_fprintf)(f, " %s\n", arm_cpu_names[i].name);
- }
-}
-
-/* return 0 if not found */
-static uint32_t cpu_arm_find_by_name(const char *name)
-{
- int i;
- uint32_t id;
-
- id = 0;
- for (i = 0; arm_cpu_names[i].name; i++) {
- if (strcmp(name, arm_cpu_names[i].name) == 0) {
- id = arm_cpu_names[i].id;
- break;
- }
- }
- return id;
-}
-
-void cpu_arm_close(CPUARMState *env)
-{
- free(env);
-}
-
-uint32_t cpsr_read(CPUARMState *env)
-{
- int ZF;
- ZF = (env->ZF == 0);
- return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
- (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
- | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
- | ((env->condexec_bits & 0xfc) << 8)
- | (env->GE << 16);
-}
-
-void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
-{
- if (mask & CPSR_NZCV) {
- env->ZF = (~val) & CPSR_Z;
- env->NF = val;
- env->CF = (val >> 29) & 1;
- env->VF = (val << 3) & 0x80000000;
- }
- if (mask & CPSR_Q)
- env->QF = ((val & CPSR_Q) != 0);
- if (mask & CPSR_T)
- env->thumb = ((val & CPSR_T) != 0);
- if (mask & CPSR_IT_0_1) {
- env->condexec_bits &= ~3;
- env->condexec_bits |= (val >> 25) & 3;
- }
- if (mask & CPSR_IT_2_7) {
- env->condexec_bits &= 3;
- env->condexec_bits |= (val >> 8) & 0xfc;
- }
- if (mask & CPSR_GE) {
- env->GE = (val >> 16) & 0xf;
- }
-
- if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
- switch_mode(env, val & CPSR_M);
- }
- mask &= ~CACHED_CPSR_BITS;
- env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
-}
-
-/* Sign/zero extend */
-uint32_t HELPER(sxtb16)(uint32_t x)
-{
- uint32_t res;
- res = (uint16_t)(int8_t)x;
- res |= (uint32_t)(int8_t)(x >> 16) << 16;
- return res;
-}
-
-uint32_t HELPER(uxtb16)(uint32_t x)
-{
- uint32_t res;
- res = (uint16_t)(uint8_t)x;
- res |= (uint32_t)(uint8_t)(x >> 16) << 16;
- return res;
-}
-
-uint32_t HELPER(clz)(uint32_t x)
-{
- int count;
- for (count = 32; x; count--)
- x >>= 1;
- return count;
-}
-
-int32_t HELPER(sdiv)(int32_t num, int32_t den)
-{
- if (den == 0)
- return 0;
- return num / den;
-}
-
-uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
-{
- if (den == 0)
- return 0;
- return num / den;
-}
-
-uint32_t HELPER(rbit)(uint32_t x)
-{
- x = ((x & 0xff000000) >> 24)
- | ((x & 0x00ff0000) >> 8)
- | ((x & 0x0000ff00) << 8)
- | ((x & 0x000000ff) << 24);
- x = ((x & 0xf0f0f0f0) >> 4)
- | ((x & 0x0f0f0f0f) << 4);
- x = ((x & 0x88888888) >> 3)
- | ((x & 0x44444444) >> 1)
- | ((x & 0x22222222) << 1)
- | ((x & 0x11111111) << 3);
- return x;
-}
-
-uint32_t HELPER(abs)(uint32_t x)
-{
- return ((int32_t)x < 0) ? -x : x;
-}
-
-#if defined(CONFIG_USER_ONLY)
-
-void do_interrupt (CPUState *env)
-{
- env->exception_index = -1;
-}
-
-/* Structure used to record exclusive memory locations. */
-typedef struct mmon_state {
- struct mmon_state *next;
- CPUARMState *cpu_env;
- uint32_t addr;
-} mmon_state;
-
-/* Chain of current locks. */
-static mmon_state* mmon_head = NULL;
-
-int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
- int mmu_idx, int is_softmmu)
-{
- if (rw == 2) {
- env->exception_index = EXCP_PREFETCH_ABORT;
- env->cp15.c6_insn = address;
- } else {
- env->exception_index = EXCP_DATA_ABORT;
- env->cp15.c6_data = address;
- }
- return 1;
-}
-
-static void allocate_mmon_state(CPUState *env)
-{
- env->mmon_entry = malloc(sizeof (mmon_state));
- if (!env->mmon_entry)
- abort();
- memset (env->mmon_entry, 0, sizeof (mmon_state));
- env->mmon_entry->cpu_env = env;
- mmon_head = env->mmon_entry;
-}
-
-/* Flush any monitor locks for the specified address. */
-static void flush_mmon(uint32_t addr)
-{
- mmon_state *mon;
-
- for (mon = mmon_head; mon; mon = mon->next)
- {
- if (mon->addr != addr)
- continue;
-
- mon->addr = 0;
- break;
- }
-}
-
-/* Mark an address for exclusive access. */
-void HELPER(mark_exclusive)(CPUState *env, uint32_t addr)
-{
- if (!env->mmon_entry)
- allocate_mmon_state(env);
- /* Clear any previous locks. */
- flush_mmon(addr);
- env->mmon_entry->addr = addr;
-}
-
-/* Test if an exclusive address is still exclusive. Returns zero
- if the address is still exclusive. */
-uint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr)
-{
- int res;
-
- if (!env->mmon_entry)
- return 1;
- if (env->mmon_entry->addr == addr)
- res = 0;
- else
- res = 1;
- flush_mmon(addr);
- return res;
-}
-
-void HELPER(clrex)(CPUState *env)
-{
- if (!(env->mmon_entry && env->mmon_entry->addr))
- return;
- flush_mmon(env->mmon_entry->addr);
-}
-
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-
-/* These should probably raise undefined insn exceptions. */
-void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
-{
- int op1 = (insn >> 8) & 0xf;
- cpu_abort(env, "cp%i insn %08x\n", op1, insn);
- return;
-}
-
-uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
-{
- int op1 = (insn >> 8) & 0xf;
- cpu_abort(env, "cp%i insn %08x\n", op1, insn);
- return 0;
-}
-
-void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
-{
- cpu_abort(env, "cp15 insn %08x\n", insn);
-}
-
-uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
-{
- cpu_abort(env, "cp15 insn %08x\n", insn);
- return 0;
-}
-
-/* These should probably raise undefined insn exceptions. */
-void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
-{
- cpu_abort(env, "v7m_mrs %d\n", reg);
-}
-
-uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
-{
- cpu_abort(env, "v7m_mrs %d\n", reg);
- return 0;
-}
-
-void switch_mode(CPUState *env, int mode)
-{
- if (mode != ARM_CPU_MODE_USR)
- cpu_abort(env, "Tried to switch out of user mode\n");
-}
-
-void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
-{
- cpu_abort(env, "banked r13 write\n");
-}
-
-uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
-{
- cpu_abort(env, "banked r13 read\n");
- return 0;
-}
-
-#else
-
-extern int semihosting_enabled;
-
-/* Map CPU modes onto saved register banks. */
-static inline int bank_number (int mode)
-{
- switch (mode) {
- case ARM_CPU_MODE_USR:
- case ARM_CPU_MODE_SYS:
- return 0;
- case ARM_CPU_MODE_SVC:
- return 1;
- case ARM_CPU_MODE_ABT:
- return 2;
- case ARM_CPU_MODE_UND:
- return 3;
- case ARM_CPU_MODE_IRQ:
- return 4;
- case ARM_CPU_MODE_FIQ:
- return 5;
- }
- cpu_abort(cpu_single_env, "Bad mode %x\n", mode);
- return -1;
-}
-
-void switch_mode(CPUState *env, int mode)
-{
- int old_mode;
- int i;
-
- old_mode = env->uncached_cpsr & CPSR_M;
- if (mode == old_mode)
- return;
-
- if (old_mode == ARM_CPU_MODE_FIQ) {
- memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
- memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
- } else if (mode == ARM_CPU_MODE_FIQ) {
- memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
- memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
- }
-
- i = bank_number(old_mode);
- env->banked_r13[i] = env->regs[13];
- env->banked_r14[i] = env->regs[14];
- env->banked_spsr[i] = env->spsr;
-
- i = bank_number(mode);
- env->regs[13] = env->banked_r13[i];
- env->regs[14] = env->banked_r14[i];
- env->spsr = env->banked_spsr[i];
-}
-
-static void v7m_push(CPUARMState *env, uint32_t val)
-{
- env->regs[13] -= 4;
- stl_phys(env->regs[13], val);
-}
-
-static uint32_t v7m_pop(CPUARMState *env)
-{
- uint32_t val;
- val = ldl_phys(env->regs[13]);
- env->regs[13] += 4;
- return val;
-}
-
-/* Switch to V7M main or process stack pointer. */
-static void switch_v7m_sp(CPUARMState *env, int process)
-{
- uint32_t tmp;
- if (env->v7m.current_sp != process) {
- tmp = env->v7m.other_sp;
- env->v7m.other_sp = env->regs[13];
- env->regs[13] = tmp;
- env->v7m.current_sp = process;
- }
-}
-
-static void do_v7m_exception_exit(CPUARMState *env)
-{
- uint32_t type;
- uint32_t xpsr;
-
- type = env->regs[15];
- if (env->v7m.exception != 0)
- armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception);
-
- /* Switch to the target stack. */
- switch_v7m_sp(env, (type & 4) != 0);
- /* Pop registers. */
- env->regs[0] = v7m_pop(env);
- env->regs[1] = v7m_pop(env);
- env->regs[2] = v7m_pop(env);
- env->regs[3] = v7m_pop(env);
- env->regs[12] = v7m_pop(env);
- env->regs[14] = v7m_pop(env);
- env->regs[15] = v7m_pop(env);
- xpsr = v7m_pop(env);
- xpsr_write(env, xpsr, 0xfffffdff);
- /* Undo stack alignment. */
- if (xpsr & 0x200)
- env->regs[13] |= 4;
- /* ??? The exception return type specifies Thread/Handler mode. However
- this is also implied by the xPSR value. Not sure what to do
- if there is a mismatch. */
- /* ??? Likewise for mismatches between the CONTROL register and the stack
- pointer. */
-}
-
-void do_interrupt_v7m(CPUARMState *env)
-{
- uint32_t xpsr = xpsr_read(env);
- uint32_t lr;
- uint32_t addr;
-
- lr = 0xfffffff1;
- if (env->v7m.current_sp)
- lr |= 4;
- if (env->v7m.exception == 0)
- lr |= 8;
-
- /* For exceptions we just mark as pending on the NVIC, and let that
- handle it. */
- /* TODO: Need to escalate if the current priority is higher than the
- one we're raising. */
- switch (env->exception_index) {
- case EXCP_UDEF:
- armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE);
- return;
- case EXCP_SWI:
- env->regs[15] += 2;
- armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC);
- return;
- case EXCP_PREFETCH_ABORT:
- case EXCP_DATA_ABORT:
- armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM);
- return;
- case EXCP_BKPT:
- if (semihosting_enabled) {
- int nr;
- nr = lduw_code(env->regs[15]) & 0xff;
- if (nr == 0xab) {
- env->regs[15] += 2;
- env->regs[0] = do_arm_semihosting(env);
- return;
- }
- }
- armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG);
- return;
- case EXCP_IRQ:
- env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic);
- break;
- case EXCP_EXCEPTION_EXIT:
- do_v7m_exception_exit(env);
- return;
- default:
- cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
- return; /* Never happens. Keep compiler happy. */
- }
-
- /* Align stack pointer. */
- /* ??? Should only do this if Configuration Control Register
- STACKALIGN bit is set. */
- if (env->regs[13] & 4) {
- env->regs[13] -= 4;
- xpsr |= 0x200;
- }
- /* Switch to the handler mode. */
- v7m_push(env, xpsr);
- v7m_push(env, env->regs[15]);
- v7m_push(env, env->regs[14]);
- v7m_push(env, env->regs[12]);
- v7m_push(env, env->regs[3]);
- v7m_push(env, env->regs[2]);
- v7m_push(env, env->regs[1]);
- v7m_push(env, env->regs[0]);
- switch_v7m_sp(env, 0);
- env->uncached_cpsr &= ~CPSR_IT;
- env->regs[14] = lr;
- addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
- env->regs[15] = addr & 0xfffffffe;
- env->thumb = addr & 1;
-}
-
-/* Handle a CPU exception. */
-void do_interrupt(CPUARMState *env)
-{
- uint32_t addr;
- uint32_t mask;
- int new_mode;
- uint32_t offset;
-
- if (IS_M(env)) {
- do_interrupt_v7m(env);
- return;
- }
- /* TODO: Vectored interrupt controller. */
- switch (env->exception_index) {
- case EXCP_UDEF:
- new_mode = ARM_CPU_MODE_UND;
- addr = 0x04;
- mask = CPSR_I;
- if (env->thumb)
- offset = 2;
- else
- offset = 4;
- break;
- case EXCP_SWI:
- if (semihosting_enabled) {
- /* Check for semihosting interrupt. */
- if (env->thumb) {
- mask = lduw_code(env->regs[15] - 2) & 0xff;
- } else {
- mask = ldl_code(env->regs[15] - 4) & 0xffffff;
- }
- /* Only intercept calls from privileged modes, to provide some
- semblance of security. */
- if (((mask == 0x123456 && !env->thumb)
- || (mask == 0xab && env->thumb))
- && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
- env->regs[0] = do_arm_semihosting(env);
- return;
- }
- }
- new_mode = ARM_CPU_MODE_SVC;
- addr = 0x08;
- mask = CPSR_I;
- /* The PC already points to the next instruction. */
- offset = 0;
- break;
- case EXCP_BKPT:
- /* See if this is a semihosting syscall. */
- if (env->thumb && semihosting_enabled) {
- mask = lduw_code(env->regs[15]) & 0xff;
- if (mask == 0xab
- && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
- env->regs[15] += 2;
- env->regs[0] = do_arm_semihosting(env);
- return;
- }
- }
- /* Fall through to prefetch abort. */
- case EXCP_PREFETCH_ABORT:
- new_mode = ARM_CPU_MODE_ABT;
- addr = 0x0c;
- mask = CPSR_A | CPSR_I;
- offset = 4;
- break;
- case EXCP_DATA_ABORT:
- new_mode = ARM_CPU_MODE_ABT;
- addr = 0x10;
- mask = CPSR_A | CPSR_I;
- offset = 8;
- break;
- case EXCP_IRQ:
- new_mode = ARM_CPU_MODE_IRQ;
- addr = 0x18;
- /* Disable IRQ and imprecise data aborts. */
- mask = CPSR_A | CPSR_I;
- offset = 4;
- break;
- case EXCP_FIQ:
- new_mode = ARM_CPU_MODE_FIQ;
- addr = 0x1c;
- /* Disable FIQ, IRQ and imprecise data aborts. */
- mask = CPSR_A | CPSR_I | CPSR_F;
- offset = 4;
- break;
- default:
- cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
- return; /* Never happens. Keep compiler happy. */
- }
- /* High vectors. */
- if (env->cp15.c1_sys & (1 << 13)) {
- addr += 0xffff0000;
- }
- switch_mode (env, new_mode);
- env->spsr = cpsr_read(env);
- /* Clear IT bits. */
- env->condexec_bits = 0;
- /* Switch to the new mode, and switch to Arm mode. */
- /* ??? Thumb interrupt handlers not implemented. */
- env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
- env->uncached_cpsr |= mask;
- env->thumb = 0;
- env->regs[14] = env->regs[15] + offset;
- env->regs[15] = addr;
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
-}
-
-/* Check section/page access permissions.
- Returns the page protection flags, or zero if the access is not
- permitted. */
-static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
- int is_user)
-{
- int prot_ro;
-
- if (domain == 3)
- return PAGE_READ | PAGE_WRITE;
-
- if (access_type == 1)
- prot_ro = 0;
- else
- prot_ro = PAGE_READ;
-
- switch (ap) {
- case 0:
- if (access_type == 1)
- return 0;
- switch ((env->cp15.c1_sys >> 8) & 3) {
- case 1:
- return is_user ? 0 : PAGE_READ;
- case 2:
- return PAGE_READ;
- default:
- return 0;
- }
- case 1:
- return is_user ? 0 : PAGE_READ | PAGE_WRITE;
- case 2:
- if (is_user)
- return prot_ro;
- else
- return PAGE_READ | PAGE_WRITE;
- case 3:
- return PAGE_READ | PAGE_WRITE;
- case 4: case 7: /* Reserved. */
- return 0;
- case 5:
- return is_user ? 0 : prot_ro;
- case 6:
- return prot_ro;
- default:
- abort();
- }
-}
-
-static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
- int is_user, uint32_t *phys_ptr, int *prot)
-{
- int code;
- uint32_t table;
- uint32_t desc;
- int type;
- int ap;
- int domain;
- uint32_t phys_addr;
-
- /* Pagetable walk. */
- /* Lookup l1 descriptor. */
- if (address & env->cp15.c2_mask)
- table = env->cp15.c2_base1;
- else
- table = env->cp15.c2_base0;
- table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
- desc = ldl_phys(table);
- type = (desc & 3);
- domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
- if (type == 0) {
- /* Section translation fault. */
- code = 5;
- goto do_fault;
- }
- if (domain == 0 || domain == 2) {
- if (type == 2)
- code = 9; /* Section domain fault. */
- else
- code = 11; /* Page domain fault. */
- goto do_fault;
- }
- if (type == 2) {
- /* 1Mb section. */
- phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
- ap = (desc >> 10) & 3;
- code = 13;
- } else {
- /* Lookup l2 entry. */
- if (type == 1) {
- /* Coarse pagetable. */
- table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
- } else {
- /* Fine pagetable. */
- table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
- }
- desc = ldl_phys(table);
- switch (desc & 3) {
- case 0: /* Page translation fault. */
- code = 7;
- goto do_fault;
- case 1: /* 64k page. */
- phys_addr = (desc & 0xffff0000) | (address & 0xffff);
- ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
- break;
- case 2: /* 4k page. */
- phys_addr = (desc & 0xfffff000) | (address & 0xfff);
- ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
- break;
- case 3: /* 1k page. */
- if (type == 1) {
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- phys_addr = (desc & 0xfffff000) | (address & 0xfff);
- } else {
- /* Page translation fault. */
- code = 7;
- goto do_fault;
- }
- } else {
- phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
- }
- ap = (desc >> 4) & 3;
- break;
- default:
- /* Never happens, but compiler isn't smart enough to tell. */
- abort();
- }
- code = 15;
- }
- *prot = check_ap(env, ap, domain, access_type, is_user);
- if (!*prot) {
- /* Access permission fault. */
- goto do_fault;
- }
- *phys_ptr = phys_addr;
- return 0;
-do_fault:
- return code | (domain << 4);
-}
-
-static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
- int is_user, uint32_t *phys_ptr, int *prot)
-{
- int code;
- uint32_t table;
- uint32_t desc;
- uint32_t xn;
- int type;
- int ap;
- int domain;
- uint32_t phys_addr;
-
- /* Pagetable walk. */
- /* Lookup l1 descriptor. */
- if (address & env->cp15.c2_mask)
- table = env->cp15.c2_base1;
- else
- table = env->cp15.c2_base0;
- table = (table & 0xffffc000) | ((address >> 18) & 0x3ffc);
- desc = ldl_phys(table);
- type = (desc & 3);
- if (type == 0) {
- /* Section translation fault. */
- code = 5;
- domain = 0;
- goto do_fault;
- } else if (type == 2 && (desc & (1 << 18))) {
- /* Supersection. */
- domain = 0;
- } else {
- /* Section or page. */
- domain = (desc >> 4) & 0x1e;
- }
- domain = (env->cp15.c3 >> domain) & 3;
- if (domain == 0 || domain == 2) {
- if (type == 2)
- code = 9; /* Section domain fault. */
- else
- code = 11; /* Page domain fault. */
- goto do_fault;
- }
- if (type == 2) {
- if (desc & (1 << 18)) {
- /* Supersection. */
- phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
- } else {
- /* Section. */
- phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
- }
- ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
- xn = desc & (1 << 4);
- code = 13;
- } else {
- /* Lookup l2 entry. */
- table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
- desc = ldl_phys(table);
- ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
- switch (desc & 3) {
- case 0: /* Page translation fault. */
- code = 7;
- goto do_fault;
- case 1: /* 64k page. */
- phys_addr = (desc & 0xffff0000) | (address & 0xffff);
- xn = desc & (1 << 15);
- break;
- case 2: case 3: /* 4k page. */
- phys_addr = (desc & 0xfffff000) | (address & 0xfff);
- xn = desc & 1;
- break;
- default:
- /* Never happens, but compiler isn't smart enough to tell. */
- abort();
- }
- code = 15;
- }
- if (xn && access_type == 2)
- goto do_fault;
-
- *prot = check_ap(env, ap, domain, access_type, is_user);
- if (!*prot) {
- /* Access permission fault. */
- goto do_fault;
- }
- *phys_ptr = phys_addr;
- return 0;
-do_fault:
- return code | (domain << 4);
-}
-
-static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
- int is_user, uint32_t *phys_ptr, int *prot)
-{
- int n;
- uint32_t mask;
- uint32_t base;
-
- *phys_ptr = address;
- for (n = 7; n >= 0; n--) {
- base = env->cp15.c6_region[n];
- if ((base & 1) == 0)
- continue;
- mask = 1 << ((base >> 1) & 0x1f);
- /* Keep this shift separate from the above to avoid an
- (undefined) << 32. */
- mask = (mask << 1) - 1;
- if (((base ^ address) & ~mask) == 0)
- break;
- }
- if (n < 0)
- return 2;
-
- if (access_type == 2) {
- mask = env->cp15.c5_insn;
- } else {
- mask = env->cp15.c5_data;
- }
- mask = (mask >> (n * 4)) & 0xf;
- switch (mask) {
- case 0:
- return 1;
- case 1:
- if (is_user)
- return 1;
- *prot = PAGE_READ | PAGE_WRITE;
- break;
- case 2:
- *prot = PAGE_READ;
- if (!is_user)
- *prot |= PAGE_WRITE;
- break;
- case 3:
- *prot = PAGE_READ | PAGE_WRITE;
- break;
- case 5:
- if (is_user)
- return 1;
- *prot = PAGE_READ;
- break;
- case 6:
- *prot = PAGE_READ;
- break;
- default:
- /* Bad permission. */
- return 1;
- }
- return 0;
-}
-
-static inline int get_phys_addr(CPUState *env, uint32_t address,
- int access_type, int is_user,
- uint32_t *phys_ptr, int *prot)
-{
- /* Fast Context Switch Extension. */
- if (address < 0x02000000)
- address += env->cp15.c13_fcse;
-
- if ((env->cp15.c1_sys & 1) == 0) {
- /* MMU/MPU disabled. */
- *phys_ptr = address;
- *prot = PAGE_READ | PAGE_WRITE;
- return 0;
- } else if (arm_feature(env, ARM_FEATURE_MPU)) {
- return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
- prot);
- } else if (env->cp15.c1_sys & (1 << 23)) {
- return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
- prot);
- } else {
- return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
- prot);
- }
-}
-
-int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
- int access_type, int mmu_idx, int is_softmmu)
-{
- uint32_t phys_addr;
- int prot;
- int ret, is_user;
-
- is_user = mmu_idx == MMU_USER_IDX;
- ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
- if (ret == 0) {
- /* Map a single [sub]page. */
- phys_addr &= ~(uint32_t)0x3ff;
- address &= ~(uint32_t)0x3ff;
- return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
- is_softmmu);
- }
-
- if (access_type == 2) {
- env->cp15.c5_insn = ret;
- env->cp15.c6_insn = address;
- env->exception_index = EXCP_PREFETCH_ABORT;
- } else {
- env->cp15.c5_data = ret;
- if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
- env->cp15.c5_data |= (1 << 11);
- env->cp15.c6_data = address;
- env->exception_index = EXCP_DATA_ABORT;
- }
- return 1;
-}
-
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- uint32_t phys_addr;
- int prot;
- int ret;
-
- ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot);
-
- if (ret != 0)
- return -1;
-
- return phys_addr;
-}
-
-/* Not really implemented. Need to figure out a sane way of doing this.
- Maybe add generic watchpoint support and use that. */
-
-void HELPER(mark_exclusive)(CPUState *env, uint32_t addr)
-{
- env->mmon_addr = addr;
-}
-
-uint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr)
-{
- return (env->mmon_addr != addr);
-}
-
-void HELPER(clrex)(CPUState *env)
-{
- env->mmon_addr = -1;
-}
-
-void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
-{
- int cp_num = (insn >> 8) & 0xf;
- int cp_info = (insn >> 5) & 7;
- int src = (insn >> 16) & 0xf;
- int operand = insn & 0xf;
-
- if (env->cp[cp_num].cp_write)
- env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
- cp_info, src, operand, val);
-}
-
-uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn)
-{
- int cp_num = (insn >> 8) & 0xf;
- int cp_info = (insn >> 5) & 7;
- int dest = (insn >> 16) & 0xf;
- int operand = insn & 0xf;
-
- if (env->cp[cp_num].cp_read)
- return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
- cp_info, dest, operand);
- return 0;
-}
-
-/* Return basic MPU access permission bits. */
-static uint32_t simple_mpu_ap_bits(uint32_t val)
-{
- uint32_t ret;
- uint32_t mask;
- int i;
- ret = 0;
- mask = 3;
- for (i = 0; i < 16; i += 2) {
- ret |= (val >> i) & mask;
- mask <<= 2;
- }
- return ret;
-}
-
-/* Pad basic MPU access permission bits to extended format. */
-static uint32_t extended_mpu_ap_bits(uint32_t val)
-{
- uint32_t ret;
- uint32_t mask;
- int i;
- ret = 0;
- mask = 3;
- for (i = 0; i < 16; i += 2) {
- ret |= (val & mask) << i;
- mask <<= 2;
- }
- return ret;
-}
-
-void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
-{
- int op1;
- int op2;
- int crm;
-
- op1 = (insn >> 21) & 7;
- op2 = (insn >> 5) & 7;
- crm = insn & 0xf;
- switch ((insn >> 16) & 0xf) {
- case 0:
- if (((insn >> 21) & 7) == 2) {
- /* ??? Select cache level. Ignore. */
- return;
- }
- /* ID codes. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- break;
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- break;
- goto bad_reg;
- case 1: /* System configuration. */
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
- env->cp15.c1_sys = val;
- /* ??? Lots of these bits are not implemented. */
- /* This may enable/disable the MMU, so do a TLB flush. */
- tlb_flush(env, 1);
- break;
- case 1: /* Auxiliary cotrol register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- env->cp15.c1_xscaleauxcr = val;
- break;
- }
- /* Not implemented. */
- break;
- case 2:
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- env->cp15.c1_coproc = val;
- /* ??? Is this safe when called from within a TB? */
- tb_flush(env);
- break;
- default:
- goto bad_reg;
- }
- break;
- case 2: /* MMU Page table control / MPU cache control. */
- if (arm_feature(env, ARM_FEATURE_MPU)) {
- switch (op2) {
- case 0:
- env->cp15.c2_data = val;
- break;
- case 1:
- env->cp15.c2_insn = val;
- break;
- default:
- goto bad_reg;
- }
- } else {
- switch (op2) {
- case 0:
- env->cp15.c2_base0 = val;
- break;
- case 1:
- env->cp15.c2_base1 = val;
- break;
- case 2:
- env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
- break;
- default:
- goto bad_reg;
- }
- }
- break;
- case 3: /* MMU Domain access control / MPU write buffer control. */
- env->cp15.c3 = val;
- tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
- break;
- case 4: /* Reserved. */
- goto bad_reg;
- case 5: /* MMU Fault status / MPU access permission. */
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- if (arm_feature(env, ARM_FEATURE_MPU))
- val = extended_mpu_ap_bits(val);
- env->cp15.c5_data = val;
- break;
- case 1:
- if (arm_feature(env, ARM_FEATURE_MPU))
- val = extended_mpu_ap_bits(val);
- env->cp15.c5_insn = val;
- break;
- case 2:
- if (!arm_feature(env, ARM_FEATURE_MPU))
- goto bad_reg;
- env->cp15.c5_data = val;
- break;
- case 3:
- if (!arm_feature(env, ARM_FEATURE_MPU))
- goto bad_reg;
- env->cp15.c5_insn = val;
- break;
- default:
- goto bad_reg;
- }
- break;
- case 6: /* MMU Fault address / MPU base/size. */
- if (arm_feature(env, ARM_FEATURE_MPU)) {
- if (crm >= 8)
- goto bad_reg;
- env->cp15.c6_region[crm] = val;
- } else {
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- env->cp15.c6_data = val;
- break;
- case 1: /* ??? This is WFAR on armv6 */
- case 2:
- env->cp15.c6_insn = val;
- break;
- default:
- goto bad_reg;
- }
- }
- break;
- case 7: /* Cache control. */
- env->cp15.c15_i_max = 0x000;
- env->cp15.c15_i_min = 0xff0;
- /* No cache, so nothing to do. */
- /* ??? MPCore has VA to PA translation functions. */
- break;
- case 8: /* MMU TLB control. */
- switch (op2) {
- case 0: /* Invalidate all. */
- tlb_flush(env, 0);
- break;
- case 1: /* Invalidate single TLB entry. */
-#if 0
- /* ??? This is wrong for large pages and sections. */
- /* As an ugly hack to make linux work we always flush a 4K
- pages. */
- val &= 0xfffff000;
- tlb_flush_page(env, val);
- tlb_flush_page(env, val + 0x400);
- tlb_flush_page(env, val + 0x800);
- tlb_flush_page(env, val + 0xc00);
-#else
- tlb_flush(env, 1);
-#endif
- break;
- case 2: /* Invalidate on ASID. */
- tlb_flush(env, val == 0);
- break;
- case 3: /* Invalidate single entry on MVA. */
- /* ??? This is like case 1, but ignores ASID. */
- tlb_flush(env, 1);
- break;
- default:
- goto bad_reg;
- }
- break;
- case 9:
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- break;
- switch (crm) {
- case 0: /* Cache lockdown. */
- switch (op1) {
- case 0: /* L1 cache. */
- switch (op2) {
- case 0:
- env->cp15.c9_data = val;
- break;
- case 1:
- env->cp15.c9_insn = val;
- break;
- default:
- goto bad_reg;
- }
- break;
- case 1: /* L2 cache. */
- /* Ignore writes to L2 lockdown/auxiliary registers. */
- break;
- default:
- goto bad_reg;
- }
- break;
- case 1: /* TCM memory region registers. */
- /* Not implemented. */
- goto bad_reg;
- default:
- goto bad_reg;
- }
- break;
- case 10: /* MMU TLB lockdown. */
- /* ??? TLB lockdown not implemented. */
- break;
- case 12: /* Reserved. */
- goto bad_reg;
- case 13: /* Process ID. */
- switch (op2) {
- case 0:
- /* Unlike real hardware the qemu TLB uses virtual addresses,
- not modified virtual addresses, so this causes a TLB flush.
- */
- if (env->cp15.c13_fcse != val)
- tlb_flush(env, 1);
- env->cp15.c13_fcse = val;
- break;
- case 1:
- /* This changes the ASID, so do a TLB flush. */
- if (env->cp15.c13_context != val
- && !arm_feature(env, ARM_FEATURE_MPU))
- tlb_flush(env, 0);
- env->cp15.c13_context = val;
- break;
- case 2:
- env->cp15.c13_tls1 = val;
- break;
- case 3:
- env->cp15.c13_tls2 = val;
- break;
- case 4:
- env->cp15.c13_tls3 = val;
- break;
- default:
- goto bad_reg;
- }
- break;
- case 14: /* Reserved. */
- goto bad_reg;
- case 15: /* Implementation specific. */
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- if (op2 == 0 && crm == 1) {
- if (env->cp15.c15_cpar != (val & 0x3fff)) {
- /* Changes cp0 to cp13 behavior, so needs a TB flush. */
- tb_flush(env);
- env->cp15.c15_cpar = val & 0x3fff;
- }
- break;
- }
- goto bad_reg;
- }
- if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
- switch (crm) {
- case 0:
- break;
- case 1: /* Set TI925T configuration. */
- env->cp15.c15_ticonfig = val & 0xe7;
- env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
- ARM_CPUID_TI915T : ARM_CPUID_TI925T;
- break;
- case 2: /* Set I_max. */
- env->cp15.c15_i_max = val;
- break;
- case 3: /* Set I_min. */
- env->cp15.c15_i_min = val;
- break;
- case 4: /* Set thread-ID. */
- env->cp15.c15_threadid = val & 0xffff;
- break;
- case 8: /* Wait-for-interrupt (deprecated). */
- cpu_interrupt(env, CPU_INTERRUPT_HALT);
- break;
- default:
- goto bad_reg;
- }
- }
- break;
- }
- return;
-bad_reg:
- /* ??? For debugging only. Should raise illegal instruction exception. */
- cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
- (insn >> 16) & 0xf, crm, op1, op2);
-}
-
-uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
-{
- int op1;
- int op2;
- int crm;
-
- op1 = (insn >> 21) & 7;
- op2 = (insn >> 5) & 7;
- crm = insn & 0xf;
- switch ((insn >> 16) & 0xf) {
- case 0: /* ID codes. */
- switch (op1) {
- case 0:
- switch (crm) {
- case 0:
- switch (op2) {
- case 0: /* Device ID. */
- return env->cp15.c0_cpuid;
- case 1: /* Cache Type. */
- return env->cp15.c0_cachetype;
- case 2: /* TCM status. */
- return 0;
- case 3: /* TLB type register. */
- return 0; /* No lockable TLB entries. */
- case 5: /* CPU ID */
- return env->cpu_index;
- default:
- goto bad_reg;
- }
- case 1:
- if (!arm_feature(env, ARM_FEATURE_V6))
- goto bad_reg;
- return env->cp15.c0_c1[op2];
- case 2:
- if (!arm_feature(env, ARM_FEATURE_V6))
- goto bad_reg;
- return env->cp15.c0_c2[op2];
- case 3: case 4: case 5: case 6: case 7:
- return 0;
- default:
- goto bad_reg;
- }
- case 1:
- /* These registers aren't documented on arm11 cores. However
- Linux looks at them anyway. */
- if (!arm_feature(env, ARM_FEATURE_V6))
- goto bad_reg;
- if (crm != 0)
- goto bad_reg;
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- return 0;
- default:
- goto bad_reg;
- }
- case 1: /* System configuration. */
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0: /* Control register. */
- return env->cp15.c1_sys;
- case 1: /* Auxiliary control register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- return env->cp15.c1_xscaleauxcr;
- if (!arm_feature(env, ARM_FEATURE_AUXCR))
- goto bad_reg;
- switch (ARM_CPUID(env)) {
- case ARM_CPUID_ARM1026:
- return 1;
- case ARM_CPUID_ARM1136:
- case ARM_CPUID_ARM1136_R2:
- return 7;
- case ARM_CPUID_ARM11MPCORE:
- return 1;
- case ARM_CPUID_CORTEXA8:
- return 0;
- default:
- goto bad_reg;
- }
- case 2: /* Coprocessor access register. */
- if (arm_feature(env, ARM_FEATURE_XSCALE))
- goto bad_reg;
- return env->cp15.c1_coproc;
- default:
- goto bad_reg;
- }
- case 2: /* MMU Page table control / MPU cache control. */
- if (arm_feature(env, ARM_FEATURE_MPU)) {
- switch (op2) {
- case 0:
- return env->cp15.c2_data;
- break;
- case 1:
- return env->cp15.c2_insn;
- break;
- default:
- goto bad_reg;
- }
- } else {
- switch (op2) {
- case 0:
- return env->cp15.c2_base0;
- case 1:
- return env->cp15.c2_base1;
- case 2:
- {
- int n;
- uint32_t mask;
- n = 0;
- mask = env->cp15.c2_mask;
- while (mask) {
- n++;
- mask <<= 1;
- }
- return n;
- }
- default:
- goto bad_reg;
- }
- }
- case 3: /* MMU Domain access control / MPU write buffer control. */
- return env->cp15.c3;
- case 4: /* Reserved. */
- goto bad_reg;
- case 5: /* MMU Fault status / MPU access permission. */
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- if (arm_feature(env, ARM_FEATURE_MPU))
- return simple_mpu_ap_bits(env->cp15.c5_data);
- return env->cp15.c5_data;
- case 1:
- if (arm_feature(env, ARM_FEATURE_MPU))
- return simple_mpu_ap_bits(env->cp15.c5_data);
- return env->cp15.c5_insn;
- case 2:
- if (!arm_feature(env, ARM_FEATURE_MPU))
- goto bad_reg;
- return env->cp15.c5_data;
- case 3:
- if (!arm_feature(env, ARM_FEATURE_MPU))
- goto bad_reg;
- return env->cp15.c5_insn;
- default:
- goto bad_reg;
- }
- case 6: /* MMU Fault address. */
- if (arm_feature(env, ARM_FEATURE_MPU)) {
- if (crm >= 8)
- goto bad_reg;
- return env->cp15.c6_region[crm];
- } else {
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- op2 = 0;
- switch (op2) {
- case 0:
- return env->cp15.c6_data;
- case 1:
- if (arm_feature(env, ARM_FEATURE_V6)) {
- /* Watchpoint Fault Adrress. */
- return 0; /* Not implemented. */
- } else {
- /* Instruction Fault Adrress. */
- /* Arm9 doesn't have an IFAR, but implementing it anyway
- shouldn't do any harm. */
- return env->cp15.c6_insn;
- }
- case 2:
- if (arm_feature(env, ARM_FEATURE_V6)) {
- /* Instruction Fault Adrress. */
- return env->cp15.c6_insn;
- } else {
- goto bad_reg;
- }
- default:
- goto bad_reg;
- }
- }
- case 7: /* Cache control. */
- /* FIXME: Should only clear Z flag if destination is r15. */
- env->ZF = 0;
- return 0;
- case 8: /* MMU TLB control. */
- goto bad_reg;
- case 9: /* Cache lockdown. */
- switch (op1) {
- case 0: /* L1 cache. */
- if (arm_feature(env, ARM_FEATURE_OMAPCP))
- return 0;
- switch (op2) {
- case 0:
- return env->cp15.c9_data;
- case 1:
- return env->cp15.c9_insn;
- default:
- goto bad_reg;
- }
- case 1: /* L2 cache */
- if (crm != 0)
- goto bad_reg;
- /* L2 Lockdown and Auxiliary control. */
- return 0;
- default:
- goto bad_reg;
- }
- case 10: /* MMU TLB lockdown. */
- /* ??? TLB lockdown not implemented. */
- return 0;
- case 11: /* TCM DMA control. */
- case 12: /* Reserved. */
- goto bad_reg;
- case 13: /* Process ID. */
- switch (op2) {
- case 0:
- return env->cp15.c13_fcse;
- case 1:
- return env->cp15.c13_context;
- case 2:
- return env->cp15.c13_tls1;
- case 3:
- return env->cp15.c13_tls2;
- case 4:
- return env->cp15.c13_tls3;
- default:
- goto bad_reg;
- }
- case 14: /* Reserved. */
- goto bad_reg;
- case 15: /* Implementation specific. */
- if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- if (op2 == 0 && crm == 1)
- return env->cp15.c15_cpar;
-
- goto bad_reg;
- }
- if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
- switch (crm) {
- case 0:
- return 0;
- case 1: /* Read TI925T configuration. */
- return env->cp15.c15_ticonfig;
- case 2: /* Read I_max. */
- return env->cp15.c15_i_max;
- case 3: /* Read I_min. */
- return env->cp15.c15_i_min;
- case 4: /* Read thread-ID. */
- return env->cp15.c15_threadid;
- case 8: /* TI925T_status */
- return 0;
- }
- /* TODO: Peripheral port remap register:
- * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
- * controller base address at $rn & ~0xfff and map size of
- * 0x200 << ($rn & 0xfff), when MMU is off. */
- goto bad_reg;
- }
- return 0;
- }
-bad_reg:
- /* ??? For debugging only. Should raise illegal instruction exception. */
- cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
- (insn >> 16) & 0xf, crm, op1, op2);
- return 0;
-}
-
-void HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val)
-{
- env->banked_r13[bank_number(mode)] = val;
-}
-
-uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
-{
- return env->banked_r13[bank_number(mode)];
-}
-
-uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg)
-{
- switch (reg) {
- case 0: /* APSR */
- return xpsr_read(env) & 0xf8000000;
- case 1: /* IAPSR */
- return xpsr_read(env) & 0xf80001ff;
- case 2: /* EAPSR */
- return xpsr_read(env) & 0xff00fc00;
- case 3: /* xPSR */
- return xpsr_read(env) & 0xff00fdff;
- case 5: /* IPSR */
- return xpsr_read(env) & 0x000001ff;
- case 6: /* EPSR */
- return xpsr_read(env) & 0x0700fc00;
- case 7: /* IEPSR */
- return xpsr_read(env) & 0x0700edff;
- case 8: /* MSP */
- return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
- case 9: /* PSP */
- return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
- case 16: /* PRIMASK */
- return (env->uncached_cpsr & CPSR_I) != 0;
- case 17: /* FAULTMASK */
- return (env->uncached_cpsr & CPSR_F) != 0;
- case 18: /* BASEPRI */
- case 19: /* BASEPRI_MAX */
- return env->v7m.basepri;
- case 20: /* CONTROL */
- return env->v7m.control;
- default:
- /* ??? For debugging only. */
- cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
- return 0;
- }
-}
-
-void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val)
-{
- switch (reg) {
- case 0: /* APSR */
- xpsr_write(env, val, 0xf8000000);
- break;
- case 1: /* IAPSR */
- xpsr_write(env, val, 0xf8000000);
- break;
- case 2: /* EAPSR */
- xpsr_write(env, val, 0xfe00fc00);
- break;
- case 3: /* xPSR */
- xpsr_write(env, val, 0xfe00fc00);
- break;
- case 5: /* IPSR */
- /* IPSR bits are readonly. */
- break;
- case 6: /* EPSR */
- xpsr_write(env, val, 0x0600fc00);
- break;
- case 7: /* IEPSR */
- xpsr_write(env, val, 0x0600fc00);
- break;
- case 8: /* MSP */
- if (env->v7m.current_sp)
- env->v7m.other_sp = val;
- else
- env->regs[13] = val;
- break;
- case 9: /* PSP */
- if (env->v7m.current_sp)
- env->regs[13] = val;
- else
- env->v7m.other_sp = val;
- break;
- case 16: /* PRIMASK */
- if (val & 1)
- env->uncached_cpsr |= CPSR_I;
- else
- env->uncached_cpsr &= ~CPSR_I;
- break;
- case 17: /* FAULTMASK */
- if (val & 1)
- env->uncached_cpsr |= CPSR_F;
- else
- env->uncached_cpsr &= ~CPSR_F;
- break;
- case 18: /* BASEPRI */
- env->v7m.basepri = val & 0xff;
- break;
- case 19: /* BASEPRI_MAX */
- val &= 0xff;
- if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
- env->v7m.basepri = val;
- break;
- case 20: /* CONTROL */
- env->v7m.control = val & 3;
- switch_v7m_sp(env, (val & 2) != 0);
- break;
- default:
- /* ??? For debugging only. */
- cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
- return;
- }
-}
-
-void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
- ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
- void *opaque)
-{
- if (cpnum < 0 || cpnum > 14) {
- cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
- return;
- }
-
- env->cp[cpnum].cp_read = cp_read;
- env->cp[cpnum].cp_write = cp_write;
- env->cp[cpnum].opaque = opaque;
-}
-
-#endif
-
-/* Note that signed overflow is undefined in C. The following routines are
- careful to use unsigned types where modulo arithmetic is required.
- Failure to do so _will_ break on newer gcc. */
-
-/* Signed saturating arithmetic. */
-
-/* Perform 16-bit signed saturating addition. */
-static inline uint16_t add16_sat(uint16_t a, uint16_t b)
-{
- uint16_t res;
-
- res = a + b;
- if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
- if (a & 0x8000)
- res = 0x8000;
- else
- res = 0x7fff;
- }
- return res;
-}
-
-/* Perform 8-bit signed saturating addition. */
-static inline uint8_t add8_sat(uint8_t a, uint8_t b)
-{
- uint8_t res;
-
- res = a + b;
- if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
- if (a & 0x80)
- res = 0x80;
- else
- res = 0x7f;
- }
- return res;
-}
-
-/* Perform 16-bit signed saturating subtraction. */
-static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
-{
- uint16_t res;
-
- res = a - b;
- if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
- if (a & 0x8000)
- res = 0x8000;
- else
- res = 0x7fff;
- }
- return res;
-}
-
-/* Perform 8-bit signed saturating subtraction. */
-static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
-{
- uint8_t res;
-
- res = a - b;
- if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
- if (a & 0x80)
- res = 0x80;
- else
- res = 0x7f;
- }
- return res;
-}
-
-#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
-#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
-#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
-#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
-#define PFX q
-
-#include "op_addsub.h"
-
-/* Unsigned saturating arithmetic. */
-static inline uint16_t add16_usat(uint16_t a, uint16_t b)
-{
- uint16_t res;
- res = a + b;
- if (res < a)
- res = 0xffff;
- return res;
-}
-
-static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
-{
- if (a < b)
- return a - b;
- else
- return 0;
-}
-
-static inline uint8_t add8_usat(uint8_t a, uint8_t b)
-{
- uint8_t res;
- res = a + b;
- if (res < a)
- res = 0xff;
- return res;
-}
-
-static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
-{
- if (a < b)
- return a - b;
- else
- return 0;
-}
-
-#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
-#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
-#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
-#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
-#define PFX uq
-
-#include "op_addsub.h"
-
-/* Signed modulo arithmetic. */
-#define SARITH16(a, b, n, op) do { \
- int32_t sum; \
- sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \
- RESULT(sum, n, 16); \
- if (sum >= 0) \
- ge |= 3 << (n * 2); \
- } while(0)
-
-#define SARITH8(a, b, n, op) do { \
- int32_t sum; \
- sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \
- RESULT(sum, n, 8); \
- if (sum >= 0) \
- ge |= 1 << n; \
- } while(0)
-
-
-#define ADD16(a, b, n) SARITH16(a, b, n, +)
-#define SUB16(a, b, n) SARITH16(a, b, n, -)
-#define ADD8(a, b, n) SARITH8(a, b, n, +)
-#define SUB8(a, b, n) SARITH8(a, b, n, -)
-#define PFX s
-#define ARITH_GE
-
-#include "op_addsub.h"
-
-/* Unsigned modulo arithmetic. */
-#define ADD16(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
- RESULT(sum, n, 16); \
- if ((sum >> 16) == 1) \
- ge |= 3 << (n * 2); \
- } while(0)
-
-#define ADD8(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
- RESULT(sum, n, 8); \
- if ((sum >> 8) == 1) \
- ge |= 1 << n; \
- } while(0)
-
-#define SUB16(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
- RESULT(sum, n, 16); \
- if ((sum >> 16) == 0) \
- ge |= 3 << (n * 2); \
- } while(0)
-
-#define SUB8(a, b, n) do { \
- uint32_t sum; \
- sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
- RESULT(sum, n, 8); \
- if ((sum >> 8) == 0) \
- ge |= 1 << n; \
- } while(0)
-
-#define PFX u
-#define ARITH_GE
-
-#include "op_addsub.h"
-
-/* Halved signed arithmetic. */
-#define ADD16(a, b, n) \
- RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
-#define SUB16(a, b, n) \
- RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
-#define ADD8(a, b, n) \
- RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
-#define SUB8(a, b, n) \
- RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
-#define PFX sh
-
-#include "op_addsub.h"
-
-/* Halved unsigned arithmetic. */
-#define ADD16(a, b, n) \
- RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
-#define SUB16(a, b, n) \
- RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
-#define ADD8(a, b, n) \
- RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
-#define SUB8(a, b, n) \
- RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
-#define PFX uh
-
-#include "op_addsub.h"
-
-static inline uint8_t do_usad(uint8_t a, uint8_t b)
-{
- if (a > b)
- return a - b;
- else
- return b - a;
-}
-
-/* Unsigned sum of absolute byte differences. */
-uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
-{
- uint32_t sum;
- sum = do_usad(a, b);
- sum += do_usad(a >> 8, b >> 8);
- sum += do_usad(a >> 16, b >>16);
- sum += do_usad(a >> 24, b >> 24);
- return sum;
-}
-
-/* For ARMv6 SEL instruction. */
-uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
-{
- uint32_t mask;
-
- mask = 0;
- if (flags & 1)
- mask |= 0xff;
- if (flags & 2)
- mask |= 0xff00;
- if (flags & 4)
- mask |= 0xff0000;
- if (flags & 8)
- mask |= 0xff000000;
- return (a & mask) | (b & ~mask);
-}
-
-uint32_t HELPER(logicq_cc)(uint64_t val)
-{
- return (val >> 32) | (val != 0);
-}
-
-/* VFP support. We follow the convention used for VFP instrunctions:
- Single precition routines have a "s" suffix, double precision a
- "d" suffix. */
-
-/* Convert host exception flags to vfp form. */
-static inline int vfp_exceptbits_from_host(int host_bits)
-{
- int target_bits = 0;
-
- if (host_bits & float_flag_invalid)
- target_bits |= 1;
- if (host_bits & float_flag_divbyzero)
- target_bits |= 2;
- if (host_bits & float_flag_overflow)
- target_bits |= 4;
- if (host_bits & float_flag_underflow)
- target_bits |= 8;
- if (host_bits & float_flag_inexact)
- target_bits |= 0x10;
- return target_bits;
-}
-
-uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
-{
- int i;
- uint32_t fpscr;
-
- fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
- | (env->vfp.vec_len << 16)
- | (env->vfp.vec_stride << 20);
- i = get_float_exception_flags(&env->vfp.fp_status);
- fpscr |= vfp_exceptbits_from_host(i);
- return fpscr;
-}
-
-/* Convert vfp exception flags to target form. */
-static inline int vfp_exceptbits_to_host(int target_bits)
-{
- int host_bits = 0;
-
- if (target_bits & 1)
- host_bits |= float_flag_invalid;
- if (target_bits & 2)
- host_bits |= float_flag_divbyzero;
- if (target_bits & 4)
- host_bits |= float_flag_overflow;
- if (target_bits & 8)
- host_bits |= float_flag_underflow;
- if (target_bits & 0x10)
- host_bits |= float_flag_inexact;
- return host_bits;
-}
-
-void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
-{
- int i;
- uint32_t changed;
-
- changed = env->vfp.xregs[ARM_VFP_FPSCR];
- env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
- env->vfp.vec_len = (val >> 16) & 7;
- env->vfp.vec_stride = (val >> 20) & 3;
-
- changed ^= val;
- if (changed & (3 << 22)) {
- i = (val >> 22) & 3;
- switch (i) {
- case 0:
- i = float_round_nearest_even;
- break;
- case 1:
- i = float_round_up;
- break;
- case 2:
- i = float_round_down;
- break;
- case 3:
- i = float_round_to_zero;
- break;
- }
- set_float_rounding_mode(i, &env->vfp.fp_status);
- }
-
- i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
- set_float_exception_flags(i, &env->vfp.fp_status);
- /* XXX: FZ and DN are not implemented. */
-}
-
-#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
-
-#define VFP_BINOP(name) \
-float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
-{ \
- return float32_ ## name (a, b, &env->vfp.fp_status); \
-} \
-float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
-{ \
- return float64_ ## name (a, b, &env->vfp.fp_status); \
-}
-VFP_BINOP(add)
-VFP_BINOP(sub)
-VFP_BINOP(mul)
-VFP_BINOP(div)
-#undef VFP_BINOP
-
-float32 VFP_HELPER(neg, s)(float32 a)
-{
- return float32_chs(a);
-}
-
-float64 VFP_HELPER(neg, d)(float64 a)
-{
- return float64_chs(a);
-}
-
-float32 VFP_HELPER(abs, s)(float32 a)
-{
- return float32_abs(a);
-}
-
-float64 VFP_HELPER(abs, d)(float64 a)
-{
- return float64_abs(a);
-}
-
-float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
-{
- return float32_sqrt(a, &env->vfp.fp_status);
-}
-
-float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
-{
- return float64_sqrt(a, &env->vfp.fp_status);
-}
-
-/* XXX: check quiet/signaling case */
-#define DO_VFP_cmp(p, type) \
-void VFP_HELPER(cmp, p)(type a, type b, CPUState *env) \
-{ \
- uint32_t flags; \
- switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
- case 0: flags = 0x6; break; \
- case -1: flags = 0x8; break; \
- case 1: flags = 0x2; break; \
- default: case 2: flags = 0x3; break; \
- } \
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
-} \
-void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
-{ \
- uint32_t flags; \
- switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
- case 0: flags = 0x6; break; \
- case -1: flags = 0x8; break; \
- case 1: flags = 0x2; break; \
- default: case 2: flags = 0x3; break; \
- } \
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
-}
-DO_VFP_cmp(s, float32)
-DO_VFP_cmp(d, float64)
-#undef DO_VFP_cmp
-
-/* Helper routines to perform bitwise copies between float and int. */
-static inline float32 vfp_itos(uint32_t i)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.i = i;
- return v.s;
-}
-
-static inline uint32_t vfp_stoi(float32 s)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.s = s;
- return v.i;
-}
-
-static inline float64 vfp_itod(uint64_t i)
-{
- union {
- uint64_t i;
- float64 d;
- } v;
-
- v.i = i;
- return v.d;
-}
-
-static inline uint64_t vfp_dtoi(float64 d)
-{
- union {
- uint64_t i;
- float64 d;
- } v;
-
- v.d = d;
- return v.i;
-}
-
-/* Integer to float conversion. */
-float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
-{
- return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
-}
-
-float64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
-{
- return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
-}
-
-float32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
-{
- return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
-}
-
-float64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
-{
- return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
-}
-
-/* Float to integer conversion. */
-float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
-{
- return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
-{
- return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
-{
- return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
-{
- return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
-{
- return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
-{
- return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
-{
- return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
-}
-
-float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
-{
- return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
-}
-
-/* floating point conversion */
-float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
-{
- return float32_to_float64(x, &env->vfp.fp_status);
-}
-
-float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
-{
- return float64_to_float32(x, &env->vfp.fp_status);
-}
-
-/* VFP3 fixed point conversion. */
-#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
-ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
-{ \
- ftype tmp; \
- tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
- &env->vfp.fp_status); \
- return ftype##_scalbn(tmp, shift, &env->vfp.fp_status); \
-} \
-ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
-{ \
- ftype tmp; \
- tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
- return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
- &env->vfp.fp_status)); \
-}
-
-VFP_CONV_FIX(sh, d, float64, int16, )
-VFP_CONV_FIX(sl, d, float64, int32, )
-VFP_CONV_FIX(uh, d, float64, uint16, u)
-VFP_CONV_FIX(ul, d, float64, uint32, u)
-VFP_CONV_FIX(sh, s, float32, int16, )
-VFP_CONV_FIX(sl, s, float32, int32, )
-VFP_CONV_FIX(uh, s, float32, uint16, u)
-VFP_CONV_FIX(ul, s, float32, uint32, u)
-#undef VFP_CONV_FIX
-
-float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
-{
- float_status *s = &env->vfp.fp_status;
- float32 two = int32_to_float32(2, s);
- return float32_sub(two, float32_mul(a, b, s), s);
-}
-
-float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
-{
- float_status *s = &env->vfp.fp_status;
- float32 three = int32_to_float32(3, s);
- return float32_sub(three, float32_mul(a, b, s), s);
-}
-
-/* NEON helpers. */
-
-/* TODO: The architecture specifies the value that the estimate functions
- should return. We return the exact reciprocal/root instead. */
-float32 HELPER(recpe_f32)(float32 a, CPUState *env)
-{
- float_status *s = &env->vfp.fp_status;
- float32 one = int32_to_float32(1, s);
- return float32_div(one, a, s);
-}
-
-float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
-{
- float_status *s = &env->vfp.fp_status;
- float32 one = int32_to_float32(1, s);
- return float32_div(one, float32_sqrt(a, s), s);
-}
-
-uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
-{
- float_status *s = &env->vfp.fp_status;
- float32 tmp;
- tmp = int32_to_float32(a, s);
- tmp = float32_scalbn(tmp, -32, s);
- tmp = helper_recpe_f32(tmp, env);
- tmp = float32_scalbn(tmp, 31, s);
- return float32_to_int32(tmp, s);
-}
-
-uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
-{
- float_status *s = &env->vfp.fp_status;
- float32 tmp;
- tmp = int32_to_float32(a, s);
- tmp = float32_scalbn(tmp, -32, s);
- tmp = helper_rsqrte_f32(tmp, env);
- tmp = float32_scalbn(tmp, 31, s);
- return float32_to_int32(tmp, s);
-}
-
-#ifdef CONFIG_TRACE
-#include "trace.h"
-void HELPER(traceTicks)(uint32_t ticks)
-{
- sim_time += ticks;
-}
-
-void HELPER(traceInsn)(void)
-{
- trace_insn_helper();
-}
-
-#if HOST_LONG_BITS == 32
-void HELPER(traceBB32)(uint32_t hi, uint32_t lo, uint32_t tb)
-{
- uint64_t bb_num = ((uint64_t)hi << 32) | lo;
- trace_bb_helper(bb_num, (void*)tb);
-}
-#endif
-
-#if HOST_LONG_BITS == 64
-void HELPER(traceBB64)(uint64_t bb_num, uint64_t tb)
-{
- trace_bb_helper(bb_num, (void*)tb);
-}
-#endif
-
-#endif /* CONFIG_TRACE */
diff --git a/target-arm/helpers.h b/target-arm/helpers.h
deleted file mode 100644
index cef53be..0000000
--- a/target-arm/helpers.h
+++ /dev/null
@@ -1,548 +0,0 @@
-#define DEF_HELPER(name, ret, args) ret glue(helper_,name) args;
-
-#ifdef GEN_HELPER
-#define DEF_HELPER_0_0(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(void) \
-{ \
- tcg_gen_helper_0_0(helper_##name); \
-}
-#define DEF_HELPER_0_1(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv arg1) \
-{ \
- tcg_gen_helper_0_1(helper_##name, arg1); \
-}
-#define DEF_HELPER_0_2(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv arg1, TCGv arg2) \
-{ \
- tcg_gen_helper_0_2(helper_##name, arg1, arg2); \
-}
-#define DEF_HELPER_0_3(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name( \
- TCGv arg1, TCGv arg2, TCGv arg3) \
-{ \
- tcg_gen_helper_0_3(helper_##name, arg1, arg2, arg3); \
-}
-#define DEF_HELPER_1_0(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv ret) \
-{ \
- tcg_gen_helper_1_0(helper_##name, ret); \
-}
-#define DEF_HELPER_1_1(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv ret, TCGv arg1) \
-{ \
- tcg_gen_helper_1_1(helper_##name, ret, arg1); \
-}
-#define DEF_HELPER_1_2(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv ret, TCGv arg1, TCGv arg2) \
-{ \
- tcg_gen_helper_1_2(helper_##name, ret, arg1, arg2); \
-}
-#define DEF_HELPER_1_3(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv ret, \
- TCGv arg1, TCGv arg2, TCGv arg3) \
-{ \
- tcg_gen_helper_1_3(helper_##name, ret, arg1, arg2, arg3); \
-}
-#define DEF_HELPER_1_4(name, ret, args) \
-DEF_HELPER(name, ret, args) \
-static inline void gen_helper_##name(TCGv ret, \
- TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) \
-{ \
- tcg_gen_helper_1_4(helper_##name, ret, arg1, arg2, arg3, arg4); \
-}
-#else /* !GEN_HELPER */
-#define DEF_HELPER_0_0 DEF_HELPER
-#define DEF_HELPER_0_1 DEF_HELPER
-#define DEF_HELPER_0_2 DEF_HELPER
-#define DEF_HELPER_0_3 DEF_HELPER
-#define DEF_HELPER_1_0 DEF_HELPER
-#define DEF_HELPER_1_1 DEF_HELPER
-#define DEF_HELPER_1_2 DEF_HELPER
-#define DEF_HELPER_1_3 DEF_HELPER
-#define DEF_HELPER_1_4 DEF_HELPER
-#define HELPER(x) glue(helper_,x)
-#endif
-
-DEF_HELPER_1_1(clz, uint32_t, (uint32_t))
-DEF_HELPER_1_1(sxtb16, uint32_t, (uint32_t))
-DEF_HELPER_1_1(uxtb16, uint32_t, (uint32_t))
-
-DEF_HELPER_1_2(add_setq, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(add_saturate, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(sub_saturate, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(add_usaturate, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(sub_usaturate, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_1(double_saturate, uint32_t, (int32_t))
-DEF_HELPER_1_2(sdiv, int32_t, (int32_t, int32_t))
-DEF_HELPER_1_2(udiv, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_1(rbit, uint32_t, (uint32_t))
-DEF_HELPER_1_1(abs, uint32_t, (uint32_t))
-
-#ifdef CONFIG_TRACE
-DEF_HELPER_0_1(traceTicks,void,(uint32_t))
-DEF_HELPER_0_0(traceInsn,void,(void))
-DEF_HELPER_0_3(traceBB32,void,(uint32_t,uint32_t,uint32_t))
-DEF_HELPER_0_2(traceBB64,void,(uint64_t,uint64_t))
-#endif
-
-#define PAS_OP(pfx) \
- DEF_HELPER_1_3(pfx ## add8, uint32_t, (uint32_t, uint32_t, uint32_t *)) \
- DEF_HELPER_1_3(pfx ## sub8, uint32_t, (uint32_t, uint32_t, uint32_t *)) \
- DEF_HELPER_1_3(pfx ## sub16, uint32_t, (uint32_t, uint32_t, uint32_t *)) \
- DEF_HELPER_1_3(pfx ## add16, uint32_t, (uint32_t, uint32_t, uint32_t *)) \
- DEF_HELPER_1_3(pfx ## addsubx, uint32_t, (uint32_t, uint32_t, uint32_t *)) \
- DEF_HELPER_1_3(pfx ## subaddx, uint32_t, (uint32_t, uint32_t, uint32_t *))
-
-PAS_OP(s)
-PAS_OP(u)
-#undef PAS_OP
-
-#define PAS_OP(pfx) \
- DEF_HELPER_1_2(pfx ## add8, uint32_t, (uint32_t, uint32_t)) \
- DEF_HELPER_1_2(pfx ## sub8, uint32_t, (uint32_t, uint32_t)) \
- DEF_HELPER_1_2(pfx ## sub16, uint32_t, (uint32_t, uint32_t)) \
- DEF_HELPER_1_2(pfx ## add16, uint32_t, (uint32_t, uint32_t)) \
- DEF_HELPER_1_2(pfx ## addsubx, uint32_t, (uint32_t, uint32_t)) \
- DEF_HELPER_1_2(pfx ## subaddx, uint32_t, (uint32_t, uint32_t))
-PAS_OP(q)
-PAS_OP(sh)
-PAS_OP(uq)
-PAS_OP(uh)
-#undef PAS_OP
-
-DEF_HELPER_1_2(ssat, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(usat, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(ssat16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(usat16, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(usad8, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_1(logicq_cc, uint32_t, (uint64_t))
-
-DEF_HELPER_1_3(sel_flags, uint32_t, (uint32_t, uint32_t, uint32_t))
-DEF_HELPER_0_1(exception, void, (uint32_t))
-DEF_HELPER_0_0(wfi, void, (void))
-
-DEF_HELPER_0_2(cpsr_write, void, (uint32_t, uint32_t))
-DEF_HELPER_1_0(cpsr_read, uint32_t, (void))
-
-DEF_HELPER_0_3(v7m_msr, void, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_2(v7m_mrs, uint32_t, (CPUState *, uint32_t))
-
-DEF_HELPER_0_3(set_cp15, void, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_2(get_cp15, uint32_t, (CPUState *, uint32_t))
-
-DEF_HELPER_0_3(set_cp, void, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_2(get_cp, uint32_t, (CPUState *, uint32_t))
-
-DEF_HELPER_1_2(get_r13_banked, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_0_3(set_r13_banked, void, (CPUState *, uint32_t, uint32_t))
-
-DEF_HELPER_0_2(mark_exclusive, void, (CPUState *, uint32_t))
-DEF_HELPER_1_2(test_exclusive, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_0_1(clrex, void, (CPUState *))
-
-DEF_HELPER_1_1(get_user_reg, uint32_t, (uint32_t))
-DEF_HELPER_0_2(set_user_reg, void, (uint32_t, uint32_t))
-
-DEF_HELPER_1_1(vfp_get_fpscr, uint32_t, (CPUState *))
-DEF_HELPER_0_2(vfp_set_fpscr, void, (CPUState *, uint32_t))
-
-DEF_HELPER_1_3(vfp_adds, float32, (float32, float32, CPUState *))
-DEF_HELPER_1_3(vfp_addd, float64, (float64, float64, CPUState *))
-DEF_HELPER_1_3(vfp_subs, float32, (float32, float32, CPUState *))
-DEF_HELPER_1_3(vfp_subd, float64, (float64, float64, CPUState *))
-DEF_HELPER_1_3(vfp_muls, float32, (float32, float32, CPUState *))
-DEF_HELPER_1_3(vfp_muld, float64, (float64, float64, CPUState *))
-DEF_HELPER_1_3(vfp_divs, float32, (float32, float32, CPUState *))
-DEF_HELPER_1_3(vfp_divd, float64, (float64, float64, CPUState *))
-DEF_HELPER_1_1(vfp_negs, float32, (float32))
-DEF_HELPER_1_1(vfp_negd, float64, (float64))
-DEF_HELPER_1_1(vfp_abss, float32, (float32))
-DEF_HELPER_1_1(vfp_absd, float64, (float64))
-DEF_HELPER_1_2(vfp_sqrts, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_sqrtd, float64, (float64, CPUState *))
-DEF_HELPER_0_3(vfp_cmps, void, (float32, float32, CPUState *))
-DEF_HELPER_0_3(vfp_cmpd, void, (float64, float64, CPUState *))
-DEF_HELPER_0_3(vfp_cmpes, void, (float32, float32, CPUState *))
-DEF_HELPER_0_3(vfp_cmped, void, (float64, float64, CPUState *))
-
-DEF_HELPER_1_2(vfp_fcvtds, float64, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_fcvtsd, float32, (float64, CPUState *))
-
-DEF_HELPER_1_2(vfp_uitos, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_uitod, float64, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_sitos, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_sitod, float64, (float32, CPUState *))
-
-DEF_HELPER_1_2(vfp_touis, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_touid, float32, (float64, CPUState *))
-DEF_HELPER_1_2(vfp_touizs, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_touizd, float32, (float64, CPUState *))
-DEF_HELPER_1_2(vfp_tosis, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_tosid, float32, (float64, CPUState *))
-DEF_HELPER_1_2(vfp_tosizs, float32, (float32, CPUState *))
-DEF_HELPER_1_2(vfp_tosizd, float32, (float64, CPUState *))
-
-DEF_HELPER_1_3(vfp_toshs, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_tosls, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_touhs, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_touls, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_toshd, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_tosld, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_touhd, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_tould, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_shtos, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_sltos, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_uhtos, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_ultos, float32, (float32, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_shtod, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_sltod, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_uhtod, float64, (float64, uint32_t, CPUState *))
-DEF_HELPER_1_3(vfp_ultod, float64, (float64, uint32_t, CPUState *))
-
-DEF_HELPER_1_3(recps_f32, float32, (float32, float32, CPUState *))
-DEF_HELPER_1_3(rsqrts_f32, float32, (float32, float32, CPUState *))
-DEF_HELPER_1_2(recpe_f32, float32, (float32, CPUState *))
-DEF_HELPER_1_2(rsqrte_f32, float32, (float32, CPUState *))
-DEF_HELPER_1_2(recpe_u32, uint32_t, (uint32_t, CPUState *))
-DEF_HELPER_1_2(rsqrte_u32, uint32_t, (uint32_t, CPUState *))
-DEF_HELPER_1_4(neon_tbl, uint32_t, (uint32_t, uint32_t, uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_add_saturate_u64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_add_saturate_s64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_sub_saturate_u64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_sub_saturate_s64, uint64_t, (uint64_t, uint64_t))
-
-DEF_HELPER_1_2(add_cc, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(adc_cc, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(sub_cc, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(sbc_cc, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(shl, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(shr, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(sar, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(ror, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(shl_cc, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(shr_cc, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(sar_cc, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(ror_cc, uint32_t, (uint32_t, uint32_t))
-
-/* neon_helper.c */
-DEF_HELPER_1_3(neon_qadd_u8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qadd_s8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qadd_u16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qadd_s16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qsub_u8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qsub_s8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qsub_u16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qsub_s16, uint32_t, (CPUState *, uint32_t, uint32_t))
-
-DEF_HELPER_1_2(neon_hadd_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hadd_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hadd_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hadd_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hadd_s32, int32_t, (int32_t, int32_t))
-DEF_HELPER_1_2(neon_hadd_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rhadd_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rhadd_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rhadd_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rhadd_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rhadd_s32, int32_t, (int32_t, int32_t))
-DEF_HELPER_1_2(neon_rhadd_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hsub_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hsub_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hsub_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hsub_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_hsub_s32, int32_t, (int32_t, int32_t))
-DEF_HELPER_1_2(neon_hsub_u32, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(neon_cgt_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cgt_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cgt_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cgt_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cgt_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cgt_s32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_s32, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(neon_min_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_min_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_min_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_min_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_min_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_min_s32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_s32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmin_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmin_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmin_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmin_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmin_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmin_s32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmax_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmax_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmax_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmax_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmax_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_pmax_s32, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(neon_abd_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abd_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abd_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abd_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abd_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abd_s32, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(neon_shl_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_shl_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_shl_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_shl_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_shl_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_shl_s32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_shl_u64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_shl_s64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_rshl_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rshl_s8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rshl_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rshl_s16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rshl_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rshl_s32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_rshl_u64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_rshl_s64, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_3(neon_qshl_u8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qshl_s8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qshl_u16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qshl_s16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qshl_u32, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qshl_s32, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qshl_u64, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(neon_qshl_s64, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(neon_qrshl_u8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrshl_s8, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrshl_u16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrshl_s16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrshl_u32, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrshl_s32, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrshl_u64, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(neon_qrshl_s64, uint64_t, (CPUState *, uint64_t, uint64_t))
-
-DEF_HELPER_1_2(neon_add_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_add_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_padd_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_padd_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_sub_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_sub_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mul_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mul_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mul_p8, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_2(neon_tst_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_tst_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_tst_u32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_ceq_u8, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_ceq_u16, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_ceq_u32, uint32_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_1(neon_abs_s8, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_abs_s16, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_clz_u8, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_clz_u16, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_cls_s8, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_cls_s16, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_cls_s32, uint32_t, (uint32_t))
-DEF_HELPER_1_1(neon_cnt_u8, uint32_t, (uint32_t))
-
-DEF_HELPER_1_3(neon_qdmulh_s16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrdmulh_s16, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qdmulh_s32, uint32_t, (CPUState *, uint32_t, uint32_t))
-DEF_HELPER_1_3(neon_qrdmulh_s32, uint32_t, (CPUState *, uint32_t, uint32_t))
-
-DEF_HELPER_1_1(neon_narrow_u8, uint32_t, (uint64_t))
-DEF_HELPER_1_1(neon_narrow_u16, uint32_t, (uint64_t))
-DEF_HELPER_1_2(neon_narrow_sat_u8, uint32_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(neon_narrow_sat_s8, uint32_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(neon_narrow_sat_u16, uint32_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(neon_narrow_sat_s16, uint32_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(neon_narrow_sat_u32, uint32_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(neon_narrow_sat_s32, uint32_t, (CPUState *, uint64_t))
-DEF_HELPER_1_1(neon_narrow_high_u8, uint32_t, (uint64_t))
-DEF_HELPER_1_1(neon_narrow_high_u16, uint32_t, (uint64_t))
-DEF_HELPER_1_1(neon_narrow_round_high_u8, uint32_t, (uint64_t))
-DEF_HELPER_1_1(neon_narrow_round_high_u16, uint32_t, (uint64_t))
-DEF_HELPER_1_1(neon_widen_u8, uint64_t, (uint32_t))
-DEF_HELPER_1_1(neon_widen_s8, uint64_t, (uint32_t))
-DEF_HELPER_1_1(neon_widen_u16, uint64_t, (uint32_t))
-DEF_HELPER_1_1(neon_widen_s16, uint64_t, (uint32_t))
-
-DEF_HELPER_1_2(neon_addl_u16, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_addl_u32, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_paddl_u16, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_paddl_u32, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_subl_u16, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_subl_u32, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_3(neon_addl_saturate_s32, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(neon_addl_saturate_s64, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_2(neon_abdl_u16, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abdl_s16, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abdl_u32, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abdl_s32, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abdl_u64, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abdl_s64, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mull_u8, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mull_s8, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mull_u16, uint64_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mull_s16, uint64_t, (uint32_t, uint32_t))
-
-DEF_HELPER_1_1(neon_negl_u16, uint64_t, (uint64_t))
-DEF_HELPER_1_1(neon_negl_u32, uint64_t, (uint64_t))
-DEF_HELPER_1_1(neon_negl_u64, uint64_t, (uint64_t))
-
-DEF_HELPER_1_2(neon_qabs_s8, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_1_2(neon_qabs_s16, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_1_2(neon_qabs_s32, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_1_2(neon_qneg_s8, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_1_2(neon_qneg_s16, uint32_t, (CPUState *, uint32_t))
-DEF_HELPER_1_2(neon_qneg_s32, uint32_t, (CPUState *, uint32_t))
-
-DEF_HELPER_0_0(neon_trn_u8, void, (void))
-DEF_HELPER_0_0(neon_trn_u16, void, (void))
-DEF_HELPER_0_0(neon_unzip_u8, void, (void))
-DEF_HELPER_0_0(neon_zip_u8, void, (void))
-DEF_HELPER_0_0(neon_zip_u16, void, (void))
-
-DEF_HELPER_1_2(neon_min_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_max_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_abd_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_add_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_sub_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_mul_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_ceq_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cge_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_cgt_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_acge_f32, uint32_t, (uint32_t, uint32_t))
-DEF_HELPER_1_2(neon_acgt_f32, uint32_t, (uint32_t, uint32_t))
-
-/* iwmmxt_helper.c */
-DEF_HELPER_1_2(iwmmxt_maddsq, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_madduq, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_sadb, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_sadw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_mulslw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_mulshw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_mululw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_muluhw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_macsw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_2(iwmmxt_macuw, uint64_t, (uint64_t, uint64_t))
-DEF_HELPER_1_1(iwmmxt_setpsr_nz, uint32_t, (uint64_t))
-
-#define DEF_IWMMXT_HELPER_SIZE_ENV(name) \
-DEF_HELPER_1_3(iwmmxt_##name##b, uint64_t, (CPUState *, uint64_t, uint64_t)) \
-DEF_HELPER_1_3(iwmmxt_##name##w, uint64_t, (CPUState *, uint64_t, uint64_t)) \
-DEF_HELPER_1_3(iwmmxt_##name##l, uint64_t, (CPUState *, uint64_t, uint64_t)) \
-
-DEF_IWMMXT_HELPER_SIZE_ENV(unpackl)
-DEF_IWMMXT_HELPER_SIZE_ENV(unpackh)
-
-DEF_HELPER_1_2(iwmmxt_unpacklub, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackluw, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpacklul, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackhub, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackhuw, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackhul, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpacklsb, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpacklsw, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpacklsl, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackhsb, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackhsw, uint64_t, (CPUState *, uint64_t))
-DEF_HELPER_1_2(iwmmxt_unpackhsl, uint64_t, (CPUState *, uint64_t))
-
-DEF_IWMMXT_HELPER_SIZE_ENV(cmpeq)
-DEF_IWMMXT_HELPER_SIZE_ENV(cmpgtu)
-DEF_IWMMXT_HELPER_SIZE_ENV(cmpgts)
-
-DEF_IWMMXT_HELPER_SIZE_ENV(mins)
-DEF_IWMMXT_HELPER_SIZE_ENV(minu)
-DEF_IWMMXT_HELPER_SIZE_ENV(maxs)
-DEF_IWMMXT_HELPER_SIZE_ENV(maxu)
-
-DEF_IWMMXT_HELPER_SIZE_ENV(subn)
-DEF_IWMMXT_HELPER_SIZE_ENV(addn)
-DEF_IWMMXT_HELPER_SIZE_ENV(subu)
-DEF_IWMMXT_HELPER_SIZE_ENV(addu)
-DEF_IWMMXT_HELPER_SIZE_ENV(subs)
-DEF_IWMMXT_HELPER_SIZE_ENV(adds)
-
-DEF_HELPER_1_3(iwmmxt_avgb0, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_avgb1, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_avgw0, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_avgw1, uint64_t, (CPUState *, uint64_t, uint64_t))
-
-DEF_HELPER_1_2(iwmmxt_msadb, uint64_t, (uint64_t, uint64_t))
-
-DEF_HELPER_1_3(iwmmxt_align, uint64_t, (uint64_t, uint64_t, uint32_t))
-DEF_HELPER_1_4(iwmmxt_insr, uint64_t, (uint64_t, uint32_t, uint32_t, uint32_t))
-
-DEF_HELPER_1_1(iwmmxt_bcstb, uint64_t, (uint32_t))
-DEF_HELPER_1_1(iwmmxt_bcstw, uint64_t, (uint32_t))
-DEF_HELPER_1_1(iwmmxt_bcstl, uint64_t, (uint32_t))
-
-DEF_HELPER_1_1(iwmmxt_addcb, uint64_t, (uint64_t))
-DEF_HELPER_1_1(iwmmxt_addcw, uint64_t, (uint64_t))
-DEF_HELPER_1_1(iwmmxt_addcl, uint64_t, (uint64_t))
-
-DEF_HELPER_1_1(iwmmxt_msbb, uint32_t, (uint64_t))
-DEF_HELPER_1_1(iwmmxt_msbw, uint32_t, (uint64_t))
-DEF_HELPER_1_1(iwmmxt_msbl, uint32_t, (uint64_t))
-
-DEF_HELPER_1_3(iwmmxt_srlw, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_srll, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_srlq, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_sllw, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_slll, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_sllq, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_sraw, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_sral, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_sraq, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_rorw, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_rorl, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_rorq, uint64_t, (CPUState *, uint64_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_shufh, uint64_t, (CPUState *, uint64_t, uint32_t))
-
-DEF_HELPER_1_3(iwmmxt_packuw, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_packul, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_packuq, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_packsw, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_packsl, uint64_t, (CPUState *, uint64_t, uint64_t))
-DEF_HELPER_1_3(iwmmxt_packsq, uint64_t, (CPUState *, uint64_t, uint64_t))
-
-DEF_HELPER_1_3(iwmmxt_muladdsl, uint64_t, (uint64_t, uint32_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_muladdsw, uint64_t, (uint64_t, uint32_t, uint32_t))
-DEF_HELPER_1_3(iwmmxt_muladdswl, uint64_t, (uint64_t, uint32_t, uint32_t))
-
-#undef DEF_HELPER
-#undef DEF_HELPER_0_0
-#undef DEF_HELPER_0_1
-#undef DEF_HELPER_0_2
-#undef DEF_HELPER_0_3
-#undef DEF_HELPER_1_0
-#undef DEF_HELPER_1_1
-#undef DEF_HELPER_1_2
-#undef DEF_HELPER_1_3
-#undef DEF_HELPER_1_4
-#undef GEN_HELPER
diff --git a/target-arm/iwmmxt_helper.c b/target-arm/iwmmxt_helper.c
deleted file mode 100644
index 6e801c8..0000000
--- a/target-arm/iwmmxt_helper.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * iwMMXt micro operations for XScale.
- *
- * Copyright (c) 2007 OpenedHand, Ltd.
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- * Copyright (c) 2008 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "helpers.h"
-
-/* iwMMXt macros extracted from GNU gdb. */
-
-/* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */
-#define SIMD8_SET( v, n, b) ((v != 0) << ((((b) + 1) * 4) + (n)))
-#define SIMD16_SET(v, n, h) ((v != 0) << ((((h) + 1) * 8) + (n)))
-#define SIMD32_SET(v, n, w) ((v != 0) << ((((w) + 1) * 16) + (n)))
-#define SIMD64_SET(v, n) ((v != 0) << (32 + (n)))
-/* Flags to pass as "n" above. */
-#define SIMD_NBIT -1
-#define SIMD_ZBIT -2
-#define SIMD_CBIT -3
-#define SIMD_VBIT -4
-/* Various status bit macros. */
-#define NBIT8(x) ((x) & 0x80)
-#define NBIT16(x) ((x) & 0x8000)
-#define NBIT32(x) ((x) & 0x80000000)
-#define NBIT64(x) ((x) & 0x8000000000000000ULL)
-#define ZBIT8(x) (((x) & 0xff) == 0)
-#define ZBIT16(x) (((x) & 0xffff) == 0)
-#define ZBIT32(x) (((x) & 0xffffffff) == 0)
-#define ZBIT64(x) (x == 0)
-/* Sign extension macros. */
-#define EXTEND8H(a) ((uint16_t) (int8_t) (a))
-#define EXTEND8(a) ((uint32_t) (int8_t) (a))
-#define EXTEND16(a) ((uint32_t) (int16_t) (a))
-#define EXTEND16S(a) ((int32_t) (int16_t) (a))
-#define EXTEND32(a) ((uint64_t) (int32_t) (a))
-
-uint64_t HELPER(iwmmxt_maddsq)(uint64_t a, uint64_t b)
-{
- a = ((
- EXTEND16S((a >> 0) & 0xffff) * EXTEND16S((b >> 0) & 0xffff) +
- EXTEND16S((a >> 16) & 0xffff) * EXTEND16S((b >> 16) & 0xffff)
- ) & 0xffffffff) | ((uint64_t) (
- EXTEND16S((a >> 32) & 0xffff) * EXTEND16S((b >> 32) & 0xffff) +
- EXTEND16S((a >> 48) & 0xffff) * EXTEND16S((b >> 48) & 0xffff)
- ) << 32);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_madduq)(uint64_t a, uint64_t b)
-{
- a = ((
- ((a >> 0) & 0xffff) * ((b >> 0) & 0xffff) +
- ((a >> 16) & 0xffff) * ((b >> 16) & 0xffff)
- ) & 0xffffffff) | ((
- ((a >> 32) & 0xffff) * ((b >> 32) & 0xffff) +
- ((a >> 48) & 0xffff) * ((b >> 48) & 0xffff)
- ) << 32);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_sadb)(uint64_t a, uint64_t b)
-{
-#define abs(x) (((x) >= 0) ? x : -x)
-#define SADB(SHR) abs((int) ((a >> SHR) & 0xff) - (int) ((b >> SHR) & 0xff))
- return
- SADB(0) + SADB(8) + SADB(16) + SADB(24) +
- SADB(32) + SADB(40) + SADB(48) + SADB(56);
-#undef SADB
-}
-
-uint64_t HELPER(iwmmxt_sadw)(uint64_t a, uint64_t b)
-{
-#define SADW(SHR) \
- abs((int) ((a >> SHR) & 0xffff) - (int) ((b >> SHR) & 0xffff))
- return SADW(0) + SADW(16) + SADW(32) + SADW(48);
-#undef SADW
-}
-
-uint64_t HELPER(iwmmxt_mulslw)(uint64_t a, uint64_t b)
-{
-#define MULS(SHR) ((uint64_t) ((( \
- EXTEND16S((a >> SHR) & 0xffff) * EXTEND16S((b >> SHR) & 0xffff) \
- ) >> 0) & 0xffff) << SHR)
- return MULS(0) | MULS(16) | MULS(32) | MULS(48);
-#undef MULS
-}
-
-uint64_t HELPER(iwmmxt_mulshw)(uint64_t a, uint64_t b)
-{
-#define MULS(SHR) ((uint64_t) ((( \
- EXTEND16S((a >> SHR) & 0xffff) * EXTEND16S((b >> SHR) & 0xffff) \
- ) >> 16) & 0xffff) << SHR)
- return MULS(0) | MULS(16) | MULS(32) | MULS(48);
-#undef MULS
-}
-
-uint64_t HELPER(iwmmxt_mululw)(uint64_t a, uint64_t b)
-{
-#define MULU(SHR) ((uint64_t) ((( \
- ((a >> SHR) & 0xffff) * ((b >> SHR) & 0xffff) \
- ) >> 0) & 0xffff) << SHR)
- return MULU(0) | MULU(16) | MULU(32) | MULU(48);
-#undef MULU
-}
-
-uint64_t HELPER(iwmmxt_muluhw)(uint64_t a, uint64_t b)
-{
-#define MULU(SHR) ((uint64_t) ((( \
- ((a >> SHR) & 0xffff) * ((b >> SHR) & 0xffff) \
- ) >> 16) & 0xffff) << SHR)
- return MULU(0) | MULU(16) | MULU(32) | MULU(48);
-#undef MULU
-}
-
-uint64_t HELPER(iwmmxt_macsw)(uint64_t a, uint64_t b)
-{
-#define MACS(SHR) ( \
- EXTEND16((a >> SHR) & 0xffff) * EXTEND16S((b >> SHR) & 0xffff))
- return (int64_t) (MACS(0) + MACS(16) + MACS(32) + MACS(48));
-#undef MACS
-}
-
-uint64_t HELPER(iwmmxt_macuw)(uint64_t a, uint64_t b)
-{
-#define MACU(SHR) ( \
- (uint32_t) ((a >> SHR) & 0xffff) * \
- (uint32_t) ((b >> SHR) & 0xffff))
- return MACU(0) + MACU(16) + MACU(32) + MACU(48);
-#undef MACU
-}
-
-#define NZBIT8(x, i) \
- SIMD8_SET(NBIT8((x) & 0xff), SIMD_NBIT, i) | \
- SIMD8_SET(ZBIT8((x) & 0xff), SIMD_ZBIT, i)
-#define NZBIT16(x, i) \
- SIMD16_SET(NBIT16((x) & 0xffff), SIMD_NBIT, i) | \
- SIMD16_SET(ZBIT16((x) & 0xffff), SIMD_ZBIT, i)
-#define NZBIT32(x, i) \
- SIMD32_SET(NBIT32((x) & 0xffffffff), SIMD_NBIT, i) | \
- SIMD32_SET(ZBIT32((x) & 0xffffffff), SIMD_ZBIT, i)
-#define NZBIT64(x) \
- SIMD64_SET(NBIT64(x), SIMD_NBIT) | \
- SIMD64_SET(ZBIT64(x), SIMD_ZBIT)
-#define IWMMXT_OP_UNPACK(S, SH0, SH1, SH2, SH3) \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, b)))(CPUState *env, \
- uint64_t a, uint64_t b) \
-{ \
- a = \
- (((a >> SH0) & 0xff) << 0) | (((b >> SH0) & 0xff) << 8) | \
- (((a >> SH1) & 0xff) << 16) | (((b >> SH1) & 0xff) << 24) | \
- (((a >> SH2) & 0xff) << 32) | (((b >> SH2) & 0xff) << 40) | \
- (((a >> SH3) & 0xff) << 48) | (((b >> SH3) & 0xff) << 56); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) | \
- NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) | \
- NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) | \
- NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7); \
- return a; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, w)))(CPUState *env, \
- uint64_t a, uint64_t b) \
-{ \
- a = \
- (((a >> SH0) & 0xffff) << 0) | \
- (((b >> SH0) & 0xffff) << 16) | \
- (((a >> SH2) & 0xffff) << 32) | \
- (((b >> SH2) & 0xffff) << 48); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 16, 1) | \
- NZBIT8(a >> 32, 2) | NZBIT8(a >> 48, 3); \
- return a; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, l)))(CPUState *env, \
- uint64_t a, uint64_t b) \
-{ \
- a = \
- (((a >> SH0) & 0xffffffff) << 0) | \
- (((b >> SH0) & 0xffffffff) << 32); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1); \
- return a; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ub)))(CPUState *env, \
- uint64_t x) \
-{ \
- x = \
- (((x >> SH0) & 0xff) << 0) | \
- (((x >> SH1) & 0xff) << 16) | \
- (((x >> SH2) & 0xff) << 32) | \
- (((x >> SH3) & 0xff) << 48); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) | \
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3); \
- return x; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, uw)))(CPUState *env, \
- uint64_t x) \
-{ \
- x = \
- (((x >> SH0) & 0xffff) << 0) | \
- (((x >> SH2) & 0xffff) << 32); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1); \
- return x; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ul)))(CPUState *env, \
- uint64_t x) \
-{ \
- x = (((x >> SH0) & 0xffffffff) << 0); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0); \
- return x; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sb)))(CPUState *env, \
- uint64_t x) \
-{ \
- x = \
- ((uint64_t) EXTEND8H((x >> SH0) & 0xff) << 0) | \
- ((uint64_t) EXTEND8H((x >> SH1) & 0xff) << 16) | \
- ((uint64_t) EXTEND8H((x >> SH2) & 0xff) << 32) | \
- ((uint64_t) EXTEND8H((x >> SH3) & 0xff) << 48); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) | \
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3); \
- return x; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sw)))(CPUState *env, \
- uint64_t x) \
-{ \
- x = \
- ((uint64_t) EXTEND16((x >> SH0) & 0xffff) << 0) | \
- ((uint64_t) EXTEND16((x >> SH2) & 0xffff) << 32); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1); \
- return x; \
-} \
-uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sl)))(CPUState *env, \
- uint64_t x) \
-{ \
- x = EXTEND32((x >> SH0) & 0xffffffff); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0); \
- return x; \
-}
-IWMMXT_OP_UNPACK(l, 0, 8, 16, 24)
-IWMMXT_OP_UNPACK(h, 32, 40, 48, 56)
-
-#define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O) \
-uint64_t HELPER(glue(iwmmxt_, glue(SUFF, b)))(CPUState *env, \
- uint64_t a, uint64_t b) \
-{ \
- a = \
- CMP(0, Tb, O, 0xff) | CMP(8, Tb, O, 0xff) | \
- CMP(16, Tb, O, 0xff) | CMP(24, Tb, O, 0xff) | \
- CMP(32, Tb, O, 0xff) | CMP(40, Tb, O, 0xff) | \
- CMP(48, Tb, O, 0xff) | CMP(56, Tb, O, 0xff); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) | \
- NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) | \
- NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) | \
- NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7); \
- return a; \
-} \
-uint64_t HELPER(glue(iwmmxt_, glue(SUFF, w)))(CPUState *env, \
- uint64_t a, uint64_t b) \
-{ \
- a = CMP(0, Tw, O, 0xffff) | CMP(16, Tw, O, 0xffff) | \
- CMP(32, Tw, O, 0xffff) | CMP(48, Tw, O, 0xffff); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) | \
- NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3); \
- return a; \
-} \
-uint64_t HELPER(glue(iwmmxt_, glue(SUFF, l)))(CPUState *env, \
- uint64_t a, uint64_t b) \
-{ \
- a = CMP(0, Tl, O, 0xffffffff) | \
- CMP(32, Tl, O, 0xffffffff); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1); \
- return a; \
-}
-#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((a >> SHR) & MASK) OPER \
- (TYPE) ((b >> SHR) & MASK)) ? (uint64_t) MASK : 0) << SHR)
-IWMMXT_OP_CMP(cmpeq, uint8_t, uint16_t, uint32_t, ==)
-IWMMXT_OP_CMP(cmpgts, int8_t, int16_t, int32_t, >)
-IWMMXT_OP_CMP(cmpgtu, uint8_t, uint16_t, uint32_t, >)
-#undef CMP
-#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((a >> SHR) & MASK) OPER \
- (TYPE) ((b >> SHR) & MASK)) ? a : b) & ((uint64_t) MASK << SHR))
-IWMMXT_OP_CMP(mins, int8_t, int16_t, int32_t, <)
-IWMMXT_OP_CMP(minu, uint8_t, uint16_t, uint32_t, <)
-IWMMXT_OP_CMP(maxs, int8_t, int16_t, int32_t, >)
-IWMMXT_OP_CMP(maxu, uint8_t, uint16_t, uint32_t, >)
-#undef CMP
-#define CMP(SHR, TYPE, OPER, MASK) ((uint64_t) (((TYPE) ((a >> SHR) & MASK) \
- OPER (TYPE) ((b >> SHR) & MASK)) & MASK) << SHR)
-IWMMXT_OP_CMP(subn, uint8_t, uint16_t, uint32_t, -)
-IWMMXT_OP_CMP(addn, uint8_t, uint16_t, uint32_t, +)
-#undef CMP
-/* TODO Signed- and Unsigned-Saturation */
-#define CMP(SHR, TYPE, OPER, MASK) ((uint64_t) (((TYPE) ((a >> SHR) & MASK) \
- OPER (TYPE) ((b >> SHR) & MASK)) & MASK) << SHR)
-IWMMXT_OP_CMP(subu, uint8_t, uint16_t, uint32_t, -)
-IWMMXT_OP_CMP(addu, uint8_t, uint16_t, uint32_t, +)
-IWMMXT_OP_CMP(subs, int8_t, int16_t, int32_t, -)
-IWMMXT_OP_CMP(adds, int8_t, int16_t, int32_t, +)
-#undef CMP
-#undef IWMMXT_OP_CMP
-
-#define AVGB(SHR) ((( \
- ((a >> SHR) & 0xff) + ((b >> SHR) & 0xff) + round) >> 1) << SHR)
-#define IWMMXT_OP_AVGB(r) \
-uint64_t HELPER(iwmmxt_avgb##r)(CPUState *env, uint64_t a, uint64_t b) \
-{ \
- const int round = r; \
- a = AVGB(0) | AVGB(8) | AVGB(16) | AVGB(24) | \
- AVGB(32) | AVGB(40) | AVGB(48) | AVGB(56); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- SIMD8_SET(ZBIT8((a >> 0) & 0xff), SIMD_ZBIT, 0) | \
- SIMD8_SET(ZBIT8((a >> 8) & 0xff), SIMD_ZBIT, 1) | \
- SIMD8_SET(ZBIT8((a >> 16) & 0xff), SIMD_ZBIT, 2) | \
- SIMD8_SET(ZBIT8((a >> 24) & 0xff), SIMD_ZBIT, 3) | \
- SIMD8_SET(ZBIT8((a >> 32) & 0xff), SIMD_ZBIT, 4) | \
- SIMD8_SET(ZBIT8((a >> 40) & 0xff), SIMD_ZBIT, 5) | \
- SIMD8_SET(ZBIT8((a >> 48) & 0xff), SIMD_ZBIT, 6) | \
- SIMD8_SET(ZBIT8((a >> 56) & 0xff), SIMD_ZBIT, 7); \
- return a; \
-}
-IWMMXT_OP_AVGB(0)
-IWMMXT_OP_AVGB(1)
-#undef IWMMXT_OP_AVGB
-#undef AVGB
-
-#define AVGW(SHR) ((( \
- ((a >> SHR) & 0xffff) + ((b >> SHR) & 0xffff) + round) >> 1) << SHR)
-#define IWMMXT_OP_AVGW(r) \
-uint64_t HELPER(iwmmxt_avgw##r)(CPUState *env, uint64_t a, uint64_t b) \
-{ \
- const int round = r; \
- a = AVGW(0) | AVGW(16) | AVGW(32) | AVGW(48); \
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = \
- SIMD16_SET(ZBIT16((a >> 0) & 0xffff), SIMD_ZBIT, 0) | \
- SIMD16_SET(ZBIT16((a >> 16) & 0xffff), SIMD_ZBIT, 1) | \
- SIMD16_SET(ZBIT16((a >> 32) & 0xffff), SIMD_ZBIT, 2) | \
- SIMD16_SET(ZBIT16((a >> 48) & 0xffff), SIMD_ZBIT, 3); \
- return a; \
-}
-IWMMXT_OP_AVGW(0)
-IWMMXT_OP_AVGW(1)
-#undef IWMMXT_OP_AVGW
-#undef AVGW
-
-uint64_t HELPER(iwmmxt_msadb)(uint64_t a, uint64_t b)
-{
- a = ((((a >> 0 ) & 0xffff) * ((b >> 0) & 0xffff) +
- ((a >> 16) & 0xffff) * ((b >> 16) & 0xffff)) & 0xffffffff) |
- ((((a >> 32) & 0xffff) * ((b >> 32) & 0xffff) +
- ((a >> 48) & 0xffff) * ((b >> 48) & 0xffff)) << 32);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_align)(uint64_t a, uint64_t b, uint32_t n)
-{
- a >>= n << 3;
- a |= b << (64 - (n << 3));
- return a;
-}
-
-uint64_t HELPER(iwmmxt_insr)(uint64_t x, uint32_t a, uint32_t b, uint32_t n)
-{
- x &= ~((uint64_t) b << n);
- x |= (uint64_t) (a & b) << n;
- return x;
-}
-
-uint32_t HELPER(iwmmxt_setpsr_nz)(uint64_t x)
-{
- return SIMD64_SET((x == 0), SIMD_ZBIT) |
- SIMD64_SET((x & (1ULL << 63)), SIMD_NBIT);
-}
-
-uint64_t HELPER(iwmmxt_bcstb)(uint32_t arg)
-{
- arg &= 0xff;
- return
- ((uint64_t) arg << 0 ) | ((uint64_t) arg << 8 ) |
- ((uint64_t) arg << 16) | ((uint64_t) arg << 24) |
- ((uint64_t) arg << 32) | ((uint64_t) arg << 40) |
- ((uint64_t) arg << 48) | ((uint64_t) arg << 56);
-}
-
-uint64_t HELPER(iwmmxt_bcstw)(uint32_t arg)
-{
- arg &= 0xffff;
- return
- ((uint64_t) arg << 0 ) | ((uint64_t) arg << 16) |
- ((uint64_t) arg << 32) | ((uint64_t) arg << 48);
-}
-
-uint64_t HELPER(iwmmxt_bcstl)(uint32_t arg)
-{
- return arg | ((uint64_t) arg << 32);
-}
-
-uint64_t HELPER(iwmmxt_addcb)(uint64_t x)
-{
- return
- ((x >> 0) & 0xff) + ((x >> 8) & 0xff) +
- ((x >> 16) & 0xff) + ((x >> 24) & 0xff) +
- ((x >> 32) & 0xff) + ((x >> 40) & 0xff) +
- ((x >> 48) & 0xff) + ((x >> 56) & 0xff);
-}
-
-uint64_t HELPER(iwmmxt_addcw)(uint64_t x)
-{
- return
- ((x >> 0) & 0xffff) + ((x >> 16) & 0xffff) +
- ((x >> 32) & 0xffff) + ((x >> 48) & 0xffff);
-}
-
-uint64_t HELPER(iwmmxt_addcl)(uint64_t x)
-{
- return (x & 0xffffffff) + (x >> 32);
-}
-
-uint32_t HELPER(iwmmxt_msbb)(uint64_t x)
-{
- return
- ((x >> 7) & 0x01) | ((x >> 14) & 0x02) |
- ((x >> 21) & 0x04) | ((x >> 28) & 0x08) |
- ((x >> 35) & 0x10) | ((x >> 42) & 0x20) |
- ((x >> 49) & 0x40) | ((x >> 56) & 0x80);
-}
-
-uint32_t HELPER(iwmmxt_msbw)(uint64_t x)
-{
- return
- ((x >> 15) & 0x01) | ((x >> 30) & 0x02) |
- ((x >> 45) & 0x04) | ((x >> 52) & 0x08);
-}
-
-uint32_t HELPER(iwmmxt_msbl)(uint64_t x)
-{
- return ((x >> 31) & 0x01) | ((x >> 62) & 0x02);
-}
-
-/* FIXME: Split wCASF setting into a separate op to avoid env use. */
-uint64_t HELPER(iwmmxt_srlw)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = (((x & (0xffffll << 0)) >> n) & (0xffffll << 0)) |
- (((x & (0xffffll << 16)) >> n) & (0xffffll << 16)) |
- (((x & (0xffffll << 32)) >> n) & (0xffffll << 32)) |
- (((x & (0xffffll << 48)) >> n) & (0xffffll << 48));
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_srll)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = ((x & (0xffffffffll << 0)) >> n) |
- ((x >> n) & (0xffffffffll << 32));
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_srlq)(CPUState *env, uint64_t x, uint32_t n)
-{
- x >>= n;
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_sllw)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = (((x & (0xffffll << 0)) << n) & (0xffffll << 0)) |
- (((x & (0xffffll << 16)) << n) & (0xffffll << 16)) |
- (((x & (0xffffll << 32)) << n) & (0xffffll << 32)) |
- (((x & (0xffffll << 48)) << n) & (0xffffll << 48));
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_slll)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = ((x << n) & (0xffffffffll << 0)) |
- ((x & (0xffffffffll << 32)) << n);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_sllq)(CPUState *env, uint64_t x, uint32_t n)
-{
- x <<= n;
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_sraw)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = ((uint64_t) ((EXTEND16(x >> 0) >> n) & 0xffff) << 0) |
- ((uint64_t) ((EXTEND16(x >> 16) >> n) & 0xffff) << 16) |
- ((uint64_t) ((EXTEND16(x >> 32) >> n) & 0xffff) << 32) |
- ((uint64_t) ((EXTEND16(x >> 48) >> n) & 0xffff) << 48);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_sral)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = (((EXTEND32(x >> 0) >> n) & 0xffffffff) << 0) |
- (((EXTEND32(x >> 32) >> n) & 0xffffffff) << 32);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_sraq)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = (int64_t) x >> n;
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_rorw)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = ((((x & (0xffffll << 0)) >> n) |
- ((x & (0xffffll << 0)) << (16 - n))) & (0xffffll << 0)) |
- ((((x & (0xffffll << 16)) >> n) |
- ((x & (0xffffll << 16)) << (16 - n))) & (0xffffll << 16)) |
- ((((x & (0xffffll << 32)) >> n) |
- ((x & (0xffffll << 32)) << (16 - n))) & (0xffffll << 32)) |
- ((((x & (0xffffll << 48)) >> n) |
- ((x & (0xffffll << 48)) << (16 - n))) & (0xffffll << 48));
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_rorl)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = ((x & (0xffffffffll << 0)) >> n) |
- ((x >> n) & (0xffffffffll << 32)) |
- ((x << (32 - n)) & (0xffffffffll << 0)) |
- ((x & (0xffffffffll << 32)) << (32 - n));
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_rorq)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = (x >> n) | (x << (64 - n));
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
- return x;
-}
-
-uint64_t HELPER(iwmmxt_shufh)(CPUState *env, uint64_t x, uint32_t n)
-{
- x = (((x >> ((n << 4) & 0x30)) & 0xffff) << 0) |
- (((x >> ((n << 2) & 0x30)) & 0xffff) << 16) |
- (((x >> ((n << 0) & 0x30)) & 0xffff) << 32) |
- (((x >> ((n >> 2) & 0x30)) & 0xffff) << 48);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
- NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
- return x;
-}
-
-/* TODO: Unsigned-Saturation */
-uint64_t HELPER(iwmmxt_packuw)(CPUState *env, uint64_t a, uint64_t b)
-{
- a = (((a >> 0) & 0xff) << 0) | (((a >> 16) & 0xff) << 8) |
- (((a >> 32) & 0xff) << 16) | (((a >> 48) & 0xff) << 24) |
- (((b >> 0) & 0xff) << 32) | (((b >> 16) & 0xff) << 40) |
- (((b >> 32) & 0xff) << 48) | (((b >> 48) & 0xff) << 56);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |
- NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |
- NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |
- NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_packul)(CPUState *env, uint64_t a, uint64_t b)
-{
- a = (((a >> 0) & 0xffff) << 0) | (((a >> 32) & 0xffff) << 16) |
- (((b >> 0) & 0xffff) << 32) | (((b >> 32) & 0xffff) << 48);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) |
- NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_packuq)(CPUState *env, uint64_t a, uint64_t b)
-{
- a = (a & 0xffffffff) | ((b & 0xffffffff) << 32);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);
- return a;
-}
-
-/* TODO: Signed-Saturation */
-uint64_t HELPER(iwmmxt_packsw)(CPUState *env, uint64_t a, uint64_t b)
-{
- a = (((a >> 0) & 0xff) << 0) | (((a >> 16) & 0xff) << 8) |
- (((a >> 32) & 0xff) << 16) | (((a >> 48) & 0xff) << 24) |
- (((b >> 0) & 0xff) << 32) | (((b >> 16) & 0xff) << 40) |
- (((b >> 32) & 0xff) << 48) | (((b >> 48) & 0xff) << 56);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |
- NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |
- NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |
- NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_packsl)(CPUState *env, uint64_t a, uint64_t b)
-{
- a = (((a >> 0) & 0xffff) << 0) | (((a >> 32) & 0xffff) << 16) |
- (((b >> 0) & 0xffff) << 32) | (((b >> 32) & 0xffff) << 48);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) |
- NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_packsq)(CPUState *env, uint64_t a, uint64_t b)
-{
- a = (a & 0xffffffff) | ((b & 0xffffffff) << 32);
- env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
- NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);
- return a;
-}
-
-uint64_t HELPER(iwmmxt_muladdsl)(uint64_t c, uint32_t a, uint32_t b)
-{
- return c + ((int32_t) EXTEND32(a) * (int32_t) EXTEND32(b));
-}
-
-uint64_t HELPER(iwmmxt_muladdsw)(uint64_t c, uint32_t a, uint32_t b)
-{
- c += EXTEND32(EXTEND16S((a >> 0) & 0xffff) *
- EXTEND16S((b >> 0) & 0xffff));
- c += EXTEND32(EXTEND16S((a >> 16) & 0xffff) *
- EXTEND16S((b >> 16) & 0xffff));
- return c;
-}
-
-uint64_t HELPER(iwmmxt_muladdswl)(uint64_t c, uint32_t a, uint32_t b)
-{
- return c + (EXTEND32(EXTEND16S(a & 0xffff) *
- EXTEND16S(b & 0xffff)));
-}
diff --git a/target-arm/machine.c b/target-arm/machine.c
deleted file mode 100644
index 3368741..0000000
--- a/target-arm/machine.c
+++ /dev/null
@@ -1,218 +0,0 @@
-#include "hw/hw.h"
-#include "hw/boards.h"
-
-void register_machines(void)
-{
-#if 0 /* ANDROID */
- qemu_register_machine(&integratorcp_machine);
- qemu_register_machine(&versatilepb_machine);
- qemu_register_machine(&versatileab_machine);
- qemu_register_machine(&realview_machine);
- qemu_register_machine(&akitapda_machine);
- qemu_register_machine(&spitzpda_machine);
- qemu_register_machine(&borzoipda_machine);
- qemu_register_machine(&terrierpda_machine);
- qemu_register_machine(&palmte_machine);
- qemu_register_machine(&n800_machine);
- qemu_register_machine(&n810_machine);
- qemu_register_machine(&lm3s811evb_machine);
- qemu_register_machine(&lm3s6965evb_machine);
- qemu_register_machine(&connex_machine);
- qemu_register_machine(&verdex_machine);
- qemu_register_machine(&mainstone2_machine);
- qemu_register_machine(&musicpal_machine);
- qemu_register_machine(&tosapda_machine);
-#endif
- qemu_register_machine(&android_arm_machine);
-}
-
-void cpu_save(QEMUFile *f, void *opaque)
-{
- int i;
- CPUARMState *env = (CPUARMState *)opaque;
-
- for (i = 0; i < 16; i++) {
- qemu_put_be32(f, env->regs[i]);
- }
- qemu_put_be32(f, cpsr_read(env));
- qemu_put_be32(f, env->spsr);
- for (i = 0; i < 6; i++) {
- qemu_put_be32(f, env->banked_spsr[i]);
- qemu_put_be32(f, env->banked_r13[i]);
- qemu_put_be32(f, env->banked_r14[i]);
- }
- for (i = 0; i < 5; i++) {
- qemu_put_be32(f, env->usr_regs[i]);
- qemu_put_be32(f, env->fiq_regs[i]);
- }
- qemu_put_be32(f, env->cp15.c0_cpuid);
- qemu_put_be32(f, env->cp15.c0_cachetype);
- qemu_put_be32(f, env->cp15.c1_sys);
- qemu_put_be32(f, env->cp15.c1_coproc);
- qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
- qemu_put_be32(f, env->cp15.c2_base0);
- qemu_put_be32(f, env->cp15.c2_base1);
- qemu_put_be32(f, env->cp15.c2_mask);
- qemu_put_be32(f, env->cp15.c2_data);
- qemu_put_be32(f, env->cp15.c2_insn);
- qemu_put_be32(f, env->cp15.c3);
- qemu_put_be32(f, env->cp15.c5_insn);
- qemu_put_be32(f, env->cp15.c5_data);
- for (i = 0; i < 8; i++) {
- qemu_put_be32(f, env->cp15.c6_region[i]);
- }
- qemu_put_be32(f, env->cp15.c6_insn);
- qemu_put_be32(f, env->cp15.c6_data);
- qemu_put_be32(f, env->cp15.c9_insn);
- qemu_put_be32(f, env->cp15.c9_data);
- qemu_put_be32(f, env->cp15.c13_fcse);
- qemu_put_be32(f, env->cp15.c13_context);
- qemu_put_be32(f, env->cp15.c13_tls1);
- qemu_put_be32(f, env->cp15.c13_tls2);
- qemu_put_be32(f, env->cp15.c13_tls3);
- qemu_put_be32(f, env->cp15.c15_cpar);
-
- qemu_put_be32(f, env->features);
-
- if (arm_feature(env, ARM_FEATURE_VFP)) {
- for (i = 0; i < 16; i++) {
- CPU_DoubleU u;
- u.d = env->vfp.regs[i];
- qemu_put_be32(f, u.l.upper);
- qemu_put_be32(f, u.l.lower);
- }
- for (i = 0; i < 16; i++) {
- qemu_put_be32(f, env->vfp.xregs[i]);
- }
-
- /* TODO: Should use proper FPSCR access functions. */
- qemu_put_be32(f, env->vfp.vec_len);
- qemu_put_be32(f, env->vfp.vec_stride);
-
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
- for (i = 16; i < 32; i++) {
- CPU_DoubleU u;
- u.d = env->vfp.regs[i];
- qemu_put_be32(f, u.l.upper);
- qemu_put_be32(f, u.l.lower);
- }
- }
- }
-
- if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
- for (i = 0; i < 16; i++) {
- qemu_put_be64(f, env->iwmmxt.regs[i]);
- }
- for (i = 0; i < 16; i++) {
- qemu_put_be32(f, env->iwmmxt.cregs[i]);
- }
- }
-
- if (arm_feature(env, ARM_FEATURE_M)) {
- qemu_put_be32(f, env->v7m.other_sp);
- qemu_put_be32(f, env->v7m.vecbase);
- qemu_put_be32(f, env->v7m.basepri);
- qemu_put_be32(f, env->v7m.control);
- qemu_put_be32(f, env->v7m.current_sp);
- qemu_put_be32(f, env->v7m.exception);
- }
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUARMState *env = (CPUARMState *)opaque;
- int i;
-
- if (version_id != CPU_SAVE_VERSION)
- return -EINVAL;
-
- for (i = 0; i < 16; i++) {
- env->regs[i] = qemu_get_be32(f);
- }
- cpsr_write(env, qemu_get_be32(f), 0xffffffff);
- env->spsr = qemu_get_be32(f);
- for (i = 0; i < 6; i++) {
- env->banked_spsr[i] = qemu_get_be32(f);
- env->banked_r13[i] = qemu_get_be32(f);
- env->banked_r14[i] = qemu_get_be32(f);
- }
- for (i = 0; i < 5; i++) {
- env->usr_regs[i] = qemu_get_be32(f);
- env->fiq_regs[i] = qemu_get_be32(f);
- }
- env->cp15.c0_cpuid = qemu_get_be32(f);
- env->cp15.c0_cachetype = qemu_get_be32(f);
- env->cp15.c1_sys = qemu_get_be32(f);
- env->cp15.c1_coproc = qemu_get_be32(f);
- env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
- env->cp15.c2_base0 = qemu_get_be32(f);
- env->cp15.c2_base1 = qemu_get_be32(f);
- env->cp15.c2_mask = qemu_get_be32(f);
- env->cp15.c2_data = qemu_get_be32(f);
- env->cp15.c2_insn = qemu_get_be32(f);
- env->cp15.c3 = qemu_get_be32(f);
- env->cp15.c5_insn = qemu_get_be32(f);
- env->cp15.c5_data = qemu_get_be32(f);
- for (i = 0; i < 8; i++) {
- env->cp15.c6_region[i] = qemu_get_be32(f);
- }
- env->cp15.c6_insn = qemu_get_be32(f);
- env->cp15.c6_data = qemu_get_be32(f);
- env->cp15.c9_insn = qemu_get_be32(f);
- env->cp15.c9_data = qemu_get_be32(f);
- env->cp15.c13_fcse = qemu_get_be32(f);
- env->cp15.c13_context = qemu_get_be32(f);
- env->cp15.c13_tls1 = qemu_get_be32(f);
- env->cp15.c13_tls2 = qemu_get_be32(f);
- env->cp15.c13_tls3 = qemu_get_be32(f);
- env->cp15.c15_cpar = qemu_get_be32(f);
-
- env->features = qemu_get_be32(f);
-
- if (arm_feature(env, ARM_FEATURE_VFP)) {
- for (i = 0; i < 16; i++) {
- CPU_DoubleU u;
- u.l.upper = qemu_get_be32(f);
- u.l.lower = qemu_get_be32(f);
- env->vfp.regs[i] = u.d;
- }
- for (i = 0; i < 16; i++) {
- env->vfp.xregs[i] = qemu_get_be32(f);
- }
-
- /* TODO: Should use proper FPSCR access functions. */
- env->vfp.vec_len = qemu_get_be32(f);
- env->vfp.vec_stride = qemu_get_be32(f);
-
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
- for (i = 0; i < 16; i++) {
- CPU_DoubleU u;
- u.l.upper = qemu_get_be32(f);
- u.l.lower = qemu_get_be32(f);
- env->vfp.regs[i] = u.d;
- }
- }
- }
-
- if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
- for (i = 0; i < 16; i++) {
- env->iwmmxt.regs[i] = qemu_get_be64(f);
- }
- for (i = 0; i < 16; i++) {
- env->iwmmxt.cregs[i] = qemu_get_be32(f);
- }
- }
-
- if (arm_feature(env, ARM_FEATURE_M)) {
- env->v7m.other_sp = qemu_get_be32(f);
- env->v7m.vecbase = qemu_get_be32(f);
- env->v7m.basepri = qemu_get_be32(f);
- env->v7m.control = qemu_get_be32(f);
- env->v7m.current_sp = qemu_get_be32(f);
- env->v7m.exception = qemu_get_be32(f);
- }
-
- return 0;
-}
-
-
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
deleted file mode 100644
index 4ee5658..0000000
--- a/target-arm/neon_helper.c
+++ /dev/null
@@ -1,1457 +0,0 @@
-/*
- * ARM NEON vector operations.
- *
- * Copyright (c) 2007, 2008 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GNU GPL v2.
- */
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "helpers.h"
-
-#define SIGNBIT (uint32_t)0x80000000
-#define SIGNBIT64 ((uint64_t)1 << 63)
-
-#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] = CPSR_Q
-
-static float_status neon_float_status;
-#define NFS &neon_float_status
-
-/* Helper routines to perform bitwise copies between float and int. */
-static inline float32 vfp_itos(uint32_t i)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.i = i;
- return v.s;
-}
-
-static inline uint32_t vfp_stoi(float32 s)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.s = s;
- return v.i;
-}
-
-#define NEON_TYPE1(name, type) \
-typedef struct \
-{ \
- type v1; \
-} neon_##name;
-#ifdef WORDS_BIGENDIAN
-#define NEON_TYPE2(name, type) \
-typedef struct \
-{ \
- type v2; \
- type v1; \
-} neon_##name;
-#define NEON_TYPE4(name, type) \
-typedef struct \
-{ \
- type v4; \
- type v3; \
- type v2; \
- type v1; \
-} neon_##name;
-#else
-#define NEON_TYPE2(name, type) \
-typedef struct \
-{ \
- type v1; \
- type v2; \
-} neon_##name;
-#define NEON_TYPE4(name, type) \
-typedef struct \
-{ \
- type v1; \
- type v2; \
- type v3; \
- type v4; \
-} neon_##name;
-#endif
-
-NEON_TYPE4(s8, int8_t)
-NEON_TYPE4(u8, uint8_t)
-NEON_TYPE2(s16, int16_t)
-NEON_TYPE2(u16, uint16_t)
-NEON_TYPE1(s32, int32_t)
-NEON_TYPE1(u32, uint32_t)
-#undef NEON_TYPE4
-#undef NEON_TYPE2
-#undef NEON_TYPE1
-
-/* Copy from a uint32_t to a vector structure type. */
-#define NEON_UNPACK(vtype, dest, val) do { \
- union { \
- vtype v; \
- uint32_t i; \
- } conv_u; \
- conv_u.i = (val); \
- dest = conv_u.v; \
- } while(0)
-
-/* Copy from a vector structure type to a uint32_t. */
-#define NEON_PACK(vtype, dest, val) do { \
- union { \
- vtype v; \
- uint32_t i; \
- } conv_u; \
- conv_u.v = (val); \
- dest = conv_u.i; \
- } while(0)
-
-#define NEON_DO1 \
- NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1);
-#define NEON_DO2 \
- NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
- NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2);
-#define NEON_DO4 \
- NEON_FN(vdest.v1, vsrc1.v1, vsrc2.v1); \
- NEON_FN(vdest.v2, vsrc1.v2, vsrc2.v2); \
- NEON_FN(vdest.v3, vsrc1.v3, vsrc2.v3); \
- NEON_FN(vdest.v4, vsrc1.v4, vsrc2.v4);
-
-#define NEON_VOP_BODY(vtype, n) \
-{ \
- uint32_t res; \
- vtype vsrc1; \
- vtype vsrc2; \
- vtype vdest; \
- NEON_UNPACK(vtype, vsrc1, arg1); \
- NEON_UNPACK(vtype, vsrc2, arg2); \
- NEON_DO##n; \
- NEON_PACK(vtype, res, vdest); \
- return res; \
-}
-
-#define NEON_VOP(name, vtype, n) \
-uint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
-NEON_VOP_BODY(vtype, n)
-
-#define NEON_VOP_ENV(name, vtype, n) \
-uint32_t HELPER(glue(neon_,name))(CPUState *env, uint32_t arg1, uint32_t arg2) \
-NEON_VOP_BODY(vtype, n)
-
-/* Pairwise operations. */
-/* For 32-bit elements each segment only contains a single element, so
- the elementwise and pairwise operations are the same. */
-#define NEON_PDO2 \
- NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
- NEON_FN(vdest.v2, vsrc2.v1, vsrc2.v2);
-#define NEON_PDO4 \
- NEON_FN(vdest.v1, vsrc1.v1, vsrc1.v2); \
- NEON_FN(vdest.v2, vsrc1.v3, vsrc1.v4); \
- NEON_FN(vdest.v3, vsrc2.v1, vsrc2.v2); \
- NEON_FN(vdest.v4, vsrc2.v3, vsrc2.v4); \
-
-#define NEON_POP(name, vtype, n) \
-uint32_t HELPER(glue(neon_,name))(uint32_t arg1, uint32_t arg2) \
-{ \
- uint32_t res; \
- vtype vsrc1; \
- vtype vsrc2; \
- vtype vdest; \
- NEON_UNPACK(vtype, vsrc1, arg1); \
- NEON_UNPACK(vtype, vsrc2, arg2); \
- NEON_PDO##n; \
- NEON_PACK(vtype, res, vdest); \
- return res; \
-}
-
-/* Unary operators. */
-#define NEON_VOP1(name, vtype, n) \
-uint32_t HELPER(glue(neon_,name))(uint32_t arg) \
-{ \
- vtype vsrc1; \
- vtype vdest; \
- NEON_UNPACK(vtype, vsrc1, arg); \
- NEON_DO##n; \
- NEON_PACK(vtype, arg, vdest); \
- return arg; \
-}
-
-
-#define NEON_USAT(dest, src1, src2, type) do { \
- uint32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
- if (tmp != (type)tmp) { \
- SET_QC(); \
- dest = ~0; \
- } else { \
- dest = tmp; \
- }} while(0)
-#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
-NEON_VOP_ENV(qadd_u8, neon_u8, 4)
-#undef NEON_FN
-#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
-NEON_VOP_ENV(qadd_u16, neon_u16, 2)
-#undef NEON_FN
-#undef NEON_USAT
-
-#define NEON_SSAT(dest, src1, src2, type) do { \
- int32_t tmp = (uint32_t)src1 + (uint32_t)src2; \
- if (tmp != (type)tmp) { \
- SET_QC(); \
- if (src2 > 0) { \
- tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
- } else { \
- tmp = 1 << (sizeof(type) * 8 - 1); \
- } \
- } \
- dest = tmp; \
- } while(0)
-#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
-NEON_VOP_ENV(qadd_s8, neon_s8, 4)
-#undef NEON_FN
-#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
-NEON_VOP_ENV(qadd_s16, neon_s16, 2)
-#undef NEON_FN
-#undef NEON_SSAT
-
-#define NEON_USAT(dest, src1, src2, type) do { \
- uint32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
- if (tmp != (type)tmp) { \
- SET_QC(); \
- dest = 0; \
- } else { \
- dest = tmp; \
- }} while(0)
-#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint8_t)
-NEON_VOP_ENV(qsub_u8, neon_u8, 4)
-#undef NEON_FN
-#define NEON_FN(dest, src1, src2) NEON_USAT(dest, src1, src2, uint16_t)
-NEON_VOP_ENV(qsub_u16, neon_u16, 2)
-#undef NEON_FN
-#undef NEON_USAT
-
-#define NEON_SSAT(dest, src1, src2, type) do { \
- int32_t tmp = (uint32_t)src1 - (uint32_t)src2; \
- if (tmp != (type)tmp) { \
- SET_QC(); \
- if (src2 < 0) { \
- tmp = (1 << (sizeof(type) * 8 - 1)) - 1; \
- } else { \
- tmp = 1 << (sizeof(type) * 8 - 1); \
- } \
- } \
- dest = tmp; \
- } while(0)
-#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int8_t)
-NEON_VOP_ENV(qsub_s8, neon_s8, 4)
-#undef NEON_FN
-#define NEON_FN(dest, src1, src2) NEON_SSAT(dest, src1, src2, int16_t)
-NEON_VOP_ENV(qsub_s16, neon_s16, 2)
-#undef NEON_FN
-#undef NEON_SSAT
-
-#define NEON_FN(dest, src1, src2) dest = (src1 + src2) >> 1
-NEON_VOP(hadd_s8, neon_s8, 4)
-NEON_VOP(hadd_u8, neon_u8, 4)
-NEON_VOP(hadd_s16, neon_s16, 2)
-NEON_VOP(hadd_u16, neon_u16, 2)
-#undef NEON_FN
-
-int32_t HELPER(neon_hadd_s32)(int32_t src1, int32_t src2)
-{
- int32_t dest;
-
- dest = (src1 >> 1) + (src2 >> 1);
- if (src1 & src2 & 1)
- dest++;
- return dest;
-}
-
-uint32_t HELPER(neon_hadd_u32)(uint32_t src1, uint32_t src2)
-{
- uint32_t dest;
-
- dest = (src1 >> 1) + (src2 >> 1);
- if (src1 & src2 & 1)
- dest++;
- return dest;
-}
-
-#define NEON_FN(dest, src1, src2) dest = (src1 + src2 + 1) >> 1
-NEON_VOP(rhadd_s8, neon_s8, 4)
-NEON_VOP(rhadd_u8, neon_u8, 4)
-NEON_VOP(rhadd_s16, neon_s16, 2)
-NEON_VOP(rhadd_u16, neon_u16, 2)
-#undef NEON_FN
-
-int32_t HELPER(neon_rhadd_s32)(int32_t src1, int32_t src2)
-{
- int32_t dest;
-
- dest = (src1 >> 1) + (src2 >> 1);
- if ((src1 | src2) & 1)
- dest++;
- return dest;
-}
-
-uint32_t HELPER(neon_rhadd_u32)(uint32_t src1, uint32_t src2)
-{
- uint32_t dest;
-
- dest = (src1 >> 1) + (src2 >> 1);
- if ((src1 | src2) & 1)
- dest++;
- return dest;
-}
-
-#define NEON_FN(dest, src1, src2) dest = (src1 - src2) >> 1
-NEON_VOP(hsub_s8, neon_s8, 4)
-NEON_VOP(hsub_u8, neon_u8, 4)
-NEON_VOP(hsub_s16, neon_s16, 2)
-NEON_VOP(hsub_u16, neon_u16, 2)
-#undef NEON_FN
-
-int32_t HELPER(neon_hsub_s32)(int32_t src1, int32_t src2)
-{
- int32_t dest;
-
- dest = (src1 >> 1) - (src2 >> 1);
- if ((~src1) & src2 & 1)
- dest--;
- return dest;
-}
-
-uint32_t HELPER(neon_hsub_u32)(uint32_t src1, uint32_t src2)
-{
- uint32_t dest;
-
- dest = (src1 >> 1) - (src2 >> 1);
- if ((~src1) & src2 & 1)
- dest--;
- return dest;
-}
-
-#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? ~0 : 0
-NEON_VOP(cgt_s8, neon_s8, 4)
-NEON_VOP(cgt_u8, neon_u8, 4)
-NEON_VOP(cgt_s16, neon_s16, 2)
-NEON_VOP(cgt_u16, neon_u16, 2)
-NEON_VOP(cgt_s32, neon_s32, 1)
-NEON_VOP(cgt_u32, neon_u32, 1)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) dest = (src1 >= src2) ? ~0 : 0
-NEON_VOP(cge_s8, neon_s8, 4)
-NEON_VOP(cge_u8, neon_u8, 4)
-NEON_VOP(cge_s16, neon_s16, 2)
-NEON_VOP(cge_u16, neon_u16, 2)
-NEON_VOP(cge_s32, neon_s32, 1)
-NEON_VOP(cge_u32, neon_u32, 1)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
-NEON_VOP(min_s8, neon_s8, 4)
-NEON_VOP(min_u8, neon_u8, 4)
-NEON_VOP(min_s16, neon_s16, 2)
-NEON_VOP(min_u16, neon_u16, 2)
-NEON_VOP(min_s32, neon_s32, 1)
-NEON_VOP(min_u32, neon_u32, 1)
-NEON_POP(pmin_s8, neon_s8, 4)
-NEON_POP(pmin_u8, neon_u8, 4)
-NEON_POP(pmin_s16, neon_s16, 2)
-NEON_POP(pmin_u16, neon_u16, 2)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? src1 : src2
-NEON_VOP(max_s8, neon_s8, 4)
-NEON_VOP(max_u8, neon_u8, 4)
-NEON_VOP(max_s16, neon_s16, 2)
-NEON_VOP(max_u16, neon_u16, 2)
-NEON_VOP(max_s32, neon_s32, 1)
-NEON_VOP(max_u32, neon_u32, 1)
-NEON_POP(pmax_s8, neon_s8, 4)
-NEON_POP(pmax_u8, neon_u8, 4)
-NEON_POP(pmax_s16, neon_s16, 2)
-NEON_POP(pmax_u16, neon_u16, 2)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) \
- dest = (src1 > src2) ? (src1 - src2) : (src2 - src1)
-NEON_VOP(abd_s8, neon_s8, 4)
-NEON_VOP(abd_u8, neon_u8, 4)
-NEON_VOP(abd_s16, neon_s16, 2)
-NEON_VOP(abd_u16, neon_u16, 2)
-NEON_VOP(abd_s32, neon_s32, 1)
-NEON_VOP(abd_u32, neon_u32, 1)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp >= sizeof(src1) * 8 || tmp <= -sizeof(src1) * 8) { \
- dest = 0; \
- } else if (tmp < 0) { \
- dest = src1 >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- }} while (0)
-NEON_VOP(shl_u8, neon_u8, 4)
-NEON_VOP(shl_u16, neon_u16, 2)
-NEON_VOP(shl_u32, neon_u32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_shl_u64)(uint64_t val, uint64_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- if (shift >= 64 || shift <= -64) {
- val = 0;
- } else if (shift < 0) {
- val >>= -shift;
- } else {
- val <<= shift;
- }
- return val;
-}
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp >= sizeof(src1) * 8) { \
- dest = 0; \
- } else if (tmp <= -sizeof(src1) * 8) { \
- dest = src1 >> (sizeof(src1) * 8 - 1); \
- } else if (tmp < 0) { \
- dest = src1 >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- }} while (0)
-NEON_VOP(shl_s8, neon_s8, 4)
-NEON_VOP(shl_s16, neon_s16, 2)
-NEON_VOP(shl_s32, neon_s32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- int64_t val = valop;
- if (shift >= 64) {
- val = 0;
- } else if (shift <= -64) {
- val >>= 63;
- } else if (shift < 0) {
- val >>= -shift;
- } else {
- val <<= shift;
- }
- return val;
-}
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp >= sizeof(src1) * 8) { \
- dest = 0; \
- } else if (tmp < -sizeof(src1) * 8) { \
- dest >>= sizeof(src1) * 8 - 1; \
- } else if (tmp == -sizeof(src1) * 8) { \
- dest = src1 >> (tmp - 1); \
- dest++; \
- src2 >>= 1; \
- } else if (tmp < 0) { \
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- }} while (0)
-NEON_VOP(rshl_s8, neon_s8, 4)
-NEON_VOP(rshl_s16, neon_s16, 2)
-NEON_VOP(rshl_s32, neon_s32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- int64_t val = valop;
- if (shift >= 64) {
- val = 0;
- } else if (shift < -64) {
- val >>= 63;
- } else if (shift == -63) {
- val >>= 63;
- val++;
- val >>= 1;
- } else if (shift < 0) {
- val = (val + ((int64_t)1 << (-1 - shift))) >> -shift;
- } else {
- val <<= shift;
- }
- return val;
-}
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp >= sizeof(src1) * 8 || tmp < -sizeof(src1) * 8) { \
- dest = 0; \
- } else if (tmp == -sizeof(src1) * 8) { \
- dest = src1 >> (tmp - 1); \
- } else if (tmp < 0) { \
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- }} while (0)
-NEON_VOP(rshl_u8, neon_u8, 4)
-NEON_VOP(rshl_u16, neon_u16, 2)
-NEON_VOP(rshl_u32, neon_u32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
-{
- int8_t shift = (uint8_t)shiftop;
- if (shift >= 64 || shift < 64) {
- val = 0;
- } else if (shift == -64) {
- /* Rounding a 1-bit result just preserves that bit. */
- val >>= 63;
- } if (shift < 0) {
- val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift;
- val >>= -shift;
- } else {
- val <<= shift;
- }
- return val;
-}
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp >= sizeof(src1) * 8) { \
- if (src1) { \
- SET_QC(); \
- dest = ~0; \
- } else { \
- dest = 0; \
- } \
- } else if (tmp <= -sizeof(src1) * 8) { \
- dest = 0; \
- } else if (tmp < 0) { \
- dest = src1 >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- if ((dest >> tmp) != src1) { \
- SET_QC(); \
- dest = ~0; \
- } \
- }} while (0)
-NEON_VOP_ENV(qshl_u8, neon_u8, 4)
-NEON_VOP_ENV(qshl_u16, neon_u16, 2)
-NEON_VOP_ENV(qshl_u32, neon_u32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_qshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- if (shift >= 64) {
- if (val) {
- val = ~(uint64_t)0;
- SET_QC();
- } else {
- val = 0;
- }
- } else if (shift <= -64) {
- val = 0;
- } else if (shift < 0) {
- val >>= -shift;
- } else {
- uint64_t tmp = val;
- val <<= shift;
- if ((val >> shift) != tmp) {
- SET_QC();
- val = ~(uint64_t)0;
- }
- }
- return val;
-}
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp >= sizeof(src1) * 8) { \
- if (src1) \
- SET_QC(); \
- dest = src1 >> 31; \
- } else if (tmp <= -sizeof(src1) * 8) { \
- dest = src1 >> 31; \
- } else if (tmp < 0) { \
- dest = src1 >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- if ((dest >> tmp) != src1) { \
- SET_QC(); \
- dest = src2 >> 31; \
- } \
- }} while (0)
-NEON_VOP_ENV(qshl_s8, neon_s8, 4)
-NEON_VOP_ENV(qshl_s16, neon_s16, 2)
-NEON_VOP_ENV(qshl_s32, neon_s32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_qshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
-{
- int8_t shift = (uint8_t)shiftop;
- int64_t val = valop;
- if (shift >= 64) {
- if (val) {
- SET_QC();
- val = (val >> 63) & ~SIGNBIT64;
- }
- } else if (shift <= 64) {
- val >>= 63;
- } else if (shift < 0) {
- val >>= -shift;
- } else {
- int64_t tmp = val;
- val <<= shift;
- if ((val >> shift) != tmp) {
- SET_QC();
- val = (tmp >> 63) ^ ~SIGNBIT64;
- }
- }
- return val;
-}
-
-
-/* FIXME: This is wrong. */
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp < 0) { \
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- if ((dest >> tmp) != src1) { \
- SET_QC(); \
- dest = ~0; \
- } \
- }} while (0)
-NEON_VOP_ENV(qrshl_u8, neon_u8, 4)
-NEON_VOP_ENV(qrshl_u16, neon_u16, 2)
-NEON_VOP_ENV(qrshl_u32, neon_u32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
-{
- int8_t shift = (int8_t)shiftop;
- if (shift < 0) {
- val = (val + (1 << (-1 - shift))) >> -shift;
- } else { \
- uint64_t tmp = val;
- val <<= shift;
- if ((val >> shift) != tmp) {
- SET_QC();
- val = ~0;
- }
- }
- return val;
-}
-
-#define NEON_FN(dest, src1, src2) do { \
- int8_t tmp; \
- tmp = (int8_t)src2; \
- if (tmp < 0) { \
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
- } else { \
- dest = src1 << tmp; \
- if ((dest >> tmp) != src1) { \
- SET_QC(); \
- dest = src1 >> 31; \
- } \
- }} while (0)
-NEON_VOP_ENV(qrshl_s8, neon_s8, 4)
-NEON_VOP_ENV(qrshl_s16, neon_s16, 2)
-NEON_VOP_ENV(qrshl_s32, neon_s32, 1)
-#undef NEON_FN
-
-uint64_t HELPER(neon_qrshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
-{
- int8_t shift = (uint8_t)shiftop;
- int64_t val = valop;
-
- if (shift < 0) {
- val = (val + (1 << (-1 - shift))) >> -shift;
- } else {
- int64_t tmp = val;;
- val <<= shift;
- if ((val >> shift) != tmp) {
- SET_QC();
- val = tmp >> 31;
- }
- }
- return val;
-}
-
-uint32_t HELPER(neon_add_u8)(uint32_t a, uint32_t b)
-{
- uint32_t mask;
- mask = (a ^ b) & 0x80808080u;
- a &= ~0x80808080u;
- b &= ~0x80808080u;
- return (a + b) ^ mask;
-}
-
-uint32_t HELPER(neon_add_u16)(uint32_t a, uint32_t b)
-{
- uint32_t mask;
- mask = (a ^ b) & 0x80008000u;
- a &= ~0x80008000u;
- b &= ~0x80008000u;
- return (a + b) ^ mask;
-}
-
-#define NEON_FN(dest, src1, src2) dest = src1 + src2
-NEON_POP(padd_u8, neon_u8, 4)
-NEON_POP(padd_u16, neon_u16, 2)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) dest = src1 - src2
-NEON_VOP(sub_u8, neon_u8, 4)
-NEON_VOP(sub_u16, neon_u16, 2)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) dest = src1 * src2
-NEON_VOP(mul_u8, neon_u8, 4)
-NEON_VOP(mul_u16, neon_u16, 2)
-#undef NEON_FN
-
-/* Polynomial multiplication is like integer multiplication except the
- partial products are XORed, not added. */
-uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
-{
- uint32_t mask;
- uint32_t result;
- result = 0;
- while (op1) {
- mask = 0;
- if (op1 & 1)
- mask |= 0xff;
- if (op1 & (1 << 8))
- mask |= (0xff << 8);
- if (op1 & (1 << 16))
- mask |= (0xff << 16);
- if (op1 & (1 << 24))
- mask |= (0xff << 24);
- result ^= op2 & mask;
- op1 = (op1 >> 1) & 0x7f7f7f7f;
- op2 = (op2 << 1) & 0xfefefefe;
- }
- return result;
-}
-
-#define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0
-NEON_VOP(tst_u8, neon_u8, 4)
-NEON_VOP(tst_u16, neon_u16, 2)
-NEON_VOP(tst_u32, neon_u32, 1)
-#undef NEON_FN
-
-#define NEON_FN(dest, src1, src2) dest = (src1 == src2) ? -1 : 0
-NEON_VOP(ceq_u8, neon_u8, 4)
-NEON_VOP(ceq_u16, neon_u16, 2)
-NEON_VOP(ceq_u32, neon_u32, 1)
-#undef NEON_FN
-
-#define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
-NEON_VOP1(abs_s8, neon_s8, 4)
-NEON_VOP1(abs_s16, neon_s16, 2)
-#undef NEON_FN
-
-/* Count Leading Sign/Zero Bits. */
-static inline int do_clz8(uint8_t x)
-{
- int n;
- for (n = 8; x; n--)
- x >>= 1;
- return n;
-}
-
-static inline int do_clz16(uint16_t x)
-{
- int n;
- for (n = 16; x; n--)
- x >>= 1;
- return n;
-}
-
-#define NEON_FN(dest, src, dummy) dest = do_clz8(src)
-NEON_VOP1(clz_u8, neon_u8, 4)
-#undef NEON_FN
-
-#define NEON_FN(dest, src, dummy) dest = do_clz16(src)
-NEON_VOP1(clz_u16, neon_u16, 2)
-#undef NEON_FN
-
-#define NEON_FN(dest, src, dummy) dest = do_clz8((src < 0) ? ~src : src) - 1
-NEON_VOP1(cls_s8, neon_s8, 4)
-#undef NEON_FN
-
-#define NEON_FN(dest, src, dummy) dest = do_clz16((src < 0) ? ~src : src) - 1
-NEON_VOP1(cls_s16, neon_s16, 2)
-#undef NEON_FN
-
-uint32_t HELPER(neon_cls_s32)(uint32_t x)
-{
- int count;
- if ((int32_t)x < 0)
- x = ~x;
- for (count = 32; x; count--)
- x = x >> 1;
- return count - 1;
-}
-
-/* Bit count. */
-uint32_t HELPER(neon_cnt_u8)(uint32_t x)
-{
- x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
- x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
- x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
- return x;
-}
-
-#define NEON_QDMULH16(dest, src1, src2, round) do { \
- uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \
- if ((tmp ^ (tmp << 1)) & SIGNBIT) { \
- SET_QC(); \
- tmp = (tmp >> 31) ^ ~SIGNBIT; \
- } \
- tmp <<= 1; \
- if (round) { \
- int32_t old = tmp; \
- tmp += 1 << 15; \
- if ((int32_t)tmp < old) { \
- SET_QC(); \
- tmp = SIGNBIT - 1; \
- } \
- } \
- dest = tmp >> 16; \
- } while(0)
-#define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 0)
-NEON_VOP_ENV(qdmulh_s16, neon_s16, 2)
-#undef NEON_FN
-#define NEON_FN(dest, src1, src2) NEON_QDMULH16(dest, src1, src2, 1)
-NEON_VOP_ENV(qrdmulh_s16, neon_s16, 2)
-#undef NEON_FN
-#undef NEON_QDMULH16
-
-#define NEON_QDMULH32(dest, src1, src2, round) do { \
- uint64_t tmp = (int64_t)(int32_t) src1 * (int32_t) src2; \
- if ((tmp ^ (tmp << 1)) & SIGNBIT64) { \
- SET_QC(); \
- tmp = (tmp >> 63) ^ ~SIGNBIT64; \
- } else { \
- tmp <<= 1; \
- } \
- if (round) { \
- int64_t old = tmp; \
- tmp += (int64_t)1 << 31; \
- if ((int64_t)tmp < old) { \
- SET_QC(); \
- tmp = SIGNBIT64 - 1; \
- } \
- } \
- dest = tmp >> 32; \
- } while(0)
-#define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 0)
-NEON_VOP_ENV(qdmulh_s32, neon_s32, 1)
-#undef NEON_FN
-#define NEON_FN(dest, src1, src2) NEON_QDMULH32(dest, src1, src2, 1)
-NEON_VOP_ENV(qrdmulh_s32, neon_s32, 1)
-#undef NEON_FN
-#undef NEON_QDMULH32
-
-uint32_t HELPER(neon_narrow_u8)(uint64_t x)
-{
- return (x & 0xffu) | ((x >> 8) & 0xff00u) | ((x >> 16) & 0xff0000u)
- | ((x >> 24) & 0xff000000u);
-}
-
-uint32_t HELPER(neon_narrow_u16)(uint64_t x)
-{
- return (x & 0xffffu) | ((x >> 16) & 0xffff0000u);
-}
-
-uint32_t HELPER(neon_narrow_high_u8)(uint64_t x)
-{
- return ((x >> 8) & 0xff) | ((x >> 16) & 0xff00)
- | ((x >> 24) & 0xff0000) | ((x >> 32) & 0xff000000);
-}
-
-uint32_t HELPER(neon_narrow_high_u16)(uint64_t x)
-{
- return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
-}
-
-uint32_t HELPER(neon_narrow_round_high_u8)(uint64_t x)
-{
- x &= 0xff80ff80ff80ff80ull;
- x += 0x0080008000800080ull;
- return ((x >> 8) & 0xff) | ((x >> 16) & 0xff00)
- | ((x >> 24) & 0xff0000) | ((x >> 32) & 0xff000000);
-}
-
-uint32_t HELPER(neon_narrow_round_high_u16)(uint64_t x)
-{
- x &= 0xffff8000ffff8000ull;
- x += 0x0000800000008000ull;
- return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000);
-}
-
-uint32_t HELPER(neon_narrow_sat_u8)(CPUState *env, uint64_t x)
-{
- uint16_t s;
- uint8_t d;
- uint32_t res = 0;
-#define SAT8(n) \
- s = x >> n; \
- if (s > 0xff) { \
- d = 0xff; \
- SET_QC(); \
- } else { \
- d = s; \
- } \
- res |= (uint32_t)d << (n / 2);
-
- SAT8(0);
- SAT8(16);
- SAT8(32);
- SAT8(48);
-#undef SAT8
- return res;
-}
-
-uint32_t HELPER(neon_narrow_sat_s8)(CPUState *env, uint64_t x)
-{
- int16_t s;
- uint8_t d;
- uint32_t res = 0;
-#define SAT8(n) \
- s = x >> n; \
- if (s != (int8_t)s) { \
- d = (s >> 15) ^ 0x7f; \
- SET_QC(); \
- } else { \
- d = s; \
- } \
- res |= (uint32_t)d << (n / 2);
-
- SAT8(0);
- SAT8(16);
- SAT8(32);
- SAT8(48);
-#undef SAT8
- return res;
-}
-
-uint32_t HELPER(neon_narrow_sat_u16)(CPUState *env, uint64_t x)
-{
- uint32_t high;
- uint32_t low;
- low = x;
- if (low > 0xffff) {
- low = 0xffff;
- SET_QC();
- }
- high = x >> 32;
- if (high > 0xffff) {
- high = 0xffff;
- SET_QC();
- }
- return low | (high << 16);
-}
-
-uint32_t HELPER(neon_narrow_sat_s16)(CPUState *env, uint64_t x)
-{
- int32_t low;
- int32_t high;
- low = x;
- if (low != (int16_t)low) {
- low = (low >> 31) ^ 0x7fff;
- SET_QC();
- }
- high = x >> 32;
- if (high != (int16_t)high) {
- high = (high >> 31) ^ 0x7fff;
- SET_QC();
- }
- return (uint16_t)low | (high << 16);
-}
-
-uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x)
-{
- if (x > 0xffffffffu) {
- SET_QC();
- return 0xffffffffu;
- }
- return x;
-}
-
-uint32_t HELPER(neon_narrow_sat_s32)(CPUState *env, uint64_t x)
-{
- if ((int64_t)x != (int32_t)x) {
- SET_QC();
- return (x >> 63) ^ 0x7fffffff;
- }
- return x;
-}
-
-uint64_t HELPER(neon_widen_u8)(uint32_t x)
-{
- uint64_t tmp;
- uint64_t ret;
- ret = (uint8_t)x;
- tmp = (uint8_t)(x >> 8);
- ret |= tmp << 16;
- tmp = (uint8_t)(x >> 16);
- ret |= tmp << 32;
- tmp = (uint8_t)(x >> 24);
- ret |= tmp << 48;
- return ret;
-}
-
-uint64_t HELPER(neon_widen_s8)(uint32_t x)
-{
- uint64_t tmp;
- uint64_t ret;
- ret = (uint16_t)(int8_t)x;
- tmp = (uint16_t)(int8_t)(x >> 8);
- ret |= tmp << 16;
- tmp = (uint16_t)(int8_t)(x >> 16);
- ret |= tmp << 32;
- tmp = (uint16_t)(int8_t)(x >> 24);
- ret |= tmp << 48;
- return ret;
-}
-
-uint64_t HELPER(neon_widen_u16)(uint32_t x)
-{
- uint64_t high = (uint16_t)(x >> 16);
- return ((uint16_t)x) | (high << 32);
-}
-
-uint64_t HELPER(neon_widen_s16)(uint32_t x)
-{
- uint64_t high = (int16_t)(x >> 16);
- return ((uint32_t)(int16_t)x) | (high << 32);
-}
-
-uint64_t HELPER(neon_addl_u16)(uint64_t a, uint64_t b)
-{
- uint64_t mask;
- mask = (a ^ b) & 0x8000800080008000ull;
- a &= ~0x8000800080008000ull;
- b &= ~0x8000800080008000ull;
- return (a + b) ^ mask;
-}
-
-uint64_t HELPER(neon_addl_u32)(uint64_t a, uint64_t b)
-{
- uint64_t mask;
- mask = (a ^ b) & 0x8000000080000000ull;
- a &= ~0x8000000080000000ull;
- b &= ~0x8000000080000000ull;
- return (a + b) ^ mask;
-}
-
-uint64_t HELPER(neon_paddl_u16)(uint64_t a, uint64_t b)
-{
- uint64_t tmp;
- uint64_t tmp2;
-
- tmp = a & 0x0000ffff0000ffffull;
- tmp += (a >> 16) & 0x0000ffff0000ffffull;
- tmp2 = b & 0xffff0000ffff0000ull;
- tmp2 += (b << 16) & 0xffff0000ffff0000ull;
- return ( tmp & 0xffff)
- | ((tmp >> 16) & 0xffff0000ull)
- | ((tmp2 << 16) & 0xffff00000000ull)
- | ( tmp2 & 0xffff000000000000ull);
-}
-
-uint64_t HELPER(neon_paddl_u32)(uint64_t a, uint64_t b)
-{
- uint32_t low = a + (a >> 32);
- uint32_t high = b + (b >> 32);
- return low + ((uint64_t)high << 32);
-}
-
-uint64_t HELPER(neon_subl_u16)(uint64_t a, uint64_t b)
-{
- uint64_t mask;
- mask = (a ^ ~b) & 0x8000800080008000ull;
- a |= 0x8000800080008000ull;
- b &= ~0x8000800080008000ull;
- return (a - b) ^ mask;
-}
-
-uint64_t HELPER(neon_subl_u32)(uint64_t a, uint64_t b)
-{
- uint64_t mask;
- mask = (a ^ ~b) & 0x8000000080000000ull;
- a |= 0x8000000080000000ull;
- b &= ~0x8000000080000000ull;
- return (a - b) ^ mask;
-}
-
-uint64_t HELPER(neon_addl_saturate_s32)(CPUState *env, uint64_t a, uint64_t b)
-{
- uint32_t x, y;
- uint32_t low, high;
-
- x = a;
- y = b;
- low = x + y;
- if (((low ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) {
- SET_QC();
- low = ((int32_t)x >> 31) ^ ~SIGNBIT;
- }
- x = a >> 32;
- y = b >> 32;
- high = x + y;
- if (((high ^ x) & SIGNBIT) && !((x ^ y) & SIGNBIT)) {
- SET_QC();
- high = ((int32_t)x >> 31) ^ ~SIGNBIT;
- }
- return low | ((uint64_t)high << 32);
-}
-
-uint64_t HELPER(neon_addl_saturate_s64)(CPUState *env, uint64_t a, uint64_t b)
-{
- uint64_t result;
-
- result = a + b;
- if (((result ^ a) & SIGNBIT64) && !((a ^ b) & SIGNBIT64)) {
- SET_QC();
- result = ((int64_t)a >> 63) ^ ~SIGNBIT64;
- }
- return result;
-}
-
-#define DO_ABD(dest, x, y, type) do { \
- type tmp_x = x; \
- type tmp_y = y; \
- dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \
- } while(0)
-
-uint64_t HELPER(neon_abdl_u16)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
- DO_ABD(result, a, b, uint8_t);
- DO_ABD(tmp, a >> 8, b >> 8, uint8_t);
- result |= tmp << 16;
- DO_ABD(tmp, a >> 16, b >> 16, uint8_t);
- result |= tmp << 32;
- DO_ABD(tmp, a >> 24, b >> 24, uint8_t);
- result |= tmp << 48;
- return result;
-}
-
-uint64_t HELPER(neon_abdl_s16)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
- DO_ABD(result, a, b, int8_t);
- DO_ABD(tmp, a >> 8, b >> 8, int8_t);
- result |= tmp << 16;
- DO_ABD(tmp, a >> 16, b >> 16, int8_t);
- result |= tmp << 32;
- DO_ABD(tmp, a >> 24, b >> 24, int8_t);
- result |= tmp << 48;
- return result;
-}
-
-uint64_t HELPER(neon_abdl_u32)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
- DO_ABD(result, a, b, uint16_t);
- DO_ABD(tmp, a >> 16, b >> 16, uint16_t);
- return result | (tmp << 32);
-}
-
-uint64_t HELPER(neon_abdl_s32)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
- DO_ABD(result, a, b, int16_t);
- DO_ABD(tmp, a >> 16, b >> 16, int16_t);
- return result | (tmp << 32);
-}
-
-uint64_t HELPER(neon_abdl_u64)(uint32_t a, uint32_t b)
-{
- uint64_t result;
- DO_ABD(result, a, b, uint32_t);
- return result;
-}
-
-uint64_t HELPER(neon_abdl_s64)(uint32_t a, uint32_t b)
-{
- uint64_t result;
- DO_ABD(result, a, b, int32_t);
- return result;
-}
-#undef DO_ABD
-
-/* Widening multiply. Named type is the source type. */
-#define DO_MULL(dest, x, y, type1, type2) do { \
- type1 tmp_x = x; \
- type1 tmp_y = y; \
- dest = (type2)((type2)tmp_x * (type2)tmp_y); \
- } while(0)
-
-uint64_t HELPER(neon_mull_u8)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
-
- DO_MULL(result, a, b, uint8_t, uint16_t);
- DO_MULL(tmp, a >> 8, b >> 8, uint8_t, uint16_t);
- result |= tmp << 16;
- DO_MULL(tmp, a >> 16, b >> 16, uint8_t, uint16_t);
- result |= tmp << 32;
- DO_MULL(tmp, a >> 24, b >> 24, uint8_t, uint16_t);
- result |= tmp << 48;
- return result;
-}
-
-uint64_t HELPER(neon_mull_s8)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
-
- DO_MULL(result, a, b, int8_t, uint16_t);
- DO_MULL(tmp, a >> 8, b >> 8, int8_t, uint16_t);
- result |= tmp << 16;
- DO_MULL(tmp, a >> 16, b >> 16, int8_t, uint16_t);
- result |= tmp << 32;
- DO_MULL(tmp, a >> 24, b >> 24, int8_t, uint16_t);
- result |= tmp << 48;
- return result;
-}
-
-uint64_t HELPER(neon_mull_u16)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
-
- DO_MULL(result, a, b, uint16_t, uint32_t);
- DO_MULL(tmp, a >> 16, b >> 16, uint16_t, uint32_t);
- return result | (tmp << 32);
-}
-
-uint64_t HELPER(neon_mull_s16)(uint32_t a, uint32_t b)
-{
- uint64_t tmp;
- uint64_t result;
-
- DO_MULL(result, a, b, int16_t, uint32_t);
- DO_MULL(tmp, a >> 16, b >> 16, int16_t, uint32_t);
- return result | (tmp << 32);
-}
-
-uint64_t HELPER(neon_negl_u16)(uint64_t x)
-{
- uint16_t tmp;
- uint64_t result;
- result = (uint16_t)-x;
- tmp = -(x >> 16);
- result |= (uint64_t)tmp << 16;
- tmp = -(x >> 32);
- result |= (uint64_t)tmp << 32;
- tmp = -(x >> 48);
- result |= (uint64_t)tmp << 48;
- return result;
-}
-
-#include <stdio.h>
-uint64_t HELPER(neon_negl_u32)(uint64_t x)
-{
- uint32_t low = -x;
- uint32_t high = -(x >> 32);
- return low | ((uint64_t)high << 32);
-}
-
-/* FIXME: There should be a native op for this. */
-uint64_t HELPER(neon_negl_u64)(uint64_t x)
-{
- return -x;
-}
-
-/* Saturnating sign manuipulation. */
-/* ??? Make these use NEON_VOP1 */
-#define DO_QABS8(x) do { \
- if (x == (int8_t)0x80) { \
- x = 0x7f; \
- SET_QC(); \
- } else if (x < 0) { \
- x = -x; \
- }} while (0)
-uint32_t HELPER(neon_qabs_s8)(CPUState *env, uint32_t x)
-{
- neon_s8 vec;
- NEON_UNPACK(neon_s8, vec, x);
- DO_QABS8(vec.v1);
- DO_QABS8(vec.v2);
- DO_QABS8(vec.v3);
- DO_QABS8(vec.v4);
- NEON_PACK(neon_s8, x, vec);
- return x;
-}
-#undef DO_QABS8
-
-#define DO_QNEG8(x) do { \
- if (x == (int8_t)0x80) { \
- x = 0x7f; \
- SET_QC(); \
- } else { \
- x = -x; \
- }} while (0)
-uint32_t HELPER(neon_qneg_s8)(CPUState *env, uint32_t x)
-{
- neon_s8 vec;
- NEON_UNPACK(neon_s8, vec, x);
- DO_QNEG8(vec.v1);
- DO_QNEG8(vec.v2);
- DO_QNEG8(vec.v3);
- DO_QNEG8(vec.v4);
- NEON_PACK(neon_s8, x, vec);
- return x;
-}
-#undef DO_QNEG8
-
-#define DO_QABS16(x) do { \
- if (x == (int16_t)0x8000) { \
- x = 0x7fff; \
- SET_QC(); \
- } else if (x < 0) { \
- x = -x; \
- }} while (0)
-uint32_t HELPER(neon_qabs_s16)(CPUState *env, uint32_t x)
-{
- neon_s16 vec;
- NEON_UNPACK(neon_s16, vec, x);
- DO_QABS16(vec.v1);
- DO_QABS16(vec.v2);
- NEON_PACK(neon_s16, x, vec);
- return x;
-}
-#undef DO_QABS16
-
-#define DO_QNEG16(x) do { \
- if (x == (int16_t)0x8000) { \
- x = 0x7fff; \
- SET_QC(); \
- } else { \
- x = -x; \
- }} while (0)
-uint32_t HELPER(neon_qneg_s16)(CPUState *env, uint32_t x)
-{
- neon_s16 vec;
- NEON_UNPACK(neon_s16, vec, x);
- DO_QNEG16(vec.v1);
- DO_QNEG16(vec.v2);
- NEON_PACK(neon_s16, x, vec);
- return x;
-}
-#undef DO_QNEG16
-
-uint32_t HELPER(neon_qabs_s32)(CPUState *env, uint32_t x)
-{
- if (x == SIGNBIT) {
- SET_QC();
- x = ~SIGNBIT;
- } else if ((int32_t)x < 0) {
- x = -x;
- }
- return x;
-}
-
-uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x)
-{
- if (x == SIGNBIT) {
- SET_QC();
- x = ~SIGNBIT;
- } else {
- x = -x;
- }
- return x;
-}
-
-/* NEON Float helpers. */
-uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b)
-{
- float32 f0 = vfp_itos(a);
- float32 f1 = vfp_itos(b);
- return (float32_compare_quiet(f0, f1, NFS) == -1) ? a : b;
-}
-
-uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b)
-{
- float32 f0 = vfp_itos(a);
- float32 f1 = vfp_itos(b);
- return (float32_compare_quiet(f0, f1, NFS) == 1) ? a : b;
-}
-
-uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b)
-{
- float32 f0 = vfp_itos(a);
- float32 f1 = vfp_itos(b);
- return vfp_stoi((float32_compare_quiet(f0, f1, NFS) == 1)
- ? float32_sub(f0, f1, NFS)
- : float32_sub(f1, f0, NFS));
-}
-
-uint32_t HELPER(neon_add_f32)(uint32_t a, uint32_t b)
-{
- return vfp_stoi(float32_add(vfp_itos(a), vfp_itos(b), NFS));
-}
-
-uint32_t HELPER(neon_sub_f32)(uint32_t a, uint32_t b)
-{
- return vfp_stoi(float32_sub(vfp_itos(a), vfp_itos(b), NFS));
-}
-
-uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b)
-{
- return vfp_stoi(float32_mul(vfp_itos(a), vfp_itos(b), NFS));
-}
-
-/* Floating point comparisons produce an integer result. */
-#define NEON_VOP_FCMP(name, cmp) \
-uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \
-{ \
- if (float32_compare_quiet(vfp_itos(a), vfp_itos(b), NFS) cmp 0) \
- return ~0; \
- else \
- return 0; \
-}
-
-NEON_VOP_FCMP(ceq_f32, ==)
-NEON_VOP_FCMP(cge_f32, >=)
-NEON_VOP_FCMP(cgt_f32, >)
-
-uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b)
-{
- float32 f0 = float32_abs(vfp_itos(a));
- float32 f1 = float32_abs(vfp_itos(b));
- return (float32_compare_quiet(f0, f1,NFS) >= 0) ? ~0 : 0;
-}
-
-uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b)
-{
- float32 f0 = float32_abs(vfp_itos(a));
- float32 f1 = float32_abs(vfp_itos(b));
- return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0;
-}
diff --git a/target-arm/op_addsub.h b/target-arm/op_addsub.h
deleted file mode 100644
index 376ee27..0000000
--- a/target-arm/op_addsub.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ARMv6 integer SIMD operations.
- *
- * Copyright (c) 2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licenced under the GPL.
- */
-
-#ifdef ARITH_GE
-#define GE_ARG , uint32_t *gep
-#define DECLARE_GE uint32_t ge = 0
-#define SET_GE *gep = ge
-#else
-#define GE_ARG
-#define DECLARE_GE do{}while(0)
-#define SET_GE do{}while(0)
-#endif
-
-#define RESULT(val, n, width) \
- res |= ((uint32_t)(glue(glue(uint,width),_t))(val)) << (n * width)
-
-uint32_t HELPER(glue(PFX,add16))(uint32_t a, uint32_t b GE_ARG)
-{
- uint32_t res = 0;
- DECLARE_GE;
-
- ADD16(a, b, 0);
- ADD16(a >> 16, b >> 16, 1);
- SET_GE;
- return res;
-}
-
-uint32_t HELPER(glue(PFX,add8))(uint32_t a, uint32_t b GE_ARG)
-{
- uint32_t res = 0;
- DECLARE_GE;
-
- ADD8(a, b, 0);
- ADD8(a >> 8, b >> 8, 1);
- ADD8(a >> 16, b >> 16, 2);
- ADD8(a >> 24, b >> 24, 3);
- SET_GE;
- return res;
-}
-
-uint32_t HELPER(glue(PFX,sub16))(uint32_t a, uint32_t b GE_ARG)
-{
- uint32_t res = 0;
- DECLARE_GE;
-
- SUB16(a, b, 0);
- SUB16(a >> 16, b >> 16, 1);
- SET_GE;
- return res;
-}
-
-uint32_t HELPER(glue(PFX,sub8))(uint32_t a, uint32_t b GE_ARG)
-{
- uint32_t res = 0;
- DECLARE_GE;
-
- SUB8(a, b, 0);
- SUB8(a >> 8, b >> 8, 1);
- SUB8(a >> 16, b >> 16, 2);
- SUB8(a >> 24, b >> 24, 3);
- SET_GE;
- return res;
-}
-
-uint32_t HELPER(glue(PFX,subaddx))(uint32_t a, uint32_t b GE_ARG)
-{
- uint32_t res = 0;
- DECLARE_GE;
-
- ADD16(a, b, 0);
- SUB16(a >> 16, b >> 16, 1);
- SET_GE;
- return res;
-}
-
-uint32_t HELPER(glue(PFX,addsubx))(uint32_t a, uint32_t b GE_ARG)
-{
- uint32_t res = 0;
- DECLARE_GE;
-
- SUB16(a, b, 0);
- ADD16(a >> 16, b >> 16, 1);
- SET_GE;
- return res;
-}
-
-#undef GE_ARG
-#undef DECLARE_GE
-#undef SET_GE
-#undef RESULT
-
-#undef ARITH_GE
-#undef PFX
-#undef ADD16
-#undef SUB16
-#undef ADD8
-#undef SUB8
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
deleted file mode 100644
index 36de55b..0000000
--- a/target-arm/op_helper.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * ARM helper routines
- *
- * Copyright (c) 2005-2007 CodeSourcery, LLC
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "exec.h"
-#include "helpers.h"
-
-#define SIGNBIT (uint32_t)0x80000000
-#define SIGNBIT64 ((uint64_t)1 << 63)
-
-void raise_exception(int tt)
-{
- env->exception_index = tt;
- cpu_loop_exit();
-}
-
-/* thread support */
-
-spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
-
-void cpu_lock(void)
-{
- spin_lock(&global_cpu_lock);
-}
-
-void cpu_unlock(void)
-{
- spin_unlock(&global_cpu_lock);
-}
-
-uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
- uint32_t rn, uint32_t maxindex)
-{
- uint32_t val;
- uint32_t tmp;
- int index;
- int shift;
- uint64_t *table;
- table = (uint64_t *)&env->vfp.regs[rn];
- val = 0;
- for (shift = 0; shift < 32; shift += 8) {
- index = (ireg >> shift) & 0xff;
- if (index < maxindex) {
- tmp = (table[index >> 3] >> (index & 7)) & 0xff;
- val |= tmp << shift;
- } else {
- val |= def & (0xff << shift);
- }
- }
- return val;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr);
-
-#define MMUSUFFIX _mmu
-#define ALIGNED_ONLY 1
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-static void do_unaligned_access (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
-{
- //printf("::UNALIGNED:: addr=%lx is_write=%d is_user=%d retaddr=%p\n", addr, is_write, is_user, retaddr);
- if (mmu_idx)
- {
- env = cpu_single_env;
- env->cp15.c5_data = 0x00000001; /* corresponds to an alignment fault */
- env->cp15.c6_data = addr;
- env->exception_index = EXCP_DATA_ABORT;
- cpu_loop_exit();
- }
-}
-
-/* try to fill the TLB and return an exception if error. If retaddr is
- NULL, it means that the function was called in C code (i.e. not
- from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
-{
- TranslationBlock *tb;
- CPUState *saved_env;
- unsigned long pc;
- int ret;
-
- /* XXX: hack to restore env in all cases, even if not called from
- generated code */
- saved_env = env;
- env = cpu_single_env;
- ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
- if (unlikely(ret)) {
- if (retaddr) {
- /* now we have a real cpu fault */
- pc = (unsigned long)retaddr;
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, pc, NULL);
- }
- }
- raise_exception(env->exception_index);
- }
- env = saved_env;
-}
-
-#if 1
-#include <string.h>
-/*
- * The following functions are address translation helper functions
- * for fast memory access in QEMU.
- */
-static target_phys_addr_t v2p_mmu(target_ulong addr, int mmu_idx)
-{
- int index;
- target_ulong tlb_addr;
- target_phys_addr_t physaddr;
- void *retaddr;
-
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- physaddr = addr + env->tlb_table[mmu_idx][index].addend;
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC();
- tlb_fill(addr, 0, mmu_idx, retaddr);
- goto redo;
- }
- return physaddr;
-}
-
-/*
- * translation from virtual address of simulated OS
- * to the address of simulation host (not the physical
- * address of simulated OS.
- */
-target_phys_addr_t v2p(target_ulong ptr, int mmu_idx)
-{
- CPUState *saved_env;
- int index;
- target_ulong addr;
- target_phys_addr_t physaddr;
-
- saved_env = env;
- env = cpu_single_env;
- addr = ptr;
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_read !=
- (addr & TARGET_PAGE_MASK), 0))
- {
- physaddr = v2p_mmu(addr, mmu_idx);
- } else {
- physaddr = (target_phys_addr_t)addr + env->tlb_table[mmu_idx][index].addend;
- }
- env = saved_env;
- return physaddr;
-}
-
-#define MINSIZE(x,y) ((x) < (y) ? (x) : (y))
-/* copy memory from the simulated virtual space to a buffer in QEMU */
-void vmemcpy(target_ulong ptr, char *buf, int size)
-{
- if (buf == NULL) return;
- while (size) {
- int page_remain = TARGET_PAGE_SIZE - (ptr & ~TARGET_PAGE_MASK);
- int to_copy = MINSIZE(size, page_remain);
- char *phys = (char *)v2p(ptr, 0);
- if (phys == NULL) return;
- memcpy(buf, phys, to_copy);
- ptr += to_copy;
- buf += to_copy;
- size -= to_copy;
- }
-}
-
-/* copy memory from the QEMU buffer to simulated virtual space */
-void pmemcpy(target_ulong ptr, const char *buf, int size)
-{
- if (buf == NULL) return;
- while (size) {
- int page_remain = TARGET_PAGE_SIZE - (ptr & ~TARGET_PAGE_MASK);
- int to_copy = MINSIZE(size, page_remain);
- char *phys = (char *)v2p(ptr, 0);
- if (phys == NULL) return;
- memcpy(phys, buf, to_copy);
- ptr += to_copy;
- buf += to_copy;
- size -= to_copy;
- }
-}
-
-/* copy a string from the simulated virtual space to a buffer in QEMU */
-void vstrcpy(target_ulong ptr, char *buf, int max)
-{
- char *phys = 0;
- unsigned long page = 0;
-
- if (buf == NULL) return;
-
- while (max) {
- if ((ptr & TARGET_PAGE_MASK) != page) {
- phys = (char *)v2p(ptr, 0);
- page = ptr & TARGET_PAGE_MASK;
- }
- *buf = *phys;
- if (*phys == '\0')
- return;
- ptr ++;
- buf ++;
- phys ++;
- max --;
- }
-}
-#endif
-#endif
-
-/* FIXME: Pass an axplicit pointer to QF to CPUState, and move saturating
- instructions into helper.c */
-uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
-{
- uint32_t res = a + b;
- if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
- env->QF = 1;
- return res;
-}
-
-uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b)
-{
- uint32_t res = a + b;
- if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
- env->QF = 1;
- res = ~(((int32_t)a >> 31) ^ SIGNBIT);
- }
- return res;
-}
-
-uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b)
-{
- uint32_t res = a - b;
- if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
- env->QF = 1;
- res = ~(((int32_t)a >> 31) ^ SIGNBIT);
- }
- return res;
-}
-
-uint32_t HELPER(double_saturate)(int32_t val)
-{
- uint32_t res;
- if (val >= 0x40000000) {
- res = ~SIGNBIT;
- env->QF = 1;
- } else if (val <= (int32_t)0xc0000000) {
- res = SIGNBIT;
- env->QF = 1;
- } else {
- res = val << 1;
- }
- return res;
-}
-
-uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b)
-{
- uint32_t res = a + b;
- if (res < a) {
- env->QF = 1;
- res = ~0;
- }
- return res;
-}
-
-uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b)
-{
- uint32_t res = a - b;
- if (res > a) {
- env->QF = 1;
- res = 0;
- }
- return res;
-}
-
-/* Signed saturation. */
-static inline uint32_t do_ssat(int32_t val, int shift)
-{
- int32_t top;
- uint32_t mask;
-
- top = val >> shift;
- mask = (1u << shift) - 1;
- if (top > 0) {
- env->QF = 1;
- return mask;
- } else if (top < -1) {
- env->QF = 1;
- return ~mask;
- }
- return val;
-}
-
-/* Unsigned saturation. */
-static inline uint32_t do_usat(int32_t val, int shift)
-{
- uint32_t max;
-
- max = (1u << shift) - 1;
- if (val < 0) {
- env->QF = 1;
- return 0;
- } else if (val > max) {
- env->QF = 1;
- return max;
- }
- return val;
-}
-
-/* Signed saturate. */
-uint32_t HELPER(ssat)(uint32_t x, uint32_t shift)
-{
- return do_ssat(x, shift);
-}
-
-/* Dual halfword signed saturate. */
-uint32_t HELPER(ssat16)(uint32_t x, uint32_t shift)
-{
- uint32_t res;
-
- res = (uint16_t)do_ssat((int16_t)x, shift);
- res |= do_ssat(((int32_t)x) >> 16, shift) << 16;
- return res;
-}
-
-/* Unsigned saturate. */
-uint32_t HELPER(usat)(uint32_t x, uint32_t shift)
-{
- return do_usat(x, shift);
-}
-
-/* Dual halfword unsigned saturate. */
-uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
-{
- uint32_t res;
-
- res = (uint16_t)do_usat((int16_t)x, shift);
- res |= do_usat(((int32_t)x) >> 16, shift) << 16;
- return res;
-}
-
-void HELPER(wfi)(void)
-{
- env->exception_index = EXCP_HLT;
- env->halted = 1;
- cpu_loop_exit();
-}
-
-void HELPER(exception)(uint32_t excp)
-{
- env->exception_index = excp;
- cpu_loop_exit();
-}
-
-uint32_t HELPER(cpsr_read)(void)
-{
- return cpsr_read(env) & ~CPSR_EXEC;
-}
-
-void HELPER(cpsr_write)(uint32_t val, uint32_t mask)
-{
- cpsr_write(env, val, mask);
-}
-
-/* Access to user mode registers from privileged modes. */
-uint32_t HELPER(get_user_reg)(uint32_t regno)
-{
- uint32_t val;
-
- if (regno == 13) {
- val = env->banked_r13[0];
- } else if (regno == 14) {
- val = env->banked_r14[0];
- } else if (regno >= 8
- && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
- val = env->usr_regs[regno - 8];
- } else {
- val = env->regs[regno];
- }
- return val;
-}
-
-void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
-{
- if (regno == 13) {
- env->banked_r13[0] = val;
- } else if (regno == 14) {
- env->banked_r14[0] = val;
- } else if (regno >= 8
- && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
- env->usr_regs[regno - 8] = val;
- } else {
- env->regs[regno] = val;
- }
-}
-
-/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
- The only way to do that in TCG is a conditional branch, which clobbers
- all our temporaries. For now implement these as helper functions. */
-
-uint32_t HELPER (add_cc)(uint32_t a, uint32_t b)
-{
- uint32_t result;
- result = T0 + T1;
- env->NF = env->ZF = result;
- env->CF = result < a;
- env->VF = (a ^ b ^ -1) & (a ^ result);
- return result;
-}
-
-uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
-{
- uint32_t result;
- if (!env->CF) {
- result = a + b;
- env->CF = result < a;
- } else {
- result = a + b + 1;
- env->CF = result <= a;
- }
- env->VF = (a ^ b ^ -1) & (a ^ result);
- env->NF = env->ZF = result;
- return result;
-}
-
-uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
-{
- uint32_t result;
- result = a - b;
- env->NF = env->ZF = result;
- env->CF = a >= b;
- env->VF = (a ^ b) & (a ^ result);
- return result;
-}
-
-uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
-{
- uint32_t result;
- if (!env->CF) {
- result = a - b - 1;
- env->CF = a > b;
- } else {
- result = a - b;
- env->CF = a >= b;
- }
- env->VF = (a ^ b) & (a ^ result);
- env->NF = env->ZF = result;
- return result;
-}
-
-/* Similarly for variable shift instructions. */
-
-uint32_t HELPER(shl)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32)
- return 0;
- return x << shift;
-}
-
-uint32_t HELPER(shr)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32)
- return 0;
- return (uint32_t)x >> shift;
-}
-
-uint32_t HELPER(sar)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32)
- shift = 31;
- return (int32_t)x >> shift;
-}
-
-uint32_t HELPER(ror)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift == 0)
- return x;
- return (x >> shift) | (x << (32 - shift));
-}
-
-uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- if (shift == 32)
- env->CF = x & 1;
- else
- env->CF = 0;
- return 0;
- } else if (shift != 0) {
- env->CF = (x >> (32 - shift)) & 1;
- return x << shift;
- }
- return x;
-}
-
-uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- if (shift == 32)
- env->CF = (x >> 31) & 1;
- else
- env->CF = 0;
- return 0;
- } else if (shift != 0) {
- env->CF = (x >> (shift - 1)) & 1;
- return x >> shift;
- }
- return x;
-}
-
-uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- env->CF = (x >> 31) & 1;
- return (int32_t)x >> 31;
- } else if (shift != 0) {
- env->CF = (x >> (shift - 1)) & 1;
- return (int32_t)x >> shift;
- }
- return x;
-}
-
-uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
-{
- int shift1, shift;
- shift1 = i & 0xff;
- shift = shift1 & 0x1f;
- if (shift == 0) {
- if (shift1 != 0)
- env->CF = (x >> 31) & 1;
- return x;
- } else {
- env->CF = (x >> (shift - 1)) & 1;
- return ((uint32_t)x >> shift) | (x << (32 - shift));
- }
-}
-
-uint64_t HELPER(neon_add_saturate_s64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- res = src1 + src2;
- if (((res ^ src1) & SIGNBIT64) && !((src1 ^ src2) & SIGNBIT64)) {
- env->QF = 1;
- res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
- }
- return res;
-}
-
-uint64_t HELPER(neon_add_saturate_u64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- res = src1 + src2;
- if (res < src1) {
- env->QF = 1;
- res = ~(uint64_t)0;
- }
- return res;
-}
-
-uint64_t HELPER(neon_sub_saturate_s64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- res = src1 - src2;
- if (((res ^ src1) & SIGNBIT64) && ((src1 ^ src2) & SIGNBIT64)) {
- env->QF = 1;
- res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64;
- }
- return res;
-}
-
-uint64_t HELPER(neon_sub_saturate_u64)(uint64_t src1, uint64_t src2)
-{
- uint64_t res;
-
- if (src1 < src2) {
- env->QF = 1;
- res = 0;
- } else {
- res = src1 - src2;
- }
- return res;
-}
-
-/* These need to return a pair of value, so still use T0/T1. */
-/* Transpose. Argument order is rather strange to avoid special casing
- the tranlation code.
- On input T0 = rm, T1 = rd. On output T0 = rd, T1 = rm */
-void HELPER(neon_trn_u8)(void)
-{
- uint32_t rd;
- uint32_t rm;
- rd = ((T0 & 0x00ff00ff) << 8) | (T1 & 0x00ff00ff);
- rm = ((T1 & 0xff00ff00) >> 8) | (T0 & 0xff00ff00);
- T0 = rd;
- T1 = rm;
- FORCE_RET();
-}
-
-void HELPER(neon_trn_u16)(void)
-{
- uint32_t rd;
- uint32_t rm;
- rd = (T0 << 16) | (T1 & 0xffff);
- rm = (T1 >> 16) | (T0 & 0xffff0000);
- T0 = rd;
- T1 = rm;
- FORCE_RET();
-}
-
-/* Worker routines for zip and unzip. */
-void HELPER(neon_unzip_u8)(void)
-{
- uint32_t rd;
- uint32_t rm;
- rd = (T0 & 0xff) | ((T0 >> 8) & 0xff00)
- | ((T1 << 16) & 0xff0000) | ((T1 << 8) & 0xff000000);
- rm = ((T0 >> 8) & 0xff) | ((T0 >> 16) & 0xff00)
- | ((T1 << 8) & 0xff0000) | (T1 & 0xff000000);
- T0 = rd;
- T1 = rm;
- FORCE_RET();
-}
-
-void HELPER(neon_zip_u8)(void)
-{
- uint32_t rd;
- uint32_t rm;
- rd = (T0 & 0xff) | ((T1 << 8) & 0xff00)
- | ((T0 << 16) & 0xff0000) | ((T1 << 24) & 0xff000000);
- rm = ((T0 >> 16) & 0xff) | ((T1 >> 8) & 0xff00)
- | ((T0 >> 8) & 0xff0000) | (T1 & 0xff000000);
- T0 = rd;
- T1 = rm;
- FORCE_RET();
-}
-
-void HELPER(neon_zip_u16)(void)
-{
- uint32_t tmp;
-
- tmp = (T0 & 0xffff) | (T1 << 16);
- T1 = (T1 & 0xffff0000) | (T0 >> 16);
- T0 = tmp;
- FORCE_RET();
-}
diff --git a/target-arm/translate.c b/target-arm/translate.c
deleted file mode 100644
index ff27d28..0000000
--- a/target-arm/translate.c
+++ /dev/null
@@ -1,8963 +0,0 @@
-/*
- * ARM translation
- *
- * Copyright (c) 2003 Fabrice Bellard
- * Copyright (c) 2005-2007 CodeSourcery
- * Copyright (c) 2007 OpenedHand, Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-#include "tcg-op.h"
-#include "qemu-log.h"
-
-#ifdef CONFIG_TRACE
-#include "trace.h"
-#endif
-
-#define GEN_HELPER 1
-#include "helpers.h"
-
-#define ENABLE_ARCH_5J 0
-#define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
-#define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
-#define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
-#define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
-
-#define ARCH(x) if (!ENABLE_ARCH_##x) goto illegal_op;
-
-/* internal defines */
-typedef struct DisasContext {
- target_ulong pc;
- int is_jmp;
- /* Nonzero if this instruction has been conditionally skipped. */
- int condjmp;
- /* The label that will be jumped to when the instruction is skipped. */
- int condlabel;
- /* Thumb-2 condtional execution bits. */
- int condexec_mask;
- int condexec_cond;
- struct TranslationBlock *tb;
- int singlestep_enabled;
- int thumb;
- int is_mem;
-#if !defined(CONFIG_USER_ONLY)
- int user;
-#endif
-} DisasContext;
-
-#if defined(CONFIG_USER_ONLY)
-#define IS_USER(s) 1
-#else
-#define IS_USER(s) (s->user)
-#endif
-
-#ifdef CONFIG_TRACE
-#include "helpers.h"
-#endif
-
-/* These instructions trap after executing, so defer them until after the
- conditional executions state has been updated. */
-#define DISAS_WFI 4
-#define DISAS_SWI 5
-
-static TCGv cpu_env;
-/* We reuse the same 64-bit temporaries for efficiency. */
-static TCGv cpu_V0, cpu_V1, cpu_M0;
-
-/* FIXME: These should be removed. */
-static TCGv cpu_T[2];
-static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
-
-#define ICOUNT_TEMP cpu_T[0]
-#include "gen-icount.h"
-
-/* initialize TCG globals. */
-void arm_translate_init(void)
-{
- cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
-
- cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
- cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
-}
-
-/* The code generator doesn't like lots of temporaries, so maintain our own
- cache for reuse within a function. */
-#define MAX_TEMPS 8
-static int num_temps;
-static TCGv temps[MAX_TEMPS];
-
-/* Allocate a temporary variable. */
-static TCGv new_tmp(void)
-{
- TCGv tmp;
- if (num_temps == MAX_TEMPS)
- abort();
-
- if (GET_TCGV(temps[num_temps]))
- return temps[num_temps++];
-
- tmp = tcg_temp_new(TCG_TYPE_I32);
- temps[num_temps++] = tmp;
- return tmp;
-}
-
-/* Release a temporary variable. */
-static void dead_tmp(TCGv tmp)
-{
- int i;
- num_temps--;
- i = num_temps;
- if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
- return;
-
- /* Shuffle this temp to the last slot. */
- while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
- i--;
- while (i < num_temps) {
- temps[i] = temps[i + 1];
- i++;
- }
- temps[i] = tmp;
-}
-
-static inline TCGv load_cpu_offset(int offset)
-{
- TCGv tmp = new_tmp();
- tcg_gen_ld_i32(tmp, cpu_env, offset);
- return tmp;
-}
-
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
-
-static inline void store_cpu_offset(TCGv var, int offset)
-{
- tcg_gen_st_i32(var, cpu_env, offset);
- dead_tmp(var);
-}
-
-#define store_cpu_field(var, name) \
- store_cpu_offset(var, offsetof(CPUState, name))
-
-/* Set a variable to the value of a CPU register. */
-static void load_reg_var(DisasContext *s, TCGv var, int reg)
-{
- if (reg == 15) {
- uint32_t addr;
- /* normaly, since we updated PC, we need only to add one insn */
- if (s->thumb)
- addr = (long)s->pc + 2;
- else
- addr = (long)s->pc + 4;
- tcg_gen_movi_i32(var, addr);
- } else {
- tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
- }
-}
-
-/* Create a new temporary and set it to the value of a CPU register. */
-static inline TCGv load_reg(DisasContext *s, int reg)
-{
- TCGv tmp = new_tmp();
- load_reg_var(s, tmp, reg);
- return tmp;
-}
-
-/* Set a CPU register. The source must be a temporary and will be
- marked as dead. */
-static void store_reg(DisasContext *s, int reg, TCGv var)
-{
- if (reg == 15) {
- tcg_gen_andi_i32(var, var, ~1);
- s->is_jmp = DISAS_JUMP;
- }
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
- dead_tmp(var);
-}
-
-
-/* Basic operations. */
-#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
-#define gen_op_movl_T1_T0() tcg_gen_mov_i32(cpu_T[1], cpu_T[0])
-#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
-#define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
-
-#define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
-#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
-
-#define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
-#define gen_op_rscl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[1], cpu_T[0])
-
-#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
-#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
-#define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
-#define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
-
-#define gen_op_shll_T0_im(im) tcg_gen_shli_i32(cpu_T[0], cpu_T[0], im)
-#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
-#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
-#define gen_op_sarl_T1_im(im) tcg_gen_sari_i32(cpu_T[1], cpu_T[1], im)
-#define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
-
-/* Value extensions. */
-#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
-#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
-#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
-#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
-
-#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
-#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
-
-#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
-
-#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
-/* Set NZCV flags from the high 4 bits of var. */
-#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
-
-#ifdef CONFIG_TRACE
-static void gen_traceTicks(int count)
-{
- TCGv t0 = new_tmp();
- tcg_gen_movi_i32(t0, count);
- gen_helper_traceTicks(t0);
- dead_tmp(t0);
-}
-
-static void gen_traceBB(uint64_t bb_num, target_phys_addr_t tb)
-{
-#if HOST_LONG_BITS ==64
- TCGv t0 = tcg_const_i64(bb_num);
- TCGv t1 = tcg_const_i64(tb);
- gen_helper_traceBB64(t0, t1);
- tcg_temp_free(t1);
- tcg_temp_free(t0);
-#else
- TCGv t0 = new_tmp();
- TCGv t1 = new_tmp();
- TCGv t2 = new_tmp();
- tcg_gen_movi_i32(t0, (int32_t)(bb_num >> 32));
- tcg_gen_movi_i32(t1, (int32_t)(bb_num));
- tcg_gen_movi_i32(t2, (int32_t)tb);
- gen_helper_traceBB32(t0, t1, t2);
- dead_tmp(t2);
- dead_tmp(t1);
- dead_tmp(t0);
-#endif
-}
-#endif /* CONFIG_TRACE */
-
-static void gen_exception(int excp)
-{
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, excp);
- gen_helper_exception(tmp);
- dead_tmp(tmp);
-}
-
-static void gen_smul_dual(TCGv a, TCGv b)
-{
- TCGv tmp1 = new_tmp();
- TCGv tmp2 = new_tmp();
- tcg_gen_ext16s_i32(tmp1, a);
- tcg_gen_ext16s_i32(tmp2, b);
- tcg_gen_mul_i32(tmp1, tmp1, tmp2);
- dead_tmp(tmp2);
- tcg_gen_sari_i32(a, a, 16);
- tcg_gen_sari_i32(b, b, 16);
- tcg_gen_mul_i32(b, b, a);
- tcg_gen_mov_i32(a, tmp1);
- dead_tmp(tmp1);
-}
-
-/* Byteswap each halfword. */
-static void gen_rev16(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_shri_i32(tmp, var, 8);
- tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
- tcg_gen_shli_i32(var, var, 8);
- tcg_gen_andi_i32(var, var, 0xff00ff00);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
-}
-
-/* Byteswap low halfword and sign extend. */
-static void gen_revsh(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_shri_i32(tmp, var, 8);
- tcg_gen_andi_i32(tmp, tmp, 0x00ff);
- tcg_gen_shli_i32(var, var, 8);
- tcg_gen_ext8s_i32(var, var);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
-}
-
-/* Unsigned bitfield extract. */
-static void gen_ubfx(TCGv var, int shift, uint32_t mask)
-{
- if (shift)
- tcg_gen_shri_i32(var, var, shift);
- tcg_gen_andi_i32(var, var, mask);
-}
-
-/* Signed bitfield extract. */
-static void gen_sbfx(TCGv var, int shift, int width)
-{
- uint32_t signbit;
-
- if (shift)
- tcg_gen_sari_i32(var, var, shift);
- if (shift + width < 32) {
- signbit = 1u << (width - 1);
- tcg_gen_andi_i32(var, var, (1u << width) - 1);
- tcg_gen_xori_i32(var, var, signbit);
- tcg_gen_subi_i32(var, var, signbit);
- }
-}
-
-/* Bitfield insertion. Insert val into base. Clobbers base and val. */
-static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
-{
- tcg_gen_andi_i32(val, val, mask);
- tcg_gen_shli_i32(val, val, shift);
- tcg_gen_andi_i32(base, base, ~(mask << shift));
- tcg_gen_or_i32(dest, base, val);
-}
-
-/* Round the top 32 bits of a 64-bit value. */
-static void gen_roundqd(TCGv a, TCGv b)
-{
- tcg_gen_shri_i32(a, a, 31);
- tcg_gen_add_i32(a, a, b);
-}
-
-/* FIXME: Most targets have native widening multiplication.
- It would be good to use that instead of a full wide multiply. */
-/* 32x32->64 multiply. Marks inputs as dead. */
-static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
-{
- TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
- TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
-
- tcg_gen_extu_i32_i64(tmp1, a);
- dead_tmp(a);
- tcg_gen_extu_i32_i64(tmp2, b);
- dead_tmp(b);
- tcg_gen_mul_i64(tmp1, tmp1, tmp2);
- return tmp1;
-}
-
-static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
-{
- TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
- TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
-
- tcg_gen_ext_i32_i64(tmp1, a);
- dead_tmp(a);
- tcg_gen_ext_i32_i64(tmp2, b);
- dead_tmp(b);
- tcg_gen_mul_i64(tmp1, tmp1, tmp2);
- return tmp1;
-}
-
-/* Unsigned 32x32->64 multiply. */
-static void gen_op_mull_T0_T1(void)
-{
- TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
- TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
-
- tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
- tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
- tcg_gen_mul_i64(tmp1, tmp1, tmp2);
- tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
- tcg_gen_shri_i64(tmp1, tmp1, 32);
- tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
-}
-
-/* Signed 32x32->64 multiply. */
-static void gen_imull(TCGv a, TCGv b)
-{
- TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
- TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
-
- tcg_gen_ext_i32_i64(tmp1, a);
- tcg_gen_ext_i32_i64(tmp2, b);
- tcg_gen_mul_i64(tmp1, tmp1, tmp2);
- tcg_gen_trunc_i64_i32(a, tmp1);
- tcg_gen_shri_i64(tmp1, tmp1, 32);
- tcg_gen_trunc_i64_i32(b, tmp1);
-}
-#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
-
-/* Swap low and high halfwords. */
-static void gen_swap_half(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_shri_i32(tmp, var, 16);
- tcg_gen_shli_i32(var, var, 16);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
-}
-
-/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
- tmp = (t0 ^ t1) & 0x8000;
- t0 &= ~0x8000;
- t1 &= ~0x8000;
- t0 = (t0 + t1) ^ tmp;
- */
-
-static void gen_add16(TCGv t0, TCGv t1)
-{
- TCGv tmp = new_tmp();
- tcg_gen_xor_i32(tmp, t0, t1);
- tcg_gen_andi_i32(tmp, tmp, 0x8000);
- tcg_gen_andi_i32(t0, t0, ~0x8000);
- tcg_gen_andi_i32(t1, t1, ~0x8000);
- tcg_gen_add_i32(t0, t0, t1);
- tcg_gen_xor_i32(t0, t0, tmp);
- dead_tmp(tmp);
- dead_tmp(t1);
-}
-
-#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
-
-/* Set CF to the top bit of var. */
-static void gen_set_CF_bit31(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_shri_i32(tmp, var, 31);
- gen_set_CF(var);
- dead_tmp(tmp);
-}
-
-/* Set N and Z flags from var. */
-static inline void gen_logic_CC(TCGv var)
-{
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
-}
-
-/* T0 += T1 + CF. */
-static void gen_adc_T0_T1(void)
-{
- TCGv tmp;
- gen_op_addl_T0_T1();
- tmp = load_cpu_field(CF);
- tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
- dead_tmp(tmp);
-}
-
-/* dest = T0 - T1 + CF - 1. */
-static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
-{
- TCGv tmp;
- tcg_gen_sub_i32(dest, t0, t1);
- tmp = load_cpu_field(CF);
- tcg_gen_add_i32(dest, dest, tmp);
- tcg_gen_subi_i32(dest, dest, 1);
- dead_tmp(tmp);
-}
-
-#define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
-#define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
-
-/* T0 &= ~T1. Clobbers T1. */
-/* FIXME: Implement bic natively. */
-static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
-{
- TCGv tmp = new_tmp();
- tcg_gen_not_i32(tmp, t1);
- tcg_gen_and_i32(dest, t0, tmp);
- dead_tmp(tmp);
-}
-static inline void gen_op_bicl_T0_T1(void)
-{
- gen_op_notl_T1();
- gen_op_andl_T0_T1();
-}
-
-/* FIXME: Implement this natively. */
-#define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
-
-/* FIXME: Implement this natively. */
-static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
-{
- TCGv tmp;
-
- if (i == 0)
- return;
-
- tmp = new_tmp();
- tcg_gen_shri_i32(tmp, t1, i);
- tcg_gen_shli_i32(t1, t1, 32 - i);
- tcg_gen_or_i32(t0, t1, tmp);
- dead_tmp(tmp);
-}
-
-static void shifter_out_im(TCGv var, int shift)
-{
- TCGv tmp = new_tmp();
- if (shift == 0) {
- tcg_gen_andi_i32(tmp, var, 1);
- } else {
- tcg_gen_shri_i32(tmp, var, shift);
- if (shift != 31);
- tcg_gen_andi_i32(tmp, tmp, 1);
- }
- gen_set_CF(tmp);
- dead_tmp(tmp);
-}
-
-/* Shift by immediate. Includes special handling for shift == 0. */
-static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
-{
- switch (shiftop) {
- case 0: /* LSL */
- if (shift != 0) {
- if (flags)
- shifter_out_im(var, 32 - shift);
- tcg_gen_shli_i32(var, var, shift);
- }
- break;
- case 1: /* LSR */
- if (shift == 0) {
- if (flags) {
- tcg_gen_shri_i32(var, var, 31);
- gen_set_CF(var);
- }
- tcg_gen_movi_i32(var, 0);
- } else {
- if (flags)
- shifter_out_im(var, shift - 1);
- tcg_gen_shri_i32(var, var, shift);
- }
- break;
- case 2: /* ASR */
- if (shift == 0)
- shift = 32;
- if (flags)
- shifter_out_im(var, shift - 1);
- if (shift == 32)
- shift = 31;
- tcg_gen_sari_i32(var, var, shift);
- break;
- case 3: /* ROR/RRX */
- if (shift != 0) {
- if (flags)
- shifter_out_im(var, shift - 1);
- tcg_gen_rori_i32(var, var, shift); break;
- } else {
- TCGv tmp = load_cpu_field(CF);
- if (flags)
- shifter_out_im(var, 0);
- tcg_gen_shri_i32(var, var, 1);
- tcg_gen_shli_i32(tmp, tmp, 31);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
- }
- }
-};
-
-static inline void gen_arm_shift_reg(TCGv var, int shiftop,
- TCGv shift, int flags)
-{
- if (flags) {
- switch (shiftop) {
- case 0: gen_helper_shl_cc(var, var, shift); break;
- case 1: gen_helper_shr_cc(var, var, shift); break;
- case 2: gen_helper_sar_cc(var, var, shift); break;
- case 3: gen_helper_ror_cc(var, var, shift); break;
- }
- } else {
- switch (shiftop) {
- case 0: gen_helper_shl(var, var, shift); break;
- case 1: gen_helper_shr(var, var, shift); break;
- case 2: gen_helper_sar(var, var, shift); break;
- case 3: gen_helper_ror(var, var, shift); break;
- }
- }
- dead_tmp(shift);
-}
-
-#define PAS_OP(pfx) \
- switch (op2) { \
- case 0: gen_pas_helper(glue(pfx,add16)); break; \
- case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
- case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
- case 3: gen_pas_helper(glue(pfx,sub16)); break; \
- case 4: gen_pas_helper(glue(pfx,add8)); break; \
- case 7: gen_pas_helper(glue(pfx,sub8)); break; \
- }
-static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
-{
- TCGv tmp;
-
- switch (op1) {
-#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
- case 1:
- tmp = tcg_temp_new(TCG_TYPE_PTR);
- tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
- PAS_OP(s)
- break;
- case 5:
- tmp = tcg_temp_new(TCG_TYPE_PTR);
- tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
- PAS_OP(u)
- break;
-#undef gen_pas_helper
-#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
- case 2:
- PAS_OP(q);
- break;
- case 3:
- PAS_OP(sh);
- break;
- case 6:
- PAS_OP(uq);
- break;
- case 7:
- PAS_OP(uh);
- break;
-#undef gen_pas_helper
- }
-}
-#undef PAS_OP
-
-/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
-#define PAS_OP(pfx) \
- switch (op2) { \
- case 0: gen_pas_helper(glue(pfx,add8)); break; \
- case 1: gen_pas_helper(glue(pfx,add16)); break; \
- case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
- case 4: gen_pas_helper(glue(pfx,sub8)); break; \
- case 5: gen_pas_helper(glue(pfx,sub16)); break; \
- case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
- }
-static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
-{
- TCGv tmp;
-
- switch (op1) {
-#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
- case 0:
- tmp = tcg_temp_new(TCG_TYPE_PTR);
- tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
- PAS_OP(s)
- break;
- case 4:
- tmp = tcg_temp_new(TCG_TYPE_PTR);
- tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
- PAS_OP(u)
- break;
-#undef gen_pas_helper
-#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
- case 1:
- PAS_OP(q);
- break;
- case 2:
- PAS_OP(sh);
- break;
- case 5:
- PAS_OP(uq);
- break;
- case 6:
- PAS_OP(uh);
- break;
-#undef gen_pas_helper
- }
-}
-#undef PAS_OP
-
-static void gen_test_cc(int cc, int label)
-{
- TCGv tmp;
- TCGv tmp2;
- int inv;
-
- switch (cc) {
- case 0: /* eq: Z */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 1: /* ne: !Z */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- break;
- case 2: /* cs: C */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- break;
- case 3: /* cc: !C */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 4: /* mi: N */
- tmp = load_cpu_field(NF);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 5: /* pl: !N */
- tmp = load_cpu_field(NF);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 6: /* vs: V */
- tmp = load_cpu_field(VF);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 7: /* vc: !V */
- tmp = load_cpu_field(VF);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 8: /* hi: C && !Z */
- inv = gen_new_label();
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
- dead_tmp(tmp);
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- gen_set_label(inv);
- break;
- case 9: /* ls: !C || Z */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- dead_tmp(tmp);
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 10: /* ge: N == V -> N ^ V == 0 */
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 11: /* lt: N != V -> N ^ V != 0 */
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 12: /* gt: !Z && N == V */
- inv = gen_new_label();
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
- dead_tmp(tmp);
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- gen_set_label(inv);
- break;
- case 13: /* le: Z || N != V */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- dead_tmp(tmp);
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- default:
- fprintf(stderr, "Bad condition code 0x%x\n", cc);
- abort();
- }
- dead_tmp(tmp);
-}
-
-const uint8_t table_logic_cc[16] = {
- 1, /* and */
- 1, /* xor */
- 0, /* sub */
- 0, /* rsb */
- 0, /* add */
- 0, /* adc */
- 0, /* sbc */
- 0, /* rsc */
- 1, /* andl */
- 1, /* xorl */
- 0, /* cmp */
- 0, /* cmn */
- 1, /* orr */
- 1, /* mov */
- 1, /* bic */
- 1, /* mvn */
-};
-
-/* Set PC and Thumb state from an immediate address. */
-static inline void gen_bx_im(DisasContext *s, uint32_t addr)
-{
- TCGv tmp;
-
- s->is_jmp = DISAS_UPDATE;
- tmp = new_tmp();
- if (s->thumb != (addr & 1)) {
- tcg_gen_movi_i32(tmp, addr & 1);
- tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
- }
- tcg_gen_movi_i32(tmp, addr & ~1);
- tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
- dead_tmp(tmp);
-}
-
-/* Set PC and Thumb state from var. var is marked as dead. */
-static inline void gen_bx(DisasContext *s, TCGv var)
-{
- TCGv tmp;
-
- s->is_jmp = DISAS_UPDATE;
- tmp = new_tmp();
- tcg_gen_andi_i32(tmp, var, 1);
- store_cpu_field(tmp, thumb);
- tcg_gen_andi_i32(var, var, ~1);
- store_cpu_field(var, regs[15]);
-}
-
-/* TODO: This should be removed. Use gen_bx instead. */
-static inline void gen_bx_T0(DisasContext *s)
-{
- TCGv tmp = new_tmp();
- tcg_gen_mov_i32(tmp, cpu_T[0]);
- gen_bx(s, tmp);
-}
-
-#if defined(CONFIG_USER_ONLY)
-#define gen_ldst(name, s) gen_op_##name##_raw()
-#else
-#define gen_ldst(name, s) do { \
- s->is_mem = 1; \
- if (IS_USER(s)) \
- gen_op_##name##_user(); \
- else \
- gen_op_##name##_kernel(); \
- } while (0)
-#endif
-static inline TCGv gen_ld8s(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld8s(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld8u(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld8u(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld16s(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld16s(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld16u(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld16u(tmp, addr, index);
- return tmp;
-}
-static inline TCGv gen_ld32(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld32u(tmp, addr, index);
- return tmp;
-}
-static inline void gen_st8(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st8(val, addr, index);
- dead_tmp(val);
-}
-static inline void gen_st16(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st16(val, addr, index);
- dead_tmp(val);
-}
-static inline void gen_st32(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st32(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_movl_T0_reg(DisasContext *s, int reg)
-{
- load_reg_var(s, cpu_T[0], reg);
-}
-
-static inline void gen_movl_T1_reg(DisasContext *s, int reg)
-{
- load_reg_var(s, cpu_T[1], reg);
-}
-
-static inline void gen_movl_T2_reg(DisasContext *s, int reg)
-{
- load_reg_var(s, cpu_T[2], reg);
-}
-
-static inline void gen_set_pc_im(uint32_t val)
-{
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_cpu_field(tmp, regs[15]);
-}
-
-static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
-{
- TCGv tmp;
- if (reg == 15) {
- tmp = new_tmp();
- tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
- } else {
- tmp = cpu_T[t];
- }
- tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
- if (reg == 15) {
- dead_tmp(tmp);
- s->is_jmp = DISAS_JUMP;
- }
-}
-
-static inline void gen_movl_reg_T0(DisasContext *s, int reg)
-{
- gen_movl_reg_TN(s, reg, 0);
-}
-
-static inline void gen_movl_reg_T1(DisasContext *s, int reg)
-{
- gen_movl_reg_TN(s, reg, 1);
-}
-
-/* Force a TB lookup after an instruction that changes the CPU state. */
-static inline void gen_lookup_tb(DisasContext *s)
-{
- gen_op_movl_T0_im(s->pc);
- gen_movl_reg_T0(s, 15);
- s->is_jmp = DISAS_UPDATE;
-}
-
-static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
- TCGv var)
-{
- int val, rm, shift, shiftop;
- TCGv offset;
-
- if (!(insn & (1 << 25))) {
- /* immediate */
- val = insn & 0xfff;
- if (!(insn & (1 << 23)))
- val = -val;
- if (val != 0)
- tcg_gen_addi_i32(var, var, val);
- } else {
- /* shift/register */
- rm = (insn) & 0xf;
- shift = (insn >> 7) & 0x1f;
- shiftop = (insn >> 5) & 3;
- offset = load_reg(s, rm);
- gen_arm_shift_im(offset, shiftop, shift, 0);
- if (!(insn & (1 << 23)))
- tcg_gen_sub_i32(var, var, offset);
- else
- tcg_gen_add_i32(var, var, offset);
- dead_tmp(offset);
- }
-}
-
-static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
- int extra, TCGv var)
-{
- int val, rm;
- TCGv offset;
-
- if (insn & (1 << 22)) {
- /* immediate */
- val = (insn & 0xf) | ((insn >> 4) & 0xf0);
- if (!(insn & (1 << 23)))
- val = -val;
- val += extra;
- if (val != 0)
- tcg_gen_addi_i32(var, var, val);
- } else {
- /* register */
- if (extra)
- tcg_gen_addi_i32(var, var, extra);
- rm = (insn) & 0xf;
- offset = load_reg(s, rm);
- if (!(insn & (1 << 23)))
- tcg_gen_sub_i32(var, var, offset);
- else
- tcg_gen_add_i32(var, var, offset);
- dead_tmp(offset);
- }
-}
-
-#define VFP_OP2(name) \
-static inline void gen_vfp_##name(int dp) \
-{ \
- if (dp) \
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
- else \
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
-}
-
-#define VFP_OP1(name) \
-static inline void gen_vfp_##name(int dp, int arg) \
-{ \
- if (dp) \
- gen_op_vfp_##name##d(arg); \
- else \
- gen_op_vfp_##name##s(arg); \
-}
-
-VFP_OP2(add)
-VFP_OP2(sub)
-VFP_OP2(mul)
-VFP_OP2(div)
-
-#undef VFP_OP2
-
-static inline void gen_vfp_abs(int dp)
-{
- if (dp)
- gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
- else
- gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
-}
-
-static inline void gen_vfp_neg(int dp)
-{
- if (dp)
- gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
- else
- gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
-}
-
-static inline void gen_vfp_sqrt(int dp)
-{
- if (dp)
- gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
- else
- gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-static inline void gen_vfp_cmp(int dp)
-{
- if (dp)
- gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
- else
- gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
-}
-
-static inline void gen_vfp_cmpe(int dp)
-{
- if (dp)
- gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
- else
- gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
-}
-
-static inline void gen_vfp_F1_ld0(int dp)
-{
- if (dp)
- tcg_gen_movi_i64(cpu_F1d, 0);
- else
- tcg_gen_movi_i32(cpu_F1s, 0);
-}
-
-static inline void gen_vfp_uito(int dp)
-{
- if (dp)
- gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
- else
- gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-static inline void gen_vfp_sito(int dp)
-{
- if (dp)
- gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
- else
- gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-static inline void gen_vfp_toui(int dp)
-{
- if (dp)
- gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
- else
- gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-static inline void gen_vfp_touiz(int dp)
-{
- if (dp)
- gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
- else
- gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-static inline void gen_vfp_tosi(int dp)
-{
- if (dp)
- gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
- else
- gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-static inline void gen_vfp_tosiz(int dp)
-{
- if (dp)
- gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
- else
- gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
-}
-
-#define VFP_GEN_FIX(name) \
-static inline void gen_vfp_##name(int dp, int shift) \
-{ \
- if (dp) \
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
- else \
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
-}
-VFP_GEN_FIX(tosh)
-VFP_GEN_FIX(tosl)
-VFP_GEN_FIX(touh)
-VFP_GEN_FIX(toul)
-VFP_GEN_FIX(shto)
-VFP_GEN_FIX(slto)
-VFP_GEN_FIX(uhto)
-VFP_GEN_FIX(ulto)
-#undef VFP_GEN_FIX
-
-static inline void gen_vfp_ld(DisasContext *s, int dp)
-{
- if (dp)
- tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
- else
- tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
-}
-
-static inline void gen_vfp_st(DisasContext *s, int dp)
-{
- if (dp)
- tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
- else
- tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
-}
-
-static inline long
-vfp_reg_offset (int dp, int reg)
-{
- if (dp)
- return offsetof(CPUARMState, vfp.regs[reg]);
- else if (reg & 1) {
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
- + offsetof(CPU_DoubleU, l.upper);
- } else {
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
- + offsetof(CPU_DoubleU, l.lower);
- }
-}
-
-/* Return the offset of a 32-bit piece of a NEON register.
- zero is the least significant end of the register. */
-static inline long
-neon_reg_offset (int reg, int n)
-{
- int sreg;
- sreg = reg * 2 + n;
- return vfp_reg_offset(0, sreg);
-}
-
-/* FIXME: Remove these. */
-#define neon_T0 cpu_T[0]
-#define neon_T1 cpu_T[1]
-#define NEON_GET_REG(T, reg, n) \
- tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
-#define NEON_SET_REG(T, reg, n) \
- tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
-
-static TCGv neon_load_reg(int reg, int pass)
-{
- TCGv tmp = new_tmp();
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
- return tmp;
-}
-
-static void neon_store_reg(int reg, int pass, TCGv var)
-{
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
- dead_tmp(var);
-}
-
-static inline void neon_load_reg64(TCGv var, int reg)
-{
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
-}
-
-static inline void neon_store_reg64(TCGv var, int reg)
-{
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
-}
-
-#define tcg_gen_ld_f32 tcg_gen_ld_i32
-#define tcg_gen_ld_f64 tcg_gen_ld_i64
-#define tcg_gen_st_f32 tcg_gen_st_i32
-#define tcg_gen_st_f64 tcg_gen_st_i64
-
-static inline void gen_mov_F0_vreg(int dp, int reg)
-{
- if (dp)
- tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
- else
- tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
-}
-
-static inline void gen_mov_F1_vreg(int dp, int reg)
-{
- if (dp)
- tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
- else
- tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
-}
-
-static inline void gen_mov_vreg_F0(int dp, int reg)
-{
- if (dp)
- tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
- else
- tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
-}
-
-#define ARM_CP_RW_BIT (1 << 20)
-
-static inline void iwmmxt_load_reg(TCGv var, int reg)
-{
- tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
-}
-
-static inline void iwmmxt_store_reg(TCGv var, int reg)
-{
- tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
-}
-
-static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
-{
- tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
-}
-
-static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
-{
- tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
-}
-
-static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
-{
- tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
-}
-
-static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
-{
- iwmmxt_store_reg(cpu_M0, rn);
-}
-
-static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_M0, rn);
-}
-
-static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_V1, rn);
- tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
-}
-
-static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_V1, rn);
- tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
-}
-
-static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_V1, rn);
- tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
-}
-
-#define IWMMXT_OP(name) \
-static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
-{ \
- iwmmxt_load_reg(cpu_V1, rn); \
- gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
-}
-
-#define IWMMXT_OP_ENV(name) \
-static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
-{ \
- iwmmxt_load_reg(cpu_V1, rn); \
- gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
-}
-
-#define IWMMXT_OP_ENV_SIZE(name) \
-IWMMXT_OP_ENV(name##b) \
-IWMMXT_OP_ENV(name##w) \
-IWMMXT_OP_ENV(name##l)
-
-#define IWMMXT_OP_ENV1(name) \
-static inline void gen_op_iwmmxt_##name##_M0(void) \
-{ \
- gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
-}
-
-IWMMXT_OP(maddsq)
-IWMMXT_OP(madduq)
-IWMMXT_OP(sadb)
-IWMMXT_OP(sadw)
-IWMMXT_OP(mulslw)
-IWMMXT_OP(mulshw)
-IWMMXT_OP(mululw)
-IWMMXT_OP(muluhw)
-IWMMXT_OP(macsw)
-IWMMXT_OP(macuw)
-
-IWMMXT_OP_ENV_SIZE(unpackl)
-IWMMXT_OP_ENV_SIZE(unpackh)
-
-IWMMXT_OP_ENV1(unpacklub)
-IWMMXT_OP_ENV1(unpackluw)
-IWMMXT_OP_ENV1(unpacklul)
-IWMMXT_OP_ENV1(unpackhub)
-IWMMXT_OP_ENV1(unpackhuw)
-IWMMXT_OP_ENV1(unpackhul)
-IWMMXT_OP_ENV1(unpacklsb)
-IWMMXT_OP_ENV1(unpacklsw)
-IWMMXT_OP_ENV1(unpacklsl)
-IWMMXT_OP_ENV1(unpackhsb)
-IWMMXT_OP_ENV1(unpackhsw)
-IWMMXT_OP_ENV1(unpackhsl)
-
-IWMMXT_OP_ENV_SIZE(cmpeq)
-IWMMXT_OP_ENV_SIZE(cmpgtu)
-IWMMXT_OP_ENV_SIZE(cmpgts)
-
-IWMMXT_OP_ENV_SIZE(mins)
-IWMMXT_OP_ENV_SIZE(minu)
-IWMMXT_OP_ENV_SIZE(maxs)
-IWMMXT_OP_ENV_SIZE(maxu)
-
-IWMMXT_OP_ENV_SIZE(subn)
-IWMMXT_OP_ENV_SIZE(addn)
-IWMMXT_OP_ENV_SIZE(subu)
-IWMMXT_OP_ENV_SIZE(addu)
-IWMMXT_OP_ENV_SIZE(subs)
-IWMMXT_OP_ENV_SIZE(adds)
-
-IWMMXT_OP_ENV(avgb0)
-IWMMXT_OP_ENV(avgb1)
-IWMMXT_OP_ENV(avgw0)
-IWMMXT_OP_ENV(avgw1)
-
-IWMMXT_OP(msadb)
-
-IWMMXT_OP_ENV(packuw)
-IWMMXT_OP_ENV(packul)
-IWMMXT_OP_ENV(packuq)
-IWMMXT_OP_ENV(packsw)
-IWMMXT_OP_ENV(packsl)
-IWMMXT_OP_ENV(packsq)
-
-static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
-{
- gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
-}
-
-static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
-{
- gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
-}
-
-static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
-{
- gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
-}
-
-static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_V1, rn);
- gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
-}
-
-static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
-{
- TCGv tmp = tcg_const_i32(shift);
- gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
-}
-
-static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
-{
- tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
- tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
- tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
-}
-
-static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
-{
- tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
- tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
- tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
-}
-
-static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
-{
- tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
- tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
- if (mask != ~0u)
- tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
-}
-
-static void gen_op_iwmmxt_set_mup(void)
-{
- TCGv tmp;
- tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
- tcg_gen_ori_i32(tmp, tmp, 2);
- store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
-}
-
-static void gen_op_iwmmxt_set_cup(void)
-{
- TCGv tmp;
- tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
- tcg_gen_ori_i32(tmp, tmp, 1);
- store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
-}
-
-static void gen_op_iwmmxt_setpsr_nz(void)
-{
- TCGv tmp = new_tmp();
- gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
- store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
-}
-
-static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_V1, rn);
- tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
- tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
-}
-
-
-static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
-{
- iwmmxt_load_reg(cpu_V0, rn);
- tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
- tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
-}
-
-static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
-{
- tcg_gen_extu_i32_i64(cpu_V0, cpu_T[0]);
- tcg_gen_extu_i32_i64(cpu_V1, cpu_T[0]);
- tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
- iwmmxt_store_reg(cpu_V0, rn);
-}
-
-static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
-{
- int rd;
- uint32_t offset;
-
- rd = (insn >> 16) & 0xf;
- gen_movl_T1_reg(s, rd);
-
- offset = (insn & 0xff) << ((insn >> 7) & 2);
- if (insn & (1 << 24)) {
- /* Pre indexed */
- if (insn & (1 << 23))
- gen_op_addl_T1_im(offset);
- else
- gen_op_addl_T1_im(-offset);
-
- if (insn & (1 << 21))
- gen_movl_reg_T1(s, rd);
- } else if (insn & (1 << 21)) {
- /* Post indexed */
- if (insn & (1 << 23))
- gen_op_movl_T0_im(offset);
- else
- gen_op_movl_T0_im(- offset);
- gen_op_addl_T0_T1();
- gen_movl_reg_T0(s, rd);
- } else if (!(insn & (1 << 23)))
- return 1;
- return 0;
-}
-
-static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
-{
- int rd = (insn >> 0) & 0xf;
-
- if (insn & (1 << 8))
- if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
- return 1;
- else
- gen_op_iwmmxt_movl_T0_wCx(rd);
- else
- gen_iwmmxt_movl_T0_T1_wRn(rd);
-
- gen_op_movl_T1_im(mask);
- gen_op_andl_T0_T1();
- return 0;
-}
-
-/* Disassemble an iwMMXt instruction. Returns nonzero if an error occured
- (ie. an undefined instruction). */
-static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
-{
- int rd, wrd;
- int rdhi, rdlo, rd0, rd1, i;
- TCGv tmp;
-
- if ((insn & 0x0e000e00) == 0x0c000000) {
- if ((insn & 0x0fe00ff0) == 0x0c400000) {
- wrd = insn & 0xf;
- rdlo = (insn >> 12) & 0xf;
- rdhi = (insn >> 16) & 0xf;
- if (insn & ARM_CP_RW_BIT) { /* TMRRC */
- gen_iwmmxt_movl_T0_T1_wRn(wrd);
- gen_movl_reg_T0(s, rdlo);
- gen_movl_reg_T1(s, rdhi);
- } else { /* TMCRR */
- gen_movl_T0_reg(s, rdlo);
- gen_movl_T1_reg(s, rdhi);
- gen_iwmmxt_movl_wRn_T0_T1(wrd);
- gen_op_iwmmxt_set_mup();
- }
- return 0;
- }
-
- wrd = (insn >> 12) & 0xf;
- if (gen_iwmmxt_address(s, insn))
- return 1;
- if (insn & ARM_CP_RW_BIT) {
- if ((insn >> 28) == 0xf) { /* WLDRW wCx */
- tmp = gen_ld32(cpu_T[1], IS_USER(s));
- tcg_gen_mov_i32(cpu_T[0], tmp);
- dead_tmp(tmp);
- gen_op_iwmmxt_movl_wCx_T0(wrd);
- } else {
- i = 1;
- if (insn & (1 << 8)) {
- if (insn & (1 << 22)) { /* WLDRD */
- tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
- i = 0;
- } else { /* WLDRW wRd */
- tmp = gen_ld32(cpu_T[1], IS_USER(s));
- }
- } else {
- if (insn & (1 << 22)) { /* WLDRH */
- tmp = gen_ld16u(cpu_T[1], IS_USER(s));
- } else { /* WLDRB */
- tmp = gen_ld8u(cpu_T[1], IS_USER(s));
- }
- }
- if (i) {
- tcg_gen_extu_i32_i64(cpu_M0, tmp);
- dead_tmp(tmp);
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- }
- } else {
- if ((insn >> 28) == 0xf) { /* WSTRW wCx */
- gen_op_iwmmxt_movl_T0_wCx(wrd);
- tmp = new_tmp();
- tcg_gen_mov_i32(tmp, cpu_T[0]);
- gen_st32(tmp, cpu_T[1], IS_USER(s));
- } else {
- gen_op_iwmmxt_movq_M0_wRn(wrd);
- tmp = new_tmp();
- if (insn & (1 << 8)) {
- if (insn & (1 << 22)) { /* WSTRD */
- dead_tmp(tmp);
- tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
- } else { /* WSTRW wRd */
- tcg_gen_trunc_i64_i32(tmp, cpu_M0);
- gen_st32(tmp, cpu_T[1], IS_USER(s));
- }
- } else {
- if (insn & (1 << 22)) { /* WSTRH */
- tcg_gen_trunc_i64_i32(tmp, cpu_M0);
- gen_st16(tmp, cpu_T[1], IS_USER(s));
- } else { /* WSTRB */
- tcg_gen_trunc_i64_i32(tmp, cpu_M0);
- gen_st8(tmp, cpu_T[1], IS_USER(s));
- }
- }
- }
- }
- return 0;
- }
-
- if ((insn & 0x0f000000) != 0x0e000000)
- return 1;
-
- switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
- case 0x000: /* WOR */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 0) & 0xf;
- rd1 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- gen_op_iwmmxt_orq_M0_wRn(rd1);
- gen_op_iwmmxt_setpsr_nz();
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x011: /* TMCR */
- if (insn & 0xf)
- return 1;
- rd = (insn >> 12) & 0xf;
- wrd = (insn >> 16) & 0xf;
- switch (wrd) {
- case ARM_IWMMXT_wCID:
- case ARM_IWMMXT_wCASF:
- break;
- case ARM_IWMMXT_wCon:
- gen_op_iwmmxt_set_cup();
- /* Fall through. */
- case ARM_IWMMXT_wCSSF:
- gen_op_iwmmxt_movl_T0_wCx(wrd);
- gen_movl_T1_reg(s, rd);
- gen_op_bicl_T0_T1();
- gen_op_iwmmxt_movl_wCx_T0(wrd);
- break;
- case ARM_IWMMXT_wCGR0:
- case ARM_IWMMXT_wCGR1:
- case ARM_IWMMXT_wCGR2:
- case ARM_IWMMXT_wCGR3:
- gen_op_iwmmxt_set_cup();
- gen_movl_reg_T0(s, rd);
- gen_op_iwmmxt_movl_wCx_T0(wrd);
- break;
- default:
- return 1;
- }
- break;
- case 0x100: /* WXOR */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 0) & 0xf;
- rd1 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- gen_op_iwmmxt_xorq_M0_wRn(rd1);
- gen_op_iwmmxt_setpsr_nz();
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x111: /* TMRC */
- if (insn & 0xf)
- return 1;
- rd = (insn >> 12) & 0xf;
- wrd = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movl_T0_wCx(wrd);
- gen_movl_reg_T0(s, rd);
- break;
- case 0x300: /* WANDN */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 0) & 0xf;
- rd1 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- tcg_gen_neg_i64(cpu_M0, cpu_M0);
- gen_op_iwmmxt_andq_M0_wRn(rd1);
- gen_op_iwmmxt_setpsr_nz();
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x200: /* WAND */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 0) & 0xf;
- rd1 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- gen_op_iwmmxt_andq_M0_wRn(rd1);
- gen_op_iwmmxt_setpsr_nz();
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x810: case 0xa10: /* WMADD */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 0) & 0xf;
- rd1 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (insn & (1 << 21))
- gen_op_iwmmxt_maddsq_M0_wRn(rd1);
- else
- gen_op_iwmmxt_madduq_M0_wRn(rd1);
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
- break;
- case 1:
- gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
- break;
- case 2:
- gen_op_iwmmxt_unpackll_M0_wRn(rd1);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
- break;
- case 1:
- gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
- break;
- case 2:
- gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (insn & (1 << 22))
- gen_op_iwmmxt_sadw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_sadb_M0_wRn(rd1);
- if (!(insn & (1 << 20)))
- gen_op_iwmmxt_addl_M0_wRn(wrd);
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (insn & (1 << 21)) {
- if (insn & (1 << 20))
- gen_op_iwmmxt_mulshw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_mulslw_M0_wRn(rd1);
- } else {
- if (insn & (1 << 20))
- gen_op_iwmmxt_muluhw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_mululw_M0_wRn(rd1);
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (insn & (1 << 21))
- gen_op_iwmmxt_macsw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_macuw_M0_wRn(rd1);
- if (!(insn & (1 << 20))) {
- iwmmxt_load_reg(cpu_V1, wrd);
- tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
- break;
- case 1:
- gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
- break;
- case 2:
- gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (insn & (1 << 22)) {
- if (insn & (1 << 20))
- gen_op_iwmmxt_avgw1_M0_wRn(rd1);
- else
- gen_op_iwmmxt_avgw0_M0_wRn(rd1);
- } else {
- if (insn & (1 << 20))
- gen_op_iwmmxt_avgb1_M0_wRn(rd1);
- else
- gen_op_iwmmxt_avgb0_M0_wRn(rd1);
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
- gen_op_movl_T1_im(7);
- gen_op_andl_T0_T1();
- gen_op_iwmmxt_align_M0_T0_wRn(rd1);
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
- rd = (insn >> 12) & 0xf;
- wrd = (insn >> 16) & 0xf;
- gen_movl_T0_reg(s, rd);
- gen_op_iwmmxt_movq_M0_wRn(wrd);
- switch ((insn >> 6) & 3) {
- case 0:
- gen_op_movl_T1_im(0xff);
- gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
- break;
- case 1:
- gen_op_movl_T1_im(0xffff);
- gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
- break;
- case 2:
- gen_op_movl_T1_im(0xffffffff);
- gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
- rd = (insn >> 12) & 0xf;
- wrd = (insn >> 16) & 0xf;
- if (rd == 15)
- return 1;
- gen_op_iwmmxt_movq_M0_wRn(wrd);
- switch ((insn >> 22) & 3) {
- case 0:
- if (insn & 8)
- gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
- else {
- gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
- }
- break;
- case 1:
- if (insn & 8)
- gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
- else {
- gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
- }
- break;
- case 2:
- gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
- break;
- case 3:
- return 1;
- }
- gen_movl_reg_T0(s, rd);
- break;
- case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
- if ((insn & 0x000ff008) != 0x0003f000)
- return 1;
- gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
- switch ((insn >> 22) & 3) {
- case 0:
- gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
- break;
- case 1:
- gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
- break;
- case 2:
- gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
- break;
- case 3:
- return 1;
- }
- gen_op_shll_T1_im(28);
- gen_set_nzcv(cpu_T[1]);
- break;
- case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
- rd = (insn >> 12) & 0xf;
- wrd = (insn >> 16) & 0xf;
- gen_movl_T0_reg(s, rd);
- switch ((insn >> 6) & 3) {
- case 0:
- gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
- break;
- case 1:
- gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
- break;
- case 2:
- gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
- if ((insn & 0x000ff00f) != 0x0003f000)
- return 1;
- gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
- switch ((insn >> 22) & 3) {
- case 0:
- for (i = 0; i < 7; i ++) {
- gen_op_shll_T1_im(4);
- gen_op_andl_T0_T1();
- }
- break;
- case 1:
- for (i = 0; i < 3; i ++) {
- gen_op_shll_T1_im(8);
- gen_op_andl_T0_T1();
- }
- break;
- case 2:
- gen_op_shll_T1_im(16);
- gen_op_andl_T0_T1();
- break;
- case 3:
- return 1;
- }
- gen_set_nzcv(cpu_T[0]);
- break;
- case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
- break;
- case 1:
- gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
- break;
- case 2:
- gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
- if ((insn & 0x000ff00f) != 0x0003f000)
- return 1;
- gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
- switch ((insn >> 22) & 3) {
- case 0:
- for (i = 0; i < 7; i ++) {
- gen_op_shll_T1_im(4);
- gen_op_orl_T0_T1();
- }
- break;
- case 1:
- for (i = 0; i < 3; i ++) {
- gen_op_shll_T1_im(8);
- gen_op_orl_T0_T1();
- }
- break;
- case 2:
- gen_op_shll_T1_im(16);
- gen_op_orl_T0_T1();
- break;
- case 3:
- return 1;
- }
- gen_set_nzcv(cpu_T[0]);
- break;
- case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
- rd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- if ((insn & 0xf) != 0)
- return 1;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
- break;
- case 1:
- gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
- break;
- case 2:
- gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
- break;
- case 3:
- return 1;
- }
- gen_movl_reg_T0(s, rd);
- break;
- case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
- case 0x906: case 0xb06: case 0xd06: case 0xf06:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- if (insn & (1 << 21))
- gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
- else
- gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
- break;
- case 1:
- if (insn & (1 << 21))
- gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
- break;
- case 2:
- if (insn & (1 << 21))
- gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
- else
- gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
- case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- if (insn & (1 << 21))
- gen_op_iwmmxt_unpacklsb_M0();
- else
- gen_op_iwmmxt_unpacklub_M0();
- break;
- case 1:
- if (insn & (1 << 21))
- gen_op_iwmmxt_unpacklsw_M0();
- else
- gen_op_iwmmxt_unpackluw_M0();
- break;
- case 2:
- if (insn & (1 << 21))
- gen_op_iwmmxt_unpacklsl_M0();
- else
- gen_op_iwmmxt_unpacklul_M0();
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
- case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- if (insn & (1 << 21))
- gen_op_iwmmxt_unpackhsb_M0();
- else
- gen_op_iwmmxt_unpackhub_M0();
- break;
- case 1:
- if (insn & (1 << 21))
- gen_op_iwmmxt_unpackhsw_M0();
- else
- gen_op_iwmmxt_unpackhuw_M0();
- break;
- case 2:
- if (insn & (1 << 21))
- gen_op_iwmmxt_unpackhsl_M0();
- else
- gen_op_iwmmxt_unpackhul_M0();
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
- case 0x214: case 0x614: case 0xa14: case 0xe14:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (gen_iwmmxt_shift(insn, 0xff))
- return 1;
- switch ((insn >> 22) & 3) {
- case 0:
- return 1;
- case 1:
- gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 2:
- gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 3:
- gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
- case 0x014: case 0x414: case 0x814: case 0xc14:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (gen_iwmmxt_shift(insn, 0xff))
- return 1;
- switch ((insn >> 22) & 3) {
- case 0:
- return 1;
- case 1:
- gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 2:
- gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 3:
- gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
- case 0x114: case 0x514: case 0x914: case 0xd14:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (gen_iwmmxt_shift(insn, 0xff))
- return 1;
- switch ((insn >> 22) & 3) {
- case 0:
- return 1;
- case 1:
- gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 2:
- gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 3:
- gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
- case 0x314: case 0x714: case 0xb14: case 0xf14:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- return 1;
- case 1:
- if (gen_iwmmxt_shift(insn, 0xf))
- return 1;
- gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 2:
- if (gen_iwmmxt_shift(insn, 0x1f))
- return 1;
- gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- case 3:
- if (gen_iwmmxt_shift(insn, 0x3f))
- return 1;
- gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- break;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
- case 0x916: case 0xb16: case 0xd16: case 0xf16:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- if (insn & (1 << 21))
- gen_op_iwmmxt_minsb_M0_wRn(rd1);
- else
- gen_op_iwmmxt_minub_M0_wRn(rd1);
- break;
- case 1:
- if (insn & (1 << 21))
- gen_op_iwmmxt_minsw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_minuw_M0_wRn(rd1);
- break;
- case 2:
- if (insn & (1 << 21))
- gen_op_iwmmxt_minsl_M0_wRn(rd1);
- else
- gen_op_iwmmxt_minul_M0_wRn(rd1);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
- case 0x816: case 0xa16: case 0xc16: case 0xe16:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 22) & 3) {
- case 0:
- if (insn & (1 << 21))
- gen_op_iwmmxt_maxsb_M0_wRn(rd1);
- else
- gen_op_iwmmxt_maxub_M0_wRn(rd1);
- break;
- case 1:
- if (insn & (1 << 21))
- gen_op_iwmmxt_maxsw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_maxuw_M0_wRn(rd1);
- break;
- case 2:
- if (insn & (1 << 21))
- gen_op_iwmmxt_maxsl_M0_wRn(rd1);
- else
- gen_op_iwmmxt_maxul_M0_wRn(rd1);
- break;
- case 3:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
- case 0x402: case 0x502: case 0x602: case 0x702:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- gen_op_movl_T0_im((insn >> 20) & 3);
- gen_op_iwmmxt_align_M0_T0_wRn(rd1);
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
- case 0x41a: case 0x51a: case 0x61a: case 0x71a:
- case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
- case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 20) & 0xf) {
- case 0x0:
- gen_op_iwmmxt_subnb_M0_wRn(rd1);
- break;
- case 0x1:
- gen_op_iwmmxt_subub_M0_wRn(rd1);
- break;
- case 0x3:
- gen_op_iwmmxt_subsb_M0_wRn(rd1);
- break;
- case 0x4:
- gen_op_iwmmxt_subnw_M0_wRn(rd1);
- break;
- case 0x5:
- gen_op_iwmmxt_subuw_M0_wRn(rd1);
- break;
- case 0x7:
- gen_op_iwmmxt_subsw_M0_wRn(rd1);
- break;
- case 0x8:
- gen_op_iwmmxt_subnl_M0_wRn(rd1);
- break;
- case 0x9:
- gen_op_iwmmxt_subul_M0_wRn(rd1);
- break;
- case 0xb:
- gen_op_iwmmxt_subsl_M0_wRn(rd1);
- break;
- default:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
- case 0x41e: case 0x51e: case 0x61e: case 0x71e:
- case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
- case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
- gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
- case 0x418: case 0x518: case 0x618: case 0x718:
- case 0x818: case 0x918: case 0xa18: case 0xb18:
- case 0xc18: case 0xd18: case 0xe18: case 0xf18:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- switch ((insn >> 20) & 0xf) {
- case 0x0:
- gen_op_iwmmxt_addnb_M0_wRn(rd1);
- break;
- case 0x1:
- gen_op_iwmmxt_addub_M0_wRn(rd1);
- break;
- case 0x3:
- gen_op_iwmmxt_addsb_M0_wRn(rd1);
- break;
- case 0x4:
- gen_op_iwmmxt_addnw_M0_wRn(rd1);
- break;
- case 0x5:
- gen_op_iwmmxt_adduw_M0_wRn(rd1);
- break;
- case 0x7:
- gen_op_iwmmxt_addsw_M0_wRn(rd1);
- break;
- case 0x8:
- gen_op_iwmmxt_addnl_M0_wRn(rd1);
- break;
- case 0x9:
- gen_op_iwmmxt_addul_M0_wRn(rd1);
- break;
- case 0xb:
- gen_op_iwmmxt_addsl_M0_wRn(rd1);
- break;
- default:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
- case 0x408: case 0x508: case 0x608: case 0x708:
- case 0x808: case 0x908: case 0xa08: case 0xb08:
- case 0xc08: case 0xd08: case 0xe08: case 0xf08:
- wrd = (insn >> 12) & 0xf;
- rd0 = (insn >> 16) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- gen_op_iwmmxt_movq_M0_wRn(rd0);
- if (!(insn & (1 << 20)))
- return 1;
- switch ((insn >> 22) & 3) {
- case 0:
- return 1;
- case 1:
- if (insn & (1 << 21))
- gen_op_iwmmxt_packsw_M0_wRn(rd1);
- else
- gen_op_iwmmxt_packuw_M0_wRn(rd1);
- break;
- case 2:
- if (insn & (1 << 21))
- gen_op_iwmmxt_packsl_M0_wRn(rd1);
- else
- gen_op_iwmmxt_packul_M0_wRn(rd1);
- break;
- case 3:
- if (insn & (1 << 21))
- gen_op_iwmmxt_packsq_M0_wRn(rd1);
- else
- gen_op_iwmmxt_packuq_M0_wRn(rd1);
- break;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- gen_op_iwmmxt_set_cup();
- break;
- case 0x201: case 0x203: case 0x205: case 0x207:
- case 0x209: case 0x20b: case 0x20d: case 0x20f:
- case 0x211: case 0x213: case 0x215: case 0x217:
- case 0x219: case 0x21b: case 0x21d: case 0x21f:
- wrd = (insn >> 5) & 0xf;
- rd0 = (insn >> 12) & 0xf;
- rd1 = (insn >> 0) & 0xf;
- if (rd0 == 0xf || rd1 == 0xf)
- return 1;
- gen_op_iwmmxt_movq_M0_wRn(wrd);
- switch ((insn >> 16) & 0xf) {
- case 0x0: /* TMIA */
- gen_movl_T0_reg(s, rd0);
- gen_movl_T1_reg(s, rd1);
- gen_op_iwmmxt_muladdsl_M0_T0_T1();
- break;
- case 0x8: /* TMIAPH */
- gen_movl_T0_reg(s, rd0);
- gen_movl_T1_reg(s, rd1);
- gen_op_iwmmxt_muladdsw_M0_T0_T1();
- break;
- case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
- gen_movl_T1_reg(s, rd0);
- if (insn & (1 << 16))
- gen_op_shrl_T1_im(16);
- gen_op_movl_T0_T1();
- gen_movl_T1_reg(s, rd1);
- if (insn & (1 << 17))
- gen_op_shrl_T1_im(16);
- gen_op_iwmmxt_muladdswl_M0_T0_T1();
- break;
- default:
- return 1;
- }
- gen_op_iwmmxt_movq_wRn_M0(wrd);
- gen_op_iwmmxt_set_mup();
- break;
- default:
- return 1;
- }
-
- return 0;
-}
-
-/* Disassemble an XScale DSP instruction. Returns nonzero if an error occured
- (ie. an undefined instruction). */
-static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
-{
- int acc, rd0, rd1, rdhi, rdlo;
-
- if ((insn & 0x0ff00f10) == 0x0e200010) {
- /* Multiply with Internal Accumulate Format */
- rd0 = (insn >> 12) & 0xf;
- rd1 = insn & 0xf;
- acc = (insn >> 5) & 7;
-
- if (acc != 0)
- return 1;
-
- switch ((insn >> 16) & 0xf) {
- case 0x0: /* MIA */
- gen_movl_T0_reg(s, rd0);
- gen_movl_T1_reg(s, rd1);
- gen_op_iwmmxt_muladdsl_M0_T0_T1();
- break;
- case 0x8: /* MIAPH */
- gen_movl_T0_reg(s, rd0);
- gen_movl_T1_reg(s, rd1);
- gen_op_iwmmxt_muladdsw_M0_T0_T1();
- break;
- case 0xc: /* MIABB */
- case 0xd: /* MIABT */
- case 0xe: /* MIATB */
- case 0xf: /* MIATT */
- gen_movl_T1_reg(s, rd0);
- if (insn & (1 << 16))
- gen_op_shrl_T1_im(16);
- gen_op_movl_T0_T1();
- gen_movl_T1_reg(s, rd1);
- if (insn & (1 << 17))
- gen_op_shrl_T1_im(16);
- gen_op_iwmmxt_muladdswl_M0_T0_T1();
- break;
- default:
- return 1;
- }
-
- gen_op_iwmmxt_movq_wRn_M0(acc);
- return 0;
- }
-
- if ((insn & 0x0fe00ff8) == 0x0c400000) {
- /* Internal Accumulator Access Format */
- rdhi = (insn >> 16) & 0xf;
- rdlo = (insn >> 12) & 0xf;
- acc = insn & 7;
-
- if (acc != 0)
- return 1;
-
- if (insn & ARM_CP_RW_BIT) { /* MRA */
- gen_iwmmxt_movl_T0_T1_wRn(acc);
- gen_movl_reg_T0(s, rdlo);
- gen_op_movl_T0_im((1 << (40 - 32)) - 1);
- gen_op_andl_T0_T1();
- gen_movl_reg_T0(s, rdhi);
- } else { /* MAR */
- gen_movl_T0_reg(s, rdlo);
- gen_movl_T1_reg(s, rdhi);
- gen_iwmmxt_movl_wRn_T0_T1(acc);
- }
- return 0;
- }
-
- return 1;
-}
-
-/* Disassemble system coprocessor instruction. Return nonzero if
- instruction is not defined. */
-static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp;
- uint32_t rd = (insn >> 12) & 0xf;
- uint32_t cp = (insn >> 8) & 0xf;
- if (IS_USER(s)) {
- return 1;
- }
-
- if (insn & ARM_CP_RW_BIT) {
- if (!env->cp[cp].cp_read)
- return 1;
- gen_set_pc_im(s->pc);
- tmp = new_tmp();
- gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
- store_reg(s, rd, tmp);
- } else {
- if (!env->cp[cp].cp_write)
- return 1;
- gen_set_pc_im(s->pc);
- tmp = load_reg(s, rd);
- gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
- dead_tmp(tmp);
- }
- return 0;
-}
-
-static int cp15_user_ok(uint32_t insn)
-{
- int cpn = (insn >> 16) & 0xf;
- int cpm = insn & 0xf;
- int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
-
- if (cpn == 13 && cpm == 0) {
- /* TLS register. */
- if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
- return 1;
- }
- if (cpn == 7) {
- /* ISB, DSB, DMB. */
- if ((cpm == 5 && op == 4)
- || (cpm == 10 && (op == 4 || op == 5)))
- return 1;
- }
- return 0;
-}
-
-/* Disassemble system coprocessor (cp15) instruction. Return nonzero if
- instruction is not defined. */
-static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
-{
- uint32_t rd;
- TCGv tmp;
-
- /* M profile cores use memory mapped registers instead of cp15. */
- if (arm_feature(env, ARM_FEATURE_M))
- return 1;
-
- if ((insn & (1 << 25)) == 0) {
- if (insn & (1 << 20)) {
- /* mrrc */
- return 1;
- }
- /* mcrr. Used for block cache operations, so implement as no-op. */
- return 0;
- }
- if ((insn & (1 << 4)) == 0) {
- /* cdp */
- return 1;
- }
- if (IS_USER(s) && !cp15_user_ok(insn)) {
- return 1;
- }
- if ((insn & 0x0fff0fff) == 0x0e070f90
- || (insn & 0x0fff0fff) == 0x0e070f58) {
- /* Wait for interrupt. */
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_WFI;
- return 0;
- }
- rd = (insn >> 12) & 0xf;
- if (insn & ARM_CP_RW_BIT) {
- tmp = new_tmp();
- gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
- /* If the destination register is r15 then sets condition codes. */
- if (rd != 15)
- store_reg(s, rd, tmp);
- else
- dead_tmp(tmp);
- } else {
- tmp = load_reg(s, rd);
- gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
- dead_tmp(tmp);
- /* Normally we would always end the TB here, but Linux
- * arch/arm/mach-pxa/sleep.S expects two instructions following
- * an MMU enable to execute from cache. Imitate this behaviour. */
- if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
- (insn & 0x0fff0fff) != 0x0e010f10)
- gen_lookup_tb(s);
- }
- return 0;
-}
-
-#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
-#define VFP_SREG(insn, bigbit, smallbit) \
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
-#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
- if (arm_feature(env, ARM_FEATURE_VFP3)) { \
- reg = (((insn) >> (bigbit)) & 0x0f) \
- | (((insn) >> ((smallbit) - 4)) & 0x10); \
- } else { \
- if (insn & (1 << (smallbit))) \
- return 1; \
- reg = ((insn) >> (bigbit)) & 0x0f; \
- }} while (0)
-
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
-#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
-#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
-#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
-
-/* Move between integer and VFP cores. */
-static TCGv gen_vfp_mrs(void)
-{
- TCGv tmp = new_tmp();
- tcg_gen_mov_i32(tmp, cpu_F0s);
- return tmp;
-}
-
-static void gen_vfp_msr(TCGv tmp)
-{
- tcg_gen_mov_i32(cpu_F0s, tmp);
- dead_tmp(tmp);
-}
-
-static inline int
-vfp_enabled(CPUState * env)
-{
- return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
-}
-
-static void gen_neon_dup_u8(TCGv var, int shift)
-{
- TCGv tmp = new_tmp();
- if (shift)
- tcg_gen_shri_i32(var, var, shift);
- tcg_gen_ext8u_i32(var, var);
- tcg_gen_shli_i32(tmp, var, 8);
- tcg_gen_or_i32(var, var, tmp);
- tcg_gen_shli_i32(tmp, var, 16);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
-}
-
-static void gen_neon_dup_low16(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_ext16u_i32(var, var);
- tcg_gen_shli_i32(tmp, var, 16);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
-}
-
-static void gen_neon_dup_high16(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_andi_i32(var, var, 0xffff0000);
- tcg_gen_shri_i32(tmp, var, 16);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
-}
-
-/* Disassemble a VFP instruction. Returns nonzero if an error occured
- (ie. an undefined instruction). */
-static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
-{
- uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
- int dp, veclen;
- TCGv tmp;
- TCGv tmp2;
-
- if (!arm_feature(env, ARM_FEATURE_VFP))
- return 1;
-
- if (!vfp_enabled(env)) {
- /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
- if ((insn & 0x0fe00fff) != 0x0ee00a10)
- return 1;
- rn = (insn >> 16) & 0xf;
- if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
- && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
- return 1;
- }
- dp = ((insn & 0xf00) == 0xb00);
- switch ((insn >> 24) & 0xf) {
- case 0xe:
- if (insn & (1 << 4)) {
- /* single register transfer */
- rd = (insn >> 12) & 0xf;
- if (dp) {
- int size;
- int pass;
-
- VFP_DREG_N(rn, insn);
- if (insn & 0xf)
- return 1;
- if (insn & 0x00c00060
- && !arm_feature(env, ARM_FEATURE_NEON))
- return 1;
-
- pass = (insn >> 21) & 1;
- if (insn & (1 << 22)) {
- size = 0;
- offset = ((insn >> 5) & 3) * 8;
- } else if (insn & (1 << 5)) {
- size = 1;
- offset = (insn & (1 << 6)) ? 16 : 0;
- } else {
- size = 2;
- offset = 0;
- }
- if (insn & ARM_CP_RW_BIT) {
- /* vfp->arm */
- tmp = neon_load_reg(rn, pass);
- switch (size) {
- case 0:
- if (offset)
- tcg_gen_shri_i32(tmp, tmp, offset);
- if (insn & (1 << 23))
- gen_uxtb(tmp);
- else
- gen_sxtb(tmp);
- break;
- case 1:
- if (insn & (1 << 23)) {
- if (offset) {
- tcg_gen_shri_i32(tmp, tmp, 16);
- } else {
- gen_uxth(tmp);
- }
- } else {
- if (offset) {
- tcg_gen_sari_i32(tmp, tmp, 16);
- } else {
- gen_sxth(tmp);
- }
- }
- break;
- case 2:
- break;
- }
- store_reg(s, rd, tmp);
- } else {
- /* arm->vfp */
- tmp = load_reg(s, rd);
- if (insn & (1 << 23)) {
- /* VDUP */
- if (size == 0) {
- gen_neon_dup_u8(tmp, 0);
- } else if (size == 1) {
- gen_neon_dup_low16(tmp);
- }
- tmp2 = new_tmp();
- tcg_gen_mov_i32(tmp2, tmp);
- neon_store_reg(rn, 0, tmp2);
- neon_store_reg(rn, 0, tmp);
- } else {
- /* VMOV */
- switch (size) {
- case 0:
- tmp2 = neon_load_reg(rn, pass);
- gen_bfi(tmp, tmp2, tmp, offset, 0xff);
- dead_tmp(tmp2);
- break;
- case 1:
- tmp2 = neon_load_reg(rn, pass);
- gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
- dead_tmp(tmp2);
- break;
- case 2:
- break;
- }
- neon_store_reg(rn, pass, tmp);
- }
- }
- } else { /* !dp */
- if ((insn & 0x6f) != 0x00)
- return 1;
- rn = VFP_SREG_N(insn);
- if (insn & ARM_CP_RW_BIT) {
- /* vfp->arm */
- if (insn & (1 << 21)) {
- /* system register */
- rn >>= 1;
-
- switch (rn) {
- case ARM_VFP_FPSID:
- /* VFP2 allows access to FSID from userspace.
- VFP3 restricts all id registers to privileged
- accesses. */
- if (IS_USER(s)
- && arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- tmp = load_cpu_field(vfp.xregs[rn]);
- break;
- case ARM_VFP_FPEXC:
- if (IS_USER(s))
- return 1;
- tmp = load_cpu_field(vfp.xregs[rn]);
- break;
- case ARM_VFP_FPINST:
- case ARM_VFP_FPINST2:
- /* Not present in VFP3. */
- if (IS_USER(s)
- || arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- tmp = load_cpu_field(vfp.xregs[rn]);
- break;
- case ARM_VFP_FPSCR:
- if (rd == 15) {
- tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
- tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
- } else {
- tmp = new_tmp();
- gen_helper_vfp_get_fpscr(tmp, cpu_env);
- }
- break;
- case ARM_VFP_MVFR0:
- case ARM_VFP_MVFR1:
- if (IS_USER(s)
- || !arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- tmp = load_cpu_field(vfp.xregs[rn]);
- break;
- default:
- return 1;
- }
- } else {
- gen_mov_F0_vreg(0, rn);
- tmp = gen_vfp_mrs();
- }
- if (rd == 15) {
- /* Set the 4 flag bits in the CPSR. */
- gen_set_nzcv(tmp);
- dead_tmp(tmp);
- } else {
- store_reg(s, rd, tmp);
- }
- } else {
- /* arm->vfp */
- tmp = load_reg(s, rd);
- if (insn & (1 << 21)) {
- rn >>= 1;
- /* system register */
- switch (rn) {
- case ARM_VFP_FPSID:
- case ARM_VFP_MVFR0:
- case ARM_VFP_MVFR1:
- /* Writes are ignored. */
- break;
- case ARM_VFP_FPSCR:
- gen_helper_vfp_set_fpscr(cpu_env, tmp);
- dead_tmp(tmp);
- gen_lookup_tb(s);
- break;
- case ARM_VFP_FPEXC:
- if (IS_USER(s))
- return 1;
- store_cpu_field(tmp, vfp.xregs[rn]);
- gen_lookup_tb(s);
- break;
- case ARM_VFP_FPINST:
- case ARM_VFP_FPINST2:
- store_cpu_field(tmp, vfp.xregs[rn]);
- break;
- default:
- return 1;
- }
- } else {
- gen_vfp_msr(tmp);
- gen_mov_vreg_F0(0, rn);
- }
- }
- }
- } else {
- /* data processing */
- /* The opcode is in bits 23, 21, 20 and 6. */
- op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
- if (dp) {
- if (op == 15) {
- /* rn is opcode */
- rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
- } else {
- /* rn is register number */
- VFP_DREG_N(rn, insn);
- }
-
- if (op == 15 && (rn == 15 || rn > 17)) {
- /* Integer or single precision destination. */
- rd = VFP_SREG_D(insn);
- } else {
- VFP_DREG_D(rd, insn);
- }
-
- if (op == 15 && (rn == 16 || rn == 17)) {
- /* Integer source. */
- rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
- } else {
- VFP_DREG_M(rm, insn);
- }
- } else {
- rn = VFP_SREG_N(insn);
- if (op == 15 && rn == 15) {
- /* Double precision destination. */
- VFP_DREG_D(rd, insn);
- } else {
- rd = VFP_SREG_D(insn);
- }
- rm = VFP_SREG_M(insn);
- }
-
- veclen = env->vfp.vec_len;
- if (op == 15 && rn > 3)
- veclen = 0;
-
- /* Shut up compiler warnings. */
- delta_m = 0;
- delta_d = 0;
- bank_mask = 0;
-
- if (veclen > 0) {
- if (dp)
- bank_mask = 0xc;
- else
- bank_mask = 0x18;
-
- /* Figure out what type of vector operation this is. */
- if ((rd & bank_mask) == 0) {
- /* scalar */
- veclen = 0;
- } else {
- if (dp)
- delta_d = (env->vfp.vec_stride >> 1) + 1;
- else
- delta_d = env->vfp.vec_stride + 1;
-
- if ((rm & bank_mask) == 0) {
- /* mixed scalar/vector */
- delta_m = 0;
- } else {
- /* vector */
- delta_m = delta_d;
- }
- }
- }
-
- /* Load the initial operands. */
- if (op == 15) {
- switch (rn) {
- case 16:
- case 17:
- /* Integer source */
- gen_mov_F0_vreg(0, rm);
- break;
- case 8:
- case 9:
- /* Compare */
- gen_mov_F0_vreg(dp, rd);
- gen_mov_F1_vreg(dp, rm);
- break;
- case 10:
- case 11:
- /* Compare with zero */
- gen_mov_F0_vreg(dp, rd);
- gen_vfp_F1_ld0(dp);
- break;
- case 20:
- case 21:
- case 22:
- case 23:
- /* Source and destination the same. */
- gen_mov_F0_vreg(dp, rd);
- break;
- default:
- /* One source operand. */
- gen_mov_F0_vreg(dp, rm);
- break;
- }
- } else {
- /* Two source operands. */
- gen_mov_F0_vreg(dp, rn);
- gen_mov_F1_vreg(dp, rm);
- }
-
- for (;;) {
- /* Perform the calculation. */
- switch (op) {
- case 0: /* mac: fd + (fn * fm) */
- gen_vfp_mul(dp);
- gen_mov_F1_vreg(dp, rd);
- gen_vfp_add(dp);
- break;
- case 1: /* nmac: fd - (fn * fm) */
- gen_vfp_mul(dp);
- gen_vfp_neg(dp);
- gen_mov_F1_vreg(dp, rd);
- gen_vfp_add(dp);
- break;
- case 2: /* msc: -fd + (fn * fm) */
- gen_vfp_mul(dp);
- gen_mov_F1_vreg(dp, rd);
- gen_vfp_sub(dp);
- break;
- case 3: /* nmsc: -fd - (fn * fm) */
- gen_vfp_mul(dp);
- gen_mov_F1_vreg(dp, rd);
- gen_vfp_add(dp);
- gen_vfp_neg(dp);
- break;
- case 4: /* mul: fn * fm */
- gen_vfp_mul(dp);
- break;
- case 5: /* nmul: -(fn * fm) */
- gen_vfp_mul(dp);
- gen_vfp_neg(dp);
- break;
- case 6: /* add: fn + fm */
- gen_vfp_add(dp);
- break;
- case 7: /* sub: fn - fm */
- gen_vfp_sub(dp);
- break;
- case 8: /* div: fn / fm */
- gen_vfp_div(dp);
- break;
- case 14: /* fconst */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
-
- n = (insn << 12) & 0x80000000;
- i = ((insn >> 12) & 0x70) | (insn & 0xf);
- if (dp) {
- if (i & 0x40)
- i |= 0x3f80;
- else
- i |= 0x4000;
- n |= i << 16;
- tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
- } else {
- if (i & 0x40)
- i |= 0x780;
- else
- i |= 0x800;
- n |= i << 19;
- tcg_gen_movi_i32(cpu_F0s, n);
- }
- break;
- case 15: /* extension space */
- switch (rn) {
- case 0: /* cpy */
- /* no-op */
- break;
- case 1: /* abs */
- gen_vfp_abs(dp);
- break;
- case 2: /* neg */
- gen_vfp_neg(dp);
- break;
- case 3: /* sqrt */
- gen_vfp_sqrt(dp);
- break;
- case 8: /* cmp */
- gen_vfp_cmp(dp);
- break;
- case 9: /* cmpe */
- gen_vfp_cmpe(dp);
- break;
- case 10: /* cmpz */
- gen_vfp_cmp(dp);
- break;
- case 11: /* cmpez */
- gen_vfp_F1_ld0(dp);
- gen_vfp_cmpe(dp);
- break;
- case 15: /* single<->double conversion */
- if (dp)
- gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
- else
- gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
- break;
- case 16: /* fuito */
- gen_vfp_uito(dp);
- break;
- case 17: /* fsito */
- gen_vfp_sito(dp);
- break;
- case 20: /* fshto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_shto(dp, rm);
- break;
- case 21: /* fslto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_slto(dp, rm);
- break;
- case 22: /* fuhto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_uhto(dp, rm);
- break;
- case 23: /* fulto */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_ulto(dp, rm);
- break;
- case 24: /* ftoui */
- gen_vfp_toui(dp);
- break;
- case 25: /* ftouiz */
- gen_vfp_touiz(dp);
- break;
- case 26: /* ftosi */
- gen_vfp_tosi(dp);
- break;
- case 27: /* ftosiz */
- gen_vfp_tosiz(dp);
- break;
- case 28: /* ftosh */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_tosh(dp, rm);
- break;
- case 29: /* ftosl */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_tosl(dp, rm);
- break;
- case 30: /* ftouh */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_touh(dp, rm);
- break;
- case 31: /* ftoul */
- if (!arm_feature(env, ARM_FEATURE_VFP3))
- return 1;
- gen_vfp_toul(dp, rm);
- break;
- default: /* undefined */
- printf ("rn:%d\n", rn);
- return 1;
- }
- break;
- default: /* undefined */
- printf ("op:%d\n", op);
- return 1;
- }
-
- /* Write back the result. */
- if (op == 15 && (rn >= 8 && rn <= 11))
- ; /* Comparison, do nothing. */
- else if (op == 15 && rn > 17)
- /* Integer result. */
- gen_mov_vreg_F0(0, rd);
- else if (op == 15 && rn == 15)
- /* conversion */
- gen_mov_vreg_F0(!dp, rd);
- else
- gen_mov_vreg_F0(dp, rd);
-
- /* break out of the loop if we have finished */
- if (veclen == 0)
- break;
-
- if (op == 15 && delta_m == 0) {
- /* single source one-many */
- while (veclen--) {
- rd = ((rd + delta_d) & (bank_mask - 1))
- | (rd & bank_mask);
- gen_mov_vreg_F0(dp, rd);
- }
- break;
- }
- /* Setup the next operands. */
- veclen--;
- rd = ((rd + delta_d) & (bank_mask - 1))
- | (rd & bank_mask);
-
- if (op == 15) {
- /* One source operand. */
- rm = ((rm + delta_m) & (bank_mask - 1))
- | (rm & bank_mask);
- gen_mov_F0_vreg(dp, rm);
- } else {
- /* Two source operands. */
- rn = ((rn + delta_d) & (bank_mask - 1))
- | (rn & bank_mask);
- gen_mov_F0_vreg(dp, rn);
- if (delta_m) {
- rm = ((rm + delta_m) & (bank_mask - 1))
- | (rm & bank_mask);
- gen_mov_F1_vreg(dp, rm);
- }
- }
- }
- }
- break;
- case 0xc:
- case 0xd:
- if (dp && (insn & 0x03e00000) == 0x00400000) {
- /* two-register transfer */
- rn = (insn >> 16) & 0xf;
- rd = (insn >> 12) & 0xf;
- if (dp) {
- VFP_DREG_M(rm, insn);
- } else {
- rm = VFP_SREG_M(insn);
- }
-
- if (insn & ARM_CP_RW_BIT) {
- /* vfp->arm */
- if (dp) {
- gen_mov_F0_vreg(0, rm * 2);
- tmp = gen_vfp_mrs();
- store_reg(s, rd, tmp);
- gen_mov_F0_vreg(0, rm * 2 + 1);
- tmp = gen_vfp_mrs();
- store_reg(s, rn, tmp);
- } else {
- gen_mov_F0_vreg(0, rm);
- tmp = gen_vfp_mrs();
- store_reg(s, rn, tmp);
- gen_mov_F0_vreg(0, rm + 1);
- tmp = gen_vfp_mrs();
- store_reg(s, rd, tmp);
- }
- } else {
- /* arm->vfp */
- if (dp) {
- tmp = load_reg(s, rd);
- gen_vfp_msr(tmp);
- gen_mov_vreg_F0(0, rm * 2);
- tmp = load_reg(s, rn);
- gen_vfp_msr(tmp);
- gen_mov_vreg_F0(0, rm * 2 + 1);
- } else {
- tmp = load_reg(s, rn);
- gen_vfp_msr(tmp);
- gen_mov_vreg_F0(0, rm);
- tmp = load_reg(s, rd);
- gen_vfp_msr(tmp);
- gen_mov_vreg_F0(0, rm + 1);
- }
- }
- } else {
- /* Load/store */
- rn = (insn >> 16) & 0xf;
- if (dp)
- VFP_DREG_D(rd, insn);
- else
- rd = VFP_SREG_D(insn);
- if (s->thumb && rn == 15) {
- gen_op_movl_T1_im(s->pc & ~2);
- } else {
- gen_movl_T1_reg(s, rn);
- }
- if ((insn & 0x01200000) == 0x01000000) {
- /* Single load/store */
- offset = (insn & 0xff) << 2;
- if ((insn & (1 << 23)) == 0)
- offset = -offset;
- gen_op_addl_T1_im(offset);
- if (insn & (1 << 20)) {
- gen_vfp_ld(s, dp);
- gen_mov_vreg_F0(dp, rd);
- } else {
- gen_mov_F0_vreg(dp, rd);
- gen_vfp_st(s, dp);
- }
- } else {
- /* load/store multiple */
- if (dp)
- n = (insn >> 1) & 0x7f;
- else
- n = insn & 0xff;
-
- if (insn & (1 << 24)) /* pre-decrement */
- gen_op_addl_T1_im(-((insn & 0xff) << 2));
-
- if (dp)
- offset = 8;
- else
- offset = 4;
- for (i = 0; i < n; i++) {
- if (insn & ARM_CP_RW_BIT) {
- /* load */
- gen_vfp_ld(s, dp);
- gen_mov_vreg_F0(dp, rd + i);
- } else {
- /* store */
- gen_mov_F0_vreg(dp, rd + i);
- gen_vfp_st(s, dp);
- }
- gen_op_addl_T1_im(offset);
- }
- if (insn & (1 << 21)) {
- /* writeback */
- if (insn & (1 << 24))
- offset = -offset * n;
- else if (dp && (insn & 1))
- offset = 4;
- else
- offset = 0;
-
- if (offset != 0)
- gen_op_addl_T1_im(offset);
- gen_movl_reg_T1(s, rn);
- }
- }
- }
- break;
- default:
- /* Should never happen. */
- return 1;
- }
- return 0;
-}
-
-static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
-{
- TranslationBlock *tb;
-
- tb = s->tb;
- if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
- tcg_gen_goto_tb(n);
- gen_set_pc_im(dest);
- tcg_gen_exit_tb((long)tb + n);
- } else {
- gen_set_pc_im(dest);
- tcg_gen_exit_tb(0);
- }
-}
-
-static inline void gen_jmp (DisasContext *s, uint32_t dest)
-{
- if (unlikely(s->singlestep_enabled)) {
- /* An indirect jump so that we still trigger the debug exception. */
- if (s->thumb)
- dest |= 1;
- gen_bx_im(s, dest);
- } else {
- gen_goto_tb(s, 0, dest);
- s->is_jmp = DISAS_TB_JUMP;
- }
-}
-
-static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
-{
- if (x)
- tcg_gen_sari_i32(t0, t0, 16);
- else
- gen_sxth(t0);
- if (y)
- tcg_gen_sari_i32(t1, t1, 16);
- else
- gen_sxth(t1);
- tcg_gen_mul_i32(t0, t0, t1);
-}
-
-/* Return the mask of PSR bits set by a MSR instruction. */
-static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
- uint32_t mask;
-
- mask = 0;
- if (flags & (1 << 0))
- mask |= 0xff;
- if (flags & (1 << 1))
- mask |= 0xff00;
- if (flags & (1 << 2))
- mask |= 0xff0000;
- if (flags & (1 << 3))
- mask |= 0xff000000;
-
- /* Mask out undefined bits. */
- mask &= ~CPSR_RESERVED;
- if (!arm_feature(env, ARM_FEATURE_V6))
- mask &= ~(CPSR_E | CPSR_GE);
- if (!arm_feature(env, ARM_FEATURE_THUMB2))
- mask &= ~CPSR_IT;
- /* Mask out execution state bits. */
- if (!spsr)
- mask &= ~CPSR_EXEC;
- /* Mask out privileged bits. */
- if (IS_USER(s))
- mask &= CPSR_USER;
- return mask;
-}
-
-/* Returns nonzero if access to the PSR is not permitted. */
-static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
-{
- TCGv tmp;
- if (spsr) {
- /* ??? This is also undefined in system mode. */
- if (IS_USER(s))
- return 1;
-
- tmp = load_cpu_field(spsr);
- tcg_gen_andi_i32(tmp, tmp, ~mask);
- tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
- tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
- store_cpu_field(tmp, spsr);
- } else {
- gen_set_cpsr(cpu_T[0], mask);
- }
- gen_lookup_tb(s);
- return 0;
-}
-
-/* Generate an old-style exception return. */
-static void gen_exception_return(DisasContext *s)
-{
- TCGv tmp;
- gen_movl_reg_T0(s, 15);
- tmp = load_cpu_field(spsr);
- gen_set_cpsr(tmp, 0xffffffff);
- dead_tmp(tmp);
- s->is_jmp = DISAS_UPDATE;
-}
-
-/* Generate a v6 exception return. Marks both values as dead. */
-static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
-{
- gen_set_cpsr(cpsr, 0xffffffff);
- dead_tmp(cpsr);
- store_reg(s, 15, pc);
- s->is_jmp = DISAS_UPDATE;
-}
-
-static inline void
-gen_set_condexec (DisasContext *s)
-{
- if (s->condexec_mask) {
- uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_cpu_field(tmp, condexec_bits);
- }
-}
-
-static void gen_nop_hint(DisasContext *s, int val)
-{
- switch (val) {
- case 3: /* wfi */
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_WFI;
- break;
- case 2: /* wfe */
- case 4: /* sev */
- /* TODO: Implement SEV and WFE. May help SMP performance. */
- default: /* nop */
- break;
- }
-}
-
-/* These macros help make the code more readable when migrating from the
- old dyngen helpers. They should probably be removed when
- T0/T1 are removed. */
-#define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
-#define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
-
-#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
-
-static inline int gen_neon_add(int size)
-{
- switch (size) {
- case 0: gen_helper_neon_add_u8(CPU_T001); break;
- case 1: gen_helper_neon_add_u16(CPU_T001); break;
- case 2: gen_op_addl_T0_T1(); break;
- default: return 1;
- }
- return 0;
-}
-
-static inline void gen_neon_rsb(int size)
-{
- switch (size) {
- case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
- case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
- case 2: gen_op_rsbl_T0_T1(); break;
- default: return;
- }
-}
-
-/* 32-bit pairwise ops end up the same as the elementwise versions. */
-#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
-#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
-#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
-#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
-
-/* FIXME: This is wrong. They set the wrong overflow bit. */
-#define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
-#define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
-#define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
-#define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
-
-#define GEN_NEON_INTEGER_OP_ENV(name) do { \
- switch ((size << 1) | u) { \
- case 0: \
- gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
- break; \
- case 1: \
- gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
- break; \
- case 2: \
- gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
- break; \
- case 3: \
- gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
- break; \
- case 4: \
- gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
- break; \
- case 5: \
- gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
- break; \
- default: return 1; \
- }} while (0)
-
-#define GEN_NEON_INTEGER_OP(name) do { \
- switch ((size << 1) | u) { \
- case 0: \
- gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
- break; \
- case 1: \
- gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
- break; \
- case 2: \
- gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
- break; \
- case 3: \
- gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
- break; \
- case 4: \
- gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
- break; \
- case 5: \
- gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
- break; \
- default: return 1; \
- }} while (0)
-
-static inline void
-gen_neon_movl_scratch_T0(int scratch)
-{
- uint32_t offset;
-
- offset = offsetof(CPUARMState, vfp.scratch[scratch]);
- tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
-}
-
-static inline void
-gen_neon_movl_scratch_T1(int scratch)
-{
- uint32_t offset;
-
- offset = offsetof(CPUARMState, vfp.scratch[scratch]);
- tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
-}
-
-static inline void
-gen_neon_movl_T0_scratch(int scratch)
-{
- uint32_t offset;
-
- offset = offsetof(CPUARMState, vfp.scratch[scratch]);
- tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
-}
-
-static inline void
-gen_neon_movl_T1_scratch(int scratch)
-{
- uint32_t offset;
-
- offset = offsetof(CPUARMState, vfp.scratch[scratch]);
- tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
-}
-
-static inline void gen_neon_get_scalar(int size, int reg)
-{
- if (size == 1) {
- NEON_GET_REG(T0, reg >> 1, reg & 1);
- } else {
- NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
- if (reg & 1)
- gen_neon_dup_low16(cpu_T[0]);
- else
- gen_neon_dup_high16(cpu_T[0]);
- }
-}
-
-static void gen_neon_unzip(int reg, int q, int tmp, int size)
-{
- int n;
-
- for (n = 0; n < q + 1; n += 2) {
- NEON_GET_REG(T0, reg, n);
- NEON_GET_REG(T0, reg, n + n);
- switch (size) {
- case 0: gen_helper_neon_unzip_u8(); break;
- case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same. */
- case 2: /* no-op */; break;
- default: abort();
- }
- gen_neon_movl_scratch_T0(tmp + n);
- gen_neon_movl_scratch_T1(tmp + n + 1);
- }
-}
-
-static struct {
- int nregs;
- int interleave;
- int spacing;
-} neon_ls_element_type[11] = {
- {4, 4, 1},
- {4, 4, 2},
- {4, 1, 1},
- {4, 2, 1},
- {3, 3, 1},
- {3, 3, 2},
- {3, 1, 1},
- {1, 1, 1},
- {2, 2, 1},
- {2, 2, 2},
- {2, 1, 1}
-};
-
-/* Translate a NEON load/store element instruction. Return nonzero if the
- instruction is invalid. */
-static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
-{
- int rd, rn, rm;
- int op;
- int nregs;
- int interleave;
- int stride;
- int size;
- int reg;
- int pass;
- int load;
- int shift;
- int n;
- TCGv tmp;
- TCGv tmp2;
-
- if (!vfp_enabled(env))
- return 1;
- VFP_DREG_D(rd, insn);
- rn = (insn >> 16) & 0xf;
- rm = insn & 0xf;
- load = (insn & (1 << 21)) != 0;
- if ((insn & (1 << 23)) == 0) {
- /* Load store all elements. */
- op = (insn >> 8) & 0xf;
- size = (insn >> 6) & 3;
- if (op > 10 || size == 3)
- return 1;
- nregs = neon_ls_element_type[op].nregs;
- interleave = neon_ls_element_type[op].interleave;
- gen_movl_T1_reg(s, rn);
- stride = (1 << size) * interleave;
- for (reg = 0; reg < nregs; reg++) {
- if (interleave > 2 || (interleave == 2 && nregs == 2)) {
- gen_movl_T1_reg(s, rn);
- gen_op_addl_T1_im((1 << size) * reg);
- } else if (interleave == 2 && nregs == 4 && reg == 2) {
- gen_movl_T1_reg(s, rn);
- gen_op_addl_T1_im(1 << size);
- }
- for (pass = 0; pass < 2; pass++) {
- if (size == 2) {
- if (load) {
- tmp = gen_ld32(cpu_T[1], IS_USER(s));
- neon_store_reg(rd, pass, tmp);
- } else {
- tmp = neon_load_reg(rd, pass);
- gen_st32(tmp, cpu_T[1], IS_USER(s));
- }
- gen_op_addl_T1_im(stride);
- } else if (size == 1) {
- if (load) {
- tmp = gen_ld16u(cpu_T[1], IS_USER(s));
- gen_op_addl_T1_im(stride);
- tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
- gen_op_addl_T1_im(stride);
- gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
- dead_tmp(tmp2);
- neon_store_reg(rd, pass, tmp);
- } else {
- tmp = neon_load_reg(rd, pass);
- tmp2 = new_tmp();
- tcg_gen_shri_i32(tmp2, tmp, 16);
- gen_st16(tmp, cpu_T[1], IS_USER(s));
- gen_op_addl_T1_im(stride);
- gen_st16(tmp2, cpu_T[1], IS_USER(s));
- gen_op_addl_T1_im(stride);
- }
- } else /* size == 0 */ {
- if (load) {
- TCGV_UNUSED(tmp2);
- for (n = 0; n < 4; n++) {
- tmp = gen_ld8u(cpu_T[1], IS_USER(s));
- gen_op_addl_T1_im(stride);
- if (n == 0) {
- tmp2 = tmp;
- } else {
- gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
- dead_tmp(tmp);
- }
- }
- neon_store_reg(rd, pass, tmp2);
- } else {
- tmp2 = neon_load_reg(rd, pass);
- for (n = 0; n < 4; n++) {
- tmp = new_tmp();
- if (n == 0) {
- tcg_gen_mov_i32(tmp, tmp2);
- } else {
- tcg_gen_shri_i32(tmp, tmp2, n * 8);
- }
- gen_st8(tmp, cpu_T[1], IS_USER(s));
- gen_op_addl_T1_im(stride);
- }
- dead_tmp(tmp2);
- }
- }
- }
- rd += neon_ls_element_type[op].spacing;
- }
- stride = nregs * 8;
- } else {
- size = (insn >> 10) & 3;
- if (size == 3) {
- /* Load single element to all lanes. */
- if (!load)
- return 1;
- size = (insn >> 6) & 3;
- nregs = ((insn >> 8) & 3) + 1;
- stride = (insn & (1 << 5)) ? 2 : 1;
- gen_movl_T1_reg(s, rn);
- for (reg = 0; reg < nregs; reg++) {
- switch (size) {
- case 0:
- tmp = gen_ld8u(cpu_T[1], IS_USER(s));
- gen_neon_dup_u8(tmp, 0);
- break;
- case 1:
- tmp = gen_ld16u(cpu_T[1], IS_USER(s));
- gen_neon_dup_low16(tmp);
- break;
- case 2:
- tmp = gen_ld32(cpu_T[0], IS_USER(s));
- break;
- case 3:
- return 1;
- default: /* Avoid compiler warnings. */
- abort();
- }
- gen_op_addl_T1_im(1 << size);
- tmp2 = new_tmp();
- tcg_gen_mov_i32(tmp2, tmp);
- neon_store_reg(rd, 0, tmp2);
- neon_store_reg(rd, 0, tmp);
- rd += stride;
- }
- stride = (1 << size) * nregs;
- } else {
- /* Single element. */
- pass = (insn >> 7) & 1;
- switch (size) {
- case 0:
- shift = ((insn >> 5) & 3) * 8;
- stride = 1;
- break;
- case 1:
- shift = ((insn >> 6) & 1) * 16;
- stride = (insn & (1 << 5)) ? 2 : 1;
- break;
- case 2:
- shift = 0;
- stride = (insn & (1 << 6)) ? 2 : 1;
- break;
- default:
- abort();
- }
- nregs = ((insn >> 8) & 3) + 1;
- gen_movl_T1_reg(s, rn);
- for (reg = 0; reg < nregs; reg++) {
- if (load) {
- switch (size) {
- case 0:
- tmp = gen_ld8u(cpu_T[1], IS_USER(s));
- break;
- case 1:
- tmp = gen_ld16u(cpu_T[1], IS_USER(s));
- break;
- case 2:
- tmp = gen_ld32(cpu_T[1], IS_USER(s));
- break;
- default: /* Avoid compiler warnings. */
- abort();
- }
- if (size != 2) {
- tmp2 = neon_load_reg(rd, pass);
- gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
- dead_tmp(tmp2);
- }
- neon_store_reg(rd, pass, tmp);
- } else { /* Store */
- tmp = neon_load_reg(rd, pass);
- if (shift)
- tcg_gen_shri_i32(tmp, tmp, shift);
- switch (size) {
- case 0:
- gen_st8(tmp, cpu_T[1], IS_USER(s));
- break;
- case 1:
- gen_st16(tmp, cpu_T[1], IS_USER(s));
- break;
- case 2:
- gen_st32(tmp, cpu_T[1], IS_USER(s));
- break;
- }
- }
- rd += stride;
- gen_op_addl_T1_im(1 << size);
- }
- stride = nregs * (1 << size);
- }
- }
- if (rm != 15) {
- TCGv base;
-
- base = load_reg(s, rn);
- if (rm == 13) {
- tcg_gen_addi_i32(base, base, stride);
- } else {
- TCGv index;
- index = load_reg(s, rm);
- tcg_gen_add_i32(base, base, index);
- dead_tmp(index);
- }
- store_reg(s, rn, base);
- }
- return 0;
-}
-
-/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
-static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
-{
- tcg_gen_and_i32(t, t, c);
- tcg_gen_bic_i32(f, f, c);
- tcg_gen_or_i32(dest, t, f);
-}
-
-static inline void gen_neon_narrow(int size, TCGv dest, TCGv src)
-{
- switch (size) {
- case 0: gen_helper_neon_narrow_u8(dest, src); break;
- case 1: gen_helper_neon_narrow_u16(dest, src); break;
- case 2: tcg_gen_trunc_i64_i32(dest, src); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv src)
-{
- switch (size) {
- case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
- case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
- case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv src)
-{
- switch (size) {
- case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
- case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
- case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
- int q, int u)
-{
- if (q) {
- if (u) {
- switch (size) {
- case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
- case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
- default: abort();
- }
- } else {
- switch (size) {
- case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
- case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
- default: abort();
- }
- }
- } else {
- if (u) {
- switch (size) {
- case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
- case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
- default: abort();
- }
- } else {
- switch (size) {
- case 1: gen_helper_neon_shl_s16(var, var, shift); break;
- case 2: gen_helper_neon_shl_s32(var, var, shift); break;
- default: abort();
- }
- }
- }
-}
-
-static inline void gen_neon_widen(TCGv dest, TCGv src, int size, int u)
-{
- if (u) {
- switch (size) {
- case 0: gen_helper_neon_widen_u8(dest, src); break;
- case 1: gen_helper_neon_widen_u16(dest, src); break;
- case 2: tcg_gen_extu_i32_i64(dest, src); break;
- default: abort();
- }
- } else {
- switch (size) {
- case 0: gen_helper_neon_widen_s8(dest, src); break;
- case 1: gen_helper_neon_widen_s16(dest, src); break;
- case 2: tcg_gen_ext_i32_i64(dest, src); break;
- default: abort();
- }
- }
- dead_tmp(src);
-}
-
-static inline void gen_neon_addl(int size)
-{
- switch (size) {
- case 0: gen_helper_neon_addl_u16(CPU_V001); break;
- case 1: gen_helper_neon_addl_u32(CPU_V001); break;
- case 2: tcg_gen_add_i64(CPU_V001); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_subl(int size)
-{
- switch (size) {
- case 0: gen_helper_neon_subl_u16(CPU_V001); break;
- case 1: gen_helper_neon_subl_u32(CPU_V001); break;
- case 2: tcg_gen_sub_i64(CPU_V001); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_negl(TCGv var, int size)
-{
- switch (size) {
- case 0: gen_helper_neon_negl_u16(var, var); break;
- case 1: gen_helper_neon_negl_u32(var, var); break;
- case 2: gen_helper_neon_negl_u64(var, var); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_addl_saturate(TCGv op0, TCGv op1, int size)
-{
- switch (size) {
- case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
- case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
- default: abort();
- }
-}
-
-static inline void gen_neon_mull(TCGv dest, TCGv a, TCGv b, int size, int u)
-{
- TCGv tmp;
-
- switch ((size << 1) | u) {
- case 0: gen_helper_neon_mull_s8(dest, a, b); break;
- case 1: gen_helper_neon_mull_u8(dest, a, b); break;
- case 2: gen_helper_neon_mull_s16(dest, a, b); break;
- case 3: gen_helper_neon_mull_u16(dest, a, b); break;
- case 4:
- tmp = gen_muls_i64_i32(a, b);
- tcg_gen_mov_i64(dest, tmp);
- break;
- case 5:
- tmp = gen_mulu_i64_i32(a, b);
- tcg_gen_mov_i64(dest, tmp);
- break;
- default: abort();
- }
- if (size < 2) {
- dead_tmp(b);
- dead_tmp(a);
- }
-}
-
-/* Translate a NEON data processing instruction. Return nonzero if the
- instruction is invalid.
- We process data in a mixture of 32-bit and 64-bit chunks.
- Mostly we use 32-bit chunks so we can use normal scalar instructions. */
-
-static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
-{
- int op;
- int q;
- int rd, rn, rm;
- int size;
- int shift;
- int pass;
- int count;
- int pairwise;
- int u;
- int n;
- uint32_t imm;
- TCGv tmp;
- TCGv tmp2;
- TCGv tmp3;
-
- if (!vfp_enabled(env))
- return 1;
- q = (insn & (1 << 6)) != 0;
- u = (insn >> 24) & 1;
- VFP_DREG_D(rd, insn);
- VFP_DREG_N(rn, insn);
- VFP_DREG_M(rm, insn);
- size = (insn >> 20) & 3;
- if ((insn & (1 << 23)) == 0) {
- /* Three register same length. */
- op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
- if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
- || op == 10 || op == 11 || op == 16)) {
- /* 64-bit element instructions. */
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
- neon_load_reg64(cpu_V0, rn + pass);
- neon_load_reg64(cpu_V1, rm + pass);
- switch (op) {
- case 1: /* VQADD */
- if (u) {
- gen_helper_neon_add_saturate_u64(CPU_V001);
- } else {
- gen_helper_neon_add_saturate_s64(CPU_V001);
- }
- break;
- case 5: /* VQSUB */
- if (u) {
- gen_helper_neon_sub_saturate_u64(CPU_V001);
- } else {
- gen_helper_neon_sub_saturate_s64(CPU_V001);
- }
- break;
- case 8: /* VSHL */
- if (u) {
- gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
- } else {
- gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
- }
- break;
- case 9: /* VQSHL */
- if (u) {
- gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
- cpu_V0, cpu_V0);
- } else {
- gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
- cpu_V1, cpu_V0);
- }
- break;
- case 10: /* VRSHL */
- if (u) {
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
- } else {
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
- }
- break;
- case 11: /* VQRSHL */
- if (u) {
- gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
- cpu_V1, cpu_V0);
- } else {
- gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
- cpu_V1, cpu_V0);
- }
- break;
- case 16:
- if (u) {
- tcg_gen_sub_i64(CPU_V001);
- } else {
- tcg_gen_add_i64(CPU_V001);
- }
- break;
- default:
- abort();
- }
- neon_store_reg64(cpu_V0, rd + pass);
- }
- return 0;
- }
- switch (op) {
- case 8: /* VSHL */
- case 9: /* VQSHL */
- case 10: /* VRSHL */
- case 11: /* VQRSHL */
- {
- int rtmp;
- /* Shift instruction operands are reversed. */
- rtmp = rn;
- rn = rm;
- rm = rtmp;
- pairwise = 0;
- }
- break;
- case 20: /* VPMAX */
- case 21: /* VPMIN */
- case 23: /* VPADD */
- pairwise = 1;
- break;
- case 26: /* VPADD (float) */
- pairwise = (u && size < 2);
- break;
- case 30: /* VPMIN/VPMAX (float) */
- pairwise = u;
- break;
- default:
- pairwise = 0;
- break;
- }
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
-
- if (pairwise) {
- /* Pairwise. */
- if (q)
- n = (pass & 1) * 2;
- else
- n = 0;
- if (pass < q + 1) {
- NEON_GET_REG(T0, rn, n);
- NEON_GET_REG(T1, rn, n + 1);
- } else {
- NEON_GET_REG(T0, rm, n);
- NEON_GET_REG(T1, rm, n + 1);
- }
- } else {
- /* Elementwise. */
- NEON_GET_REG(T0, rn, pass);
- NEON_GET_REG(T1, rm, pass);
- }
- switch (op) {
- case 0: /* VHADD */
- GEN_NEON_INTEGER_OP(hadd);
- break;
- case 1: /* VQADD */
- GEN_NEON_INTEGER_OP_ENV(qadd);
- break;
- case 2: /* VRHADD */
- GEN_NEON_INTEGER_OP(rhadd);
- break;
- case 3: /* Logic ops. */
- switch ((u << 2) | size) {
- case 0: /* VAND */
- gen_op_andl_T0_T1();
- break;
- case 1: /* BIC */
- gen_op_bicl_T0_T1();
- break;
- case 2: /* VORR */
- gen_op_orl_T0_T1();
- break;
- case 3: /* VORN */
- gen_op_notl_T1();
- gen_op_orl_T0_T1();
- break;
- case 4: /* VEOR */
- gen_op_xorl_T0_T1();
- break;
- case 5: /* VBSL */
- tmp = neon_load_reg(rd, pass);
- gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
- dead_tmp(tmp);
- break;
- case 6: /* VBIT */
- tmp = neon_load_reg(rd, pass);
- gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
- dead_tmp(tmp);
- break;
- case 7: /* VBIF */
- tmp = neon_load_reg(rd, pass);
- gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
- dead_tmp(tmp);
- break;
- }
- break;
- case 4: /* VHSUB */
- GEN_NEON_INTEGER_OP(hsub);
- break;
- case 5: /* VQSUB */
- GEN_NEON_INTEGER_OP_ENV(qsub);
- break;
- case 6: /* VCGT */
- GEN_NEON_INTEGER_OP(cgt);
- break;
- case 7: /* VCGE */
- GEN_NEON_INTEGER_OP(cge);
- break;
- case 8: /* VSHL */
- GEN_NEON_INTEGER_OP(shl);
- break;
- case 9: /* VQSHL */
- GEN_NEON_INTEGER_OP_ENV(qshl);
- break;
- case 10: /* VRSHL */
- GEN_NEON_INTEGER_OP(rshl);
- break;
- case 11: /* VQRSHL */
- GEN_NEON_INTEGER_OP_ENV(qrshl);
- break;
- case 12: /* VMAX */
- GEN_NEON_INTEGER_OP(max);
- break;
- case 13: /* VMIN */
- GEN_NEON_INTEGER_OP(min);
- break;
- case 14: /* VABD */
- GEN_NEON_INTEGER_OP(abd);
- break;
- case 15: /* VABA */
- GEN_NEON_INTEGER_OP(abd);
- NEON_GET_REG(T1, rd, pass);
- gen_neon_add(size);
- break;
- case 16:
- if (!u) { /* VADD */
- if (gen_neon_add(size))
- return 1;
- } else { /* VSUB */
- switch (size) {
- case 0: gen_helper_neon_sub_u8(CPU_T001); break;
- case 1: gen_helper_neon_sub_u16(CPU_T001); break;
- case 2: gen_op_subl_T0_T1(); break;
- default: return 1;
- }
- }
- break;
- case 17:
- if (!u) { /* VTST */
- switch (size) {
- case 0: gen_helper_neon_tst_u8(CPU_T001); break;
- case 1: gen_helper_neon_tst_u16(CPU_T001); break;
- case 2: gen_helper_neon_tst_u32(CPU_T001); break;
- default: return 1;
- }
- } else { /* VCEQ */
- switch (size) {
- case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
- case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
- case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
- default: return 1;
- }
- }
- break;
- case 18: /* Multiply. */
- switch (size) {
- case 0: gen_helper_neon_mul_u8(CPU_T001); break;
- case 1: gen_helper_neon_mul_u16(CPU_T001); break;
- case 2: gen_op_mul_T0_T1(); break;
- default: return 1;
- }
- NEON_GET_REG(T1, rd, pass);
- if (u) { /* VMLS */
- gen_neon_rsb(size);
- } else { /* VMLA */
- gen_neon_add(size);
- }
- break;
- case 19: /* VMUL */
- if (u) { /* polynomial */
- gen_helper_neon_mul_p8(CPU_T001);
- } else { /* Integer */
- switch (size) {
- case 0: gen_helper_neon_mul_u8(CPU_T001); break;
- case 1: gen_helper_neon_mul_u16(CPU_T001); break;
- case 2: gen_op_mul_T0_T1(); break;
- default: return 1;
- }
- }
- break;
- case 20: /* VPMAX */
- GEN_NEON_INTEGER_OP(pmax);
- break;
- case 21: /* VPMIN */
- GEN_NEON_INTEGER_OP(pmin);
- break;
- case 22: /* Hultiply high. */
- if (!u) { /* VQDMULH */
- switch (size) {
- case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
- case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
- default: return 1;
- }
- } else { /* VQRDHMUL */
- switch (size) {
- case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
- case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
- default: return 1;
- }
- }
- break;
- case 23: /* VPADD */
- if (u)
- return 1;
- switch (size) {
- case 0: gen_helper_neon_padd_u8(CPU_T001); break;
- case 1: gen_helper_neon_padd_u16(CPU_T001); break;
- case 2: gen_op_addl_T0_T1(); break;
- default: return 1;
- }
- break;
- case 26: /* Floating point arithnetic. */
- switch ((u << 2) | size) {
- case 0: /* VADD */
- gen_helper_neon_add_f32(CPU_T001);
- break;
- case 2: /* VSUB */
- gen_helper_neon_sub_f32(CPU_T001);
- break;
- case 4: /* VPADD */
- gen_helper_neon_add_f32(CPU_T001);
- break;
- case 6: /* VABD */
- gen_helper_neon_abd_f32(CPU_T001);
- break;
- default:
- return 1;
- }
- break;
- case 27: /* Float multiply. */
- gen_helper_neon_mul_f32(CPU_T001);
- if (!u) {
- NEON_GET_REG(T1, rd, pass);
- if (size == 0) {
- gen_helper_neon_add_f32(CPU_T001);
- } else {
- gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
- }
- }
- break;
- case 28: /* Float compare. */
- if (!u) {
- gen_helper_neon_ceq_f32(CPU_T001);
- } else {
- if (size == 0)
- gen_helper_neon_cge_f32(CPU_T001);
- else
- gen_helper_neon_cgt_f32(CPU_T001);
- }
- break;
- case 29: /* Float compare absolute. */
- if (!u)
- return 1;
- if (size == 0)
- gen_helper_neon_acge_f32(CPU_T001);
- else
- gen_helper_neon_acgt_f32(CPU_T001);
- break;
- case 30: /* Float min/max. */
- if (size == 0)
- gen_helper_neon_max_f32(CPU_T001);
- else
- gen_helper_neon_min_f32(CPU_T001);
- break;
- case 31:
- if (size == 0)
- gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
- else
- gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
- break;
- default:
- abort();
- }
- /* Save the result. For elementwise operations we can put it
- straight into the destination register. For pairwise operations
- we have to be careful to avoid clobbering the source operands. */
- if (pairwise && rd == rm) {
- gen_neon_movl_scratch_T0(pass);
- } else {
- NEON_SET_REG(T0, rd, pass);
- }
-
- } /* for pass */
- if (pairwise && rd == rm) {
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- gen_neon_movl_T0_scratch(pass);
- NEON_SET_REG(T0, rd, pass);
- }
- }
- /* End of 3 register same size operations. */
- } else if (insn & (1 << 4)) {
- if ((insn & 0x00380080) != 0) {
- /* Two registers and shift. */
- op = (insn >> 8) & 0xf;
- if (insn & (1 << 7)) {
- /* 64-bit shift. */
- size = 3;
- } else {
- size = 2;
- while ((insn & (1 << (size + 19))) == 0)
- size--;
- }
- shift = (insn >> 16) & ((1 << (3 + size)) - 1);
- /* To avoid excessive dumplication of ops we implement shift
- by immediate using the variable shift operations. */
- if (op < 8) {
- /* Shift by immediate:
- VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
- /* Right shifts are encoded as N - shift, where N is the
- element size in bits. */
- if (op <= 4)
- shift = shift - (1 << (size + 3));
- if (size == 3) {
- count = q + 1;
- } else {
- count = q ? 4: 2;
- }
- switch (size) {
- case 0:
- imm = (uint8_t) shift;
- imm |= imm << 8;
- imm |= imm << 16;
- break;
- case 1:
- imm = (uint16_t) shift;
- imm |= imm << 16;
- break;
- case 2:
- case 3:
- imm = shift;
- break;
- default:
- abort();
- }
-
- for (pass = 0; pass < count; pass++) {
- if (size == 3) {
- neon_load_reg64(cpu_V0, rm + pass);
- tcg_gen_movi_i64(cpu_V1, imm);
- switch (op) {
- case 0: /* VSHR */
- case 1: /* VSRA */
- if (u)
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
- else
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
- break;
- case 2: /* VRSHR */
- case 3: /* VRSRA */
- if (u)
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
- else
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
- break;
- case 4: /* VSRI */
- if (!u)
- return 1;
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
- break;
- case 5: /* VSHL, VSLI */
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
- break;
- case 6: /* VQSHL */
- if (u)
- gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
- else
- gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
- break;
- case 7: /* VQSHLU */
- gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
- break;
- }
- if (op == 1 || op == 3) {
- /* Accumulate. */
- neon_load_reg64(cpu_V0, rd + pass);
- tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
- } else if (op == 4 || (op == 5 && u)) {
- /* Insert */
- cpu_abort(env, "VS[LR]I.64 not implemented");
- }
- neon_store_reg64(cpu_V0, rd + pass);
- } else { /* size < 3 */
- /* Operands in T0 and T1. */
- gen_op_movl_T1_im(imm);
- NEON_GET_REG(T0, rm, pass);
- switch (op) {
- case 0: /* VSHR */
- case 1: /* VSRA */
- GEN_NEON_INTEGER_OP(shl);
- break;
- case 2: /* VRSHR */
- case 3: /* VRSRA */
- GEN_NEON_INTEGER_OP(rshl);
- break;
- case 4: /* VSRI */
- if (!u)
- return 1;
- GEN_NEON_INTEGER_OP(shl);
- break;
- case 5: /* VSHL, VSLI */
- switch (size) {
- case 0: gen_helper_neon_shl_u8(CPU_T001); break;
- case 1: gen_helper_neon_shl_u16(CPU_T001); break;
- case 2: gen_helper_neon_shl_u32(CPU_T001); break;
- default: return 1;
- }
- break;
- case 6: /* VQSHL */
- GEN_NEON_INTEGER_OP_ENV(qshl);
- break;
- case 7: /* VQSHLU */
- switch (size) {
- case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
- case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
- case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
- default: return 1;
- }
- break;
- }
-
- if (op == 1 || op == 3) {
- /* Accumulate. */
- NEON_GET_REG(T1, rd, pass);
- gen_neon_add(size);
- } else if (op == 4 || (op == 5 && u)) {
- /* Insert */
- switch (size) {
- case 0:
- if (op == 4)
- imm = 0xff >> -shift;
- else
- imm = (uint8_t)(0xff << shift);
- imm |= imm << 8;
- imm |= imm << 16;
- break;
- case 1:
- if (op == 4)
- imm = 0xffff >> -shift;
- else
- imm = (uint16_t)(0xffff << shift);
- imm |= imm << 16;
- break;
- case 2:
- if (op == 4)
- imm = 0xffffffffu >> -shift;
- else
- imm = 0xffffffffu << shift;
- break;
- default:
- abort();
- }
- tmp = neon_load_reg(rd, pass);
- tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
- tcg_gen_andi_i32(tmp, tmp, ~imm);
- tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
- }
- NEON_SET_REG(T0, rd, pass);
- }
- } /* for pass */
- } else if (op < 10) {
- /* Shift by immediate and narrow:
- VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
- shift = shift - (1 << (size + 3));
- size++;
- switch (size) {
- case 1:
- imm = (uint16_t)shift;
- imm |= imm << 16;
- tmp2 = tcg_const_i32(imm);
- break;
- case 2:
- imm = (uint32_t)shift;
- tmp2 = tcg_const_i32(imm);
- case 3:
- tmp2 = tcg_const_i64(shift);
- break;
- default:
- abort();
- }
-
- for (pass = 0; pass < 2; pass++) {
- if (size == 3) {
- neon_load_reg64(cpu_V0, rm + pass);
- if (q) {
- if (u)
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp2);
- else
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp2);
- } else {
- if (u)
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp2);
- else
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp2);
- }
- } else {
- tmp = neon_load_reg(rm + pass, 0);
- gen_neon_shift_narrow(size, tmp, tmp2, q, u);
- tcg_gen_extu_i32_i64(cpu_V0, tmp);
- dead_tmp(tmp);
- tmp = neon_load_reg(rm + pass, 1);
- gen_neon_shift_narrow(size, tmp, tmp2, q, u);
- tcg_gen_extu_i32_i64(cpu_V1, tmp);
- dead_tmp(tmp);
- tcg_gen_shli_i64(cpu_V1, cpu_V1, 32);
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
- }
- tmp = new_tmp();
- if (op == 8 && !u) {
- gen_neon_narrow(size - 1, tmp, cpu_V0);
- } else {
- if (op == 8)
- gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
- else
- gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
- }
- if (pass == 0) {
- tmp2 = tmp;
- } else {
- neon_store_reg(rd, 0, tmp2);
- neon_store_reg(rd, 1, tmp);
- }
- } /* for pass */
- } else if (op == 10) {
- /* VSHLL */
- if (q || size == 3)
- return 1;
- tmp = neon_load_reg(rm, 0);
- tmp2 = neon_load_reg(rm, 1);
- for (pass = 0; pass < 2; pass++) {
- if (pass == 1)
- tmp = tmp2;
-
- gen_neon_widen(cpu_V0, tmp, size, u);
-
- if (shift != 0) {
- /* The shift is less than the width of the source
- type, so we can just shift the whole register. */
- tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
- if (size < 2 || !u) {
- uint64_t imm64;
- if (size == 0) {
- imm = (0xffu >> (8 - shift));
- imm |= imm << 16;
- } else {
- imm = 0xffff >> (16 - shift);
- }
- imm64 = imm | (((uint64_t)imm) << 32);
- tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
- }
- }
- neon_store_reg64(cpu_V0, rd + pass);
- }
- } else if (op == 15 || op == 16) {
- /* VCVT fixed-point. */
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
- if (op & 1) {
- if (u)
- gen_vfp_ulto(0, shift);
- else
- gen_vfp_slto(0, shift);
- } else {
- if (u)
- gen_vfp_toul(0, shift);
- else
- gen_vfp_tosl(0, shift);
- }
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
- }
- } else {
- return 1;
- }
- } else { /* (insn & 0x00380080) == 0 */
- int invert;
-
- op = (insn >> 8) & 0xf;
- /* One register and immediate. */
- imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
- invert = (insn & (1 << 5)) != 0;
- switch (op) {
- case 0: case 1:
- /* no-op */
- break;
- case 2: case 3:
- imm <<= 8;
- break;
- case 4: case 5:
- imm <<= 16;
- break;
- case 6: case 7:
- imm <<= 24;
- break;
- case 8: case 9:
- imm |= imm << 16;
- break;
- case 10: case 11:
- imm = (imm << 8) | (imm << 24);
- break;
- case 12:
- imm = (imm < 8) | 0xff;
- break;
- case 13:
- imm = (imm << 16) | 0xffff;
- break;
- case 14:
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
- if (invert)
- imm = ~imm;
- break;
- case 15:
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
- break;
- }
- if (invert)
- imm = ~imm;
-
- if (op != 14 || !invert)
- gen_op_movl_T1_im(imm);
-
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- if (op & 1 && op < 12) {
- tmp = neon_load_reg(rd, pass);
- if (invert) {
- /* The immediate value has already been inverted, so
- BIC becomes AND. */
- tcg_gen_andi_i32(tmp, tmp, imm);
- } else {
- tcg_gen_ori_i32(tmp, tmp, imm);
- }
- } else {
- /* VMOV, VMVN. */
- tmp = new_tmp();
- if (op == 14 && invert) {
- uint32_t val;
- val = 0;
- for (n = 0; n < 4; n++) {
- if (imm & (1 << (n + (pass & 1) * 4)))
- val |= 0xff << (n * 8);
- }
- tcg_gen_movi_i32(tmp, val);
- } else {
- tcg_gen_movi_i32(tmp, imm);
- }
- }
- neon_store_reg(rd, pass, tmp);
- }
- }
- } else { /* (insn & 0x00800010 == 0x00800010) */
- if (size != 3) {
- op = (insn >> 8) & 0xf;
- if ((insn & (1 << 6)) == 0) {
- /* Three registers of different lengths. */
- int src1_wide;
- int src2_wide;
- int prewiden;
- /* prewiden, src1_wide, src2_wide */
- static const int neon_3reg_wide[16][3] = {
- {1, 0, 0}, /* VADDL */
- {1, 1, 0}, /* VADDW */
- {1, 0, 0}, /* VSUBL */
- {1, 1, 0}, /* VSUBW */
- {0, 1, 1}, /* VADDHN */
- {0, 0, 0}, /* VABAL */
- {0, 1, 1}, /* VSUBHN */
- {0, 0, 0}, /* VABDL */
- {0, 0, 0}, /* VMLAL */
- {0, 0, 0}, /* VQDMLAL */
- {0, 0, 0}, /* VMLSL */
- {0, 0, 0}, /* VQDMLSL */
- {0, 0, 0}, /* Integer VMULL */
- {0, 0, 0}, /* VQDMULL */
- {0, 0, 0} /* Polynomial VMULL */
- };
-
- prewiden = neon_3reg_wide[op][0];
- src1_wide = neon_3reg_wide[op][1];
- src2_wide = neon_3reg_wide[op][2];
-
- if (size == 0 && (op == 9 || op == 11 || op == 13))
- return 1;
-
- /* Avoid overlapping operands. Wide source operands are
- always aligned so will never overlap with wide
- destinations in problematic ways. */
- if (rd == rm && !src2_wide) {
- NEON_GET_REG(T0, rm, 1);
- gen_neon_movl_scratch_T0(2);
- } else if (rd == rn && !src1_wide) {
- NEON_GET_REG(T0, rn, 1);
- gen_neon_movl_scratch_T0(2);
- }
- TCGV_UNUSED(tmp3);
- for (pass = 0; pass < 2; pass++) {
- if (src1_wide) {
- neon_load_reg64(cpu_V0, rn + pass);
- TCGV_UNUSED(tmp);
- } else {
- if (pass == 1 && rd == rn) {
- gen_neon_movl_T0_scratch(2);
- tmp = new_tmp();
- tcg_gen_mov_i32(tmp, cpu_T[0]);
- } else {
- tmp = neon_load_reg(rn, pass);
- }
- if (prewiden) {
- gen_neon_widen(cpu_V0, tmp, size, u);
- }
- }
- if (src2_wide) {
- neon_load_reg64(cpu_V1, rm + pass);
- TCGV_UNUSED(tmp2);
- } else {
- if (pass == 1 && rd == rm) {
- gen_neon_movl_T0_scratch(2);
- tmp2 = new_tmp();
- tcg_gen_mov_i32(tmp2, cpu_T[0]);
- } else {
- tmp2 = neon_load_reg(rm, pass);
- }
- if (prewiden) {
- gen_neon_widen(cpu_V1, tmp2, size, u);
- }
- }
- switch (op) {
- case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
- gen_neon_addl(size);
- break;
- case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
- gen_neon_subl(size);
- break;
- case 5: case 7: /* VABAL, VABDL */
- switch ((size << 1) | u) {
- case 0:
- gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
- break;
- case 1:
- gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
- break;
- case 2:
- gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
- break;
- case 3:
- gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
- break;
- case 4:
- gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
- break;
- case 5:
- gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
- break;
- default: abort();
- }
- dead_tmp(tmp2);
- dead_tmp(tmp);
- break;
- case 8: case 9: case 10: case 11: case 12: case 13:
- /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
- gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
- break;
- case 14: /* Polynomial VMULL */
- cpu_abort(env, "Polynomial VMULL not implemented");
-
- default: /* 15 is RESERVED. */
- return 1;
- }
- if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
- /* Accumulate. */
- if (op == 10 || op == 11) {
- gen_neon_negl(cpu_V0, size);
- }
-
- if (op != 13) {
- neon_load_reg64(cpu_V1, rd + pass);
- }
-
- switch (op) {
- case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
- gen_neon_addl(size);
- break;
- case 9: case 11: /* VQDMLAL, VQDMLSL */
- gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
- break;
- /* Fall through. */
- case 13: /* VQDMULL */
- gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- break;
- default:
- abort();
- }
- neon_store_reg64(cpu_V0, rd + pass);
- } else if (op == 4 || op == 6) {
- /* Narrowing operation. */
- tmp = new_tmp();
- if (u) {
- switch (size) {
- case 0:
- gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
- break;
- case 1:
- gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
- break;
- case 2:
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
- tcg_gen_trunc_i64_i32(tmp, cpu_V0);
- break;
- default: abort();
- }
- } else {
- switch (size) {
- case 0:
- gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
- break;
- case 1:
- gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
- break;
- case 2:
- tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
- tcg_gen_trunc_i64_i32(tmp, cpu_V0);
- break;
- default: abort();
- }
- }
- if (pass == 0) {
- tmp3 = tmp;
- } else {
- neon_store_reg(rd, 0, tmp3);
- neon_store_reg(rd, 1, tmp);
- }
- } else {
- /* Write back the result. */
- neon_store_reg64(cpu_V0, rd + pass);
- }
- }
- } else {
- /* Two registers and a scalar. */
- switch (op) {
- case 0: /* Integer VMLA scalar */
- case 1: /* Float VMLA scalar */
- case 4: /* Integer VMLS scalar */
- case 5: /* Floating point VMLS scalar */
- case 8: /* Integer VMUL scalar */
- case 9: /* Floating point VMUL scalar */
- case 12: /* VQDMULH scalar */
- case 13: /* VQRDMULH scalar */
- gen_neon_get_scalar(size, rm);
- gen_neon_movl_scratch_T0(0);
- for (pass = 0; pass < (u ? 4 : 2); pass++) {
- if (pass != 0)
- gen_neon_movl_T0_scratch(0);
- NEON_GET_REG(T1, rn, pass);
- if (op == 12) {
- if (size == 1) {
- gen_helper_neon_qdmulh_s16(CPU_T0E01);
- } else {
- gen_helper_neon_qdmulh_s32(CPU_T0E01);
- }
- } else if (op == 13) {
- if (size == 1) {
- gen_helper_neon_qrdmulh_s16(CPU_T0E01);
- } else {
- gen_helper_neon_qrdmulh_s32(CPU_T0E01);
- }
- } else if (op & 1) {
- gen_helper_neon_mul_f32(CPU_T001);
- } else {
- switch (size) {
- case 0: gen_helper_neon_mul_u8(CPU_T001); break;
- case 1: gen_helper_neon_mul_u16(CPU_T001); break;
- case 2: gen_op_mul_T0_T1(); break;
- default: return 1;
- }
- }
- if (op < 8) {
- /* Accumulate. */
- NEON_GET_REG(T1, rd, pass);
- switch (op) {
- case 0:
- gen_neon_add(size);
- break;
- case 1:
- gen_helper_neon_add_f32(CPU_T001);
- break;
- case 4:
- gen_neon_rsb(size);
- break;
- case 5:
- gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
- break;
- default:
- abort();
- }
- }
- NEON_SET_REG(T0, rd, pass);
- }
- break;
- case 2: /* VMLAL sclar */
- case 3: /* VQDMLAL scalar */
- case 6: /* VMLSL scalar */
- case 7: /* VQDMLSL scalar */
- case 10: /* VMULL scalar */
- case 11: /* VQDMULL scalar */
- if (size == 0 && (op == 3 || op == 7 || op == 11))
- return 1;
-
- gen_neon_get_scalar(size, rm);
- NEON_GET_REG(T1, rn, 1);
-
- for (pass = 0; pass < 2; pass++) {
- if (pass == 0) {
- tmp = neon_load_reg(rn, 0);
- } else {
- tmp = new_tmp();
- tcg_gen_mov_i32(tmp, cpu_T[1]);
- }
- tmp2 = new_tmp();
- tcg_gen_mov_i32(tmp2, cpu_T[0]);
- gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
- if (op == 6 || op == 7) {
- gen_neon_negl(cpu_V0, size);
- }
- if (op != 11) {
- neon_load_reg64(cpu_V1, rd + pass);
- }
- switch (op) {
- case 2: case 6:
- gen_neon_addl(size);
- break;
- case 3: case 7:
- gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
- break;
- case 10:
- /* no-op */
- break;
- case 11:
- gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
- break;
- default:
- abort();
- }
- neon_store_reg64(cpu_V0, rd + pass);
- }
- break;
- default: /* 14 and 15 are RESERVED */
- return 1;
- }
- }
- } else { /* size == 3 */
- if (!u) {
- /* Extract. */
- imm = (insn >> 8) & 0xf;
- count = q + 1;
-
- if (imm > 7 && !q)
- return 1;
-
- if (imm == 0) {
- neon_load_reg64(cpu_V0, rn);
- if (q) {
- neon_load_reg64(cpu_V1, rn + 1);
- }
- } else if (imm == 8) {
- neon_load_reg64(cpu_V0, rn + 1);
- if (q) {
- neon_load_reg64(cpu_V1, rm);
- }
- } else if (q) {
- tmp = tcg_temp_new(TCG_TYPE_I64);
- if (imm < 8) {
- neon_load_reg64(cpu_V0, rn);
- neon_load_reg64(tmp, rn + 1);
- } else {
- neon_load_reg64(cpu_V0, rn + 1);
- neon_load_reg64(tmp, rm);
- }
- tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
- tcg_gen_shli_i64(cpu_V1, tmp, 64 - ((imm & 7) * 8));
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
- if (imm < 8) {
- neon_load_reg64(cpu_V1, rm);
- } else {
- neon_load_reg64(cpu_V1, rm + 1);
- imm -= 8;
- }
- tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
- tcg_gen_shri_i64(tmp, tmp, imm * 8);
- tcg_gen_or_i64(cpu_V1, cpu_V1, tmp);
- } else {
- neon_load_reg64(cpu_V0, rn);
- tcg_gen_shri_i32(cpu_V0, cpu_V0, imm * 8);
- neon_load_reg64(cpu_V1, rm);
- tcg_gen_shli_i32(cpu_V1, cpu_V1, 64 - (imm * 8));
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
- }
- neon_store_reg64(cpu_V0, rd);
- if (q) {
- neon_store_reg64(cpu_V1, rd + 1);
- }
- } else if ((insn & (1 << 11)) == 0) {
- /* Two register misc. */
- op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
- size = (insn >> 18) & 3;
- switch (op) {
- case 0: /* VREV64 */
- if (size == 3)
- return 1;
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
- NEON_GET_REG(T0, rm, pass * 2);
- NEON_GET_REG(T1, rm, pass * 2 + 1);
- switch (size) {
- case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
- case 1: gen_swap_half(cpu_T[0]); break;
- case 2: /* no-op */ break;
- default: abort();
- }
- NEON_SET_REG(T0, rd, pass * 2 + 1);
- if (size == 2) {
- NEON_SET_REG(T1, rd, pass * 2);
- } else {
- gen_op_movl_T0_T1();
- switch (size) {
- case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
- case 1: gen_swap_half(cpu_T[0]); break;
- default: abort();
- }
- NEON_SET_REG(T0, rd, pass * 2);
- }
- }
- break;
- case 4: case 5: /* VPADDL */
- case 12: case 13: /* VPADAL */
- if (size == 3)
- return 1;
- for (pass = 0; pass < q + 1; pass++) {
- tmp = neon_load_reg(rm, pass * 2);
- gen_neon_widen(cpu_V0, tmp, size, op & 1);
- tmp = neon_load_reg(rm, pass * 2 + 1);
- gen_neon_widen(cpu_V1, tmp, size, op & 1);
- switch (size) {
- case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
- case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
- case 2: tcg_gen_add_i64(CPU_V001); break;
- default: abort();
- }
- if (op >= 12) {
- /* Accumulate. */
- neon_load_reg64(cpu_V1, rd + pass);
- gen_neon_addl(size);
- }
- neon_store_reg64(cpu_V0, rd + pass);
- }
- break;
- case 33: /* VTRN */
- if (size == 2) {
- for (n = 0; n < (q ? 4 : 2); n += 2) {
- NEON_GET_REG(T0, rm, n);
- NEON_GET_REG(T1, rd, n + 1);
- NEON_SET_REG(T1, rm, n);
- NEON_SET_REG(T0, rd, n + 1);
- }
- } else {
- goto elementwise;
- }
- break;
- case 34: /* VUZP */
- /* Reg Before After
- Rd A3 A2 A1 A0 B2 B0 A2 A0
- Rm B3 B2 B1 B0 B3 B1 A3 A1
- */
- if (size == 3)
- return 1;
- gen_neon_unzip(rd, q, 0, size);
- gen_neon_unzip(rm, q, 4, size);
- if (q) {
- static int unzip_order_q[8] =
- {0, 2, 4, 6, 1, 3, 5, 7};
- for (n = 0; n < 8; n++) {
- int reg = (n < 4) ? rd : rm;
- gen_neon_movl_T0_scratch(unzip_order_q[n]);
- NEON_SET_REG(T0, reg, n % 4);
- }
- } else {
- static int unzip_order[4] =
- {0, 4, 1, 5};
- for (n = 0; n < 4; n++) {
- int reg = (n < 2) ? rd : rm;
- gen_neon_movl_T0_scratch(unzip_order[n]);
- NEON_SET_REG(T0, reg, n % 2);
- }
- }
- break;
- case 35: /* VZIP */
- /* Reg Before After
- Rd A3 A2 A1 A0 B1 A1 B0 A0
- Rm B3 B2 B1 B0 B3 A3 B2 A2
- */
- if (size == 3)
- return 1;
- count = (q ? 4 : 2);
- for (n = 0; n < count; n++) {
- NEON_GET_REG(T0, rd, n);
- NEON_GET_REG(T1, rd, n);
- switch (size) {
- case 0: gen_helper_neon_zip_u8(); break;
- case 1: gen_helper_neon_zip_u16(); break;
- case 2: /* no-op */; break;
- default: abort();
- }
- gen_neon_movl_scratch_T0(n * 2);
- gen_neon_movl_scratch_T1(n * 2 + 1);
- }
- for (n = 0; n < count * 2; n++) {
- int reg = (n < count) ? rd : rm;
- gen_neon_movl_T0_scratch(n);
- NEON_SET_REG(T0, reg, n % count);
- }
- break;
- case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
- if (size == 3)
- return 1;
- TCGV_UNUSED(tmp2);
- for (pass = 0; pass < 2; pass++) {
- neon_load_reg64(cpu_V0, rm + pass);
- tmp = new_tmp();
- if (op == 36 && q == 0) {
- gen_neon_narrow(size, tmp, cpu_V0);
- } else if (q) {
- gen_neon_narrow_satu(size, tmp, cpu_V0);
- } else {
- gen_neon_narrow_sats(size, tmp, cpu_V0);
- }
- if (pass == 0) {
- tmp2 = tmp;
- } else {
- neon_store_reg(rd, 0, tmp2);
- neon_store_reg(rd, 1, tmp);
- }
- }
- break;
- case 38: /* VSHLL */
- if (q || size == 3)
- return 1;
- tmp = neon_load_reg(rm, 0);
- tmp2 = neon_load_reg(rm, 1);
- for (pass = 0; pass < 2; pass++) {
- if (pass == 1)
- tmp = tmp2;
- gen_neon_widen(cpu_V0, tmp, size, 1);
- neon_store_reg64(cpu_V0, rd + pass);
- }
- break;
- default:
- elementwise:
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- if (op == 30 || op == 31 || op >= 58) {
- tcg_gen_ld_f32(cpu_F0s, cpu_env,
- neon_reg_offset(rm, pass));
- } else {
- NEON_GET_REG(T0, rm, pass);
- }
- switch (op) {
- case 1: /* VREV32 */
- switch (size) {
- case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
- case 1: gen_swap_half(cpu_T[0]); break;
- default: return 1;
- }
- break;
- case 2: /* VREV16 */
- if (size != 0)
- return 1;
- gen_rev16(cpu_T[0]);
- break;
- case 8: /* CLS */
- switch (size) {
- case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
- case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
- case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
- default: return 1;
- }
- break;
- case 9: /* CLZ */
- switch (size) {
- case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
- case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
- case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
- default: return 1;
- }
- break;
- case 10: /* CNT */
- if (size != 0)
- return 1;
- gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
- break;
- case 11: /* VNOT */
- if (size != 0)
- return 1;
- gen_op_notl_T0();
- break;
- case 14: /* VQABS */
- switch (size) {
- case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
- case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
- case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
- default: return 1;
- }
- break;
- case 15: /* VQNEG */
- switch (size) {
- case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
- case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
- case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
- default: return 1;
- }
- break;
- case 16: case 19: /* VCGT #0, VCLE #0 */
- gen_op_movl_T1_im(0);
- switch(size) {
- case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
- case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
- case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
- default: return 1;
- }
- if (op == 19)
- gen_op_notl_T0();
- break;
- case 17: case 20: /* VCGE #0, VCLT #0 */
- gen_op_movl_T1_im(0);
- switch(size) {
- case 0: gen_helper_neon_cge_s8(CPU_T001); break;
- case 1: gen_helper_neon_cge_s16(CPU_T001); break;
- case 2: gen_helper_neon_cge_s32(CPU_T001); break;
- default: return 1;
- }
- if (op == 20)
- gen_op_notl_T0();
- break;
- case 18: /* VCEQ #0 */
- gen_op_movl_T1_im(0);
- switch(size) {
- case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
- case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
- case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
- default: return 1;
- }
- break;
- case 22: /* VABS */
- switch(size) {
- case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
- case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
- case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
- default: return 1;
- }
- break;
- case 23: /* VNEG */
- gen_op_movl_T1_im(0);
- if (size == 3)
- return 1;
- gen_neon_rsb(size);
- break;
- case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
- gen_op_movl_T1_im(0);
- gen_helper_neon_cgt_f32(CPU_T001);
- if (op == 27)
- gen_op_notl_T0();
- break;
- case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
- gen_op_movl_T1_im(0);
- gen_helper_neon_cge_f32(CPU_T001);
- if (op == 28)
- gen_op_notl_T0();
- break;
- case 26: /* Float VCEQ #0 */
- gen_op_movl_T1_im(0);
- gen_helper_neon_ceq_f32(CPU_T001);
- break;
- case 30: /* Float VABS */
- gen_vfp_abs(0);
- break;
- case 31: /* Float VNEG */
- gen_vfp_neg(0);
- break;
- case 32: /* VSWP */
- NEON_GET_REG(T1, rd, pass);
- NEON_SET_REG(T1, rm, pass);
- break;
- case 33: /* VTRN */
- NEON_GET_REG(T1, rd, pass);
- switch (size) {
- case 0: gen_helper_neon_trn_u8(); break;
- case 1: gen_helper_neon_trn_u16(); break;
- case 2: abort();
- default: return 1;
- }
- NEON_SET_REG(T1, rm, pass);
- break;
- case 56: /* Integer VRECPE */
- gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
- break;
- case 57: /* Integer VRSQRTE */
- gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
- break;
- case 58: /* Float VRECPE */
- gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
- break;
- case 59: /* Float VRSQRTE */
- gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
- break;
- case 60: /* VCVT.F32.S32 */
- gen_vfp_tosiz(0);
- break;
- case 61: /* VCVT.F32.U32 */
- gen_vfp_touiz(0);
- break;
- case 62: /* VCVT.S32.F32 */
- gen_vfp_sito(0);
- break;
- case 63: /* VCVT.U32.F32 */
- gen_vfp_uito(0);
- break;
- default:
- /* Reserved: 21, 29, 39-56 */
- return 1;
- }
- if (op == 30 || op == 31 || op >= 58) {
- tcg_gen_st_f32(cpu_F0s, cpu_env,
- neon_reg_offset(rd, pass));
- } else {
- NEON_SET_REG(T0, rd, pass);
- }
- }
- break;
- }
- } else if ((insn & (1 << 10)) == 0) {
- /* VTBL, VTBX. */
- n = (insn >> 5) & 0x18;
- if (insn & (1 << 6)) {
- tmp = neon_load_reg(rd, 0);
- } else {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- }
- tmp2 = neon_load_reg(rm, 0);
- gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
- tcg_const_i32(n));
- if (insn & (1 << 6)) {
- tmp = neon_load_reg(rd, 1);
- } else {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- }
- tmp3 = neon_load_reg(rm, 1);
- gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
- tcg_const_i32(n));
- neon_store_reg(rd, 0, tmp2);
- neon_store_reg(rd, 1, tmp2);
- } else if ((insn & 0x380) == 0) {
- /* VDUP */
- if (insn & (1 << 19)) {
- NEON_SET_REG(T0, rm, 1);
- } else {
- NEON_SET_REG(T0, rm, 0);
- }
- if (insn & (1 << 16)) {
- gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
- } else if (insn & (1 << 17)) {
- if ((insn >> 18) & 1)
- gen_neon_dup_high16(cpu_T[0]);
- else
- gen_neon_dup_low16(cpu_T[0]);
- }
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- NEON_SET_REG(T0, rd, pass);
- }
- } else {
- return 1;
- }
- }
- }
- return 0;
-}
-
-static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
-{
- int cpnum;
-
- cpnum = (insn >> 8) & 0xf;
- if (arm_feature(env, ARM_FEATURE_XSCALE)
- && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
- return 1;
-
- switch (cpnum) {
- case 0:
- case 1:
- if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
- return disas_iwmmxt_insn(env, s, insn);
- } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- return disas_dsp_insn(env, s, insn);
- }
- return 1;
- case 10:
- case 11:
- return disas_vfp_insn (env, s, insn);
- case 15:
- return disas_cp15_insn (env, s, insn);
- default:
- /* Unknown coprocessor. See if the board has hooked it. */
- return disas_cp_insn (env, s, insn);
- }
-}
-
-
-/* Store a 64-bit value to a register pair. Clobbers val. */
-static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
-{
- TCGv tmp;
- tmp = new_tmp();
- tcg_gen_trunc_i64_i32(tmp, val);
- store_reg(s, rlow, tmp);
- tmp = new_tmp();
- tcg_gen_shri_i64(val, val, 32);
- tcg_gen_trunc_i64_i32(tmp, val);
- store_reg(s, rhigh, tmp);
-}
-
-/* load a 32-bit value from a register and perform a 64-bit accumulate. */
-static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
-{
- TCGv tmp;
- TCGv tmp2;
-
- /* Load 64-bit value rd:rn. */
- tmp = tcg_temp_new(TCG_TYPE_I64);
- tmp2 = load_reg(s, rlow);
- tcg_gen_extu_i32_i64(tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_add_i64(val, val, tmp);
-}
-
-/* load and add a 64-bit value from a register pair. */
-static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
-{
- TCGv tmp;
- TCGv tmp2;
-
- /* Load 64-bit value rd:rn. */
- tmp = tcg_temp_new(TCG_TYPE_I64);
- tmp2 = load_reg(s, rhigh);
- tcg_gen_extu_i32_i64(tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_shli_i64(tmp, tmp, 32);
- tcg_gen_add_i64(val, val, tmp);
-
- tmp2 = load_reg(s, rlow);
- tcg_gen_extu_i32_i64(tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_add_i64(val, val, tmp);
-}
-
-/* Set N and Z flags from a 64-bit value. */
-static void gen_logicq_cc(TCGv val)
-{
- TCGv tmp = new_tmp();
- gen_helper_logicq_cc(tmp, val);
- gen_logic_CC(tmp);
- dead_tmp(tmp);
-}
-
-static void disas_arm_insn(CPUState * env, DisasContext *s)
-{
- unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
- TCGv tmp;
- TCGv tmp2;
- TCGv tmp3;
- TCGv addr;
-#ifdef CONFIG_TRACE
- int ticks = 0;
-#endif
-
- insn = ldl_code(s->pc);
-#ifdef CONFIG_TRACE
- if (tracing) {
- trace_add_insn(insn);
- ticks = get_insn_ticks_arm(insn);
- gen_helper_traceInsn();
- }
-#endif
- s->pc += 4;
-
- /* M variants do not implement ARM mode. */
- if (IS_M(env))
- goto illegal_op;
- cond = insn >> 28;
- if (cond == 0xf){
-#ifdef CONFIG_TRACE
- if (tracing) {
- gen_traceTicks(ticks);
- }
-#endif
- /* Unconditional instructions. */
- if (((insn >> 25) & 7) == 1) {
- /* NEON Data processing. */
- if (!arm_feature(env, ARM_FEATURE_NEON))
- goto illegal_op;
-
- if (disas_neon_data_insn(env, s, insn))
- goto illegal_op;
- return;
- }
- if ((insn & 0x0f100000) == 0x04000000) {
- /* NEON load/store. */
- if (!arm_feature(env, ARM_FEATURE_NEON))
- goto illegal_op;
-
- if (disas_neon_ls_insn(env, s, insn))
- goto illegal_op;
- return;
- }
- if ((insn & 0x0d70f000) == 0x0550f000)
- return; /* PLD */
- else if ((insn & 0x0ffffdff) == 0x01010000) {
- ARCH(6);
- /* setend */
- if (insn & (1 << 9)) {
- /* BE8 mode not implemented. */
- goto illegal_op;
- }
- return;
- } else if ((insn & 0x0fffff00) == 0x057ff000) {
- switch ((insn >> 4) & 0xf) {
- case 1: /* clrex */
- ARCH(6K);
- gen_helper_clrex(cpu_env);
- return;
- case 4: /* dsb */
- case 5: /* dmb */
- case 6: /* isb */
- ARCH(7);
- /* We don't emulate caches so these are a no-op. */
- return;
- default:
- goto illegal_op;
- }
- } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
- /* srs */
- uint32_t offset;
- if (IS_USER(s))
- goto illegal_op;
- ARCH(6);
- op1 = (insn & 0x1f);
- if (op1 == (env->uncached_cpsr & CPSR_M)) {
- addr = load_reg(s, 13);
- } else {
- addr = new_tmp();
- gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
- }
- i = (insn >> 23) & 3;
- switch (i) {
- case 0: offset = -4; break; /* DA */
- case 1: offset = -8; break; /* DB */
- case 2: offset = 0; break; /* IA */
- case 3: offset = 4; break; /* IB */
- default: abort();
- }
- if (offset)
- tcg_gen_addi_i32(addr, addr, offset);
- tmp = load_reg(s, 14);
- gen_st32(tmp, addr, 0);
- tmp = new_tmp();
- gen_helper_cpsr_read(tmp);
- tcg_gen_addi_i32(addr, addr, 4);
- gen_st32(tmp, addr, 0);
- if (insn & (1 << 21)) {
- /* Base writeback. */
- switch (i) {
- case 0: offset = -8; break;
- case 1: offset = -4; break;
- case 2: offset = 4; break;
- case 3: offset = 0; break;
- default: abort();
- }
- if (offset)
- tcg_gen_addi_i32(addr, tmp, offset);
- if (op1 == (env->uncached_cpsr & CPSR_M)) {
- gen_movl_reg_T1(s, 13);
- } else {
- gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
- }
- } else {
- dead_tmp(addr);
- }
- } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
- /* rfe */
- uint32_t offset;
- if (IS_USER(s))
- goto illegal_op;
- ARCH(6);
- rn = (insn >> 16) & 0xf;
- addr = load_reg(s, rn);
- i = (insn >> 23) & 3;
- switch (i) {
- case 0: offset = -4; break; /* DA */
- case 1: offset = -8; break; /* DB */
- case 2: offset = 0; break; /* IA */
- case 3: offset = 4; break; /* IB */
- default: abort();
- }
- if (offset)
- tcg_gen_addi_i32(addr, addr, offset);
- /* Load PC into tmp and CPSR into tmp2. */
- tmp = gen_ld32(addr, 0);
- tcg_gen_addi_i32(addr, addr, 4);
- tmp2 = gen_ld32(addr, 0);
- if (insn & (1 << 21)) {
- /* Base writeback. */
- switch (i) {
- case 0: offset = -8; break;
- case 1: offset = -4; break;
- case 2: offset = 4; break;
- case 3: offset = 0; break;
- default: abort();
- }
- if (offset)
- tcg_gen_addi_i32(addr, addr, offset);
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- gen_rfe(s, tmp, tmp2);
- } else if ((insn & 0x0e000000) == 0x0a000000) {
- /* branch link and change to thumb (blx <offset>) */
- int32_t offset;
-
- val = (uint32_t)s->pc;
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_reg(s, 14, tmp);
- /* Sign-extend the 24-bit offset */
- offset = (((int32_t)insn) << 8) >> 8;
- /* offset * 4 + bit24 * 2 + (thumb bit) */
- val += (offset << 2) | ((insn >> 23) & 2) | 1;
- /* pipeline offset */
- val += 4;
- gen_bx_im(s, val);
- return;
- } else if ((insn & 0x0e000f00) == 0x0c000100) {
- if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
- /* iWMMXt register transfer. */
- if (env->cp15.c15_cpar & (1 << 1))
- if (!disas_iwmmxt_insn(env, s, insn))
- return;
- }
- } else if ((insn & 0x0fe00000) == 0x0c400000) {
- /* Coprocessor double register transfer. */
- } else if ((insn & 0x0f000010) == 0x0e000010) {
- /* Additional coprocessor register transfer. */
- } else if ((insn & 0x0ff10020) == 0x01000000) {
- uint32_t mask;
- uint32_t val;
- /* cps (privileged) */
- if (IS_USER(s))
- return;
- mask = val = 0;
- if (insn & (1 << 19)) {
- if (insn & (1 << 8))
- mask |= CPSR_A;
- if (insn & (1 << 7))
- mask |= CPSR_I;
- if (insn & (1 << 6))
- mask |= CPSR_F;
- if (insn & (1 << 18))
- val |= mask;
- }
- if (insn & (1 << 17)) {
- mask |= CPSR_M;
- val |= (insn & 0x1f);
- }
- if (mask) {
- gen_op_movl_T0_im(val);
- gen_set_psr_T0(s, mask, 0);
- }
- return;
- }
- goto illegal_op;
- }
- if (cond != 0xe) {
-#ifdef CONFIG_TRACE
- if (tracing) {
- /* a non-executed conditional instruction takes */
- /* only 1 cycle */
- gen_traceTicks(1);
- ticks -= 1;
- }
-#endif
- /* if not always execute, we generate a conditional jump to
- next instruction */
- s->condlabel = gen_new_label();
- gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
- }
-#ifdef CONFIG_TRACE
- if (tracing && ticks > 0) {
- gen_traceTicks(ticks);
- }
-#endif
- if ((insn & 0x0f900000) == 0x03000000) {
- if ((insn & (1 << 21)) == 0) {
- ARCH(6T2);
- rd = (insn >> 12) & 0xf;
- val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
- if ((insn & (1 << 22)) == 0) {
- /* MOVW */
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- } else {
- /* MOVT */
- tmp = load_reg(s, rd);
- tcg_gen_ext16u_i32(tmp, tmp);
- tcg_gen_ori_i32(tmp, tmp, val << 16);
- }
- store_reg(s, rd, tmp);
- } else {
- if (((insn >> 12) & 0xf) != 0xf)
- goto illegal_op;
- if (((insn >> 16) & 0xf) == 0) {
- gen_nop_hint(s, insn & 0xff);
- } else {
- /* CPSR = immediate */
- val = insn & 0xff;
- shift = ((insn >> 8) & 0xf) * 2;
- if (shift)
- val = (val >> shift) | (val << (32 - shift));
- gen_op_movl_T0_im(val);
- i = ((insn & (1 << 22)) != 0);
- if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
- goto illegal_op;
- }
- }
- } else if ((insn & 0x0f900000) == 0x01000000
- && (insn & 0x00000090) != 0x00000090) {
- /* miscellaneous instructions */
- op1 = (insn >> 21) & 3;
- sh = (insn >> 4) & 0xf;
- rm = insn & 0xf;
- switch (sh) {
- case 0x0: /* move program status register */
- if (op1 & 1) {
- /* PSR = reg */
- gen_movl_T0_reg(s, rm);
- i = ((op1 & 2) != 0);
- if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
- goto illegal_op;
- } else {
- /* reg = PSR */
- rd = (insn >> 12) & 0xf;
- if (op1 & 2) {
- if (IS_USER(s))
- goto illegal_op;
- tmp = load_cpu_field(spsr);
- } else {
- tmp = new_tmp();
- gen_helper_cpsr_read(tmp);
- }
- store_reg(s, rd, tmp);
- }
- break;
- case 0x1:
- if (op1 == 1) {
- /* branch/exchange thumb (bx). */
- tmp = load_reg(s, rm);
- gen_bx(s, tmp);
- } else if (op1 == 3) {
- /* clz */
- rd = (insn >> 12) & 0xf;
- tmp = load_reg(s, rm);
- gen_helper_clz(tmp, tmp);
- store_reg(s, rd, tmp);
- } else {
- goto illegal_op;
- }
- break;
- case 0x2:
- if (op1 == 1) {
- ARCH(5J); /* bxj */
- /* Trivial implementation equivalent to bx. */
- tmp = load_reg(s, rm);
- gen_bx(s, tmp);
- } else {
- goto illegal_op;
- }
- break;
- case 0x3:
- if (op1 != 1)
- goto illegal_op;
-
- /* branch link/exchange thumb (blx) */
- tmp = load_reg(s, rm);
- tmp2 = new_tmp();
- tcg_gen_movi_i32(tmp2, s->pc);
- store_reg(s, 14, tmp2);
- gen_bx(s, tmp);
- break;
- case 0x5: /* saturating add/subtract */
- rd = (insn >> 12) & 0xf;
- rn = (insn >> 16) & 0xf;
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rn);
- if (op1 & 2)
- gen_helper_double_saturate(tmp2, tmp2);
- if (op1 & 1)
- gen_helper_sub_saturate(tmp, tmp, tmp2);
- else
- gen_helper_add_saturate(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- store_reg(s, rd, tmp);
- break;
- case 7: /* bkpt */
- gen_set_condexec(s);
- gen_set_pc_im(s->pc - 4);
- gen_exception(EXCP_BKPT);
- s->is_jmp = DISAS_JUMP;
- break;
- case 0x8: /* signed multiply */
- case 0xa:
- case 0xc:
- case 0xe:
- rs = (insn >> 8) & 0xf;
- rn = (insn >> 12) & 0xf;
- rd = (insn >> 16) & 0xf;
- if (op1 == 1) {
- /* (32 * 16) >> 16 */
- tmp = load_reg(s, rm);
- tmp2 = load_reg(s, rs);
- if (sh & 4)
- tcg_gen_sari_i32(tmp2, tmp2, 16);
- else
- gen_sxth(tmp2);
- tmp2 = gen_muls_i64_i32(tmp, tmp2);
- tcg_gen_shri_i64(tmp2, tmp2, 16);
- tmp = new_tmp();
- tcg_gen_trunc_i64_i32(tmp, tmp2);
- if ((sh & 2) == 0) {
- tmp2 = load_reg(s, rn);
- gen_helper_add_setq(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- store_reg(s, rd, tmp);
- } else {
- /* 16 * 16 */
- tmp = load_reg(s, rm);
- tmp2 = load_reg(s, rs);
- gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
- dead_tmp(tmp2);
- if (op1 == 2) {
- tmp2 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_ext_i32_i64(tmp2, tmp);
- dead_tmp(tmp);
- gen_addq(s, tmp2, rn, rd);
- gen_storeq_reg(s, rn, rd, tmp2);
- } else {
- if (op1 == 0) {
- tmp2 = load_reg(s, rn);
- gen_helper_add_setq(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- store_reg(s, rd, tmp);
- }
- }
- break;
- default:
- goto illegal_op;
- }
- } else if (((insn & 0x0e000000) == 0 &&
- (insn & 0x00000090) != 0x90) ||
- ((insn & 0x0e000000) == (1 << 25))) {
- int set_cc, logic_cc, shiftop;
-
- op1 = (insn >> 21) & 0xf;
- set_cc = (insn >> 20) & 1;
- logic_cc = table_logic_cc[op1] & set_cc;
-
- /* data processing instruction */
- if (insn & (1 << 25)) {
- /* immediate operand */
- val = insn & 0xff;
- shift = ((insn >> 8) & 0xf) * 2;
- if (shift)
- val = (val >> shift) | (val << (32 - shift));
- gen_op_movl_T1_im(val);
- if (logic_cc && shift)
- gen_set_CF_bit31(cpu_T[1]);
- } else {
- /* register */
- rm = (insn) & 0xf;
- gen_movl_T1_reg(s, rm);
- shiftop = (insn >> 5) & 3;
- if (!(insn & (1 << 4))) {
- shift = (insn >> 7) & 0x1f;
- gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
- } else {
- rs = (insn >> 8) & 0xf;
- tmp = load_reg(s, rs);
- gen_arm_shift_reg(cpu_T[1], shiftop, tmp, logic_cc);
- }
- }
- if (op1 != 0x0f && op1 != 0x0d) {
- rn = (insn >> 16) & 0xf;
- gen_movl_T0_reg(s, rn);
- }
- rd = (insn >> 12) & 0xf;
- switch(op1) {
- case 0x00:
- gen_op_andl_T0_T1();
- gen_movl_reg_T0(s, rd);
- if (logic_cc)
- gen_op_logic_T0_cc();
- break;
- case 0x01:
- gen_op_xorl_T0_T1();
- gen_movl_reg_T0(s, rd);
- if (logic_cc)
- gen_op_logic_T0_cc();
- break;
- case 0x02:
- if (set_cc && rd == 15) {
- /* SUBS r15, ... is used for exception return. */
- if (IS_USER(s))
- goto illegal_op;
- gen_op_subl_T0_T1_cc();
- gen_exception_return(s);
- } else {
- if (set_cc)
- gen_op_subl_T0_T1_cc();
- else
- gen_op_subl_T0_T1();
- gen_movl_reg_T0(s, rd);
- }
- break;
- case 0x03:
- if (set_cc)
- gen_op_rsbl_T0_T1_cc();
- else
- gen_op_rsbl_T0_T1();
- gen_movl_reg_T0(s, rd);
- break;
- case 0x04:
- if (set_cc)
- gen_op_addl_T0_T1_cc();
- else
- gen_op_addl_T0_T1();
- gen_movl_reg_T0(s, rd);
- break;
- case 0x05:
- if (set_cc)
- gen_op_adcl_T0_T1_cc();
- else
- gen_adc_T0_T1();
- gen_movl_reg_T0(s, rd);
- break;
- case 0x06:
- if (set_cc)
- gen_op_sbcl_T0_T1_cc();
- else
- gen_sbc_T0_T1();
- gen_movl_reg_T0(s, rd);
- break;
- case 0x07:
- if (set_cc)
- gen_op_rscl_T0_T1_cc();
- else
- gen_rsc_T0_T1();
- gen_movl_reg_T0(s, rd);
- break;
- case 0x08:
- if (set_cc) {
- gen_op_andl_T0_T1();
- gen_op_logic_T0_cc();
- }
- break;
- case 0x09:
- if (set_cc) {
- gen_op_xorl_T0_T1();
- gen_op_logic_T0_cc();
- }
- break;
- case 0x0a:
- if (set_cc) {
- gen_op_subl_T0_T1_cc();
- }
- break;
- case 0x0b:
- if (set_cc) {
- gen_op_addl_T0_T1_cc();
- }
- break;
- case 0x0c:
- gen_op_orl_T0_T1();
- gen_movl_reg_T0(s, rd);
- if (logic_cc)
- gen_op_logic_T0_cc();
- break;
- case 0x0d:
- if (logic_cc && rd == 15) {
- /* MOVS r15, ... is used for exception return. */
- if (IS_USER(s))
- goto illegal_op;
- gen_op_movl_T0_T1();
- gen_exception_return(s);
- } else {
- gen_movl_reg_T1(s, rd);
- if (logic_cc)
- gen_op_logic_T1_cc();
- }
- break;
- case 0x0e:
- gen_op_bicl_T0_T1();
- gen_movl_reg_T0(s, rd);
- if (logic_cc)
- gen_op_logic_T0_cc();
- break;
- default:
- case 0x0f:
- gen_op_notl_T1();
- gen_movl_reg_T1(s, rd);
- if (logic_cc)
- gen_op_logic_T1_cc();
- break;
- }
- } else {
- /* other instructions */
- op1 = (insn >> 24) & 0xf;
- switch(op1) {
- case 0x0:
- case 0x1:
- /* multiplies, extra load/stores */
- sh = (insn >> 5) & 3;
- if (sh == 0) {
- if (op1 == 0x0) {
- rd = (insn >> 16) & 0xf;
- rn = (insn >> 12) & 0xf;
- rs = (insn >> 8) & 0xf;
- rm = (insn) & 0xf;
- op1 = (insn >> 20) & 0xf;
- switch (op1) {
- case 0: case 1: case 2: case 3: case 6:
- /* 32 bit mul */
- tmp = load_reg(s, rs);
- tmp2 = load_reg(s, rm);
- tcg_gen_mul_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- if (insn & (1 << 22)) {
- /* Subtract (mls) */
- ARCH(6T2);
- tmp2 = load_reg(s, rn);
- tcg_gen_sub_i32(tmp, tmp2, tmp);
- dead_tmp(tmp2);
- } else if (insn & (1 << 21)) {
- /* Add */
- tmp2 = load_reg(s, rn);
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- if (insn & (1 << 20))
- gen_logic_CC(tmp);
- store_reg(s, rd, tmp);
- break;
- default:
- /* 64 bit mul */
- tmp = load_reg(s, rs);
- tmp2 = load_reg(s, rm);
- if (insn & (1 << 22))
- tmp = gen_muls_i64_i32(tmp, tmp2);
- else
- tmp = gen_mulu_i64_i32(tmp, tmp2);
- if (insn & (1 << 21)) /* mult accumulate */
- gen_addq(s, tmp, rn, rd);
- if (!(insn & (1 << 23))) { /* double accumulate */
- ARCH(6);
- gen_addq_lo(s, tmp, rn);
- gen_addq_lo(s, tmp, rd);
- }
- if (insn & (1 << 20))
- gen_logicq_cc(tmp);
- gen_storeq_reg(s, rn, rd, tmp);
- break;
- }
- } else {
- rn = (insn >> 16) & 0xf;
- rd = (insn >> 12) & 0xf;
- if (insn & (1 << 23)) {
- /* load/store exclusive */
- gen_movl_T1_reg(s, rn);
- addr = cpu_T[1];
- if (insn & (1 << 20)) {
- gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- int label = gen_new_label();
- rm = insn & 0xf;
- gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
- tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
- 0, label);
- tmp = load_reg(s,rm);
- gen_st32(tmp, cpu_T[1], IS_USER(s));
- gen_set_label(label);
- gen_movl_reg_T0(s, rd);
- }
- } else {
- /* SWP instruction */
- rm = (insn) & 0xf;
-
- /* ??? This is not really atomic. However we know
- we never have multiple CPUs running in parallel,
- so it is good enough. */
- addr = load_reg(s, rn);
- tmp = load_reg(s, rm);
- if (insn & (1 << 22)) {
- tmp2 = gen_ld8u(addr, IS_USER(s));
- gen_st8(tmp, addr, IS_USER(s));
- } else {
- tmp2 = gen_ld32(addr, IS_USER(s));
- gen_st32(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- store_reg(s, rd, tmp2);
- }
- }
- } else {
- int address_offset;
- int load;
- /* Misc load/store */
- rn = (insn >> 16) & 0xf;
- rd = (insn >> 12) & 0xf;
- addr = load_reg(s, rn);
- if (insn & (1 << 24))
- gen_add_datah_offset(s, insn, 0, addr);
- address_offset = 0;
- if (insn & (1 << 20)) {
- /* load */
- switch(sh) {
- case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
- break;
- case 2:
- tmp = gen_ld8s(addr, IS_USER(s));
- break;
- default:
- case 3:
- tmp = gen_ld16s(addr, IS_USER(s));
- break;
- }
- load = 1;
- } else if (sh & 2) {
- /* doubleword */
- if (sh & 1) {
- /* store */
- tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = load_reg(s, rd + 1);
- gen_st32(tmp, addr, IS_USER(s));
- load = 0;
- } else {
- /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = gen_ld32(addr, IS_USER(s));
- rd++;
- load = 1;
- }
- address_offset = -4;
- } else {
- /* store */
- tmp = load_reg(s, rd);
- gen_st16(tmp, addr, IS_USER(s));
- load = 0;
- }
- /* Perform base writeback before the loaded value to
- ensure correct behavior with overlapping index registers.
- ldrd with base writeback is is undefined if the
- destination and index registers overlap. */
- if (!(insn & (1 << 24))) {
- gen_add_datah_offset(s, insn, address_offset, addr);
- store_reg(s, rn, addr);
- } else if (insn & (1 << 21)) {
- if (address_offset)
- tcg_gen_addi_i32(addr, addr, address_offset);
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- if (load) {
- /* Complete the load. */
- store_reg(s, rd, tmp);
- }
- }
- break;
- case 0x4:
- case 0x5:
- goto do_ldst;
- case 0x6:
- case 0x7:
- if (insn & (1 << 4)) {
- ARCH(6);
- /* Armv6 Media instructions. */
- rm = insn & 0xf;
- rn = (insn >> 16) & 0xf;
- rd = (insn >> 12) & 0xf;
- rs = (insn >> 8) & 0xf;
- switch ((insn >> 23) & 3) {
- case 0: /* Parallel add/subtract. */
- op1 = (insn >> 20) & 7;
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- sh = (insn >> 5) & 7;
- if ((op1 & 3) == 0 || sh == 5 || sh == 6)
- goto illegal_op;
- gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
- dead_tmp(tmp2);
- store_reg(s, rd, tmp);
- break;
- case 1:
- if ((insn & 0x00700020) == 0) {
- /* Halfword pack. */
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- shift = (insn >> 7) & 0x1f;
- if (insn & (1 << 6)) {
- /* pkhtb */
- if (shift == 0)
- shift = 31;
- tcg_gen_sari_i32(tmp2, tmp2, shift);
- tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
- tcg_gen_ext16u_i32(tmp2, tmp2);
- } else {
- /* pkhbt */
- if (shift)
- tcg_gen_shli_i32(tmp2, tmp2, shift);
- tcg_gen_ext16u_i32(tmp, tmp);
- tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
- }
- tcg_gen_or_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- store_reg(s, rd, tmp);
- } else if ((insn & 0x00200020) == 0x00200000) {
- /* [us]sat */
- tmp = load_reg(s, rm);
- shift = (insn >> 7) & 0x1f;
- if (insn & (1 << 6)) {
- if (shift == 0)
- shift = 31;
- tcg_gen_sari_i32(tmp, tmp, shift);
- } else {
- tcg_gen_shli_i32(tmp, tmp, shift);
- }
- sh = (insn >> 16) & 0x1f;
- if (sh != 0) {
- if (insn & (1 << 22))
- gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
- else
- gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
- }
- store_reg(s, rd, tmp);
- } else if ((insn & 0x00300fe0) == 0x00200f20) {
- /* [us]sat16 */
- tmp = load_reg(s, rm);
- sh = (insn >> 16) & 0x1f;
- if (sh != 0) {
- if (insn & (1 << 22))
- gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
- else
- gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
- }
- store_reg(s, rd, tmp);
- } else if ((insn & 0x00700fe0) == 0x00000fa0) {
- /* Select bytes. */
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- tmp3 = new_tmp();
- tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
- gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
- dead_tmp(tmp3);
- dead_tmp(tmp2);
- store_reg(s, rd, tmp);
- } else if ((insn & 0x000003e0) == 0x00000060) {
- tmp = load_reg(s, rm);
- shift = (insn >> 10) & 3;
- /* ??? In many cases it's not neccessary to do a
- rotate, a shift is sufficient. */
- if (shift != 0)
- tcg_gen_rori_i32(tmp, tmp, shift * 8);
- op1 = (insn >> 20) & 7;
- switch (op1) {
- case 0: gen_sxtb16(tmp); break;
- case 2: gen_sxtb(tmp); break;
- case 3: gen_sxth(tmp); break;
- case 4: gen_uxtb16(tmp); break;
- case 6: gen_uxtb(tmp); break;
- case 7: gen_uxth(tmp); break;
- default: goto illegal_op;
- }
- if (rn != 15) {
- tmp2 = load_reg(s, rn);
- if ((op1 & 3) == 0) {
- gen_add16(tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- }
- store_reg(s, rd, tmp);
- } else if ((insn & 0x003f0f60) == 0x003f0f20) {
- /* rev */
- tmp = load_reg(s, rm);
- if (insn & (1 << 22)) {
- if (insn & (1 << 7)) {
- gen_revsh(tmp);
- } else {
- ARCH(6T2);
- gen_helper_rbit(tmp, tmp);
- }
- } else {
- if (insn & (1 << 7))
- gen_rev16(tmp);
- else
- tcg_gen_bswap_i32(tmp, tmp);
- }
- store_reg(s, rd, tmp);
- } else {
- goto illegal_op;
- }
- break;
- case 2: /* Multiplies (Type 3). */
- tmp = load_reg(s, rm);
- tmp2 = load_reg(s, rs);
- if (insn & (1 << 20)) {
- /* Signed multiply most significant [accumulate]. */
- tmp2 = gen_muls_i64_i32(tmp, tmp2);
- if (insn & (1 << 5))
- tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
- tcg_gen_shri_i64(tmp2, tmp2, 32);
- tmp = new_tmp();
- tcg_gen_trunc_i64_i32(tmp, tmp2);
- if (rn != 15) {
- tmp2 = load_reg(s, rn);
- if (insn & (1 << 6)) {
- tcg_gen_sub_i32(tmp, tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- }
- dead_tmp(tmp2);
- }
- store_reg(s, rd, tmp);
- } else {
- if (insn & (1 << 5))
- gen_swap_half(tmp2);
- gen_smul_dual(tmp, tmp2);
- /* This addition cannot overflow. */
- if (insn & (1 << 6)) {
- tcg_gen_sub_i32(tmp, tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- }
- dead_tmp(tmp2);
- if (insn & (1 << 22)) {
- /* smlald, smlsld */
- tmp2 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_ext_i32_i64(tmp2, tmp);
- dead_tmp(tmp);
- gen_addq(s, tmp2, rd, rn);
- gen_storeq_reg(s, rd, rn, tmp2);
- } else {
- /* smuad, smusd, smlad, smlsd */
- if (rd != 15)
- {
- tmp2 = load_reg(s, rd);
- gen_helper_add_setq(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- store_reg(s, rn, tmp);
- }
- }
- break;
- case 3:
- op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
- switch (op1) {
- case 0: /* Unsigned sum of absolute differences. */
- ARCH(6);
- tmp = load_reg(s, rm);
- tmp2 = load_reg(s, rs);
- gen_helper_usad8(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- if (rn != 15) {
- tmp2 = load_reg(s, rn);
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- store_reg(s, rd, tmp);
- break;
- case 0x20: case 0x24: case 0x28: case 0x2c:
- /* Bitfield insert/clear. */
- ARCH(6T2);
- shift = (insn >> 7) & 0x1f;
- i = (insn >> 16) & 0x1f;
- i = i + 1 - shift;
- if (rm == 15) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- } else {
- tmp = load_reg(s, rm);
- }
- if (i != 32) {
- tmp2 = load_reg(s, rd);
- gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
- dead_tmp(tmp2);
- }
- store_reg(s, rd, tmp);
- break;
- case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
- case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
- tmp = load_reg(s, rm);
- shift = (insn >> 7) & 0x1f;
- i = ((insn >> 16) & 0x1f) + 1;
- if (shift + i > 32)
- goto illegal_op;
- if (i < 32) {
- if (op1 & 0x20) {
- gen_ubfx(tmp, shift, (1u << i) - 1);
- } else {
- gen_sbfx(tmp, shift, i);
- }
- }
- store_reg(s, rd, tmp);
- break;
- default:
- goto illegal_op;
- }
- break;
- }
- break;
- }
- do_ldst:
- /* Check for undefined extension instructions
- * per the ARM Bible IE:
- * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
- */
- sh = (0xf << 20) | (0xf << 4);
- if (op1 == 0x7 && ((insn & sh) == sh))
- {
- goto illegal_op;
- }
- /* load/store byte/word */
- rn = (insn >> 16) & 0xf;
- rd = (insn >> 12) & 0xf;
- tmp2 = load_reg(s, rn);
- i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
- if (insn & (1 << 24))
- gen_add_data_offset(s, insn, tmp2);
- if (insn & (1 << 20)) {
- /* load */
- s->is_mem = 1;
- if (insn & (1 << 22)) {
- tmp = gen_ld8u(tmp2, i);
- } else {
- tmp = gen_ld32(tmp2, i);
- }
- } else {
- /* store */
- tmp = load_reg(s, rd);
- if (insn & (1 << 22))
- gen_st8(tmp, tmp2, i);
- else
- gen_st32(tmp, tmp2, i);
- }
- if (!(insn & (1 << 24))) {
- gen_add_data_offset(s, insn, tmp2);
- store_reg(s, rn, tmp2);
- } else if (insn & (1 << 21)) {
- store_reg(s, rn, tmp2);
- } else {
- dead_tmp(tmp2);
- }
- if (insn & (1 << 20)) {
- /* Complete the load. */
- if (rd == 15)
- gen_bx(s, tmp);
- else
- store_reg(s, rd, tmp);
- }
- break;
- case 0x08:
- case 0x09:
- {
- int j, n, user, loaded_base;
- TCGv loaded_var;
- /* load/store multiple words */
- /* XXX: store correct base if write back */
- user = 0;
- if (insn & (1 << 22)) {
- if (IS_USER(s))
- goto illegal_op; /* only usable in supervisor mode */
-
- if ((insn & (1 << 15)) == 0)
- user = 1;
- }
- rn = (insn >> 16) & 0xf;
- addr = load_reg(s, rn);
-
- /* compute total size */
- loaded_base = 0;
- TCGV_UNUSED(loaded_var);
- n = 0;
- for(i=0;i<16;i++) {
- if (insn & (1 << i))
- n++;
- }
- /* XXX: test invalid n == 0 case ? */
- if (insn & (1 << 23)) {
- if (insn & (1 << 24)) {
- /* pre increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } else {
- /* post increment */
- }
- } else {
- if (insn & (1 << 24)) {
- /* pre decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- } else {
- /* post decrement */
- if (n != 1)
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- }
- j = 0;
- for(i=0;i<16;i++) {
- if (insn & (1 << i)) {
- if (insn & (1 << 20)) {
- /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- if (i == 15) {
- gen_bx(s, tmp);
- } else if (user) {
- gen_helper_set_user_reg(tcg_const_i32(i), tmp);
- dead_tmp(tmp);
- } else if (i == rn) {
- loaded_var = tmp;
- loaded_base = 1;
- } else {
- store_reg(s, i, tmp);
- }
- } else {
- /* store */
- if (i == 15) {
- /* special case: r15 = PC + 8 */
- val = (long)s->pc + 4;
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- } else if (user) {
- tmp = new_tmp();
- gen_helper_get_user_reg(tmp, tcg_const_i32(i));
- } else {
- tmp = load_reg(s, i);
- }
- gen_st32(tmp, addr, IS_USER(s));
- }
- j++;
- /* no need to add after the last transfer */
- if (j != n)
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
- if (insn & (1 << 21)) {
- /* write back */
- if (insn & (1 << 23)) {
- if (insn & (1 << 24)) {
- /* pre increment */
- } else {
- /* post increment */
- tcg_gen_addi_i32(addr, addr, 4);
- }
- } else {
- if (insn & (1 << 24)) {
- /* pre decrement */
- if (n != 1)
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- } else {
- /* post decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- }
- }
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- if (loaded_base) {
- store_reg(s, rn, loaded_var);
- }
- if ((insn & (1 << 22)) && !user) {
- /* Restore CPSR from SPSR. */
- tmp = load_cpu_field(spsr);
- gen_set_cpsr(tmp, 0xffffffff);
- dead_tmp(tmp);
- s->is_jmp = DISAS_UPDATE;
- }
- }
- break;
- case 0xa:
- case 0xb:
- {
- int32_t offset;
-
- /* branch (and link) */
- val = (int32_t)s->pc;
- if (insn & (1 << 24)) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_reg(s, 14, tmp);
- }
- offset = (((int32_t)insn << 8) >> 8);
- val += (offset << 2) + 4;
- gen_jmp(s, val);
- }
- break;
- case 0xc:
- case 0xd:
- case 0xe:
- /* Coprocessor. */
- if (disas_coproc_insn(env, s, insn))
- goto illegal_op;
- break;
- case 0xf:
- /* swi */
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_SWI;
- break;
- default:
- illegal_op:
- gen_set_condexec(s);
- gen_set_pc_im(s->pc - 4);
- gen_exception(EXCP_UDEF);
- s->is_jmp = DISAS_JUMP;
- break;
- }
- }
-}
-
-/* Return true if this is a Thumb-2 logical op. */
-static int
-thumb2_logic_op(int op)
-{
- return (op < 8);
-}
-
-/* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
- then set condition code flags based on the result of the operation.
- If SHIFTER_OUT is nonzero then set the carry flag for logical operations
- to the high bit of T1.
- Returns zero if the opcode is valid. */
-
-static int
-gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
-{
- int logic_cc;
-
- logic_cc = 0;
- switch (op) {
- case 0: /* and */
- gen_op_andl_T0_T1();
- logic_cc = conds;
- break;
- case 1: /* bic */
- gen_op_bicl_T0_T1();
- logic_cc = conds;
- break;
- case 2: /* orr */
- gen_op_orl_T0_T1();
- logic_cc = conds;
- break;
- case 3: /* orn */
- gen_op_notl_T1();
- gen_op_orl_T0_T1();
- logic_cc = conds;
- break;
- case 4: /* eor */
- gen_op_xorl_T0_T1();
- logic_cc = conds;
- break;
- case 8: /* add */
- if (conds)
- gen_op_addl_T0_T1_cc();
- else
- gen_op_addl_T0_T1();
- break;
- case 10: /* adc */
- if (conds)
- gen_op_adcl_T0_T1_cc();
- else
- gen_adc_T0_T1();
- break;
- case 11: /* sbc */
- if (conds)
- gen_op_sbcl_T0_T1_cc();
- else
- gen_sbc_T0_T1();
- break;
- case 13: /* sub */
- if (conds)
- gen_op_subl_T0_T1_cc();
- else
- gen_op_subl_T0_T1();
- break;
- case 14: /* rsb */
- if (conds)
- gen_op_rsbl_T0_T1_cc();
- else
- gen_op_rsbl_T0_T1();
- break;
- default: /* 5, 6, 7, 9, 12, 15. */
- return 1;
- }
- if (logic_cc) {
- gen_op_logic_T0_cc();
- if (shifter_out)
- gen_set_CF_bit31(cpu_T[1]);
- }
- return 0;
-}
-
-/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
- is not legal. */
-static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
-{
- uint32_t insn, imm, shift, offset;
- uint32_t rd, rn, rm, rs;
- TCGv tmp;
- TCGv tmp2;
- TCGv tmp3;
- TCGv addr;
- int op;
- int shiftop;
- int conds;
- int logic_cc;
-
- if (!(arm_feature(env, ARM_FEATURE_THUMB2)
- || arm_feature (env, ARM_FEATURE_M))) {
- /* Thumb-1 cores may need to treat bl and blx as a pair of
- 16-bit instructions to get correct prefetch abort behavior. */
- insn = insn_hw1;
- if ((insn & (1 << 12)) == 0) {
- /* Second half of blx. */
- offset = ((insn & 0x7ff) << 1);
- tmp = load_reg(s, 14);
- tcg_gen_addi_i32(tmp, tmp, offset);
- tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
-
- tmp2 = new_tmp();
- tcg_gen_movi_i32(tmp2, s->pc | 1);
- store_reg(s, 14, tmp2);
- gen_bx(s, tmp);
- return 0;
- }
- if (insn & (1 << 11)) {
- /* Second half of bl. */
- offset = ((insn & 0x7ff) << 1) | 1;
- tmp = load_reg(s, 14);
- tcg_gen_addi_i32(tmp, tmp, offset);
-
- tmp2 = new_tmp();
- tcg_gen_movi_i32(tmp2, s->pc | 1);
- store_reg(s, 14, tmp2);
- gen_bx(s, tmp);
- return 0;
- }
- if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
- /* Instruction spans a page boundary. Implement it as two
- 16-bit instructions in case the second half causes an
- prefetch abort. */
- offset = ((int32_t)insn << 21) >> 9;
- gen_op_movl_T0_im(s->pc + 2 + offset);
- gen_movl_reg_T0(s, 14);
- return 0;
- }
- /* Fall through to 32-bit decode. */
- }
-
- insn = lduw_code(s->pc);
-#ifdef CONFIG_TRACE
- if (tracing) {
- int ticks = get_insn_ticks_thumb(insn);
- trace_add_insn( insn_wrap_thumb(insn), 1 );
- gen_helper_traceInsn();
- gen_traceTicks(ticks);
- }
-#endif
- s->pc += 2;
- insn |= (uint32_t)insn_hw1 << 16;
-
- if ((insn & 0xf800e800) != 0xf000e800) {
- ARCH(6T2);
- }
-
- rn = (insn >> 16) & 0xf;
- rs = (insn >> 12) & 0xf;
- rd = (insn >> 8) & 0xf;
- rm = insn & 0xf;
- switch ((insn >> 25) & 0xf) {
- case 0: case 1: case 2: case 3:
- /* 16-bit instructions. Should never happen. */
- abort();
- case 4:
- if (insn & (1 << 22)) {
- /* Other load/store, table branch. */
- if (insn & 0x01200000) {
- /* Load/store doubleword. */
- if (rn == 15) {
- addr = new_tmp();
- tcg_gen_movi_i32(addr, s->pc & ~3);
- } else {
- addr = load_reg(s, rn);
- }
- offset = (insn & 0xff) * 4;
- if ((insn & (1 << 23)) == 0)
- offset = -offset;
- if (insn & (1 << 24)) {
- tcg_gen_addi_i32(addr, addr, offset);
- offset = 0;
- }
- if (insn & (1 << 20)) {
- /* ldrd */
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rs, tmp);
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- /* strd */
- tmp = load_reg(s, rs);
- gen_st32(tmp, addr, IS_USER(s));
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
- }
- if (insn & (1 << 21)) {
- /* Base writeback. */
- if (rn == 15)
- goto illegal_op;
- tcg_gen_addi_i32(addr, addr, offset - 4);
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- } else if ((insn & (1 << 23)) == 0) {
- /* Load/store exclusive word. */
- gen_movl_T1_reg(s, rn);
- addr = cpu_T[1];
- if (insn & (1 << 20)) {
- gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- int label = gen_new_label();
- gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
- tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
- 0, label);
- tmp = load_reg(s, rs);
- gen_st32(tmp, cpu_T[1], IS_USER(s));
- gen_set_label(label);
- gen_movl_reg_T0(s, rd);
- }
- } else if ((insn & (1 << 6)) == 0) {
- /* Table Branch. */
- if (rn == 15) {
- addr = new_tmp();
- tcg_gen_movi_i32(addr, s->pc);
- } else {
- addr = load_reg(s, rn);
- }
- tmp = load_reg(s, rm);
- tcg_gen_add_i32(addr, addr, tmp);
- if (insn & (1 << 4)) {
- /* tbh */
- tcg_gen_add_i32(addr, addr, tmp);
- dead_tmp(tmp);
- tmp = gen_ld16u(addr, IS_USER(s));
- } else { /* tbb */
- dead_tmp(tmp);
- tmp = gen_ld8u(addr, IS_USER(s));
- }
- dead_tmp(addr);
- tcg_gen_shli_i32(tmp, tmp, 1);
- tcg_gen_addi_i32(tmp, tmp, s->pc);
- store_reg(s, 15, tmp);
- } else {
- /* Load/store exclusive byte/halfword/doubleword. */
- /* ??? These are not really atomic. However we know
- we never have multiple CPUs running in parallel,
- so it is good enough. */
- op = (insn >> 4) & 0x3;
- /* Must use a global reg for the address because we have
- a conditional branch in the store instruction. */
- gen_movl_T1_reg(s, rn);
- addr = cpu_T[1];
- if (insn & (1 << 20)) {
- gen_helper_mark_exclusive(cpu_env, addr);
- switch (op) {
- case 0:
- tmp = gen_ld8u(addr, IS_USER(s));
- break;
- case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
- break;
- case 3:
- tmp = gen_ld32(addr, IS_USER(s));
- tcg_gen_addi_i32(addr, addr, 4);
- tmp2 = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp2);
- break;
- default:
- goto illegal_op;
- }
- store_reg(s, rs, tmp);
- } else {
- int label = gen_new_label();
- /* Must use a global that is not killed by the branch. */
- gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
- tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
- tmp = load_reg(s, rs);
- switch (op) {
- case 0:
- gen_st8(tmp, addr, IS_USER(s));
- break;
- case 1:
- gen_st16(tmp, addr, IS_USER(s));
- break;
- case 3:
- gen_st32(tmp, addr, IS_USER(s));
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
- break;
- default:
- goto illegal_op;
- }
- gen_set_label(label);
- gen_movl_reg_T0(s, rm);
- }
- }
- } else {
- /* Load/store multiple, RFE, SRS. */
- if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
- /* Not available in user mode. */
- if (IS_USER(s))
- goto illegal_op;
- if (insn & (1 << 20)) {
- /* rfe */
- addr = load_reg(s, rn);
- if ((insn & (1 << 24)) == 0)
- tcg_gen_addi_i32(addr, addr, -8);
- /* Load PC into tmp and CPSR into tmp2. */
- tmp = gen_ld32(addr, 0);
- tcg_gen_addi_i32(addr, addr, 4);
- tmp2 = gen_ld32(addr, 0);
- if (insn & (1 << 21)) {
- /* Base writeback. */
- if (insn & (1 << 24)) {
- tcg_gen_addi_i32(addr, addr, 4);
- } else {
- tcg_gen_addi_i32(addr, addr, -4);
- }
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- gen_rfe(s, tmp, tmp2);
- } else {
- /* srs */
- op = (insn & 0x1f);
- if (op == (env->uncached_cpsr & CPSR_M)) {
- addr = load_reg(s, 13);
- } else {
- addr = new_tmp();
- gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
- }
- if ((insn & (1 << 24)) == 0) {
- tcg_gen_addi_i32(addr, addr, -8);
- }
- tmp = load_reg(s, 14);
- gen_st32(tmp, addr, 0);
- tcg_gen_addi_i32(addr, addr, 4);
- tmp = new_tmp();
- gen_helper_cpsr_read(tmp);
- gen_st32(tmp, addr, 0);
- if (insn & (1 << 21)) {
- if ((insn & (1 << 24)) == 0) {
- tcg_gen_addi_i32(addr, addr, -4);
- } else {
- tcg_gen_addi_i32(addr, addr, 4);
- }
- if (op == (env->uncached_cpsr & CPSR_M)) {
- store_reg(s, 13, addr);
- } else {
- gen_helper_set_r13_banked(cpu_env,
- tcg_const_i32(op), addr);
- }
- } else {
- dead_tmp(addr);
- }
- }
- } else {
- int i;
- /* Load/store multiple. */
- addr = load_reg(s, rn);
- offset = 0;
- for (i = 0; i < 16; i++) {
- if (insn & (1 << i))
- offset += 4;
- }
- if (insn & (1 << 24)) {
- tcg_gen_addi_i32(addr, addr, -offset);
- }
-
- for (i = 0; i < 16; i++) {
- if ((insn & (1 << i)) == 0)
- continue;
- if (insn & (1 << 20)) {
- /* Load. */
- tmp = gen_ld32(addr, IS_USER(s));
- if (i == 15) {
- gen_bx(s, tmp);
- } else {
- store_reg(s, i, tmp);
- }
- } else {
- /* Store. */
- tmp = load_reg(s, i);
- gen_st32(tmp, addr, IS_USER(s));
- }
- tcg_gen_addi_i32(addr, addr, 4);
- }
- if (insn & (1 << 21)) {
- /* Base register writeback. */
- if (insn & (1 << 24)) {
- tcg_gen_addi_i32(addr, addr, -offset);
- }
- /* Fault if writeback register is in register list. */
- if (insn & (1 << rn))
- goto illegal_op;
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- }
- }
- break;
- case 5: /* Data processing register constant shift. */
- if (rn == 15)
- gen_op_movl_T0_im(0);
- else
- gen_movl_T0_reg(s, rn);
- gen_movl_T1_reg(s, rm);
- op = (insn >> 21) & 0xf;
- shiftop = (insn >> 4) & 3;
- shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
- conds = (insn & (1 << 20)) != 0;
- logic_cc = (conds && thumb2_logic_op(op));
- gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
- if (gen_thumb2_data_op(s, op, conds, 0))
- goto illegal_op;
- if (rd != 15)
- gen_movl_reg_T0(s, rd);
- break;
- case 13: /* Misc data processing. */
- op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
- if (op < 4 && (insn & 0xf000) != 0xf000)
- goto illegal_op;
- switch (op) {
- case 0: /* Register controlled shift. */
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- if ((insn & 0x70) != 0)
- goto illegal_op;
- op = (insn >> 21) & 3;
- logic_cc = (insn & (1 << 20)) != 0;
- gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
- if (logic_cc)
- gen_logic_CC(tmp);
- store_reg(s, rd, tmp);
- break;
- case 1: /* Sign/zero extend. */
- tmp = load_reg(s, rm);
- shift = (insn >> 4) & 3;
- /* ??? In many cases it's not neccessary to do a
- rotate, a shift is sufficient. */
- if (shift != 0)
- tcg_gen_rori_i32(tmp, tmp, shift * 8);
- op = (insn >> 20) & 7;
- switch (op) {
- case 0: gen_sxth(tmp); break;
- case 1: gen_uxth(tmp); break;
- case 2: gen_sxtb16(tmp); break;
- case 3: gen_uxtb16(tmp); break;
- case 4: gen_sxtb(tmp); break;
- case 5: gen_uxtb(tmp); break;
- default: goto illegal_op;
- }
- if (rn != 15) {
- tmp2 = load_reg(s, rn);
- if ((op >> 1) == 1) {
- gen_add16(tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- }
- store_reg(s, rd, tmp);
- break;
- case 2: /* SIMD add/subtract. */
- op = (insn >> 20) & 7;
- shift = (insn >> 4) & 7;
- if ((op & 3) == 3 || (shift & 3) == 3)
- goto illegal_op;
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
- dead_tmp(tmp2);
- store_reg(s, rd, tmp);
- break;
- case 3: /* Other data processing. */
- op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
- if (op < 4) {
- /* Saturating add/subtract. */
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- if (op & 2)
- gen_helper_double_saturate(tmp, tmp);
- if (op & 1)
- gen_helper_sub_saturate(tmp, tmp2, tmp);
- else
- gen_helper_add_saturate(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- } else {
- tmp = load_reg(s, rn);
- switch (op) {
- case 0x0a: /* rbit */
- gen_helper_rbit(tmp, tmp);
- break;
- case 0x08: /* rev */
- tcg_gen_bswap_i32(tmp, tmp);
- break;
- case 0x09: /* rev16 */
- gen_rev16(tmp);
- break;
- case 0x0b: /* revsh */
- gen_revsh(tmp);
- break;
- case 0x10: /* sel */
- tmp2 = load_reg(s, rm);
- tmp3 = new_tmp();
- tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
- gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
- dead_tmp(tmp3);
- dead_tmp(tmp2);
- break;
- case 0x18: /* clz */
- gen_helper_clz(tmp, tmp);
- break;
- default:
- goto illegal_op;
- }
- }
- store_reg(s, rd, tmp);
- break;
- case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
- op = (insn >> 4) & 0xf;
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- switch ((insn >> 20) & 7) {
- case 0: /* 32 x 32 -> 32 */
- tcg_gen_mul_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- if (rs != 15) {
- tmp2 = load_reg(s, rs);
- if (op)
- tcg_gen_sub_i32(tmp, tmp2, tmp);
- else
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- break;
- case 1: /* 16 x 16 -> 32 */
- gen_mulxy(tmp, tmp2, op & 2, op & 1);
- dead_tmp(tmp2);
- if (rs != 15) {
- tmp2 = load_reg(s, rs);
- gen_helper_add_setq(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- break;
- case 2: /* Dual multiply add. */
- case 4: /* Dual multiply subtract. */
- if (op)
- gen_swap_half(tmp2);
- gen_smul_dual(tmp, tmp2);
- /* This addition cannot overflow. */
- if (insn & (1 << 22)) {
- tcg_gen_sub_i32(tmp, tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- }
- dead_tmp(tmp2);
- if (rs != 15)
- {
- tmp2 = load_reg(s, rs);
- gen_helper_add_setq(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- break;
- case 3: /* 32 * 16 -> 32msb */
- if (op)
- tcg_gen_sari_i32(tmp2, tmp2, 16);
- else
- gen_sxth(tmp2);
- tmp2 = gen_muls_i64_i32(tmp, tmp2);
- tcg_gen_shri_i64(tmp2, tmp2, 16);
- tmp = new_tmp();
- tcg_gen_trunc_i64_i32(tmp, tmp2);
- if (rs != 15)
- {
- tmp2 = load_reg(s, rs);
- gen_helper_add_setq(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- break;
- case 5: case 6: /* 32 * 32 -> 32msb */
- gen_imull(tmp, tmp2);
- if (insn & (1 << 5)) {
- gen_roundqd(tmp, tmp2);
- dead_tmp(tmp2);
- } else {
- dead_tmp(tmp);
- tmp = tmp2;
- }
- if (rs != 15) {
- tmp2 = load_reg(s, rs);
- if (insn & (1 << 21)) {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- } else {
- tcg_gen_sub_i32(tmp, tmp2, tmp);
- }
- dead_tmp(tmp2);
- }
- break;
- case 7: /* Unsigned sum of absolute differences. */
- gen_helper_usad8(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- if (rs != 15) {
- tmp2 = load_reg(s, rs);
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- break;
- }
- store_reg(s, rd, tmp);
- break;
- case 6: case 7: /* 64-bit multiply, Divide. */
- op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
- tmp = load_reg(s, rn);
- tmp2 = load_reg(s, rm);
- if ((op & 0x50) == 0x10) {
- /* sdiv, udiv */
- if (!arm_feature(env, ARM_FEATURE_DIV))
- goto illegal_op;
- if (op & 0x20)
- gen_helper_udiv(tmp, tmp, tmp2);
- else
- gen_helper_sdiv(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- store_reg(s, rd, tmp);
- } else if ((op & 0xe) == 0xc) {
- /* Dual multiply accumulate long. */
- if (op & 1)
- gen_swap_half(tmp2);
- gen_smul_dual(tmp, tmp2);
- if (op & 0x10) {
- tcg_gen_sub_i32(tmp, tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- }
- dead_tmp(tmp2);
- tmp2 = tcg_temp_new(TCG_TYPE_I64);
- gen_addq(s, tmp, rs, rd);
- gen_storeq_reg(s, rs, rd, tmp);
- } else {
- if (op & 0x20) {
- /* Unsigned 64-bit multiply */
- tmp = gen_mulu_i64_i32(tmp, tmp2);
- } else {
- if (op & 8) {
- /* smlalxy */
- gen_mulxy(tmp, tmp2, op & 2, op & 1);
- dead_tmp(tmp2);
- tmp2 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_ext_i32_i64(tmp2, tmp);
- dead_tmp(tmp);
- tmp = tmp2;
- } else {
- /* Signed 64-bit multiply */
- tmp = gen_muls_i64_i32(tmp, tmp2);
- }
- }
- if (op & 4) {
- /* umaal */
- gen_addq_lo(s, tmp, rs);
- gen_addq_lo(s, tmp, rd);
- } else if (op & 0x40) {
- /* 64-bit accumulate. */
- gen_addq(s, tmp, rs, rd);
- }
- gen_storeq_reg(s, rs, rd, tmp);
- }
- break;
- }
- break;
- case 6: case 7: case 14: case 15:
- /* Coprocessor. */
- if (((insn >> 24) & 3) == 3) {
- /* Translate into the equivalent ARM encoding. */
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
- if (disas_neon_data_insn(env, s, insn))
- goto illegal_op;
- } else {
- if (insn & (1 << 28))
- goto illegal_op;
- if (disas_coproc_insn (env, s, insn))
- goto illegal_op;
- }
- break;
- case 8: case 9: case 10: case 11:
- if (insn & (1 << 15)) {
- /* Branches, misc control. */
- if (insn & 0x5000) {
- /* Unconditional branch. */
- /* signextend(hw1[10:0]) -> offset[:12]. */
- offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
- /* hw1[10:0] -> offset[11:1]. */
- offset |= (insn & 0x7ff) << 1;
- /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
- offset[24:22] already have the same value because of the
- sign extension above. */
- offset ^= ((~insn) & (1 << 13)) << 10;
- offset ^= ((~insn) & (1 << 11)) << 11;
-
- if (insn & (1 << 14)) {
- /* Branch and link. */
- gen_op_movl_T1_im(s->pc | 1);
- gen_movl_reg_T1(s, 14);
- }
-
- offset += s->pc;
- if (insn & (1 << 12)) {
- /* b/bl */
- gen_jmp(s, offset);
- } else {
- /* blx */
- offset &= ~(uint32_t)2;
- gen_bx_im(s, offset);
- }
- } else if (((insn >> 23) & 7) == 7) {
- /* Misc control */
- if (insn & (1 << 13))
- goto illegal_op;
-
- if (insn & (1 << 26)) {
- /* Secure monitor call (v6Z) */
- goto illegal_op; /* not implemented. */
- } else {
- op = (insn >> 20) & 7;
- switch (op) {
- case 0: /* msr cpsr. */
- if (IS_M(env)) {
- tmp = load_reg(s, rn);
- addr = tcg_const_i32(insn & 0xff);
- gen_helper_v7m_msr(cpu_env, addr, tmp);
- gen_lookup_tb(s);
- break;
- }
- /* fall through */
- case 1: /* msr spsr. */
- if (IS_M(env))
- goto illegal_op;
- gen_movl_T0_reg(s, rn);
- if (gen_set_psr_T0(s,
- msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
- op == 1))
- goto illegal_op;
- break;
- case 2: /* cps, nop-hint. */
- if (((insn >> 8) & 7) == 0) {
- gen_nop_hint(s, insn & 0xff);
- }
- /* Implemented as NOP in user mode. */
- if (IS_USER(s))
- break;
- offset = 0;
- imm = 0;
- if (insn & (1 << 10)) {
- if (insn & (1 << 7))
- offset |= CPSR_A;
- if (insn & (1 << 6))
- offset |= CPSR_I;
- if (insn & (1 << 5))
- offset |= CPSR_F;
- if (insn & (1 << 9))
- imm = CPSR_A | CPSR_I | CPSR_F;
- }
- if (insn & (1 << 8)) {
- offset |= 0x1f;
- imm |= (insn & 0x1f);
- }
- if (offset) {
- gen_op_movl_T0_im(imm);
- gen_set_psr_T0(s, offset, 0);
- }
- break;
- case 3: /* Special control operations. */
- op = (insn >> 4) & 0xf;
- switch (op) {
- case 2: /* clrex */
- gen_helper_clrex(cpu_env);
- break;
- case 4: /* dsb */
- case 5: /* dmb */
- case 6: /* isb */
- /* These execute as NOPs. */
- ARCH(7);
- break;
- default:
- goto illegal_op;
- }
- break;
- case 4: /* bxj */
- /* Trivial implementation equivalent to bx. */
- tmp = load_reg(s, rn);
- gen_bx(s, tmp);
- break;
- case 5: /* Exception return. */
- /* Unpredictable in user mode. */
- goto illegal_op;
- case 6: /* mrs cpsr. */
- tmp = new_tmp();
- if (IS_M(env)) {
- addr = tcg_const_i32(insn & 0xff);
- gen_helper_v7m_mrs(tmp, cpu_env, addr);
- } else {
- gen_helper_cpsr_read(tmp);
- }
- store_reg(s, rd, tmp);
- break;
- case 7: /* mrs spsr. */
- /* Not accessible in user mode. */
- if (IS_USER(s) || IS_M(env))
- goto illegal_op;
- tmp = load_cpu_field(spsr);
- store_reg(s, rd, tmp);
- break;
- }
- }
- } else {
- /* Conditional branch. */
- op = (insn >> 22) & 0xf;
- /* Generate a conditional jump to next instruction. */
- s->condlabel = gen_new_label();
- gen_test_cc(op ^ 1, s->condlabel);
- s->condjmp = 1;
-
- /* offset[11:1] = insn[10:0] */
- offset = (insn & 0x7ff) << 1;
- /* offset[17:12] = insn[21:16]. */
- offset |= (insn & 0x003f0000) >> 4;
- /* offset[31:20] = insn[26]. */
- offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
- /* offset[18] = insn[13]. */
- offset |= (insn & (1 << 13)) << 5;
- /* offset[19] = insn[11]. */
- offset |= (insn & (1 << 11)) << 8;
-
- /* jump to the offset */
- gen_jmp(s, s->pc + offset);
- }
- } else {
- /* Data processing immediate. */
- if (insn & (1 << 25)) {
- if (insn & (1 << 24)) {
- if (insn & (1 << 20))
- goto illegal_op;
- /* Bitfield/Saturate. */
- op = (insn >> 21) & 7;
- imm = insn & 0x1f;
- shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
- if (rn == 15) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- } else {
- tmp = load_reg(s, rn);
- }
- switch (op) {
- case 2: /* Signed bitfield extract. */
- imm++;
- if (shift + imm > 32)
- goto illegal_op;
- if (imm < 32)
- gen_sbfx(tmp, shift, imm);
- break;
- case 6: /* Unsigned bitfield extract. */
- imm++;
- if (shift + imm > 32)
- goto illegal_op;
- if (imm < 32)
- gen_ubfx(tmp, shift, (1u << imm) - 1);
- break;
- case 3: /* Bitfield insert/clear. */
- if (imm < shift)
- goto illegal_op;
- imm = imm + 1 - shift;
- if (imm != 32) {
- tmp2 = load_reg(s, rd);
- gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
- dead_tmp(tmp2);
- }
- break;
- case 7:
- goto illegal_op;
- default: /* Saturate. */
- if (shift) {
- if (op & 1)
- tcg_gen_sari_i32(tmp, tmp, shift);
- else
- tcg_gen_shli_i32(tmp, tmp, shift);
- }
- tmp2 = tcg_const_i32(imm);
- if (op & 4) {
- /* Unsigned. */
- if ((op & 1) && shift == 0)
- gen_helper_usat16(tmp, tmp, tmp2);
- else
- gen_helper_usat(tmp, tmp, tmp2);
- } else {
- /* Signed. */
- if ((op & 1) && shift == 0)
- gen_helper_ssat16(tmp, tmp, tmp2);
- else
- gen_helper_ssat(tmp, tmp, tmp2);
- }
- break;
- }
- store_reg(s, rd, tmp);
- } else {
- imm = ((insn & 0x04000000) >> 15)
- | ((insn & 0x7000) >> 4) | (insn & 0xff);
- if (insn & (1 << 22)) {
- /* 16-bit immediate. */
- imm |= (insn >> 4) & 0xf000;
- if (insn & (1 << 23)) {
- /* movt */
- tmp = load_reg(s, rd);
- tcg_gen_ext16u_i32(tmp, tmp);
- tcg_gen_ori_i32(tmp, tmp, imm << 16);
- } else {
- /* movw */
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, imm);
- }
- } else {
- /* Add/sub 12-bit immediate. */
- if (rn == 15) {
- offset = s->pc & ~(uint32_t)3;
- if (insn & (1 << 23))
- offset -= imm;
- else
- offset += imm;
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, offset);
- } else {
- tmp = load_reg(s, rn);
- if (insn & (1 << 23))
- tcg_gen_subi_i32(tmp, tmp, imm);
- else
- tcg_gen_addi_i32(tmp, tmp, imm);
- }
- }
- store_reg(s, rd, tmp);
- }
- } else {
- int shifter_out = 0;
- /* modified 12-bit immediate. */
- shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
- imm = (insn & 0xff);
- switch (shift) {
- case 0: /* XY */
- /* Nothing to do. */
- break;
- case 1: /* 00XY00XY */
- imm |= imm << 16;
- break;
- case 2: /* XY00XY00 */
- imm |= imm << 16;
- imm <<= 8;
- break;
- case 3: /* XYXYXYXY */
- imm |= imm << 16;
- imm |= imm << 8;
- break;
- default: /* Rotated constant. */
- shift = (shift << 1) | (imm >> 7);
- imm |= 0x80;
- imm = imm << (32 - shift);
- shifter_out = 1;
- break;
- }
- gen_op_movl_T1_im(imm);
- rn = (insn >> 16) & 0xf;
- if (rn == 15)
- gen_op_movl_T0_im(0);
- else
- gen_movl_T0_reg(s, rn);
- op = (insn >> 21) & 0xf;
- if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
- shifter_out))
- goto illegal_op;
- rd = (insn >> 8) & 0xf;
- if (rd != 15) {
- gen_movl_reg_T0(s, rd);
- }
- }
- }
- break;
- case 12: /* Load/store single data item. */
- {
- int postinc = 0;
- int writeback = 0;
- int user;
- if ((insn & 0x01100000) == 0x01000000) {
- if (disas_neon_ls_insn(env, s, insn))
- goto illegal_op;
- break;
- }
- user = IS_USER(s);
- if (rn == 15) {
- addr = new_tmp();
- /* PC relative. */
- /* s->pc has already been incremented by 4. */
- imm = s->pc & 0xfffffffc;
- if (insn & (1 << 23))
- imm += insn & 0xfff;
- else
- imm -= insn & 0xfff;
- tcg_gen_movi_i32(addr, imm);
- } else {
- addr = load_reg(s, rn);
- if (insn & (1 << 23)) {
- /* Positive offset. */
- imm = insn & 0xfff;
- tcg_gen_addi_i32(addr, addr, imm);
- } else {
- op = (insn >> 8) & 7;
- imm = insn & 0xff;
- switch (op) {
- case 0: case 8: /* Shifted Register. */
- shift = (insn >> 4) & 0xf;
- if (shift > 3)
- goto illegal_op;
- tmp = load_reg(s, rm);
- if (shift)
- tcg_gen_shli_i32(tmp, tmp, shift);
- tcg_gen_add_i32(addr, addr, tmp);
- dead_tmp(tmp);
- break;
- case 4: /* Negative offset. */
- tcg_gen_addi_i32(addr, addr, -imm);
- break;
- case 6: /* User privilege. */
- tcg_gen_addi_i32(addr, addr, imm);
- user = 1;
- break;
- case 1: /* Post-decrement. */
- imm = -imm;
- /* Fall through. */
- case 3: /* Post-increment. */
- postinc = 1;
- writeback = 1;
- break;
- case 5: /* Pre-decrement. */
- imm = -imm;
- /* Fall through. */
- case 7: /* Pre-increment. */
- tcg_gen_addi_i32(addr, addr, imm);
- writeback = 1;
- break;
- default:
- goto illegal_op;
- }
- }
- }
- op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
- if (insn & (1 << 20)) {
- /* Load. */
- if (rs == 15 && op != 2) {
- if (op & 2)
- goto illegal_op;
- /* Memory hint. Implemented as NOP. */
- } else {
- switch (op) {
- case 0: tmp = gen_ld8u(addr, user); break;
- case 4: tmp = gen_ld8s(addr, user); break;
- case 1: tmp = gen_ld16u(addr, user); break;
- case 5: tmp = gen_ld16s(addr, user); break;
- case 2: tmp = gen_ld32(addr, user); break;
- default: goto illegal_op;
- }
- if (rs == 15) {
- gen_bx(s, tmp);
- } else {
- store_reg(s, rs, tmp);
- }
- }
- } else {
- /* Store. */
- if (rs == 15)
- goto illegal_op;
- tmp = load_reg(s, rs);
- switch (op) {
- case 0: gen_st8(tmp, addr, user); break;
- case 1: gen_st16(tmp, addr, user); break;
- case 2: gen_st32(tmp, addr, user); break;
- default: goto illegal_op;
- }
- }
- if (postinc)
- tcg_gen_addi_i32(addr, addr, imm);
- if (writeback) {
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- }
- break;
- default:
- goto illegal_op;
- }
- return 0;
-illegal_op:
- return 1;
-}
-
-static void disas_thumb_insn(CPUState *env, DisasContext *s)
-{
- uint32_t val, insn, op, rm, rn, rd, shift, cond;
- int32_t offset;
- int i;
- TCGv tmp;
- TCGv tmp2;
- TCGv addr;
-
- if (s->condexec_mask) {
- cond = s->condexec_cond;
- s->condlabel = gen_new_label();
- gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
- }
-
- insn = lduw_code(s->pc);
-#ifdef CONFIG_TRACE
- if (tracing) {
- int ticks = get_insn_ticks_thumb(insn);
- trace_add_insn( insn_wrap_thumb(insn), 1 );
- gen_helper_traceInsn();
- gen_traceTicks(ticks);
- }
-#endif
- s->pc += 2;
-
- switch (insn >> 12) {
- case 0: case 1:
- rd = insn & 7;
- op = (insn >> 11) & 3;
- if (op == 3) {
- /* add/subtract */
- rn = (insn >> 3) & 7;
- gen_movl_T0_reg(s, rn);
- if (insn & (1 << 10)) {
- /* immediate */
- gen_op_movl_T1_im((insn >> 6) & 7);
- } else {
- /* reg */
- rm = (insn >> 6) & 7;
- gen_movl_T1_reg(s, rm);
- }
- if (insn & (1 << 9)) {
- if (s->condexec_mask)
- gen_op_subl_T0_T1();
- else
- gen_op_subl_T0_T1_cc();
- } else {
- if (s->condexec_mask)
- gen_op_addl_T0_T1();
- else
- gen_op_addl_T0_T1_cc();
- }
- gen_movl_reg_T0(s, rd);
- } else {
- /* shift immediate */
- rm = (insn >> 3) & 7;
- shift = (insn >> 6) & 0x1f;
- tmp = load_reg(s, rm);
- gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
- if (!s->condexec_mask)
- gen_logic_CC(tmp);
- store_reg(s, rd, tmp);
- }
- break;
- case 2: case 3:
- /* arithmetic large immediate */
- op = (insn >> 11) & 3;
- rd = (insn >> 8) & 0x7;
- if (op == 0) {
- gen_op_movl_T0_im(insn & 0xff);
- } else {
- gen_movl_T0_reg(s, rd);
- gen_op_movl_T1_im(insn & 0xff);
- }
- switch (op) {
- case 0: /* mov */
- if (!s->condexec_mask)
- gen_op_logic_T0_cc();
- break;
- case 1: /* cmp */
- gen_op_subl_T0_T1_cc();
- break;
- case 2: /* add */
- if (s->condexec_mask)
- gen_op_addl_T0_T1();
- else
- gen_op_addl_T0_T1_cc();
- break;
- case 3: /* sub */
- if (s->condexec_mask)
- gen_op_subl_T0_T1();
- else
- gen_op_subl_T0_T1_cc();
- break;
- }
- if (op != 1)
- gen_movl_reg_T0(s, rd);
- break;
- case 4:
- if (insn & (1 << 11)) {
- rd = (insn >> 8) & 7;
- /* load pc-relative. Bit 1 of PC is ignored. */
- val = s->pc + 2 + ((insn & 0xff) * 4);
- val &= ~(uint32_t)2;
- addr = new_tmp();
- tcg_gen_movi_i32(addr, val);
- tmp = gen_ld32(addr, IS_USER(s));
- dead_tmp(addr);
- store_reg(s, rd, tmp);
- break;
- }
- if (insn & (1 << 10)) {
- /* data processing extended or blx */
- rd = (insn & 7) | ((insn >> 4) & 8);
- rm = (insn >> 3) & 0xf;
- op = (insn >> 8) & 3;
- switch (op) {
- case 0: /* add */
- gen_movl_T0_reg(s, rd);
- gen_movl_T1_reg(s, rm);
- gen_op_addl_T0_T1();
- gen_movl_reg_T0(s, rd);
- break;
- case 1: /* cmp */
- gen_movl_T0_reg(s, rd);
- gen_movl_T1_reg(s, rm);
- gen_op_subl_T0_T1_cc();
- break;
- case 2: /* mov/cpy */
- gen_movl_T0_reg(s, rm);
- gen_movl_reg_T0(s, rd);
- break;
- case 3:/* branch [and link] exchange thumb register */
- tmp = load_reg(s, rm);
- if (insn & (1 << 7)) {
- val = (uint32_t)s->pc | 1;
- tmp2 = new_tmp();
- tcg_gen_movi_i32(tmp2, val);
- store_reg(s, 14, tmp2);
- }
- gen_bx(s, tmp);
- break;
- }
- break;
- }
-
- /* data processing register */
- rd = insn & 7;
- rm = (insn >> 3) & 7;
- op = (insn >> 6) & 0xf;
- if (op == 2 || op == 3 || op == 4 || op == 7) {
- /* the shift/rotate ops want the operands backwards */
- val = rm;
- rm = rd;
- rd = val;
- val = 1;
- } else {
- val = 0;
- }
-
- if (op == 9) /* neg */
- gen_op_movl_T0_im(0);
- else if (op != 0xf) /* mvn doesn't read its first operand */
- gen_movl_T0_reg(s, rd);
-
- gen_movl_T1_reg(s, rm);
- switch (op) {
- case 0x0: /* and */
- gen_op_andl_T0_T1();
- if (!s->condexec_mask)
- gen_op_logic_T0_cc();
- break;
- case 0x1: /* eor */
- gen_op_xorl_T0_T1();
- if (!s->condexec_mask)
- gen_op_logic_T0_cc();
- break;
- case 0x2: /* lsl */
- if (s->condexec_mask) {
- gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
- } else {
- gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
- gen_op_logic_T1_cc();
- }
- break;
- case 0x3: /* lsr */
- if (s->condexec_mask) {
- gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
- } else {
- gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
- gen_op_logic_T1_cc();
- }
- break;
- case 0x4: /* asr */
- if (s->condexec_mask) {
- gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
- } else {
- gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
- gen_op_logic_T1_cc();
- }
- break;
- case 0x5: /* adc */
- if (s->condexec_mask)
- gen_adc_T0_T1();
- else
- gen_op_adcl_T0_T1_cc();
- break;
- case 0x6: /* sbc */
- if (s->condexec_mask)
- gen_sbc_T0_T1();
- else
- gen_op_sbcl_T0_T1_cc();
- break;
- case 0x7: /* ror */
- if (s->condexec_mask) {
- gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
- } else {
- gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
- gen_op_logic_T1_cc();
- }
- break;
- case 0x8: /* tst */
- gen_op_andl_T0_T1();
- gen_op_logic_T0_cc();
- rd = 16;
- break;
- case 0x9: /* neg */
- if (s->condexec_mask)
- tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
- else
- gen_op_subl_T0_T1_cc();
- break;
- case 0xa: /* cmp */
- gen_op_subl_T0_T1_cc();
- rd = 16;
- break;
- case 0xb: /* cmn */
- gen_op_addl_T0_T1_cc();
- rd = 16;
- break;
- case 0xc: /* orr */
- gen_op_orl_T0_T1();
- if (!s->condexec_mask)
- gen_op_logic_T0_cc();
- break;
- case 0xd: /* mul */
- gen_op_mull_T0_T1();
- if (!s->condexec_mask)
- gen_op_logic_T0_cc();
- break;
- case 0xe: /* bic */
- gen_op_bicl_T0_T1();
- if (!s->condexec_mask)
- gen_op_logic_T0_cc();
- break;
- case 0xf: /* mvn */
- gen_op_notl_T1();
- if (!s->condexec_mask)
- gen_op_logic_T1_cc();
- val = 1;
- rm = rd;
- break;
- }
- if (rd != 16) {
- if (val)
- gen_movl_reg_T1(s, rm);
- else
- gen_movl_reg_T0(s, rd);
- }
- break;
-
- case 5:
- /* load/store register offset. */
- rd = insn & 7;
- rn = (insn >> 3) & 7;
- rm = (insn >> 6) & 7;
- op = (insn >> 9) & 7;
- addr = load_reg(s, rn);
- tmp = load_reg(s, rm);
- tcg_gen_add_i32(addr, addr, tmp);
- dead_tmp(tmp);
-
- if (op < 3) /* store */
- tmp = load_reg(s, rd);
-
- switch (op) {
- case 0: /* str */
- gen_st32(tmp, addr, IS_USER(s));
- break;
- case 1: /* strh */
- gen_st16(tmp, addr, IS_USER(s));
- break;
- case 2: /* strb */
- gen_st8(tmp, addr, IS_USER(s));
- break;
- case 3: /* ldrsb */
- tmp = gen_ld8s(addr, IS_USER(s));
- break;
- case 4: /* ldr */
- tmp = gen_ld32(addr, IS_USER(s));
- break;
- case 5: /* ldrh */
- tmp = gen_ld16u(addr, IS_USER(s));
- break;
- case 6: /* ldrb */
- tmp = gen_ld8u(addr, IS_USER(s));
- break;
- case 7: /* ldrsh */
- tmp = gen_ld16s(addr, IS_USER(s));
- break;
- }
- if (op >= 3) /* load */
- store_reg(s, rd, tmp);
- dead_tmp(addr);
- break;
-
- case 6:
- /* load/store word immediate offset */
- rd = insn & 7;
- rn = (insn >> 3) & 7;
- addr = load_reg(s, rn);
- val = (insn >> 4) & 0x7c;
- tcg_gen_addi_i32(addr, addr, val);
-
- if (insn & (1 << 11)) {
- /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- /* store */
- tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- break;
-
- case 7:
- /* load/store byte immediate offset */
- rd = insn & 7;
- rn = (insn >> 3) & 7;
- addr = load_reg(s, rn);
- val = (insn >> 6) & 0x1f;
- tcg_gen_addi_i32(addr, addr, val);
-
- if (insn & (1 << 11)) {
- /* load */
- tmp = gen_ld8u(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- /* store */
- tmp = load_reg(s, rd);
- gen_st8(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- break;
-
- case 8:
- /* load/store halfword immediate offset */
- rd = insn & 7;
- rn = (insn >> 3) & 7;
- addr = load_reg(s, rn);
- val = (insn >> 5) & 0x3e;
- tcg_gen_addi_i32(addr, addr, val);
-
- if (insn & (1 << 11)) {
- /* load */
- tmp = gen_ld16u(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- /* store */
- tmp = load_reg(s, rd);
- gen_st16(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- break;
-
- case 9:
- /* load/store from stack */
- rd = (insn >> 8) & 7;
- addr = load_reg(s, 13);
- val = (insn & 0xff) * 4;
- tcg_gen_addi_i32(addr, addr, val);
-
- if (insn & (1 << 11)) {
- /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, rd, tmp);
- } else {
- /* store */
- tmp = load_reg(s, rd);
- gen_st32(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- break;
-
- case 10:
- /* add to high reg */
- rd = (insn >> 8) & 7;
- if (insn & (1 << 11)) {
- /* SP */
- tmp = load_reg(s, 13);
- } else {
- /* PC. bit 1 is ignored. */
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
- }
- val = (insn & 0xff) * 4;
- tcg_gen_addi_i32(tmp, tmp, val);
- store_reg(s, rd, tmp);
- break;
-
- case 11:
- /* misc */
- op = (insn >> 8) & 0xf;
- switch (op) {
- case 0:
- /* adjust stack pointer */
- tmp = load_reg(s, 13);
- val = (insn & 0x7f) * 4;
- if (insn & (1 << 7))
- val = -(int32_t)val;
- tcg_gen_addi_i32(tmp, tmp, val);
- store_reg(s, 13, tmp);
- break;
-
- case 2: /* sign/zero extend. */
- ARCH(6);
- rd = insn & 7;
- rm = (insn >> 3) & 7;
- tmp = load_reg(s, rm);
- switch ((insn >> 6) & 3) {
- case 0: gen_sxth(tmp); break;
- case 1: gen_sxtb(tmp); break;
- case 2: gen_uxth(tmp); break;
- case 3: gen_uxtb(tmp); break;
- }
- store_reg(s, rd, tmp);
- break;
- case 4: case 5: case 0xc: case 0xd:
- /* push/pop */
- addr = load_reg(s, 13);
- if (insn & (1 << 8))
- offset = 4;
- else
- offset = 0;
- for (i = 0; i < 8; i++) {
- if (insn & (1 << i))
- offset += 4;
- }
- if ((insn & (1 << 11)) == 0) {
- tcg_gen_addi_i32(addr, addr, -offset);
- }
- for (i = 0; i < 8; i++) {
- if (insn & (1 << i)) {
- if (insn & (1 << 11)) {
- /* pop */
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, i, tmp);
- } else {
- /* push */
- tmp = load_reg(s, i);
- gen_st32(tmp, addr, IS_USER(s));
- }
- /* advance to the next address. */
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
- TCGV_UNUSED(tmp);
- if (insn & (1 << 8)) {
- if (insn & (1 << 11)) {
- /* pop pc */
- tmp = gen_ld32(addr, IS_USER(s));
- /* don't set the pc until the rest of the instruction
- has completed */
- } else {
- /* push lr */
- tmp = load_reg(s, 14);
- gen_st32(tmp, addr, IS_USER(s));
- }
- tcg_gen_addi_i32(addr, addr, 4);
- }
- if ((insn & (1 << 11)) == 0) {
- tcg_gen_addi_i32(addr, addr, -offset);
- }
- /* write back the new stack pointer */
- store_reg(s, 13, addr);
- /* set the new PC value */
- if ((insn & 0x0900) == 0x0900)
- gen_bx(s, tmp);
- break;
-
- case 1: case 3: case 9: case 11: /* czb */
- rm = insn & 7;
- tmp = load_reg(s, rm);
- s->condlabel = gen_new_label();
- s->condjmp = 1;
- if (insn & (1 << 11))
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
- else
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
- dead_tmp(tmp);
- offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
- val = (uint32_t)s->pc + 2;
- val += offset;
- gen_jmp(s, val);
- break;
-
- case 15: /* IT, nop-hint. */
- if ((insn & 0xf) == 0) {
- gen_nop_hint(s, (insn >> 4) & 0xf);
- break;
- }
- /* If Then. */
- s->condexec_cond = (insn >> 4) & 0xe;
- s->condexec_mask = insn & 0x1f;
- /* No actual code generated for this insn, just setup state. */
- break;
-
- case 0xe: /* bkpt */
- gen_set_condexec(s);
- gen_set_pc_im(s->pc - 2);
- gen_exception(EXCP_BKPT);
- s->is_jmp = DISAS_JUMP;
- break;
-
- case 0xa: /* rev */
- ARCH(6);
- rn = (insn >> 3) & 0x7;
- rd = insn & 0x7;
- tmp = load_reg(s, rn);
- switch ((insn >> 6) & 3) {
- case 0: tcg_gen_bswap_i32(tmp, tmp); break;
- case 1: gen_rev16(tmp); break;
- case 3: gen_revsh(tmp); break;
- default: goto illegal_op;
- }
- store_reg(s, rd, tmp);
- break;
-
- case 6: /* cps */
- ARCH(6);
- if (IS_USER(s))
- break;
- if (IS_M(env)) {
- tmp = tcg_const_i32((insn & (1 << 4)) != 0);
- /* PRIMASK */
- if (insn & 1) {
- addr = tcg_const_i32(16);
- gen_helper_v7m_msr(cpu_env, addr, tmp);
- }
- /* FAULTMASK */
- if (insn & 2) {
- addr = tcg_const_i32(17);
- gen_helper_v7m_msr(cpu_env, addr, tmp);
- }
- gen_lookup_tb(s);
- } else {
- if (insn & (1 << 4))
- shift = CPSR_A | CPSR_I | CPSR_F;
- else
- shift = 0;
-
- val = ((insn & 7) << 6) & shift;
- gen_op_movl_T0_im(val);
- gen_set_psr_T0(s, shift, 0);
- }
- break;
-
- default:
- goto undef;
- }
- break;
-
- case 12:
- /* load/store multiple */
- rn = (insn >> 8) & 0x7;
- addr = load_reg(s, rn);
- for (i = 0; i < 8; i++) {
- if (insn & (1 << i)) {
- if (insn & (1 << 11)) {
- /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- store_reg(s, i, tmp);
- } else {
- /* store */
- tmp = load_reg(s, i);
- gen_st32(tmp, addr, IS_USER(s));
- }
- /* advance to the next address */
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
- /* Base register writeback. */
- if ((insn & (1 << rn)) == 0) {
- store_reg(s, rn, addr);
- } else {
- dead_tmp(addr);
- }
- break;
-
- case 13:
- /* conditional branch or swi */
- cond = (insn >> 8) & 0xf;
- if (cond == 0xe)
- goto undef;
-
- if (cond == 0xf) {
- /* swi */
- gen_set_condexec(s);
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_SWI;
- break;
- }
- /* generate a conditional jump to next instruction */
- s->condlabel = gen_new_label();
- gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
- gen_movl_T1_reg(s, 15);
-
- /* jump to the offset */
- val = (uint32_t)s->pc + 2;
- offset = ((int32_t)insn << 24) >> 24;
- val += offset << 1;
- gen_jmp(s, val);
- break;
-
- case 14:
- if (insn & (1 << 11)) {
- if (disas_thumb2_insn(env, s, insn))
- goto undef32;
- break;
- }
- /* unconditional branch */
- val = (uint32_t)s->pc;
- offset = ((int32_t)insn << 21) >> 21;
- val += (offset << 1) + 2;
- gen_jmp(s, val);
- break;
-
- case 15:
- if (disas_thumb2_insn(env, s, insn))
- goto undef32;
- break;
- }
- return;
-undef32:
- gen_set_condexec(s);
- gen_set_pc_im(s->pc - 4);
- gen_exception(EXCP_UDEF);
- s->is_jmp = DISAS_JUMP;
- return;
-illegal_op:
-undef:
- gen_set_condexec(s);
- gen_set_pc_im(s->pc - 2);
- gen_exception(EXCP_UDEF);
- s->is_jmp = DISAS_JUMP;
-}
-
-/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
- basic block 'tb'. If search_pc is TRUE, also generate PC
- information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUState *env,
- TranslationBlock *tb,
- int search_pc)
-{
- DisasContext dc1, *dc = &dc1;
- uint16_t *gen_opc_end;
- int j, lj;
- target_ulong pc_start;
- uint32_t next_page_start;
- int num_insns;
- int max_insns;
-
- /* generate intermediate code */
- num_temps = 0;
- memset(temps, 0, sizeof(temps));
-
- pc_start = tb->pc;
-
- dc->tb = tb;
-
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-
- dc->is_jmp = DISAS_NEXT;
- dc->pc = pc_start;
- dc->singlestep_enabled = env->singlestep_enabled;
- dc->condjmp = 0;
- dc->thumb = env->thumb;
- dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
- dc->condexec_cond = env->condexec_bits >> 4;
- dc->is_mem = 0;
-#if !defined(CONFIG_USER_ONLY)
- if (IS_M(env)) {
- dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
- } else {
- dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
- }
-#endif
- cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
- cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
- cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
- cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
- cpu_V0 = cpu_F0d;
- cpu_V1 = cpu_F1d;
- /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
- cpu_M0 = tcg_temp_new(TCG_TYPE_I64);
- next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
- lj = -1;
- num_insns = 0;
- max_insns = tb->cflags & CF_COUNT_MASK;
- if (max_insns == 0)
- max_insns = CF_COUNT_MASK;
-
- gen_icount_start();
- /* Reset the conditional execution bits immediately. This avoids
- complications trying to do it at the end of the block. */
- if (env->condexec_bits)
- {
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- store_cpu_field(tmp, condexec_bits);
- }
-#ifdef CONFIG_TRACE
- if (tracing) {
- gen_traceBB(trace_static.bb_num, (target_phys_addr_t)tb );
- trace_bb_start(dc->pc);
- }
-#endif
-
- do {
-#ifdef CONFIG_USER_ONLY
- /* Intercept jump to the magic kernel page. */
- if (dc->pc >= 0xffff0000) {
- /* We always get here via a jump, so know we are not in a
- conditional execution block. */
- gen_exception(EXCP_KERNEL_TRAP);
- dc->is_jmp = DISAS_UPDATE;
- break;
- }
-#else
- if (dc->pc >= 0xfffffff0 && IS_M(env)) {
- /* We always get here via a jump, so know we are not in a
- conditional execution block. */
- gen_exception(EXCP_EXCEPTION_EXIT);
- dc->is_jmp = DISAS_UPDATE;
- break;
- }
-#endif
-
- if (env->nb_breakpoints > 0) {
- for(j = 0; j < env->nb_breakpoints; j++) {
- if (env->breakpoints[j] == dc->pc) {
- gen_set_condexec(dc);
- gen_set_pc_im(dc->pc);
- gen_exception(EXCP_DEBUG);
- dc->is_jmp = DISAS_JUMP;
- /* Advance PC so that clearing the breakpoint will
- invalidate this TB. */
- dc->pc += 2;
- goto done_generating;
- break;
- }
- }
- }
- if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
- if (lj < j) {
- lj++;
- while (lj < j)
- gen_opc_instr_start[lj++] = 0;
- }
- gen_opc_pc[lj] = dc->pc;
- gen_opc_instr_start[lj] = 1;
- gen_opc_icount[lj] = num_insns;
- }
-
- if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
- gen_io_start();
-
- if (env->thumb) {
- disas_thumb_insn(env, dc);
- if (dc->condexec_mask) {
- dc->condexec_cond = (dc->condexec_cond & 0xe)
- | ((dc->condexec_mask >> 4) & 1);
- dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
- if (dc->condexec_mask == 0) {
- dc->condexec_cond = 0;
- }
- }
- } else {
- disas_arm_insn(env, dc);
- }
- if (num_temps) {
- fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
- num_temps = 0;
- }
-
- if (dc->condjmp && !dc->is_jmp) {
- gen_set_label(dc->condlabel);
- dc->condjmp = 0;
- }
- /* Terminate the TB on memory ops if watchpoints are present. */
- /* FIXME: This should be replacd by the deterministic execution
- * IRQ raising bits. */
- if (dc->is_mem && env->nb_watchpoints)
- break;
-
- /* Translation stops when a conditional branch is enoutered.
- * Otherwise the subsequent code could get translated several times.
- * Also stop translation when a page boundary is reached. This
- * ensures prefetch aborts occur at the right place. */
- num_insns ++;
- } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
- !env->singlestep_enabled &&
- dc->pc < next_page_start &&
- num_insns < max_insns);
-
-#ifdef CONFIG_TRACE
- if (tracing) {
- trace_bb_end();
- }
-#endif
-
- if (tb->cflags & CF_LAST_IO) {
- if (dc->condjmp) {
- /* FIXME: This can theoretically happen with self-modifying
- code. */
- cpu_abort(env, "IO on conditional branch instruction");
- }
- gen_io_end();
- }
-
- /* At this stage dc->condjmp will only be set when the skipped
- instruction was a conditional branch or trap, and the PC has
- already been written. */
- if (unlikely(env->singlestep_enabled)) {
- /* Make sure the pc is updated, and raise a debug exception. */
- if (dc->condjmp) {
- gen_set_condexec(dc);
- if (dc->is_jmp == DISAS_SWI) {
- gen_exception(EXCP_SWI);
- } else {
- gen_exception(EXCP_DEBUG);
- }
- gen_set_label(dc->condlabel);
- }
- if (dc->condjmp || !dc->is_jmp) {
- gen_set_pc_im(dc->pc);
- dc->condjmp = 0;
- }
- gen_set_condexec(dc);
- if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
- gen_exception(EXCP_SWI);
- } else {
- /* FIXME: Single stepping a WFI insn will not halt
- the CPU. */
- gen_exception(EXCP_DEBUG);
- }
- } else {
- /* While branches must always occur at the end of an IT block,
- there are a few other things that can cause us to terminate
- the TB in the middel of an IT block:
- - Exception generating instructions (bkpt, swi, undefined).
- - Page boundaries.
- - Hardware watchpoints.
- Hardware breakpoints have already been handled and skip this code.
- */
- gen_set_condexec(dc);
- switch(dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, dc->pc);
- break;
- default:
- case DISAS_JUMP:
- case DISAS_UPDATE:
- /* indicate that the hash table must be used to find the next TB */
- tcg_gen_exit_tb(0);
- break;
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
- case DISAS_WFI:
- gen_helper_wfi();
- break;
- case DISAS_SWI:
- gen_exception(EXCP_SWI);
- break;
- }
- if (dc->condjmp) {
- gen_set_label(dc->condlabel);
- gen_set_condexec(dc);
- gen_goto_tb(dc, 1, dc->pc);
- dc->condjmp = 0;
- }
- }
-
-done_generating:
- gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
-
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "----------------\n");
- fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
- target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
- fprintf(logfile, "\n");
- }
-#endif
- if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
- lj++;
- while (lj <= j)
- gen_opc_instr_start[lj++] = 0;
- } else {
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
- }
-}
-
-void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
-{
- gen_intermediate_code_internal(env, tb, 0);
-}
-
-void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
-{
- gen_intermediate_code_internal(env, tb, 1);
-}
-
-static const char *cpu_mode_names[16] = {
- "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
- "???", "???", "???", "und", "???", "???", "???", "sys"
-};
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags)
-{
- int i;
-#if 0
- union {
- uint32_t i;
- float s;
- } s0, s1;
- CPU_DoubleU d;
- /* ??? This assumes float64 and double have the same layout.
- Oh well, it's only debug dumps. */
- union {
- float64 f64;
- double d;
- } d0;
-#endif
- uint32_t psr;
-
- for(i=0;i<16;i++) {
- cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
- if ((i % 4) == 3)
- cpu_fprintf(f, "\n");
- else
- cpu_fprintf(f, " ");
- }
- psr = cpsr_read(env);
- cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
- psr,
- psr & (1 << 31) ? 'N' : '-',
- psr & (1 << 30) ? 'Z' : '-',
- psr & (1 << 29) ? 'C' : '-',
- psr & (1 << 28) ? 'V' : '-',
- psr & CPSR_T ? 'T' : 'A',
- cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
-
-#if 0
- for (i = 0; i < 16; i++) {
- d.d = env->vfp.regs[i];
- s0.i = d.l.lower;
- s1.i = d.l.upper;
- d0.f64 = d.d;
- cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
- i * 2, (int)s0.i, s0.s,
- i * 2 + 1, (int)s1.i, s1.s,
- i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
- d0.d);
- }
- cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
-#endif
-}
-
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc)
-{
- env->regs[15] = gen_opc_pc[pc_pos];
-}
diff --git a/tcg/LICENSE b/tcg/LICENSE
deleted file mode 100644
index be817fa..0000000
--- a/tcg/LICENSE
+++ /dev/null
@@ -1,3 +0,0 @@
-All the files in this directory and subdirectories are released under
-a BSD like license (see header in each file). No other license is
-accepted.
diff --git a/tcg/README b/tcg/README
deleted file mode 100644
index b03432e..0000000
--- a/tcg/README
+++ /dev/null
@@ -1,425 +0,0 @@
-Tiny Code Generator - Fabrice Bellard.
-
-1) Introduction
-
-TCG (Tiny Code Generator) began as a generic backend for a C
-compiler. It was simplified to be used in QEMU. It also has its roots
-in the QOP code generator written by Paul Brook.
-
-2) Definitions
-
-The TCG "target" is the architecture for which we generate the
-code. It is of course not the same as the "target" of QEMU which is
-the emulated architecture. As TCG started as a generic C backend used
-for cross compiling, it is assumed that the TCG target is different
-from the host, although it is never the case for QEMU.
-
-A TCG "function" corresponds to a QEMU Translated Block (TB).
-
-A TCG "temporary" is a variable only live in a basic
-block. Temporaries are allocated explicitly in each function.
-
-A TCG "local temporary" is a variable only live in a function. Local
-temporaries are allocated explicitly in each function.
-
-A TCG "global" is a variable which is live in all the functions
-(equivalent of a C global variable). They are defined before the
-functions defined. A TCG global can be a memory location (e.g. a QEMU
-CPU register), a fixed host register (e.g. the QEMU CPU state pointer)
-or a memory location which is stored in a register outside QEMU TBs
-(not implemented yet).
-
-A TCG "basic block" corresponds to a list of instructions terminated
-by a branch instruction.
-
-3) Intermediate representation
-
-3.1) Introduction
-
-TCG instructions operate on variables which are temporaries, local
-temporaries or globals. TCG instructions and variables are strongly
-typed. Two types are supported: 32 bit integers and 64 bit
-integers. Pointers are defined as an alias to 32 bit or 64 bit
-integers depending on the TCG target word size.
-
-Each instruction has a fixed number of output variable operands, input
-variable operands and always constant operands.
-
-The notable exception is the call instruction which has a variable
-number of outputs and inputs.
-
-In the textual form, output operands usually come first, followed by
-input operands, followed by constant operands. The output type is
-included in the instruction name. Constants are prefixed with a '$'.
-
-add_i32 t0, t1, t2 (t0 <- t1 + t2)
-
-3.2) Assumptions
-
-* Basic blocks
-
-- Basic blocks end after branches (e.g. brcond_i32 instruction),
- goto_tb and exit_tb instructions.
-- Basic blocks end before legacy dyngen operations.
-- Basic blocks start after the end of a previous basic block, at a
- set_label instruction or after a legacy dyngen operation.
-
-After the end of a basic block, the content of temporaries is
-destroyed, but local temporaries and globals are preserved.
-
-* Floating point types are not supported yet
-
-* Pointers: depending on the TCG target, pointer size is 32 bit or 64
- bit. The type TCG_TYPE_PTR is an alias to TCG_TYPE_I32 or
- TCG_TYPE_I64.
-
-* Helpers:
-
-Using the tcg_gen_helper_x_y it is possible to call any function
-taking i32, i64 or pointer types. Before calling an helper, all
-globals are stored at their canonical location and it is assumed that
-the function can modify them. In the future, function modifiers will
-be allowed to tell that the helper does not read or write some globals.
-
-On some TCG targets (e.g. x86), several calling conventions are
-supported.
-
-* Branches:
-
-Use the instruction 'br' to jump to a label. Use 'jmp' to jump to an
-explicit address. Conditional branches can only jump to labels.
-
-3.3) Code Optimizations
-
-When generating instructions, you can count on at least the following
-optimizations:
-
-- Single instructions are simplified, e.g.
-
- and_i32 t0, t0, $0xffffffff
-
- is suppressed.
-
-- A liveness analysis is done at the basic block level. The
- information is used to suppress moves from a dead variable to
- another one. It is also used to remove instructions which compute
- dead results. The later is especially useful for condition code
- optimization in QEMU.
-
- In the following example:
-
- add_i32 t0, t1, t2
- add_i32 t0, t0, $1
- mov_i32 t0, $1
-
- only the last instruction is kept.
-
-3.4) Instruction Reference
-
-********* Function call
-
-* call <ret> <params> ptr
-
-call function 'ptr' (pointer type)
-
-<ret> optional 32 bit or 64 bit return value
-<params> optional 32 bit or 64 bit parameters
-
-********* Jumps/Labels
-
-* jmp t0
-
-Absolute jump to address t0 (pointer type).
-
-* set_label $label
-
-Define label 'label' at the current program point.
-
-* br $label
-
-Jump to label.
-
-* brcond_i32/i64 cond, t0, t1, label
-
-Conditional jump if t0 cond t1 is true. cond can be:
- TCG_COND_EQ
- TCG_COND_NE
- TCG_COND_LT /* signed */
- TCG_COND_GE /* signed */
- TCG_COND_LE /* signed */
- TCG_COND_GT /* signed */
- TCG_COND_LTU /* unsigned */
- TCG_COND_GEU /* unsigned */
- TCG_COND_LEU /* unsigned */
- TCG_COND_GTU /* unsigned */
-
-********* Arithmetic
-
-* add_i32/i64 t0, t1, t2
-
-t0=t1+t2
-
-* sub_i32/i64 t0, t1, t2
-
-t0=t1-t2
-
-* neg_i32/i64 t0, t1
-
-t0=-t1 (two's complement)
-
-* mul_i32/i64 t0, t1, t2
-
-t0=t1*t2
-
-* div_i32/i64 t0, t1, t2
-
-t0=t1/t2 (signed). Undefined behavior if division by zero or overflow.
-
-* divu_i32/i64 t0, t1, t2
-
-t0=t1/t2 (unsigned). Undefined behavior if division by zero.
-
-* rem_i32/i64 t0, t1, t2
-
-t0=t1%t2 (signed). Undefined behavior if division by zero or overflow.
-
-* remu_i32/i64 t0, t1, t2
-
-t0=t1%t2 (unsigned). Undefined behavior if division by zero.
-
-********* Logical
-
-* and_i32/i64 t0, t1, t2
-
-t0=t1&t2
-
-* or_i32/i64 t0, t1, t2
-
-t0=t1|t2
-
-* xor_i32/i64 t0, t1, t2
-
-t0=t1^t2
-
-* not_i32/i64 t0, t1
-
-t0=~t1
-
-********* Shifts
-
-* shl_i32/i64 t0, t1, t2
-
-t0=t1 << t2. Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
-
-* shr_i32/i64 t0, t1, t2
-
-t0=t1 >> t2 (unsigned). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
-
-* sar_i32/i64 t0, t1, t2
-
-t0=t1 >> t2 (signed). Undefined behavior if t2 < 0 or t2 >= 32 (resp 64)
-
-********* Misc
-
-* mov_i32/i64 t0, t1
-
-t0 = t1
-
-Move t1 to t0 (both operands must have the same type).
-
-* ext8s_i32/i64 t0, t1
-ext8u_i32/i64 t0, t1
-ext16s_i32/i64 t0, t1
-ext16u_i32/i64 t0, t1
-ext32s_i64 t0, t1
-ext32u_i64 t0, t1
-
-8, 16 or 32 bit sign/zero extension (both operands must have the same type)
-
-* bswap16_i32 t0, t1
-
-16 bit byte swap on a 32 bit value. The two high order bytes must be set
-to zero.
-
-* bswap_i32 t0, t1
-
-32 bit byte swap
-
-* bswap_i64 t0, t1
-
-64 bit byte swap
-
-* discard_i32/i64 t0
-
-Indicate that the value of t0 won't be used later. It is useful to
-force dead code elimination.
-
-********* Type conversions
-
-* ext_i32_i64 t0, t1
-Convert t1 (32 bit) to t0 (64 bit) and does sign extension
-
-* extu_i32_i64 t0, t1
-Convert t1 (32 bit) to t0 (64 bit) and does zero extension
-
-* trunc_i64_i32 t0, t1
-Truncate t1 (64 bit) to t0 (32 bit)
-
-********* Load/Store
-
-* ld_i32/i64 t0, t1, offset
-ld8s_i32/i64 t0, t1, offset
-ld8u_i32/i64 t0, t1, offset
-ld16s_i32/i64 t0, t1, offset
-ld16u_i32/i64 t0, t1, offset
-ld32s_i64 t0, t1, offset
-ld32u_i64 t0, t1, offset
-
-t0 = read(t1 + offset)
-Load 8, 16, 32 or 64 bits with or without sign extension from host memory.
-offset must be a constant.
-
-* st_i32/i64 t0, t1, offset
-st8_i32/i64 t0, t1, offset
-st16_i32/i64 t0, t1, offset
-st32_i64 t0, t1, offset
-
-write(t0, t1 + offset)
-Write 8, 16, 32 or 64 bits to host memory.
-
-********* QEMU specific operations
-
-* tb_exit t0
-
-Exit the current TB and return the value t0 (word type).
-
-* goto_tb index
-
-Exit the current TB and jump to the TB index 'index' (constant) if the
-current TB was linked to this TB. Otherwise execute the next
-instructions.
-
-* qemu_ld_i32/i64 t0, t1, flags
-qemu_ld8u_i32/i64 t0, t1, flags
-qemu_ld8s_i32/i64 t0, t1, flags
-qemu_ld16u_i32/i64 t0, t1, flags
-qemu_ld16s_i32/i64 t0, t1, flags
-qemu_ld32u_i64 t0, t1, flags
-qemu_ld32s_i64 t0, t1, flags
-
-Load data at the QEMU CPU address t1 into t0. t1 has the QEMU CPU
-address type. 'flags' contains the QEMU memory index (selects user or
-kernel access) for example.
-
-* qemu_st_i32/i64 t0, t1, flags
-qemu_st8_i32/i64 t0, t1, flags
-qemu_st16_i32/i64 t0, t1, flags
-qemu_st32_i64 t0, t1, flags
-
-Store the data t0 at the QEMU CPU Address t1. t1 has the QEMU CPU
-address type. 'flags' contains the QEMU memory index (selects user or
-kernel access) for example.
-
-Note 1: Some shortcuts are defined when the last operand is known to be
-a constant (e.g. addi for add, movi for mov).
-
-Note 2: When using TCG, the opcodes must never be generated directly
-as some of them may not be available as "real" opcodes. Always use the
-function tcg_gen_xxx(args).
-
-4) Backend
-
-tcg-target.h contains the target specific definitions. tcg-target.c
-contains the target specific code.
-
-4.1) Assumptions
-
-The target word size (TCG_TARGET_REG_BITS) is expected to be 32 bit or
-64 bit. It is expected that the pointer has the same size as the word.
-
-On a 32 bit target, all 64 bit operations are converted to 32 bits. A
-few specific operations must be implemented to allow it (see add2_i32,
-sub2_i32, brcond2_i32).
-
-Floating point operations are not supported in this version. A
-previous incarnation of the code generator had full support of them,
-but it is better to concentrate on integer operations first.
-
-On a 64 bit target, no assumption is made in TCG about the storage of
-the 32 bit values in 64 bit registers.
-
-4.2) Constraints
-
-GCC like constraints are used to define the constraints of every
-instruction. Memory constraints are not supported in this
-version. Aliases are specified in the input operands as for GCC.
-
-A target can define specific register or constant constraints. If an
-operation uses a constant input constraint which does not allow all
-constants, it must also accept registers in order to have a fallback.
-
-The movi_i32 and movi_i64 operations must accept any constants.
-
-The mov_i32 and mov_i64 operations must accept any registers of the
-same type.
-
-The ld/st instructions must accept signed 32 bit constant offsets. It
-can be implemented by reserving a specific register to compute the
-address if the offset is too big.
-
-The ld/st instructions must accept any destination (ld) or source (st)
-register.
-
-4.3) Function call assumptions
-
-- The only supported types for parameters and return value are: 32 and
- 64 bit integers and pointer.
-- The stack grows downwards.
-- The first N parameters are passed in registers.
-- The next parameters are passed on the stack by storing them as words.
-- Some registers are clobbered during the call.
-- The function can return 0 or 1 value in registers. On a 32 bit
- target, functions must be able to return 2 values in registers for
- 64 bit return type.
-
-5) Migration from dyngen to TCG
-
-TCG is backward compatible with QEMU "dyngen" operations. It means
-that TCG instructions can be freely mixed with dyngen operations. It
-is expected that QEMU targets will be progressively fully converted to
-TCG. Once a target is fully converted to TCG, it will be possible
-to apply more optimizations because more registers will be free for
-the generated code.
-
-The exception model is the same as the dyngen one.
-
-6) Recommended coding rules for best performance
-
-- Use globals to represent the parts of the QEMU CPU state which are
- often modified, e.g. the integer registers and the condition
- codes. TCG will be able to use host registers to store them.
-
-- Avoid globals stored in fixed registers. They must be used only to
- store the pointer to the CPU state and possibly to store a pointer
- to a register window. The other uses are to ensure backward
- compatibility with dyngen during the porting a new target to TCG.
-
-- Use temporaries. Use local temporaries only when really needed,
- e.g. when you need to use a value after a jump. Local temporaries
- introduce a performance hit in the current TCG implementation: their
- content is saved to memory at end of each basic block.
-
-- Free temporaries and local temporaries when they are no longer used
- (tcg_temp_free). Since tcg_const_x() also creates a temporary, you
- should free it after it is used. Freeing temporaries does not yield
- a better generated code, but it reduces the memory usage of TCG and
- the speed of the translation.
-
-- Don't hesitate to use helpers for complicated or seldom used target
- intructions. There is little performance advantage in using TCG to
- implement target instructions taking more than about twenty TCG
- instructions.
-
-- Use the 'discard' instruction if you know that TCG won't be able to
- prove that a given global is "dead" at a given program point. The
- x86 target uses it to improve the condition codes optimisation.
diff --git a/tcg/TODO b/tcg/TODO
deleted file mode 100644
index 5ca35e9..0000000
--- a/tcg/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
-- Add new instructions such as: andnot, ror, rol, setcond, clz, ctz,
- popcnt.
-
-- See if it is worth exporting mul2, mulu2, div2, divu2.
-
-- Support of globals saved in fixed registers between TBs.
-
-Ideas:
-
-- Move the slow part of the qemu_ld/st ops after the end of the TB.
-
-- Change exception syntax to get closer to QOP system (exception
- parameters given with a specific instruction).
-
-- Add float and vector support.
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
deleted file mode 100644
index dee1ebc..0000000
--- a/tcg/arm/tcg-target.c
+++ /dev/null
@@ -1,1584 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Andrzej Zaborowski
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-const char *tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%r0",
- "%r1",
- "%r2",
- "%r3",
- "%r4",
- "%r5",
- "%r6",
- "%r7",
- "%r8",
- "%r9",
- "%r10",
- "%r11",
- "%r12",
- "%r13",
- "%r14",
-};
-
-int tcg_target_reg_alloc_order[] = {
- TCG_REG_R0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
-};
-
-const int tcg_target_call_iarg_regs[4] = {
- TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3
-};
-const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_R0, TCG_REG_R1
-};
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- switch (type) {
- case R_ARM_ABS32:
- *(uint32_t *) code_ptr = value;
- break;
-
- case R_ARM_CALL:
- case R_ARM_JUMP24:
- default:
- tcg_abort();
-
- case R_ARM_PC24:
- *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & 0xff000000) |
- (((value - ((tcg_target_long) code_ptr + 8)) >> 2) & 0xffffff);
- break;
- }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
- return 4;
-}
-
-/* parse target specific constraints */
-int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch (ct_str[0]) {
- case 'r':
-#ifndef CONFIG_SOFTMMU
- case 'd':
- case 'D':
- case 'x':
- case 'X':
-#endif
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- break;
-
-#ifdef CONFIG_SOFTMMU
- /* qemu_ld/st inputs (unless 'X', 'd' or 'D') */
- case 'x':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
- break;
-
- /* qemu_ld64 data_reg */
- case 'd':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- /* r1 is still needed to load data_reg2, so don't use it. */
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
- break;
-
- /* qemu_ld/st64 data_reg2 */
- case 'D':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- /* r0, r1 and optionally r2 will be overwritten by the address
- * and the low word of data, so don't use these. */
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
-# if TARGET_LONG_BITS == 64
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
-# endif
- break;
-
-# if TARGET_LONG_BITS == 64
- /* qemu_ld/st addr_reg2 */
- case 'X':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- /* r0 will be overwritten by the low word of base, so don't use it. */
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
- break;
-# endif
-#endif
-
- case '1':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
- break;
-
- case '2':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
- break;
-
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
-
- return 0;
-}
-
-/* Test if a constant matches the constraint.
- * TODO: define constraints for:
- *
- * ldr/str offset: between -0xfff and 0xfff
- * ldrh/strh offset: between -0xff and 0xff
- * mov operand2: values represented with x << (2 * y), x < 0x100
- * add, sub, eor...: ditto
- */
-static inline int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- else
- return 0;
-}
-
-enum arm_data_opc_e {
- ARITH_AND = 0x0,
- ARITH_EOR = 0x1,
- ARITH_SUB = 0x2,
- ARITH_RSB = 0x3,
- ARITH_ADD = 0x4,
- ARITH_ADC = 0x5,
- ARITH_SBC = 0x6,
- ARITH_RSC = 0x7,
- ARITH_TST = 0x8,
- ARITH_CMP = 0xa,
- ARITH_CMN = 0xb,
- ARITH_ORR = 0xc,
- ARITH_MOV = 0xd,
- ARITH_BIC = 0xe,
- ARITH_MVN = 0xf,
-};
-
-#define TO_CPSR(opc) \
- ((opc == ARITH_CMP || opc == ARITH_CMN || opc == ARITH_TST) << 20)
-
-#define SHIFT_IMM_LSL(im) (((im) << 7) | 0x00)
-#define SHIFT_IMM_LSR(im) (((im) << 7) | 0x20)
-#define SHIFT_IMM_ASR(im) (((im) << 7) | 0x40)
-#define SHIFT_IMM_ROR(im) (((im) << 7) | 0x60)
-#define SHIFT_REG_LSL(rs) (((rs) << 8) | 0x10)
-#define SHIFT_REG_LSR(rs) (((rs) << 8) | 0x30)
-#define SHIFT_REG_ASR(rs) (((rs) << 8) | 0x50)
-#define SHIFT_REG_ROR(rs) (((rs) << 8) | 0x70)
-
-enum arm_cond_code_e {
- COND_EQ = 0x0,
- COND_NE = 0x1,
- COND_CS = 0x2, /* Unsigned greater or equal */
- COND_CC = 0x3, /* Unsigned less than */
- COND_MI = 0x4, /* Negative */
- COND_PL = 0x5, /* Zero or greater */
- COND_VS = 0x6, /* Overflow */
- COND_VC = 0x7, /* No overflow */
- COND_HI = 0x8, /* Unsigned greater than */
- COND_LS = 0x9, /* Unsigned less or equal */
- COND_GE = 0xa,
- COND_LT = 0xb,
- COND_GT = 0xc,
- COND_LE = 0xd,
- COND_AL = 0xe,
-};
-
-static const uint8_t tcg_cond_to_arm_cond[10] = {
- [TCG_COND_EQ] = COND_EQ,
- [TCG_COND_NE] = COND_NE,
- [TCG_COND_LT] = COND_LT,
- [TCG_COND_GE] = COND_GE,
- [TCG_COND_LE] = COND_LE,
- [TCG_COND_GT] = COND_GT,
- /* unsigned */
- [TCG_COND_LTU] = COND_CC,
- [TCG_COND_GEU] = COND_CS,
- [TCG_COND_LEU] = COND_LS,
- [TCG_COND_GTU] = COND_HI,
-};
-
-static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
-{
- tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
-}
-
-static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
-{
- tcg_out32(s, (cond << 28) | 0x0a000000 |
- (((offset - 8) >> 2) & 0x00ffffff));
-}
-
-static inline void tcg_out_b_noaddr(TCGContext *s, int cond)
-{
-#ifdef WORDS_BIGENDIAN
- tcg_out8(s, (cond << 4) | 0x0a);
- s->code_ptr += 3;
-#else
- s->code_ptr += 3;
- tcg_out8(s, (cond << 4) | 0x0a);
-#endif
-}
-
-static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
-{
- tcg_out32(s, (cond << 28) | 0x0b000000 |
- (((offset - 8) >> 2) & 0x00ffffff));
-}
-
-static inline void tcg_out_dat_reg(TCGContext *s,
- int cond, int opc, int rd, int rn, int rm, int shift)
-{
- tcg_out32(s, (cond << 28) | (0 << 25) | (opc << 21) | TO_CPSR(opc) |
- (rn << 16) | (rd << 12) | shift | rm);
-}
-
-static inline void tcg_out_dat_reg2(TCGContext *s,
- int cond, int opc0, int opc1, int rd0, int rd1,
- int rn0, int rn1, int rm0, int rm1, int shift)
-{
- tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
- (rn0 << 16) | (rd0 << 12) | shift | rm0);
- tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
- (rn1 << 16) | (rd1 << 12) | shift | rm1);
-}
-
-static inline void tcg_out_dat_imm(TCGContext *s,
- int cond, int opc, int rd, int rn, int im)
-{
- tcg_out32(s, (cond << 28) | (1 << 25) | (opc << 21) | TO_CPSR(opc) |
- (rn << 16) | (rd << 12) | im);
-}
-
-static inline void tcg_out_movi32(TCGContext *s,
- int cond, int rd, int32_t arg)
-{
- int offset = (uint32_t) arg - ((uint32_t) s->code_ptr + 8);
-
- /* TODO: This is very suboptimal, we can easily have a constant
- * pool somewhere after all the instructions. */
-
- if (arg < 0 && arg > -0x100)
- return tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0, (~arg) & 0xff);
-
- if (offset < 0x100 && offset > -0x100)
- return offset >= 0 ?
- tcg_out_dat_imm(s, cond, ARITH_ADD, rd, 15, offset) :
- tcg_out_dat_imm(s, cond, ARITH_SUB, rd, 15, -offset);
-
- tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0, arg & 0xff);
- if (arg & 0x0000ff00)
- tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd,
- ((arg >> 8) & 0xff) | 0xc00);
- if (arg & 0x00ff0000)
- tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd,
- ((arg >> 16) & 0xff) | 0x800);
- if (arg & 0xff000000)
- tcg_out_dat_imm(s, cond, ARITH_ORR, rd, rd,
- ((arg >> 24) & 0xff) | 0x400);
-}
-
-static inline void tcg_out_mul32(TCGContext *s,
- int cond, int rd, int rs, int rm)
-{
- if (rd != rm)
- tcg_out32(s, (cond << 28) | (rd << 16) | (0 << 12) |
- (rs << 8) | 0x90 | rm);
- else if (rd != rs)
- tcg_out32(s, (cond << 28) | (rd << 16) | (0 << 12) |
- (rm << 8) | 0x90 | rs);
- else {
- tcg_out32(s, (cond << 28) | ( 8 << 16) | (0 << 12) |
- (rs << 8) | 0x90 | rm);
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- rd, 0, 8, SHIFT_IMM_LSL(0));
- }
-}
-
-static inline void tcg_out_umull32(TCGContext *s,
- int cond, int rd0, int rd1, int rs, int rm)
-{
- if (rd0 != rm && rd1 != rm)
- tcg_out32(s, (cond << 28) | 0x800090 |
- (rd1 << 16) | (rd0 << 12) | (rs << 8) | rm);
- else if (rd0 != rs && rd1 != rs)
- tcg_out32(s, (cond << 28) | 0x800090 |
- (rd1 << 16) | (rd0 << 12) | (rm << 8) | rs);
- else {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- TCG_REG_R8, 0, rm, SHIFT_IMM_LSL(0));
- tcg_out32(s, (cond << 28) | 0x800098 |
- (rd1 << 16) | (rd0 << 12) | (rs << 8));
- }
-}
-
-static inline void tcg_out_smull32(TCGContext *s,
- int cond, int rd0, int rd1, int rs, int rm)
-{
- if (rd0 != rm && rd1 != rm)
- tcg_out32(s, (cond << 28) | 0xc00090 |
- (rd1 << 16) | (rd0 << 12) | (rs << 8) | rm);
- else if (rd0 != rs && rd1 != rs)
- tcg_out32(s, (cond << 28) | 0xc00090 |
- (rd1 << 16) | (rd0 << 12) | (rm << 8) | rs);
- else {
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- TCG_REG_R8, 0, rm, SHIFT_IMM_LSL(0));
- tcg_out32(s, (cond << 28) | 0xc00098 |
- (rd1 << 16) | (rd0 << 12) | (rs << 8));
- }
-}
-
-static inline void tcg_out_ld32_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05900000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05100000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_st32_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05800000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05000000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_ld32_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x07900000 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st32_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x07800000 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-/* Register pre-increment with base writeback. */
-static inline void tcg_out_ld32_rwb(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x07b00000 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st32_rwb(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x07a00000 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld16u_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01d000b0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x015000b0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_st16u_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01c000b0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x014000b0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_ld16u_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x019000b0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st16u_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x018000b0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld16s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01d000f0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x015000f0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_st16s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01c000f0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x014000f0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_ld16s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x019000f0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st16s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x018000f0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld8_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05d00000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05500000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_st8_12(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x05c00000 |
- (rn << 16) | (rd << 12) | (im & 0xfff));
- else
- tcg_out32(s, (cond << 28) | 0x05400000 |
- (rn << 16) | (rd << 12) | ((-im) & 0xfff));
-}
-
-static inline void tcg_out_ld8_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x07d00000 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st8_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x07c00000 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld8s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01d000d0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x015000d0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_st8s_8(TCGContext *s, int cond,
- int rd, int rn, tcg_target_long im)
-{
- if (im >= 0)
- tcg_out32(s, (cond << 28) | 0x01c000d0 |
- (rn << 16) | (rd << 12) |
- ((im & 0xf0) << 4) | (im & 0xf));
- else
- tcg_out32(s, (cond << 28) | 0x014000d0 |
- (rn << 16) | (rd << 12) |
- (((-im) & 0xf0) << 4) | ((-im) & 0xf));
-}
-
-static inline void tcg_out_ld8s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x019000d0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_st8s_r(TCGContext *s, int cond,
- int rd, int rn, int rm)
-{
- tcg_out32(s, (cond << 28) | 0x018000d0 |
- (rn << 16) | (rd << 12) | rm);
-}
-
-static inline void tcg_out_ld32u(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xfff || offset < -0xfff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_ld32_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_st32(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xfff || offset < -0xfff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_st32_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_st32_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld16u(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xff || offset < -0xff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_ld16u_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld16s(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xff || offset < -0xff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_ld16s_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_ld16s_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_st16u(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xff || offset < -0xff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_st16u_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_st16u_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld8u(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xfff || offset < -0xfff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_ld8_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_ld8s(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xff || offset < -0xff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_ld8s_8(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_st8u(TCGContext *s, int cond,
- int rd, int rn, int32_t offset)
-{
- if (offset > 0xfff || offset < -0xfff) {
- tcg_out_movi32(s, cond, TCG_REG_R8, offset);
- tcg_out_st8_r(s, cond, rd, rn, TCG_REG_R8);
- } else
- tcg_out_st8_12(s, cond, rd, rn, offset);
-}
-
-static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
-{
- int32_t val;
-
- val = addr - (tcg_target_long) s->code_ptr;
- if (val - 8 < 0x01fffffd && val - 8 > -0x01fffffd)
- tcg_out_b(s, cond, val);
- else {
-#if 1
- tcg_abort();
-#else
- if (cond == COND_AL) {
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
- tcg_out32(s, addr); /* XXX: This is l->u.value, can we use it? */
- } else {
- tcg_out_movi32(s, cond, TCG_REG_R8, val - 8);
- tcg_out_dat_reg(s, cond, ARITH_ADD,
- 15, 15, TCG_REG_R8, SHIFT_IMM_LSL(0));
- }
-#endif
- }
-}
-
-static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr)
-{
- int32_t val;
-
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R8, 0, 14, SHIFT_IMM_LSL(0));
-#endif
-
- val = addr - (tcg_target_long) s->code_ptr;
- if (val < 0x01fffffd && val > -0x01fffffd)
- tcg_out_bl(s, cond, val);
- else {
-#if 1
- tcg_abort();
-#else
- if (cond == COND_AL) {
- tcg_out_dat_imm(s, cond, ARITH_ADD, 14, 15, 4);
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
- tcg_out32(s, addr); /* XXX: This is l->u.value, can we use it? */
- } else {
- tcg_out_movi32(s, cond, TCG_REG_R9, addr);
- tcg_out_dat_imm(s, cond, ARITH_MOV, 14, 0, 15);
- tcg_out_bx(s, cond, TCG_REG_R9);
- }
-#endif
- }
-
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
-#endif
-}
-
-static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
-{
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R8, 0, 14, SHIFT_IMM_LSL(0));
-#endif
- /* TODO: on ARMv5 and ARMv6 replace with tcg_out_blx(s, cond, arg); */
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 15, SHIFT_IMM_LSL(0));
- tcg_out_bx(s, cond, arg);
-#ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
-#endif
-}
-
-static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
-{
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value)
- tcg_out_goto(s, cond, l->u.value);
- else if (cond == COND_AL) {
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
- tcg_out_reloc(s, s->code_ptr, R_ARM_ABS32, label_index, 31337);
- s->code_ptr += 4;
- } else {
- /* Probably this should be preferred even for COND_AL... */
- tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 31337);
- tcg_out_b_noaddr(s, cond);
- }
-}
-
-static void tcg_out_div_helper(TCGContext *s, int cond, const TCGArg *args,
- void *helper_div, void *helper_rem, int shift)
-{
- int div_reg = args[0];
- int rem_reg = args[1];
-
- /* stmdb sp!, { r0 - r3, ip, lr } */
- /* (Note that we need an even number of registers as per EABI) */
- tcg_out32(s, (cond << 28) | 0x092d500f);
-
- tcg_out_dat_reg(s, cond, ARITH_MOV, 0, 0, args[2], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, 1, 0, args[3], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, 2, 0, args[4], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, 3, 0, 2, shift);
-
- tcg_out_call(s, cond, (uint32_t) helper_div);
- tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 0, SHIFT_IMM_LSL(0));
-
- /* ldmia sp, { r0 - r3, fp, lr } */
- tcg_out32(s, (cond << 28) | 0x089d500f);
-
- tcg_out_dat_reg(s, cond, ARITH_MOV, 0, 0, args[2], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, 1, 0, args[3], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, 2, 0, args[4], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, 3, 0, 2, shift);
-
- tcg_out_call(s, cond, (uint32_t) helper_rem);
-
- tcg_out_dat_reg(s, cond, ARITH_MOV, rem_reg, 0, 0, SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, cond, ARITH_MOV, div_reg, 0, 8, SHIFT_IMM_LSL(0));
-
- /* ldr r0, [sp], #4 */
- if (rem_reg != 0 && div_reg != 0)
- tcg_out32(s, (cond << 28) | 0x04bd0004);
- /* ldr r1, [sp], #4 */
- if (rem_reg != 1 && div_reg != 1)
- tcg_out32(s, (cond << 28) | 0x04bd1004);
- /* ldr r2, [sp], #4 */
- if (rem_reg != 2 && div_reg != 2)
- tcg_out32(s, (cond << 28) | 0x04bd2004);
- /* ldr r3, [sp], #4 */
- if (rem_reg != 3 && div_reg != 3)
- tcg_out32(s, (cond << 28) | 0x04bd3004);
- /* ldr ip, [sp], #4 */
- if (rem_reg != 12 && div_reg != 12)
- tcg_out32(s, (cond << 28) | 0x04bdc004);
- /* ldr lr, [sp], #4 */
- if (rem_reg != 14 && div_reg != 14)
- tcg_out32(s, (cond << 28) | 0x04bde004);
-}
-
-#ifdef CONFIG_SOFTMMU
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-#define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
-
-static inline void tcg_out_qemu_ld(TCGContext *s, int cond,
- const TCGArg *args, int opc)
-{
- int addr_reg, data_reg, data_reg2;
-#ifdef CONFIG_SOFTMMU
- int mem_index, s_bits;
-# if TARGET_LONG_BITS == 64
- int addr_reg2;
-# endif
- uint32_t *label_ptr;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0; /* surpress warning */
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
-#ifdef CONFIG_SOFTMMU
- mem_index = *args;
- s_bits = opc & 3;
-
- /* Should generate something like the following:
- * shr r8, addr_reg, #TARGET_PAGE_BITS
- * and r0, r8, #(CPU_TLB_SIZE - 1) @ Assumption: CPU_TLB_BITS <= 8
- * add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
- */
-# if CPU_TLB_BITS > 8
-# error
-# endif
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- 8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
- tcg_out_dat_imm(s, COND_AL, ARITH_AND,
- 0, 8, CPU_TLB_SIZE - 1);
- tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
- 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
- /* In the
- * ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_read))]
- * below, the offset is likely to exceed 12 bits if mem_index != 0 and
- * not exceed otherwise, so use an
- * add r0, r0, #(mem_index * sizeof *CPUState.tlb_table)
- * before.
- */
- if (mem_index)
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0,
- (mem_index << (TLB_SHIFT & 1)) |
- ((16 - (TLB_SHIFT >> 1)) << 8));
- tcg_out_ld32_12(s, COND_AL, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addr_read));
- tcg_out_dat_reg(s, COND_AL, ARITH_CMP,
- 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
- /* Check alignment. */
- if (s_bits)
- tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
- 0, addr_reg, (1 << s_bits) - 1);
-# if TARGET_LONG_BITS == 64
- /* XXX: possibly we could use a block data load or writeback in
- * the first access. */
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addr_read) + 4);
- tcg_out_dat_reg(s, COND_EQ, ARITH_CMP,
- 0, 1, addr_reg2, SHIFT_IMM_LSL(0));
-# endif
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addend));
-
- switch (opc) {
- case 0:
- tcg_out_ld8_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 0 | 4:
- tcg_out_ld8s_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 1:
- tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 1 | 4:
- tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 2:
- default:
- tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 3:
- tcg_out_ld32_rwb(s, COND_EQ, data_reg, 1, addr_reg);
- tcg_out_ld32_12(s, COND_EQ, data_reg2, 1, 4);
- break;
- }
-
- label_ptr = (void *) s->code_ptr;
- tcg_out_b(s, COND_EQ, 8);
-
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0));
-# endif
-
- /* TODO: move this code to where the constants pool will be */
- if (addr_reg)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, addr_reg, SHIFT_IMM_LSL(0));
-# if TARGET_LONG_BITS == 32
- tcg_out_dat_imm(s, cond, ARITH_MOV, 1, 0, mem_index);
-# else
- if (addr_reg2 != 1)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, addr_reg2, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
-# endif
- tcg_out_bl(s, cond, (tcg_target_long) qemu_ld_helpers[s_bits] -
- (tcg_target_long) s->code_ptr);
-
- switch (opc) {
- case 0 | 4:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, 0, SHIFT_IMM_LSL(24));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_ASR(24));
- break;
- case 1 | 4:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, 0, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_ASR(16));
- break;
- case 0:
- case 1:
- case 2:
- default:
- if (data_reg)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_LSL(0));
- break;
- case 3:
- if (data_reg != 0)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg, 0, 0, SHIFT_IMM_LSL(0));
- if (data_reg2 != 1)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- data_reg2, 0, 1, SHIFT_IMM_LSL(0));
- break;
- }
-
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 8, SHIFT_IMM_LSL(0));
-# endif
-
- *label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
-#else
- switch (opc) {
- case 0:
- tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 0 | 4:
- tcg_out_ld8s_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 1:
- tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 1 | 4:
- tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 2:
- default:
- tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 3:
- /* TODO: use block load -
- * check that data_reg2 > data_reg or the other way */
- tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
- tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, 4);
- break;
- }
-#endif
-}
-
-static inline void tcg_out_qemu_st(TCGContext *s, int cond,
- const TCGArg *args, int opc)
-{
- int addr_reg, data_reg, data_reg2;
-#ifdef CONFIG_SOFTMMU
- int mem_index, s_bits;
-# if TARGET_LONG_BITS == 64
- int addr_reg2;
-# endif
- uint32_t *label_ptr;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0; /* surpress warning */
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
-#ifdef CONFIG_SOFTMMU
- mem_index = *args;
- s_bits = opc & 3;
-
- /* Should generate something like the following:
- * shr r8, addr_reg, #TARGET_PAGE_BITS
- * and r0, r8, #(CPU_TLB_SIZE - 1) @ Assumption: CPU_TLB_BITS <= 8
- * add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
- */
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- 8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
- tcg_out_dat_imm(s, COND_AL, ARITH_AND,
- 0, 8, CPU_TLB_SIZE - 1);
- tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
- 0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
- /* In the
- * ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_write))]
- * below, the offset is likely to exceed 12 bits if mem_index != 0 and
- * not exceed otherwise, so use an
- * add r0, r0, #(mem_index * sizeof *CPUState.tlb_table)
- * before.
- */
- if (mem_index)
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0,
- (mem_index << (TLB_SHIFT & 1)) |
- ((16 - (TLB_SHIFT >> 1)) << 8));
- tcg_out_ld32_12(s, COND_AL, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addr_write));
- tcg_out_dat_reg(s, COND_AL, ARITH_CMP,
- 0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
- /* Check alignment. */
- if (s_bits)
- tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
- 0, addr_reg, (1 << s_bits) - 1);
-# if TARGET_LONG_BITS == 64
- /* XXX: possibly we could use a block data load or writeback in
- * the first access. */
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addr_write)
- + 4);
- tcg_out_dat_reg(s, COND_EQ, ARITH_CMP,
- 0, 1, addr_reg2, SHIFT_IMM_LSL(0));
-# endif
- tcg_out_ld32_12(s, COND_EQ, 1, 0,
- offsetof(CPUState, tlb_table[0][0].addend));
-
- switch (opc) {
- case 0:
- tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 0 | 4:
- tcg_out_st8s_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 1:
- tcg_out_st16u_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 1 | 4:
- tcg_out_st16s_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 2:
- default:
- tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, 1);
- break;
- case 3:
- tcg_out_st32_rwb(s, COND_EQ, data_reg, 1, addr_reg);
- tcg_out_st32_12(s, COND_EQ, data_reg2, 1, 4);
- break;
- }
-
- label_ptr = (void *) s->code_ptr;
- tcg_out_b(s, COND_EQ, 8);
-
- /* TODO: move this code to where the constants pool will be */
- if (addr_reg)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 0, 0, addr_reg, SHIFT_IMM_LSL(0));
-# if TARGET_LONG_BITS == 32
- switch (opc) {
- case 0:
- tcg_out_dat_imm(s, cond, ARITH_AND, 1, data_reg, 0xff);
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
- break;
- case 1:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, data_reg, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, 1, SHIFT_IMM_LSR(16));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
- break;
- case 2:
- if (data_reg != 1)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, data_reg, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);
- break;
- case 3:
- if (data_reg != 1)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, data_reg, SHIFT_IMM_LSL(0));
- if (data_reg2 != 2)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg2, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
- break;
- }
-# else
- if (addr_reg2 != 1)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 1, 0, addr_reg2, SHIFT_IMM_LSL(0));
- switch (opc) {
- case 0:
- tcg_out_dat_imm(s, cond, ARITH_AND, 2, data_reg, 0xff);
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
- break;
- case 1:
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg, SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, 2, SHIFT_IMM_LSR(16));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
- break;
- case 2:
- if (data_reg != 2)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg, SHIFT_IMM_LSL(0));
- tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);
- break;
- case 3:
- tcg_out_dat_imm(s, cond, ARITH_MOV, 8, 0, mem_index);
- tcg_out32(s, (cond << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
- if (data_reg != 2)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 2, 0, data_reg, SHIFT_IMM_LSL(0));
- if (data_reg2 != 3)
- tcg_out_dat_reg(s, cond, ARITH_MOV,
- 3, 0, data_reg2, SHIFT_IMM_LSL(0));
- break;
- }
-# endif
-
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0));
-# endif
-
- tcg_out_bl(s, cond, (tcg_target_long) qemu_st_helpers[s_bits] -
- (tcg_target_long) s->code_ptr);
-# if TARGET_LONG_BITS == 64
- if (opc == 3)
- tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 0x10);
-# endif
-
-# ifdef SAVE_LR
- tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 8, SHIFT_IMM_LSL(0));
-# endif
-
- *label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;
-#else
- switch (opc) {
- case 0:
- tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 0 | 4:
- tcg_out_st8s_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 1:
- tcg_out_st16u_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 1 | 4:
- tcg_out_st16s_8(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 2:
- default:
- tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
- break;
- case 3:
- /* TODO: use block store -
- * check that data_reg2 > data_reg or the other way */
- tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
- tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
- break;
- }
-#endif
-}
-
-static uint8_t *tb_ret_addr;
-
-static inline void tcg_out_op(TCGContext *s, int opc,
- const TCGArg *args, const int *const_args)
-{
- int c;
-
- switch (opc) {
- case INDEX_op_exit_tb:
-#ifdef SAVE_LR
- if (args[0] >> 8)
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, 15, 0);
- else
- tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, 15, 0, 14, SHIFT_IMM_LSL(0));
- if (args[0] >> 8)
- tcg_out32(s, args[0]);
-#else
- if (args[0] >> 8)
- tcg_out_ld32_12(s, COND_AL, 0, 15, 0);
- else
- tcg_out_dat_imm(s, COND_AL, ARITH_MOV, 0, 0, args[0]);
- tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
- if (args[0] >> 8)
- tcg_out32(s, args[0]);
-#endif
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* Direct jump method */
-#if 1
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- tcg_out_b(s, COND_AL, 8);
-#else
- tcg_out_ld32_12(s, COND_AL, 15, 15, -4);
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- tcg_out32(s, 0);
-#endif
- } else {
- /* Indirect jump method */
-#if 1
- c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);
- if (c > 0xfff || c < -0xfff) {
- tcg_out_movi32(s, COND_AL, TCG_REG_R0,
- (tcg_target_long) (s->tb_next + args[0]));
- tcg_out_ld32_12(s, COND_AL, 15, TCG_REG_R0, 0);
- } else
- tcg_out_ld32_12(s, COND_AL, 15, 15, c);
-#else
- tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, 15, 0);
- tcg_out_ld32_12(s, COND_AL, 15, TCG_REG_R0, 0);
- tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
-#endif
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_call:
- if (const_args[0])
- tcg_out_call(s, COND_AL, args[0]);
- else
- tcg_out_callr(s, COND_AL, args[0]);
- break;
- case INDEX_op_jmp:
- if (const_args[0])
- tcg_out_goto(s, COND_AL, args[0]);
- else
- tcg_out_bx(s, COND_AL, args[0]);
- break;
- case INDEX_op_br:
- tcg_out_goto_label(s, COND_AL, args[0]);
- break;
-
- case INDEX_op_ld8u_i32:
- tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld8s_i32:
- tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16u_i32:
- tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16s_i32:
- tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld_i32:
- tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_st8_i32:
- tcg_out_st8u(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_st16_i32:
- tcg_out_st16u(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_st_i32:
- tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
- break;
-
- case INDEX_op_mov_i32:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[1], SHIFT_IMM_LSL(0));
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi32(s, COND_AL, args[0], args[1]);
- break;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
- goto gen_arith;
- case INDEX_op_sub_i32:
- c = ARITH_SUB;
- goto gen_arith;
- case INDEX_op_and_i32:
- c = ARITH_AND;
- goto gen_arith;
- case INDEX_op_or_i32:
- c = ARITH_ORR;
- goto gen_arith;
- case INDEX_op_xor_i32:
- c = ARITH_EOR;
- /* Fall through. */
- gen_arith:
- tcg_out_dat_reg(s, COND_AL, c,
- args[0], args[1], args[2], SHIFT_IMM_LSL(0));
- break;
- case INDEX_op_add2_i32:
- tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC,
- args[0], args[1], args[2], args[3],
- args[4], args[5], SHIFT_IMM_LSL(0));
- break;
- case INDEX_op_sub2_i32:
- tcg_out_dat_reg2(s, COND_AL, ARITH_SUB, ARITH_SBC,
- args[0], args[1], args[2], args[3],
- args[4], args[5], SHIFT_IMM_LSL(0));
- break;
- case INDEX_op_neg_i32:
- tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
- break;
- case INDEX_op_mul_i32:
- tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
- break;
- case INDEX_op_mulu2_i32:
- tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
- break;
- case INDEX_op_div2_i32:
- tcg_out_div_helper(s, COND_AL, args,
- tcg_helper_div_i64, tcg_helper_rem_i64,
- SHIFT_IMM_ASR(31));
- break;
- case INDEX_op_divu2_i32:
- tcg_out_div_helper(s, COND_AL, args,
- tcg_helper_divu_i64, tcg_helper_remu_i64,
- SHIFT_IMM_LSR(31));
- break;
- /* XXX: Perhaps args[2] & 0x1f is wrong */
- case INDEX_op_shl_i32:
- c = const_args[2] ?
- SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
- goto gen_shift32;
- case INDEX_op_shr_i32:
- c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
- SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
- goto gen_shift32;
- case INDEX_op_sar_i32:
- c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
- SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
- /* Fall through. */
- gen_shift32:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
- break;
-
- case INDEX_op_brcond_i32:
- tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
- args[0], args[1], SHIFT_IMM_LSL(0));
- tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
- break;
- case INDEX_op_brcond2_i32:
- /* The resulting conditions are:
- * TCG_COND_EQ --> a0 == a2 && a1 == a3,
- * TCG_COND_NE --> (a0 != a2 && a1 == a3) || a1 != a3,
- * TCG_COND_LT(U) --> (a0 < a2 && a1 == a3) || a1 < a3,
- * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),
- * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),
- * TCG_COND_GT(U) --> (a0 > a2 && a1 == a3) || a1 > a3,
- */
- tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
- args[1], args[3], SHIFT_IMM_LSL(0));
- tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
- args[0], args[2], SHIFT_IMM_LSL(0));
- tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, COND_AL, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, COND_AL, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, COND_AL, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, COND_AL, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, COND_AL, args, 2);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, COND_AL, args, 3);
- break;
-
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, COND_AL, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, COND_AL, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, COND_AL, args, 2);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, COND_AL, args, 3);
- break;
-
- case INDEX_op_ext8s_i32:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[1], SHIFT_IMM_LSL(24));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[0], SHIFT_IMM_ASR(24));
- break;
- case INDEX_op_ext16s_i32:
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[1], SHIFT_IMM_LSL(16));
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
- args[0], 0, args[0], SHIFT_IMM_ASR(16));
- break;
-
- default:
- tcg_abort();
- }
-}
-
-static const TCGTargetOpDef arm_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } },
- { INDEX_op_jmp, { "ri" } },
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
-
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- /* TODO: "r", "r", "ri" */
- { INDEX_op_add_i32, { "r", "r", "r" } },
- { INDEX_op_sub_i32, { "r", "r", "r" } },
- { INDEX_op_mul_i32, { "r", "r", "r" } },
- { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
- { INDEX_op_div2_i32, { "r", "r", "r", "1", "2" } },
- { INDEX_op_divu2_i32, { "r", "r", "r", "1", "2" } },
- { INDEX_op_and_i32, { "r", "r", "r" } },
- { INDEX_op_or_i32, { "r", "r", "r" } },
- { INDEX_op_xor_i32, { "r", "r", "r" } },
- { INDEX_op_neg_i32, { "r", "r" } },
-
- { INDEX_op_shl_i32, { "r", "r", "ri" } },
- { INDEX_op_shr_i32, { "r", "r", "ri" } },
- { INDEX_op_sar_i32, { "r", "r", "ri" } },
-
- { INDEX_op_brcond_i32, { "r", "r" } },
-
- /* TODO: "r", "r", "r", "r", "ri", "ri" */
- { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
- { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
- { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
-
- { INDEX_op_qemu_ld8u, { "r", "x", "X" } },
- { INDEX_op_qemu_ld8s, { "r", "x", "X" } },
- { INDEX_op_qemu_ld16u, { "r", "x", "X" } },
- { INDEX_op_qemu_ld16s, { "r", "x", "X" } },
- { INDEX_op_qemu_ld32u, { "r", "x", "X" } },
- { INDEX_op_qemu_ld64, { "d", "r", "x", "X" } },
-
- { INDEX_op_qemu_st8, { "x", "x", "X" } },
- { INDEX_op_qemu_st16, { "x", "x", "X" } },
- { INDEX_op_qemu_st32, { "x", "x", "X" } },
- { INDEX_op_qemu_st64, { "x", "D", "x", "X" } },
-
- { INDEX_op_ext8s_i32, { "r", "r" } },
- { INDEX_op_ext16s_i32, { "r", "r" } },
-
- { -1 },
-};
-
-void tcg_target_init(TCGContext *s)
-{
- /* fail safe */
- if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
- tcg_abort();
-
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0,
- ((2 << TCG_REG_R14) - 1) & ~(1 << TCG_REG_R8));
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- ((2 << TCG_REG_R3) - 1) |
- (1 << TCG_REG_R12) | (1 << TCG_REG_R14));
-
- tcg_regset_clear(s->reserved_regs);
-#ifdef SAVE_LR
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R14);
-#endif
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R8);
-
- tcg_add_target_add_op_defs(arm_op_defs);
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
- int arg1, tcg_target_long arg2)
-{
- tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
- int arg1, tcg_target_long arg2)
-{
- tcg_out_st32(s, COND_AL, arg, arg1, arg2);
-}
-
-void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val > 0)
- if (val < 0x100)
- tcg_out_dat_imm(s, COND_AL, ARITH_ADD, reg, reg, val);
- else
- tcg_abort();
- else if (val < 0) {
- if (val > -0x100)
- tcg_out_dat_imm(s, COND_AL, ARITH_SUB, reg, reg, -val);
- else
- tcg_abort();
- }
-}
-
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
- tcg_out_movi32(s, COND_AL, ret, arg);
-}
-
-void tcg_target_qemu_prologue(TCGContext *s)
-{
- /* stmdb sp!, { r9 - r11, lr } */
- tcg_out32(s, (COND_AL << 28) | 0x092d4e00);
-
- tcg_out_bx(s, COND_AL, TCG_REG_R0);
- tb_ret_addr = s->code_ptr;
-
- /* ldmia sp!, { r9 - r11, pc } */
- tcg_out32(s, (COND_AL << 28) | 0x08bd8e00);
-}
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
deleted file mode 100644
index 6c180af..0000000
--- a/tcg/arm/tcg-target.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- * Copyright (c) 2008 Andrzej Zaborowski
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_ARM 1
-
-#define TCG_TARGET_REG_BITS 32
-#undef TCG_TARGET_WORDS_BIGENDIAN
-#undef TCG_TARGET_HAS_div_i32
-#undef TCG_TARGET_HAS_div_i64
-#undef TCG_TARGET_HAS_bswap_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_neg_i32
-#undef TCG_TARGET_HAS_neg_i64
-#undef TCG_TARGET_STACK_GROWSUP
-
-enum {
- TCG_REG_R0 = 0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_TARGET_NB_REGS
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_R13
-#define TCG_TARGET_STACK_ALIGN 8
-#define TCG_TARGET_CALL_STACK_OFFSET 0
-
-enum {
- /* Note: must be synced with dyngen-exec.h */
- TCG_AREG0 = TCG_REG_R7,
- TCG_AREG1 = TCG_REG_R4,
- TCG_AREG2 = TCG_REG_R5,
- TCG_AREG3 = TCG_REG_R6,
-};
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- register unsigned long _beg __asm ("a1") = start;
- register unsigned long _end __asm ("a2") = stop;
- register unsigned long _flg __asm ("a3") = 0;
- __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-}
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
deleted file mode 100644
index 3affd26..0000000
--- a/tcg/hppa/tcg-target.c
+++ /dev/null
@@ -1,973 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%r0",
- "%r1",
- "%rp",
- "%r3",
- "%r4",
- "%r5",
- "%r6",
- "%r7",
- "%r8",
- "%r9",
- "%r10",
- "%r11",
- "%r12",
- "%r13",
- "%r14",
- "%r15",
- "%r16",
- "%r17",
- "%r18",
- "%r19",
- "%r20",
- "%r21",
- "%r22",
- "%r23",
- "%r24",
- "%r25",
- "%r26",
- "%dp",
- "%ret0",
- "%ret1",
- "%sp",
- "%r31",
-};
-
-static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
-
- TCG_REG_R17,
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
-};
-
-static const int tcg_target_call_iarg_regs[4] = {
- TCG_REG_R26,
- TCG_REG_R25,
- TCG_REG_R24,
- TCG_REG_R23,
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_RET0,
- TCG_REG_RET1,
-};
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- switch (type) {
- case R_PARISC_PCREL17F:
- hppa_patch17f((uint32_t *)code_ptr, value, addend);
- break;
- default:
- tcg_abort();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
- return 4;
-}
-
-/* parse target specific constraints */
-int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch (ct_str[0]) {
- case 'r':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- break;
- case 'L': /* qemu_ld/st constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R26);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R25);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R24);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R23);
- break;
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
-
- ct = arg_ct->ct;
-
- /* TODO */
-
- return 0;
-}
-
-#define INSN_OP(x) ((x) << 26)
-#define INSN_EXT3BR(x) ((x) << 13)
-#define INSN_EXT3SH(x) ((x) << 10)
-#define INSN_EXT4(x) ((x) << 6)
-#define INSN_EXT5(x) (x)
-#define INSN_EXT6(x) ((x) << 6)
-#define INSN_EXT7(x) ((x) << 6)
-#define INSN_EXT8A(x) ((x) << 6)
-#define INSN_EXT8B(x) ((x) << 5)
-#define INSN_T(x) (x)
-#define INSN_R1(x) ((x) << 16)
-#define INSN_R2(x) ((x) << 21)
-#define INSN_DEP_LEN(x) (32 - (x))
-#define INSN_SHDEP_CP(x) ((31 - (x)) << 5)
-#define INSN_SHDEP_P(x) ((x) << 5)
-#define INSN_COND(x) ((x) << 13)
-
-#define COND_NEVER 0
-#define COND_EQUAL 1
-#define COND_LT 2
-#define COND_LTEQ 3
-#define COND_LTU 4
-#define COND_LTUEQ 5
-#define COND_SV 6
-#define COND_OD 7
-
-
-/* Logical ADD */
-#define ARITH_ADD (INSN_OP(0x02) | INSN_EXT6(0x28))
-#define ARITH_AND (INSN_OP(0x02) | INSN_EXT6(0x08))
-#define ARITH_OR (INSN_OP(0x02) | INSN_EXT6(0x09))
-#define ARITH_XOR (INSN_OP(0x02) | INSN_EXT6(0x0a))
-#define ARITH_SUB (INSN_OP(0x02) | INSN_EXT6(0x10))
-
-#define SHD (INSN_OP(0x34) | INSN_EXT3SH(2))
-#define VSHD (INSN_OP(0x34) | INSN_EXT3SH(0))
-#define DEP (INSN_OP(0x35) | INSN_EXT3SH(3))
-#define ZDEP (INSN_OP(0x35) | INSN_EXT3SH(2))
-#define ZVDEP (INSN_OP(0x35) | INSN_EXT3SH(0))
-#define EXTRU (INSN_OP(0x34) | INSN_EXT3SH(6))
-#define EXTRS (INSN_OP(0x34) | INSN_EXT3SH(7))
-#define VEXTRS (INSN_OP(0x34) | INSN_EXT3SH(5))
-
-#define SUBI (INSN_OP(0x25))
-#define MTCTL (INSN_OP(0x00) | INSN_EXT8B(0xc2))
-
-#define BL (INSN_OP(0x3a) | INSN_EXT3BR(0))
-#define BLE_SR4 (INSN_OP(0x39) | (1 << 13))
-#define BV (INSN_OP(0x3a) | INSN_EXT3BR(6))
-#define BV_N (INSN_OP(0x3a) | INSN_EXT3BR(6) | 2)
-#define LDIL (INSN_OP(0x08))
-#define LDO (INSN_OP(0x0d))
-
-#define LDB (INSN_OP(0x10))
-#define LDH (INSN_OP(0x11))
-#define LDW (INSN_OP(0x12))
-#define LDWM (INSN_OP(0x13))
-
-#define STB (INSN_OP(0x18))
-#define STH (INSN_OP(0x19))
-#define STW (INSN_OP(0x1a))
-#define STWM (INSN_OP(0x1b))
-
-#define COMBT (INSN_OP(0x20))
-#define COMBF (INSN_OP(0x22))
-
-static int lowsignext(uint32_t val, int start, int length)
-{
- return (((val << 1) & ~(~0 << length)) |
- ((val >> (length - 1)) & 1)) << start;
-}
-
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- /* PA1.1 defines COPY as OR r,0,t */
- tcg_out32(s, ARITH_OR | INSN_T(ret) | INSN_R1(arg) | INSN_R2(TCG_REG_R0));
-
- /* PA2.0 defines COPY as LDO 0(r),t
- * but hppa-dis.c is unaware of this definition */
- /* tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(arg) | reassemble_14(0)); */
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
- if (arg == (arg & 0x1fff)) {
- tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(TCG_REG_R0) |
- reassemble_14(arg));
- } else {
- tcg_out32(s, LDIL | INSN_R2(ret) |
- reassemble_21(lrsel((uint32_t)arg, 0)));
- if (arg & 0x7ff)
- tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(ret) |
- reassemble_14(rrsel((uint32_t)arg, 0)));
- }
-}
-
-static inline void tcg_out_ld_raw(TCGContext *s, int ret,
- tcg_target_long arg)
-{
- tcg_out32(s, LDIL | INSN_R2(ret) |
- reassemble_21(lrsel((uint32_t)arg, 0)));
- tcg_out32(s, LDW | INSN_R1(ret) | INSN_R2(ret) |
- reassemble_14(rrsel((uint32_t)arg, 0)));
-}
-
-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
- tcg_target_long arg)
-{
- tcg_out_ld_raw(s, ret, arg);
-}
-
-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset,
- int op)
-{
- if (offset == (offset & 0xfff))
- tcg_out32(s, op | INSN_R1(ret) | INSN_R2(addr) |
- reassemble_14(offset));
- else {
- fprintf(stderr, "unimplemented %s with offset %d\n", __func__, offset);
- tcg_abort();
- }
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
- int arg1, tcg_target_long arg2)
-{
- fprintf(stderr, "unimplemented %s\n", __func__);
- tcg_abort();
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int ret,
- int arg1, tcg_target_long arg2)
-{
- fprintf(stderr, "unimplemented %s\n", __func__);
- tcg_abort();
-}
-
-static inline void tcg_out_arith(TCGContext *s, int t, int r1, int r2, int op)
-{
- tcg_out32(s, op | INSN_T(t) | INSN_R1(r1) | INSN_R2(r2));
-}
-
-static inline void tcg_out_arithi(TCGContext *s, int t, int r1,
- tcg_target_long val, int op)
-{
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, val);
- tcg_out_arith(s, t, r1, TCG_REG_R20, op);
-}
-
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
-}
-
-static inline void tcg_out_nop(TCGContext *s)
-{
- tcg_out32(s, ARITH_OR | INSN_T(TCG_REG_R0) | INSN_R1(TCG_REG_R0) |
- INSN_R2(TCG_REG_R0));
-}
-
-static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg) {
- tcg_out32(s, EXTRS | INSN_R1(ret) | INSN_R2(arg) |
- INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
-}
-
-static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg) {
- tcg_out32(s, EXTRS | INSN_R1(ret) | INSN_R2(arg) |
- INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
-}
-
-static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg) {
- if(ret != arg)
- tcg_out_mov(s, ret, arg);
- tcg_out32(s, DEP | INSN_R2(ret) | INSN_R1(ret) |
- INSN_SHDEP_CP(15) | INSN_DEP_LEN(8));
- tcg_out32(s, SHD | INSN_T(ret) | INSN_R1(TCG_REG_R0) |
- INSN_R2(ret) | INSN_SHDEP_CP(8));
-}
-
-static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp) {
- tcg_out32(s, SHD | INSN_T(temp) | INSN_R1(arg) |
- INSN_R2(arg) | INSN_SHDEP_CP(16));
- tcg_out32(s, DEP | INSN_R2(temp) | INSN_R1(temp) |
- INSN_SHDEP_CP(15) | INSN_DEP_LEN(8));
- tcg_out32(s, SHD | INSN_T(ret) | INSN_R1(arg) |
- INSN_R2(temp) | INSN_SHDEP_CP(8));
-}
-
-static inline void tcg_out_call(TCGContext *s, void *func)
-{
- uint32_t val = (uint32_t)__canonicalize_funcptr_for_compare(func);
- tcg_out32(s, LDIL | INSN_R2(TCG_REG_R20) |
- reassemble_21(lrsel(val, 0)));
- tcg_out32(s, BLE_SR4 | INSN_R2(TCG_REG_R20) |
- reassemble_17(rrsel(val, 0) >> 2));
- tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
-{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
-#if defined(CONFIG_SOFTMMU)
- uint32_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-#if defined(CONFIG_SOFTMMU)
- uint32_t *label3_ptr;
-#endif
- int addr_reg2;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0; /* surpress warning */
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
- s_bits = opc & 3;
-
- r0 = TCG_REG_R26;
- r1 = TCG_REG_R25;
-
-#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
-
- tcg_out_mov(s, r0, addr_reg);
-
- tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |
- INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
-
- tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
- ARITH_AND);
-
- tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
- ARITH_AND);
-
- tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);
- tcg_out_arithi(s, r1, r1,
- offsetof(CPUState, tlb_table[mem_index][0].addr_read),
- ARITH_ADD);
-
- tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);
-
-#if TARGET_LONG_BITS == 32
- /* if equal, jump to label1 */
- label1_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
- INSN_COND(COND_EQUAL));
- tcg_out_mov(s, r0, addr_reg); /* delay slot */
-#else
- /* if not equal, jump to label3 */
- label3_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
- INSN_COND(COND_EQUAL));
- tcg_out_mov(s, r0, addr_reg); /* delay slot */
-
- tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);
-
- /* if equal, jump to label1 */
- label1_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |
- INSN_COND(COND_EQUAL));
- tcg_out_nop(s); /* delay slot */
-
- /* label3: */
- *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);
-#endif
-
-#if TARGET_LONG_BITS == 32
- tcg_out_mov(s, TCG_REG_R26, addr_reg);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R25, mem_index);
-#else
- tcg_out_mov(s, TCG_REG_R26, addr_reg);
- tcg_out_mov(s, TCG_REG_R25, addr_reg2);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);
-#endif
-
- tcg_out_call(s, qemu_ld_helpers[s_bits]);
-
- switch(opc) {
- case 0 | 4:
- tcg_out_ext8s(s, data_reg, TCG_REG_RET0);
- break;
- case 1 | 4:
- tcg_out_ext16s(s, data_reg, TCG_REG_RET0);
- break;
- case 0:
- case 1:
- case 2:
- default:
- tcg_out_mov(s, data_reg, TCG_REG_RET0);
- break;
- case 3:
- tcg_abort();
- tcg_out_mov(s, data_reg, TCG_REG_RET0);
- tcg_out_mov(s, data_reg2, TCG_REG_RET1);
- break;
- }
-
- /* jump to label2 */
- label2_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);
-
- /* label1: */
- *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);
-
- tcg_out_arithi(s, TCG_REG_R20, r1,
- offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read),
- ARITH_ADD);
- tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);
- tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);
-#else
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 0;
-#else
- bswap = 1;
-#endif
- switch (opc) {
- case 0:
- tcg_out_ldst(s, data_reg, r0, 0, LDB);
- break;
- case 0 | 4:
- tcg_out_ldst(s, data_reg, r0, 0, LDB);
- tcg_out_ext8s(s, data_reg, data_reg);
- break;
- case 1:
- tcg_out_ldst(s, data_reg, r0, 0, LDH);
- if (bswap)
- tcg_out_bswap16(s, data_reg, data_reg);
- break;
- case 1 | 4:
- tcg_out_ldst(s, data_reg, r0, 0, LDH);
- if (bswap)
- tcg_out_bswap16(s, data_reg, data_reg);
- tcg_out_ext16s(s, data_reg, data_reg);
- break;
- case 2:
- tcg_out_ldst(s, data_reg, r0, 0, LDW);
- if (bswap)
- tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
- break;
- case 3:
- tcg_abort();
- if (!bswap) {
- tcg_out_ldst(s, data_reg, r0, 0, LDW);
- tcg_out_ldst(s, data_reg2, r0, 4, LDW);
- } else {
- tcg_out_ldst(s, data_reg, r0, 4, LDW);
- tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
- tcg_out_ldst(s, data_reg2, r0, 0, LDW);
- tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);
- }
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);
-#endif
-}
-
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
-{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
-#if defined(CONFIG_SOFTMMU)
- uint32_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-#if defined(CONFIG_SOFTMMU)
- uint32_t *label3_ptr;
-#endif
- int addr_reg2;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0; /* surpress warning */
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
-
- s_bits = opc;
-
- r0 = TCG_REG_R26;
- r1 = TCG_REG_R25;
-
-#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
-
- tcg_out_mov(s, r0, addr_reg);
-
- tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |
- INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
-
- tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
- ARITH_AND);
-
- tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
- ARITH_AND);
-
- tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);
- tcg_out_arithi(s, r1, r1,
- offsetof(CPUState, tlb_table[mem_index][0].addr_write),
- ARITH_ADD);
-
- tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);
-
-#if TARGET_LONG_BITS == 32
- /* if equal, jump to label1 */
- label1_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
- INSN_COND(COND_EQUAL));
- tcg_out_mov(s, r0, addr_reg); /* delay slot */
-#else
- /* if not equal, jump to label3 */
- label3_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
- INSN_COND(COND_EQUAL));
- tcg_out_mov(s, r0, addr_reg); /* delay slot */
-
- tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);
-
- /* if equal, jump to label1 */
- label1_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |
- INSN_COND(COND_EQUAL));
- tcg_out_nop(s); /* delay slot */
-
- /* label3: */
- *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);
-#endif
-
- tcg_out_mov(s, TCG_REG_R26, addr_reg);
-#if TARGET_LONG_BITS == 64
- tcg_out_mov(s, TCG_REG_R25, addr_reg2);
- if (opc == 3) {
- tcg_abort();
- tcg_out_mov(s, TCG_REG_R24, data_reg);
- tcg_out_mov(s, TCG_REG_R23, data_reg2);
- /* TODO: push mem_index */
- tcg_abort();
- } else {
- switch(opc) {
- case 0:
- tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |
- INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
- break;
- case 1:
- tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |
- INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
- break;
- case 2:
- tcg_out_mov(s, TCG_REG_R24, data_reg);
- break;
- }
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);
- }
-#else
- if (opc == 3) {
- tcg_abort();
- tcg_out_mov(s, TCG_REG_R25, data_reg);
- tcg_out_mov(s, TCG_REG_R24, data_reg2);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);
- } else {
- switch(opc) {
- case 0:
- tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |
- INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
- break;
- case 1:
- tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |
- INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
- break;
- case 2:
- tcg_out_mov(s, TCG_REG_R25, data_reg);
- break;
- }
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);
- }
-#endif
- tcg_out_call(s, qemu_st_helpers[s_bits]);
-
- /* jump to label2 */
- label2_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);
-
- /* label1: */
- *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);
-
- tcg_out_arithi(s, TCG_REG_R20, r1,
- offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write),
- ARITH_ADD);
- tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);
- tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);
-#else
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 0;
-#else
- bswap = 1;
-#endif
- switch (opc) {
- case 0:
- tcg_out_ldst(s, data_reg, r0, 0, STB);
- break;
- case 1:
- if (bswap) {
- tcg_out_bswap16(s, TCG_REG_R20, data_reg);
- data_reg = TCG_REG_R20;
- }
- tcg_out_ldst(s, data_reg, r0, 0, STH);
- break;
- case 2:
- if (bswap) {
- tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
- data_reg = TCG_REG_R20;
- }
- tcg_out_ldst(s, data_reg, r0, 0, STW);
- break;
- case 3:
- tcg_abort();
- if (!bswap) {
- tcg_out_ldst(s, data_reg, r0, 0, STW);
- tcg_out_ldst(s, data_reg2, r0, 4, STW);
- } else {
- tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
- tcg_out_ldst(s, TCG_REG_R20, r0, 4, STW);
- tcg_out_bswap32(s, TCG_REG_R20, data_reg2, TCG_REG_R20);
- tcg_out_ldst(s, TCG_REG_R20, r0, 0, STW);
- }
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);
-#endif
-}
-
-static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
- const int *const_args)
-{
- int c;
-
- switch (opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, args[0]);
- tcg_out32(s, BV_N | INSN_R2(TCG_REG_R18));
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
- fprintf(stderr, "goto_tb direct\n");
- tcg_abort();
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, args[0]);
- tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- } else {
- /* indirect jump method */
- tcg_out_ld_ptr(s, TCG_REG_R20,
- (tcg_target_long)(s->tb_next + args[0]));
- tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_call:
- tcg_out32(s, BLE_SR4 | INSN_R2(args[0]));
- tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
- break;
- case INDEX_op_jmp:
- fprintf(stderr, "unimplemented jmp\n");
- tcg_abort();
- break;
- case INDEX_op_br:
- fprintf(stderr, "unimplemented br\n");
- tcg_abort();
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
- break;
-
- case INDEX_op_ld8u_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], LDB);
- break;
- case INDEX_op_ld8s_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], LDB);
- tcg_out_ext8s(s, args[0], args[0]);
- break;
- case INDEX_op_ld16u_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], LDH);
- break;
- case INDEX_op_ld16s_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], LDH);
- tcg_out_ext16s(s, args[0], args[0]);
- break;
- case INDEX_op_ld_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], LDW);
- break;
-
- case INDEX_op_st8_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], STB);
- break;
- case INDEX_op_st16_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], STH);
- break;
- case INDEX_op_st_i32:
- tcg_out_ldst(s, args[0], args[1], args[2], STW);
- break;
-
- case INDEX_op_sub_i32:
- c = ARITH_SUB;
- goto gen_arith;
- case INDEX_op_and_i32:
- c = ARITH_AND;
- goto gen_arith;
- case INDEX_op_or_i32:
- c = ARITH_OR;
- goto gen_arith;
- case INDEX_op_xor_i32:
- c = ARITH_XOR;
- goto gen_arith;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
- goto gen_arith;
-
- case INDEX_op_shl_i32:
- tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |
- lowsignext(0x1f, 0, 11));
- tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));
- tcg_out32(s, ZVDEP | INSN_R2(args[0]) | INSN_R1(args[1]) |
- INSN_DEP_LEN(32));
- break;
- case INDEX_op_shr_i32:
- tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(args[2]));
- tcg_out32(s, VSHD | INSN_T(args[0]) | INSN_R1(TCG_REG_R0) |
- INSN_R2(args[1]));
- break;
- case INDEX_op_sar_i32:
- tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |
- lowsignext(0x1f, 0, 11));
- tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));
- tcg_out32(s, VEXTRS | INSN_R1(args[0]) | INSN_R2(args[1]) |
- INSN_DEP_LEN(32));
- break;
-
- case INDEX_op_mul_i32:
- fprintf(stderr, "unimplemented mul\n");
- tcg_abort();
- break;
- case INDEX_op_mulu2_i32:
- fprintf(stderr, "unimplemented mulu2\n");
- tcg_abort();
- break;
- case INDEX_op_div2_i32:
- fprintf(stderr, "unimplemented div2\n");
- tcg_abort();
- break;
- case INDEX_op_divu2_i32:
- fprintf(stderr, "unimplemented divu2\n");
- tcg_abort();
- break;
-
- case INDEX_op_brcond_i32:
- fprintf(stderr, "unimplemented brcond\n");
- tcg_abort();
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, args, 2);
- break;
-
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, args, 2);
- break;
-
- default:
- fprintf(stderr, "unknown opcode 0x%x\n", opc);
- tcg_abort();
- }
- return;
-
-gen_arith:
- tcg_out_arith(s, args[0], args[1], args[2], c);
-}
-
-static const TCGTargetOpDef hppa_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
-
- { INDEX_op_call, { "r" } },
- { INDEX_op_jmp, { "r" } },
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "r", "r" } },
- { INDEX_op_sub_i32, { "r", "r", "r" } },
- { INDEX_op_and_i32, { "r", "r", "r" } },
- { INDEX_op_or_i32, { "r", "r", "r" } },
- { INDEX_op_xor_i32, { "r", "r", "r" } },
-
- { INDEX_op_shl_i32, { "r", "r", "r" } },
- { INDEX_op_shr_i32, { "r", "r", "r" } },
- { INDEX_op_sar_i32, { "r", "r", "r" } },
-
- { INDEX_op_brcond_i32, { "r", "r" } },
-
-#if TARGET_LONG_BITS == 32
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld64, { "r", "r", "L" } },
-
- { INDEX_op_qemu_st8, { "L", "L" } },
- { INDEX_op_qemu_st16, { "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L", "L" } },
-#else
- { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
-
- { INDEX_op_qemu_st8, { "L", "L", "L" } },
- { INDEX_op_qemu_st16, { "L", "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
-#endif
- { -1 },
-};
-
-void tcg_target_init(TCGContext *s)
-{
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_R20) |
- (1 << TCG_REG_R21) |
- (1 << TCG_REG_R22) |
- (1 << TCG_REG_R23) |
- (1 << TCG_REG_R24) |
- (1 << TCG_REG_R25) |
- (1 << TCG_REG_R26));
-
- tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* hardwired to zero */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* addil target */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_RP); /* link register */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3); /* frame pointer */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R18); /* return pointer */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R19); /* clobbered w/o pic */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R20); /* reserved */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP); /* data pointer */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
-
- tcg_add_target_add_op_defs(hppa_op_defs);
-}
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
deleted file mode 100644
index 8e2693d..0000000
--- a/tcg/hppa/tcg-target.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#define TCG_TARGET_HPPA 1
-
-#if defined(_PA_RISC1_1)
-#define TCG_TARGET_REG_BITS 32
-#else
-#error unsupported
-#endif
-
-#define TCG_TARGET_WORDS_BIGENDIAN
-
-#define TCG_TARGET_NB_REGS 32
-
-enum {
- TCG_REG_R0 = 0,
- TCG_REG_R1,
- TCG_REG_RP,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R24,
- TCG_REG_R25,
- TCG_REG_R26,
- TCG_REG_DP,
- TCG_REG_RET0,
- TCG_REG_RET1,
- TCG_REG_SP,
- TCG_REG_R31,
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_SP
-#define TCG_TARGET_STACK_ALIGN 16
-#define TCG_TARGET_STACK_GROWSUP
-
-/* optional instructions */
-//#define TCG_TARGET_HAS_ext8s_i32
-//#define TCG_TARGET_HAS_ext16s_i32
-//#define TCG_TARGET_HAS_bswap16_i32
-//#define TCG_TARGET_HAS_bswap_i32
-
-/* Note: must be synced with dyngen-exec.h */
-#define TCG_AREG0 TCG_REG_R17
-#define TCG_AREG1 TCG_REG_R14
-#define TCG_AREG2 TCG_REG_R15
-#define TCG_AREG3 TCG_REG_R16
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- start &= ~31;
- while (start <= stop)
- {
- asm volatile ("fdc 0(%0)\n"
- "sync\n"
- "fic 0(%%sr4, %0)\n"
- "sync\n"
- : : "r"(start) : "memory");
- start += 32;
- }
-}
-
-/* supplied by libgcc */
-extern void *__canonicalize_funcptr_for_compare(void *);
-
-/* Field selection types defined by hppa */
-#define rnd(x) (((x)+0x1000)&~0x1fff)
-/* lsel: select left 21 bits */
-#define lsel(v,a) (((v)+(a))>>11)
-/* rsel: select right 11 bits */
-#define rsel(v,a) (((v)+(a))&0x7ff)
-/* lrsel with rounding of addend to nearest 8k */
-#define lrsel(v,a) (((v)+rnd(a))>>11)
-/* rrsel with rounding of addend to nearest 8k */
-#define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
-
-#define mask(x,sz) ((x) & ~((1<<(sz))-1))
-
-static inline int reassemble_12(int as12)
-{
- return (((as12 & 0x800) >> 11) |
- ((as12 & 0x400) >> 8) |
- ((as12 & 0x3ff) << 3));
-}
-
-static inline int reassemble_14(int as14)
-{
- return (((as14 & 0x1fff) << 1) |
- ((as14 & 0x2000) >> 13));
-}
-
-static inline int reassemble_17(int as17)
-{
- return (((as17 & 0x10000) >> 16) |
- ((as17 & 0x0f800) << 5) |
- ((as17 & 0x00400) >> 8) |
- ((as17 & 0x003ff) << 3));
-}
-
-static inline int reassemble_21(int as21)
-{
- return (((as21 & 0x100000) >> 20) |
- ((as21 & 0x0ffe00) >> 8) |
- ((as21 & 0x000180) << 7) |
- ((as21 & 0x00007c) << 14) |
- ((as21 & 0x000003) << 12));
-}
-
-static inline void hppa_patch21l(uint32_t *insn, int val, int addend)
-{
- val = lrsel(val, addend);
- *insn = mask(*insn, 21) | reassemble_21(val);
-}
-
-static inline void hppa_patch14r(uint32_t *insn, int val, int addend)
-{
- val = rrsel(val, addend);
- *insn = mask(*insn, 14) | reassemble_14(val);
-}
-
-static inline void hppa_patch17r(uint32_t *insn, int val, int addend)
-{
- val = rrsel(val, addend);
- *insn = (*insn & ~0x1f1ffd) | reassemble_17(val);
-}
-
-
-static inline void hppa_patch21l_dprel(uint32_t *insn, int val, int addend)
-{
- register unsigned int dp asm("r27");
- hppa_patch21l(insn, val - dp, addend);
-}
-
-static inline void hppa_patch14r_dprel(uint32_t *insn, int val, int addend)
-{
- register unsigned int dp asm("r27");
- hppa_patch14r(insn, val - dp, addend);
-}
-
-static inline void hppa_patch17f(uint32_t *insn, int val, int addend)
-{
- int dot = (int)insn & ~0x3;
- int v = ((val + addend) - dot - 8) / 4;
- if (v > (1 << 16) || v < -(1 << 16)) {
- printf("cannot fit branch to offset %d [%08x->%08x]\n", v, dot, val);
- abort();
- }
- *insn = (*insn & ~0x1f1ffd) | reassemble_17(v);
-}
-
-static inline void hppa_load_imm21l(uint32_t *insn, int val, int addend)
-{
- /* Transform addil L'sym(%dp) to ldil L'val, %r1 */
- *insn = 0x20200000 | reassemble_21(lrsel(val, 0));
-}
-
-static inline void hppa_load_imm14r(uint32_t *insn, int val, int addend)
-{
- /* Transform ldw R'sym(%r1), %rN to ldo R'sym(%r1), %rN */
- hppa_patch14r(insn, val, addend);
- /* HACK */
- if (addend == 0)
- *insn = (*insn & ~0xfc000000) | (0x0d << 26);
-}
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
deleted file mode 100644
index 08bb783..0000000
--- a/tcg/i386/tcg-target.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-const char *tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%eax",
- "%ecx",
- "%edx",
- "%ebx",
- "%esp",
- "%ebp",
- "%esi",
- "%edi",
-};
-
-int tcg_target_reg_alloc_order[] = {
- TCG_REG_EAX,
- TCG_REG_EDX,
- TCG_REG_ECX,
- TCG_REG_EBX,
- TCG_REG_ESI,
- TCG_REG_EDI,
- TCG_REG_EBP,
-};
-
-const int tcg_target_call_iarg_regs[3] = { TCG_REG_EAX, TCG_REG_EDX, TCG_REG_ECX };
-const int tcg_target_call_oarg_regs[2] = { TCG_REG_EAX, TCG_REG_EDX };
-
-static uint8_t *tb_ret_addr;
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- value += addend;
- switch(type) {
- case R_386_32:
- *(uint32_t *)code_ptr = value;
- break;
- case R_386_PC32:
- *(uint32_t *)code_ptr = value - (long)code_ptr;
- break;
- default:
- tcg_abort();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
- flags &= TCG_CALL_TYPE_MASK;
- switch(flags) {
- case TCG_CALL_TYPE_STD:
- return 0;
- case TCG_CALL_TYPE_REGPARM_1:
- case TCG_CALL_TYPE_REGPARM_2:
- case TCG_CALL_TYPE_REGPARM:
- return flags - TCG_CALL_TYPE_REGPARM_1 + 1;
- default:
- tcg_abort();
- }
-}
-
-/* parse target specific constraints */
-int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch(ct_str[0]) {
- case 'a':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
- break;
- case 'b':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
- break;
- case 'c':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
- break;
- case 'd':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
- break;
- case 'S':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
- break;
- case 'D':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
- break;
- case 'q':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xf);
- break;
- case 'r':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xff);
- break;
-
- /* qemu_ld/st address constraint */
- case 'L':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
- break;
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- else
- return 0;
-}
-
-#define ARITH_ADD 0
-#define ARITH_OR 1
-#define ARITH_ADC 2
-#define ARITH_SBB 3
-#define ARITH_AND 4
-#define ARITH_SUB 5
-#define ARITH_XOR 6
-#define ARITH_CMP 7
-
-#define SHIFT_SHL 4
-#define SHIFT_SHR 5
-#define SHIFT_SAR 7
-
-#define JCC_JMP (-1)
-#define JCC_JO 0x0
-#define JCC_JNO 0x1
-#define JCC_JB 0x2
-#define JCC_JAE 0x3
-#define JCC_JE 0x4
-#define JCC_JNE 0x5
-#define JCC_JBE 0x6
-#define JCC_JA 0x7
-#define JCC_JS 0x8
-#define JCC_JNS 0x9
-#define JCC_JP 0xa
-#define JCC_JNP 0xb
-#define JCC_JL 0xc
-#define JCC_JGE 0xd
-#define JCC_JLE 0xe
-#define JCC_JG 0xf
-
-#define P_EXT 0x100 /* 0x0f opcode prefix */
-
-static const uint8_t tcg_cond_to_jcc[10] = {
- [TCG_COND_EQ] = JCC_JE,
- [TCG_COND_NE] = JCC_JNE,
- [TCG_COND_LT] = JCC_JL,
- [TCG_COND_GE] = JCC_JGE,
- [TCG_COND_LE] = JCC_JLE,
- [TCG_COND_GT] = JCC_JG,
- [TCG_COND_LTU] = JCC_JB,
- [TCG_COND_GEU] = JCC_JAE,
- [TCG_COND_LEU] = JCC_JBE,
- [TCG_COND_GTU] = JCC_JA,
-};
-
-static inline void tcg_out_opc(TCGContext *s, int opc)
-{
- if (opc & P_EXT)
- tcg_out8(s, 0x0f);
- tcg_out8(s, opc);
-}
-
-static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
-{
- tcg_out_opc(s, opc);
- tcg_out8(s, 0xc0 | (r << 3) | rm);
-}
-
-/* rm == -1 means no register index */
-static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
- int32_t offset)
-{
- tcg_out_opc(s, opc);
- if (rm == -1) {
- tcg_out8(s, 0x05 | (r << 3));
- tcg_out32(s, offset);
- } else if (offset == 0 && rm != TCG_REG_EBP) {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x04 | (r << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x00 | (r << 3) | rm);
- }
- } else if ((int8_t)offset == offset) {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x44 | (r << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x40 | (r << 3) | rm);
- }
- tcg_out8(s, offset);
- } else {
- if (rm == TCG_REG_ESP) {
- tcg_out8(s, 0x84 | (r << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x80 | (r << 3) | rm);
- }
- tcg_out32(s, offset);
- }
-}
-
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- if (arg != ret)
- tcg_out_modrm(s, 0x8b, ret, arg);
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, int32_t arg)
-{
- if (arg == 0) {
- /* xor r0,r0 */
- tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret);
- } else {
- tcg_out8(s, 0xb8 + ret);
- tcg_out32(s, arg);
- }
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
- int arg1, tcg_target_long arg2)
-{
- /* movl */
- tcg_out_modrm_offset(s, 0x8b, ret, arg1, arg2);
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
- int arg1, tcg_target_long arg2)
-{
- /* movl */
- tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2);
-}
-
-static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val)
-{
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83, c, r0);
- tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x81, c, r0);
- tcg_out32(s, val);
- }
-}
-
-void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val != 0)
- tgen_arithi(s, ARITH_ADD, reg, val);
-}
-
-static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
-{
- int32_t val, val1;
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value) {
- val = l->u.value - (tcg_target_long)s->code_ptr;
- val1 = val - 2;
- if ((int8_t)val1 == val1) {
- if (opc == -1)
- tcg_out8(s, 0xeb);
- else
- tcg_out8(s, 0x70 + opc);
- tcg_out8(s, val1);
- } else {
- if (opc == -1) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, val - 5);
- } else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
- tcg_out32(s, val - 6);
- }
- }
- } else {
- if (opc == -1) {
- tcg_out8(s, 0xe9);
- } else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
- }
- tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
- s->code_ptr += 4;
- }
-}
-
-static void tcg_out_brcond(TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index)
-{
- if (const_arg2) {
- if (arg2 == 0) {
- /* test r, r */
- tcg_out_modrm(s, 0x85, arg1, arg1);
- } else {
- tgen_arithi(s, ARITH_CMP, arg1, arg2);
- }
- } else {
- tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3), arg2, arg1);
- }
- tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
-}
-
-/* XXX: we implement it at the target level to avoid having to
- handle cross basic blocks temporaries */
-static void tcg_out_brcond2(TCGContext *s,
- const TCGArg *args, const int *const_args)
-{
- int label_next;
- label_next = gen_new_label();
- switch(args[4]) {
- case TCG_COND_EQ:
- tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next);
- tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]);
- break;
- case TCG_COND_NE:
- tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]);
- tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]);
- break;
- case TCG_COND_LT:
- tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_LE:
- tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_GT:
- tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_GE:
- tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_LTU:
- tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_LEU:
- tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_GTU:
- tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
- break;
- case TCG_COND_GEU:
- tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
- tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
- break;
- default:
- tcg_abort();
- }
- tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
- EAX. It will be useful once fixed registers globals are less
- common. */
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label3_ptr;
-#endif
- int addr_reg2;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0;
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
- s_bits = opc & 3;
-
- r0 = TCG_REG_EAX;
- r1 = TCG_REG_EDX;
-
-#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
-
- tcg_out_mov(s, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (5 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_read));
-
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
-
- tcg_out_mov(s, r0, addr_reg);
-
-#if TARGET_LONG_BITS == 32
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-#else
- /* jne label3 */
- tcg_out8(s, 0x70 + JCC_JNE);
- label3_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* cmp 4(r1), addr_reg2 */
- tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label3: */
- *label3_ptr = s->code_ptr - label3_ptr - 1;
-#endif
-
- /* XXX: move that code at the end of the TB */
-#if TARGET_LONG_BITS == 32
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EDX, mem_index);
-#else
- tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
-#endif
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-
- switch(opc) {
- case 0 | 4:
- /* movsbl */
- tcg_out_modrm(s, 0xbe | P_EXT, data_reg, TCG_REG_EAX);
- break;
- case 1 | 4:
- /* movswl */
- tcg_out_modrm(s, 0xbf | P_EXT, data_reg, TCG_REG_EAX);
- break;
- case 0:
- case 1:
- case 2:
- default:
- tcg_out_mov(s, data_reg, TCG_REG_EAX);
- break;
- case 3:
- if (data_reg == TCG_REG_EDX) {
- tcg_out_opc(s, 0x90 + TCG_REG_EDX); /* xchg %edx, %eax */
- tcg_out_mov(s, data_reg2, TCG_REG_EAX);
- } else {
- tcg_out_mov(s, data_reg, TCG_REG_EAX);
- tcg_out_mov(s, data_reg2, TCG_REG_EDX);
- }
- break;
- }
-
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_read));
-#else
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
-#else
- bswap = 0;
-#endif
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
- break;
- case 0 | 4:
- /* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, data_reg, r0, 0);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
- if (bswap) {
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
- }
- break;
- case 1 | 4:
- /* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, data_reg, r0, 0);
- if (bswap) {
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
-
- /* movswl data_reg, data_reg */
- tcg_out_modrm(s, 0xbf | P_EXT, data_reg, data_reg);
- }
- break;
- case 2:
- /* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- if (bswap) {
- /* bswap */
- tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
- }
- break;
- case 3:
- /* XXX: could be nicer */
- if (r0 == data_reg) {
- r1 = TCG_REG_EDX;
- if (r1 == data_reg)
- r1 = TCG_REG_EAX;
- tcg_out_mov(s, r1, r0);
- r0 = r1;
- }
- if (!bswap) {
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 4);
- } else {
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 4);
- tcg_out_opc(s, (0xc8 + data_reg) | P_EXT);
-
- tcg_out_modrm_offset(s, 0x8b, data_reg2, r0, 0);
- /* bswap */
- tcg_out_opc(s, (0xc8 + data_reg2) | P_EXT);
- }
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-#endif
-}
-
-
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label3_ptr;
-#endif
- int addr_reg2;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0;
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
-
- s_bits = opc;
-
- r0 = TCG_REG_EAX;
- r1 = TCG_REG_EDX;
-
-#if defined(CONFIG_SOFTMMU)
- tcg_out_mov(s, r1, addr_reg);
-
- tcg_out_mov(s, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- tcg_out_opc(s, 0x8d); /* lea offset(r1, %ebp), r1 */
- tcg_out8(s, 0x80 | (r1 << 3) | 0x04);
- tcg_out8(s, (5 << 3) | r1);
- tcg_out32(s, offsetof(CPUState, tlb_table[mem_index][0].addr_write));
-
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b, r0, r1, 0);
-
- tcg_out_mov(s, r0, addr_reg);
-
-#if TARGET_LONG_BITS == 32
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-#else
- /* jne label3 */
- tcg_out8(s, 0x70 + JCC_JNE);
- label3_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* cmp 4(r1), addr_reg2 */
- tcg_out_modrm_offset(s, 0x3b, addr_reg2, r1, 4);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label3: */
- *label3_ptr = s->code_ptr - label3_ptr - 1;
-#endif
-
- /* XXX: move that code at the end of the TB */
-#if TARGET_LONG_BITS == 32
- if (opc == 3) {
- tcg_out_mov(s, TCG_REG_EDX, data_reg);
- tcg_out_mov(s, TCG_REG_ECX, data_reg2);
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- tcg_out_addi(s, TCG_REG_ESP, 4);
- } else {
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_EDX, data_reg);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_EDX, data_reg);
- break;
- case 2:
- tcg_out_mov(s, TCG_REG_EDX, data_reg);
- break;
- }
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- }
-#else
- if (opc == 3) {
- tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out_opc(s, 0x50 + data_reg2); /* push */
- tcg_out_opc(s, 0x50 + data_reg); /* push */
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- tcg_out_addi(s, TCG_REG_ESP, 12);
- } else {
- tcg_out_mov(s, TCG_REG_EDX, addr_reg2);
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT, TCG_REG_ECX, data_reg);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_ECX, data_reg);
- break;
- case 2:
- tcg_out_mov(s, TCG_REG_ECX, data_reg);
- break;
- }
- tcg_out8(s, 0x6a); /* push Ib */
- tcg_out8(s, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
- tcg_out_addi(s, TCG_REG_ESP, 4);
- }
-#endif
-
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_write));
-#else
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
-#else
- bswap = 0;
-#endif
- switch(opc) {
- case 0:
- /* movb */
- tcg_out_modrm_offset(s, 0x88, data_reg, r0, 0);
- break;
- case 1:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg);
- tcg_out8(s, 0x66); /* rolw $8, %ecx */
- tcg_out_modrm(s, 0xc1, 0, r1);
- tcg_out8(s, 8);
- data_reg = r1;
- }
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 2:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- data_reg = r1;
- }
- /* movl */
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 3:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg2);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- tcg_out_modrm_offset(s, 0x89, r1, r0, 0);
- tcg_out_mov(s, r1, data_reg);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT);
- tcg_out_modrm_offset(s, 0x89, r1, r0, 4);
- } else {
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- tcg_out_modrm_offset(s, 0x89, data_reg2, r0, 4);
- }
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-#endif
-}
-
-static inline void tcg_out_op(TCGContext *s, int opc,
- const TCGArg *args, const int *const_args)
-{
- int c;
-
- switch(opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_EAX, args[0]);
- tcg_out8(s, 0xe9); /* jmp tb_ret_addr */
- tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
- tcg_out8(s, 0xe9); /* jmp im */
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- tcg_out32(s, 0);
- } else {
- /* indirect jump method */
- /* jmp Ev */
- tcg_out_modrm_offset(s, 0xff, 4, -1,
- (tcg_target_long)(s->tb_next + args[0]));
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_call:
- if (const_args[0]) {
- tcg_out8(s, 0xe8);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
- } else {
- tcg_out_modrm(s, 0xff, 2, args[0]);
- }
- break;
- case INDEX_op_jmp:
- if (const_args[0]) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
- } else {
- tcg_out_modrm(s, 0xff, 4, args[0]);
- }
- break;
- case INDEX_op_br:
- tcg_out_jxx(s, JCC_JMP, args[0]);
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
- break;
- case INDEX_op_ld8u_i32:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld8s_i32:
- /* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16u_i32:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16s_i32:
- /* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld_i32:
- /* movl */
- tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]);
- break;
- case INDEX_op_st8_i32:
- /* movb */
- tcg_out_modrm_offset(s, 0x88, args[0], args[1], args[2]);
- break;
- case INDEX_op_st16_i32:
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
- break;
- case INDEX_op_st_i32:
- /* movl */
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
- break;
- case INDEX_op_sub_i32:
- c = ARITH_SUB;
- goto gen_arith;
- case INDEX_op_and_i32:
- c = ARITH_AND;
- goto gen_arith;
- case INDEX_op_or_i32:
- c = ARITH_OR;
- goto gen_arith;
- case INDEX_op_xor_i32:
- c = ARITH_XOR;
- goto gen_arith;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
- gen_arith:
- if (const_args[2]) {
- tgen_arithi(s, c, args[0], args[2]);
- } else {
- tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
- }
- break;
- case INDEX_op_mul_i32:
- if (const_args[2]) {
- int32_t val;
- val = args[2];
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b, args[0], args[0]);
- tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x69, args[0], args[0]);
- tcg_out32(s, val);
- }
- } else {
- tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
- }
- break;
- case INDEX_op_mulu2_i32:
- tcg_out_modrm(s, 0xf7, 4, args[3]);
- break;
- case INDEX_op_div2_i32:
- tcg_out_modrm(s, 0xf7, 7, args[4]);
- break;
- case INDEX_op_divu2_i32:
- tcg_out_modrm(s, 0xf7, 6, args[4]);
- break;
- case INDEX_op_shl_i32:
- c = SHIFT_SHL;
- gen_shift32:
- if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1, c, args[0]);
- tcg_out8(s, args[2]);
- }
- } else {
- tcg_out_modrm(s, 0xd3, c, args[0]);
- }
- break;
- case INDEX_op_shr_i32:
- c = SHIFT_SHR;
- goto gen_shift32;
- case INDEX_op_sar_i32:
- c = SHIFT_SAR;
- goto gen_shift32;
-
- case INDEX_op_add2_i32:
- if (const_args[4])
- tgen_arithi(s, ARITH_ADD, args[0], args[4]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_ADD << 3), args[4], args[0]);
- if (const_args[5])
- tgen_arithi(s, ARITH_ADC, args[1], args[5]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_ADC << 3), args[5], args[1]);
- break;
- case INDEX_op_sub2_i32:
- if (const_args[4])
- tgen_arithi(s, ARITH_SUB, args[0], args[4]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_SUB << 3), args[4], args[0]);
- if (const_args[5])
- tgen_arithi(s, ARITH_SBB, args[1], args[5]);
- else
- tcg_out_modrm(s, 0x01 | (ARITH_SBB << 3), args[5], args[1]);
- break;
- case INDEX_op_brcond_i32:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], args[3]);
- break;
- case INDEX_op_brcond2_i32:
- tcg_out_brcond2(s, args, const_args);
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, args, 2);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, args, 3);
- break;
-
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, args, 2);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, args, 3);
- break;
-
- default:
- tcg_abort();
- }
-}
-
-static const TCGTargetOpDef x86_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } },
- { INDEX_op_jmp, { "ri" } },
- { INDEX_op_br, { } },
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "q", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "0", "ri" } },
- { INDEX_op_sub_i32, { "r", "0", "ri" } },
- { INDEX_op_mul_i32, { "r", "0", "ri" } },
- { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
- { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
- { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
- { INDEX_op_and_i32, { "r", "0", "ri" } },
- { INDEX_op_or_i32, { "r", "0", "ri" } },
- { INDEX_op_xor_i32, { "r", "0", "ri" } },
-
- { INDEX_op_shl_i32, { "r", "0", "ci" } },
- { INDEX_op_shr_i32, { "r", "0", "ci" } },
- { INDEX_op_sar_i32, { "r", "0", "ci" } },
-
- { INDEX_op_brcond_i32, { "r", "ri" } },
-
- { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
- { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
- { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
-
-#if TARGET_LONG_BITS == 32
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld64, { "r", "r", "L" } },
-
- { INDEX_op_qemu_st8, { "cb", "L" } },
- { INDEX_op_qemu_st16, { "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L", "L" } },
-#else
- { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
-
- { INDEX_op_qemu_st8, { "cb", "L", "L" } },
- { INDEX_op_qemu_st16, { "L", "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
-#endif
- { -1 },
-};
-
-static int tcg_target_callee_save_regs[] = {
- /* TCG_REG_EBP, */ /* currently used for the global env, so no
- need to save */
- TCG_REG_EBX,
- TCG_REG_ESI,
- TCG_REG_EDI,
-};
-
-static inline void tcg_out_push(TCGContext *s, int reg)
-{
- tcg_out_opc(s, 0x50 + reg);
-}
-
-static inline void tcg_out_pop(TCGContext *s, int reg)
-{
- tcg_out_opc(s, 0x58 + reg);
-}
-
-/* Generate global QEMU prologue and epilogue code */
-void tcg_target_qemu_prologue(TCGContext *s)
-{
- int i, frame_size, push_size, stack_addend;
-
- /* TB prologue */
- /* save all callee saved registers */
- for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
- tcg_out_push(s, tcg_target_callee_save_regs[i]);
- }
- /* reserve some stack space */
- push_size = 4 + ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
- frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
- frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
- ~(TCG_TARGET_STACK_ALIGN - 1);
- stack_addend = frame_size - push_size;
- tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
-
- tcg_out_modrm(s, 0xff, 4, TCG_REG_EAX); /* jmp *%eax */
-
- /* TB epilogue */
- tb_ret_addr = s->code_ptr;
- tcg_out_addi(s, TCG_REG_ESP, stack_addend);
- for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
- tcg_out_pop(s, tcg_target_callee_save_regs[i]);
- }
- tcg_out8(s, 0xc3); /* ret */
-}
-
-void tcg_target_init(TCGContext *s)
-{
- /* fail safe */
- if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
- tcg_abort();
-
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_EAX) |
- (1 << TCG_REG_EDX) |
- (1 << TCG_REG_ECX));
-
- tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
-
- tcg_add_target_add_op_defs(x86_op_defs);
-}
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
deleted file mode 100644
index 37fdaa5..0000000
--- a/tcg/i386/tcg-target.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_I386 1
-
-#define TCG_TARGET_REG_BITS 32
-//#define TCG_TARGET_WORDS_BIGENDIAN
-
-#define TCG_TARGET_NB_REGS 8
-
-enum {
- TCG_REG_EAX = 0,
- TCG_REG_ECX,
- TCG_REG_EDX,
- TCG_REG_EBX,
- TCG_REG_ESP,
- TCG_REG_EBP,
- TCG_REG_ESI,
- TCG_REG_EDI,
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_ESP
-#define TCG_TARGET_STACK_ALIGN 16
-#define TCG_TARGET_CALL_STACK_OFFSET 0
-
-/* Note: must be synced with dyngen-exec.h */
-#define TCG_AREG0 TCG_REG_EBP
-#define TCG_AREG1 TCG_REG_EBX
-#define TCG_AREG2 TCG_REG_ESI
-#define TCG_AREG3 TCG_REG_EDI
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
deleted file mode 100644
index ad17468..0000000
--- a/tcg/ppc/tcg-target.c
+++ /dev/null
@@ -1,1492 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static uint8_t *tb_ret_addr;
-
-#ifdef __APPLE__
-#define LINKAGE_AREA_SIZE 24
-#define BACK_CHAIN_OFFSET 8
-#else
-#define LINKAGE_AREA_SIZE 8
-#define BACK_CHAIN_OFFSET 4
-#endif
-
-#define FAST_PATH
-#if TARGET_PHYS_ADDR_BITS <= 32
-#define ADDEND_OFFSET 0
-#else
-#define ADDEND_OFFSET 4
-#endif
-
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "r0",
- "r1",
- "rp",
- "r3",
- "r4",
- "r5",
- "r6",
- "r7",
- "r8",
- "r9",
- "r10",
- "r11",
- "r12",
- "r13",
- "r14",
- "r15",
- "r16",
- "r17",
- "r18",
- "r19",
- "r20",
- "r21",
- "r22",
- "r23",
- "r24",
- "r25",
- "r26",
- "r27",
- "r28",
- "r29",
- "r30",
- "r31"
-};
-
-static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R28,
- TCG_REG_R29,
- TCG_REG_R30,
- TCG_REG_R31,
-#ifdef __APPLE__
- TCG_REG_R2,
-#endif
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
-#ifndef __APPLE__
- TCG_REG_R11,
-#endif
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R24,
- TCG_REG_R25,
- TCG_REG_R26,
- TCG_REG_R27
-};
-
-static const int tcg_target_call_iarg_regs[] = {
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_R3,
- TCG_REG_R4
-};
-
-static const int tcg_target_callee_save_regs[] = {
-#ifdef __APPLE__
- TCG_REG_R11,
- TCG_REG_R13,
-#endif
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R28,
- TCG_REG_R29,
- TCG_REG_R30,
- TCG_REG_R31
-};
-
-static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
-{
- tcg_target_long disp;
-
- disp = target - (tcg_target_long) pc;
- if ((disp << 6) >> 6 != disp)
- tcg_abort ();
-
- return disp & 0x3fffffc;
-}
-
-static void reloc_pc24 (void *pc, tcg_target_long target)
-{
- *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
- | reloc_pc24_val (pc, target);
-}
-
-static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
-{
- tcg_target_long disp;
-
- disp = target - (tcg_target_long) pc;
- if (disp != (int16_t) disp)
- tcg_abort ();
-
- return disp & 0xfffc;
-}
-
-static void reloc_pc14 (void *pc, tcg_target_long target)
-{
- *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
- | reloc_pc14_val (pc, target);
-}
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- value += addend;
- switch (type) {
- case R_PPC_REL14:
- reloc_pc14 (code_ptr, value);
- break;
- case R_PPC_REL24:
- reloc_pc24 (code_ptr, value);
- break;
- default:
- tcg_abort();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static int tcg_target_get_call_iarg_regs_count(int flags)
-{
- return sizeof (tcg_target_call_iarg_regs) / sizeof (tcg_target_call_iarg_regs[0]);
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch (ct_str[0]) {
- case 'A': case 'B': case 'C': case 'D':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
- break;
- case 'r':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- break;
-#ifdef CONFIG_SOFTMMU
- case 'L': /* qemu_ld constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
- break;
- case 'K': /* qemu_st[8..32] constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
-#if TARGET_LONG_BITS == 64
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
-#endif
- break;
- case 'M': /* qemu_st64 constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
- break;
-#else
- case 'L':
- case 'K':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- break;
- case 'M':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
- break;
-#endif
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
-
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- return 0;
-}
-
-#define OPCD(opc) ((opc)<<26)
-#define XO31(opc) (OPCD(31)|((opc)<<1))
-#define XO19(opc) (OPCD(19)|((opc)<<1))
-
-#define B OPCD(18)
-#define BC OPCD(16)
-#define LBZ OPCD(34)
-#define LHZ OPCD(40)
-#define LHA OPCD(42)
-#define LWZ OPCD(32)
-#define STB OPCD(38)
-#define STH OPCD(44)
-#define STW OPCD(36)
-
-#define ADDI OPCD(14)
-#define ADDIS OPCD(15)
-#define ORI OPCD(24)
-#define ORIS OPCD(25)
-#define XORI OPCD(26)
-#define XORIS OPCD(27)
-#define ANDI OPCD(28)
-#define ANDIS OPCD(29)
-#define MULLI OPCD( 7)
-#define CMPLI OPCD(10)
-#define CMPI OPCD(11)
-
-#define LWZU OPCD(33)
-#define STWU OPCD(37)
-
-#define RLWINM OPCD(21)
-
-#define BCLR XO19( 16)
-#define BCCTR XO19(528)
-#define CRAND XO19(257)
-#define CRANDC XO19(129)
-#define CRNAND XO19(225)
-#define CROR XO19(449)
-
-#define EXTSB XO31(954)
-#define EXTSH XO31(922)
-#define ADD XO31(266)
-#define ADDE XO31(138)
-#define ADDC XO31( 10)
-#define AND XO31( 28)
-#define SUBF XO31( 40)
-#define SUBFC XO31( 8)
-#define SUBFE XO31(136)
-#define OR XO31(444)
-#define XOR XO31(316)
-#define MULLW XO31(235)
-#define MULHWU XO31( 11)
-#define DIVW XO31(491)
-#define DIVWU XO31(459)
-#define CMP XO31( 0)
-#define CMPL XO31( 32)
-#define LHBRX XO31(790)
-#define LWBRX XO31(534)
-#define STHBRX XO31(918)
-#define STWBRX XO31(662)
-#define MFSPR XO31(339)
-#define MTSPR XO31(467)
-#define SRAWI XO31(824)
-#define NEG XO31(104)
-
-#define LBZX XO31( 87)
-#define LHZX XO31(276)
-#define LHAX XO31(343)
-#define LWZX XO31( 23)
-#define STBX XO31(215)
-#define STHX XO31(407)
-#define STWX XO31(151)
-
-#define SPR(a,b) ((((a)<<5)|(b))<<11)
-#define LR SPR(8, 0)
-#define CTR SPR(9, 0)
-
-#define SLW XO31( 24)
-#define SRW XO31(536)
-#define SRAW XO31(792)
-
-#define LMW OPCD(46)
-#define STMW OPCD(47)
-
-#define TW XO31(4)
-#define TRAP (TW | TO (31))
-
-#define RT(r) ((r)<<21)
-#define RS(r) ((r)<<21)
-#define RA(r) ((r)<<16)
-#define RB(r) ((r)<<11)
-#define TO(t) ((t)<<21)
-#define SH(s) ((s)<<11)
-#define MB(b) ((b)<<6)
-#define ME(e) ((e)<<1)
-#define BO(o) ((o)<<21)
-
-#define LK 1
-
-#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
-#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
-
-#define BF(n) ((n)<<23)
-#define BI(n, c) (((c)+((n)*4))<<16)
-#define BT(n, c) (((c)+((n)*4))<<21)
-#define BA(n, c) (((c)+((n)*4))<<16)
-#define BB(n, c) (((c)+((n)*4))<<11)
-
-#define BO_COND_TRUE BO (12)
-#define BO_COND_FALSE BO (4)
-#define BO_ALWAYS BO (20)
-
-enum {
- CR_LT,
- CR_GT,
- CR_EQ,
- CR_SO
-};
-
-static const uint32_t tcg_to_bc[10] = {
- [TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE,
- [TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE,
- [TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE,
- [TCG_COND_GE] = BC | BI (7, CR_LT) | BO_COND_FALSE,
- [TCG_COND_LE] = BC | BI (7, CR_GT) | BO_COND_FALSE,
- [TCG_COND_GT] = BC | BI (7, CR_GT) | BO_COND_TRUE,
- [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
- [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
- [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
- [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
-};
-
-static void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- tcg_out32 (s, OR | SAB (arg, ret, arg));
-}
-
-static void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
- if (arg == (int16_t) arg)
- tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
- else {
- tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
- if (arg & 0xffff)
- tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
- }
-}
-
-static void tcg_out_ldst (TCGContext *s, int ret, int addr,
- int offset, int op1, int op2)
-{
- if (offset == (int16_t) offset)
- tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
- else {
- tcg_out_movi (s, TCG_TYPE_I32, 0, offset);
- tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
- }
-}
-
-static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
-{
- tcg_target_long disp;
-
- disp = target - (tcg_target_long) s->code_ptr;
- if ((disp << 6) >> 6 == disp)
- tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
- else {
- tcg_out_movi (s, TCG_TYPE_I32, 0, (tcg_target_long) target);
- tcg_out32 (s, MTSPR | RS (0) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
- }
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
-{
- int addr_reg, data_reg, data_reg2, r0, mem_index, s_bits, bswap;
-#ifdef CONFIG_SOFTMMU
- int r1, r2;
- void *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
- int addr_reg2;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0;
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
- s_bits = opc & 3;
-
-#ifdef CONFIG_SOFTMMU
- r0 = 3;
- r1 = 4;
- r2 = 0;
-
- tcg_out32 (s, (RLWINM
- | RA (r0)
- | RS (addr_reg)
- | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
- | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
- | ME (31 - CPU_TLB_ENTRY_BITS)
- )
- );
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
- tcg_out32 (s, (LWZU
- | RT (r1)
- | RA (r0)
- | offsetof (CPUState, tlb_table[mem_index][0].addr_read)
- )
- );
- tcg_out32 (s, (RLWINM
- | RA (r2)
- | RS (addr_reg)
- | SH (0)
- | MB ((32 - s_bits) & 31)
- | ME (31 - TARGET_PAGE_BITS)
- )
- );
-
- tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
-#if TARGET_LONG_BITS == 64
- tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
- tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
-#endif
-
- label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
- tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
- /* slow path */
-#if TARGET_LONG_BITS == 32
- tcg_out_mov (s, 3, addr_reg);
- tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);
-#else
- tcg_out_mov (s, 3, addr_reg2);
- tcg_out_mov (s, 4, addr_reg);
- tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
-#endif
-
- tcg_out_b (s, LK, (tcg_target_long) qemu_ld_helpers[s_bits]);
- switch (opc) {
- case 0|4:
- tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
- break;
- case 1|4:
- tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
- break;
- case 0:
- case 1:
- case 2:
- if (data_reg != 3)
- tcg_out_mov (s, data_reg, 3);
- break;
- case 3:
- if (data_reg == 3) {
- if (data_reg2 == 4) {
- tcg_out_mov (s, 0, 4);
- tcg_out_mov (s, 4, 3);
- tcg_out_mov (s, 3, 0);
- }
- else {
- tcg_out_mov (s, data_reg2, 3);
- tcg_out_mov (s, 3, 4);
- }
- }
- else {
- if (data_reg != 4) tcg_out_mov (s, data_reg, 4);
- if (data_reg2 != 3) tcg_out_mov (s, data_reg2, 3);
- }
- break;
- }
- label2_ptr = s->code_ptr;
- tcg_out32 (s, B);
-
- /* label1: fast path */
-#ifdef FAST_PATH
- reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
- /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
- tcg_out32 (s, (LWZ
- | RT (r0)
- | RA (r0)
- | (ADDEND_OFFSET + offsetof (CPUTLBEntry, addend)
- - offsetof (CPUTLBEntry, addr_read))
- ));
- /* r0 = env->tlb_table[mem_index][index].addend */
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
- /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else /* !CONFIG_SOFTMMU */
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 0;
-#else
- bswap = 1;
-#endif
- switch (opc) {
- default:
- case 0:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
- break;
- case 0|4:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
- tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
- break;
- case 1:
- if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
- break;
- case 1|4:
- if (bswap) {
- tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
- tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
- }
- else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
- break;
- case 2:
- if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
- break;
- case 3:
- if (bswap) {
- if (r0 == data_reg) {
- tcg_out32 (s, LWBRX | RT (0) | RB (r0));
- tcg_out32 (s, ADDI | RT (r0) | RA (r0) | 4);
- tcg_out32 (s, LWBRX | RT (data_reg2) | RB (r0));
- tcg_out_mov (s, data_reg, 0);
- }
- else {
- tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- tcg_out32 (s, ADDI | RT (r0) | RA (r0) | 4);
- tcg_out32 (s, LWBRX | RT (data_reg2) | RB (r0));
- }
- }
- else {
- if (r0 == data_reg2) {
- tcg_out32 (s, LWZ | RT (0) | RA (r0));
- tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
- tcg_out_mov (s, data_reg2, 0);
- }
- else {
- tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
- tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
- }
- }
- break;
- }
-
-#ifdef CONFIG_SOFTMMU
- reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
-{
- int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap;
-#ifdef CONFIG_SOFTMMU
- int r2, ir;
- void *label1_ptr, *label2_ptr;
-#endif
-#if TARGET_LONG_BITS == 64
- int addr_reg2;
-#endif
-
- data_reg = *args++;
- if (opc == 3)
- data_reg2 = *args++;
- else
- data_reg2 = 0;
- addr_reg = *args++;
-#if TARGET_LONG_BITS == 64
- addr_reg2 = *args++;
-#endif
- mem_index = *args;
-
-#ifdef CONFIG_SOFTMMU
- r0 = 3;
- r1 = 4;
- r2 = 0;
-
- tcg_out32 (s, (RLWINM
- | RA (r0)
- | RS (addr_reg)
- | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
- | MB (32 - (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS))
- | ME (31 - CPU_TLB_ENTRY_BITS)
- )
- );
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
- tcg_out32 (s, (LWZU
- | RT (r1)
- | RA (r0)
- | offsetof (CPUState, tlb_table[mem_index][0].addr_write)
- )
- );
- tcg_out32 (s, (RLWINM
- | RA (r2)
- | RS (addr_reg)
- | SH (0)
- | MB ((32 - opc) & 31)
- | ME (31 - TARGET_PAGE_BITS)
- )
- );
-
- tcg_out32 (s, CMP | (7 << 23) | RA (r2) | RB (r1));
-#if TARGET_LONG_BITS == 64
- tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));
- tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
-#endif
-
- label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
- tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
- /* slow path */
-#if TARGET_LONG_BITS == 32
- tcg_out_mov (s, 3, addr_reg);
- ir = 4;
-#else
- tcg_out_mov (s, 3, addr_reg2);
- tcg_out_mov (s, 4, addr_reg);
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
- ir = 5;
-#else
- ir = 4;
-#endif
-#endif
-
- switch (opc) {
- case 0:
- tcg_out32 (s, (RLWINM
- | RA (ir)
- | RS (data_reg)
- | SH (0)
- | MB (24)
- | ME (31)));
- break;
- case 1:
- tcg_out32 (s, (RLWINM
- | RA (ir)
- | RS (data_reg)
- | SH (0)
- | MB (16)
- | ME (31)));
- break;
- case 2:
- tcg_out_mov (s, ir, data_reg);
- break;
- case 3:
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
- ir = 5;
-#endif
- tcg_out_mov (s, ir++, data_reg2);
- tcg_out_mov (s, ir, data_reg);
- break;
- }
- ir++;
-
- tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
- tcg_out_b (s, LK, (tcg_target_long) qemu_st_helpers[opc]);
- label2_ptr = s->code_ptr;
- tcg_out32 (s, B);
-
- /* label1: fast path */
-#ifdef FAST_PATH
- reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
- tcg_out32 (s, (LWZ
- | RT (r0)
- | RA (r0)
- | (ADDEND_OFFSET + offsetof (CPUTLBEntry, addend)
- - offsetof (CPUTLBEntry, addr_write))
- ));
- /* r0 = env->tlb_table[mem_index][index].addend */
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
- /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else /* !CONFIG_SOFTMMU */
- r1 = 3;
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 0;
-#else
- bswap = 1;
-#endif
- switch (opc) {
- case 0:
- tcg_out32 (s, STB | RS (data_reg) | RA (r0));
- break;
- case 1:
- if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
- break;
- case 2:
- if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
- break;
- case 3:
- if (bswap) {
- tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- tcg_out32 (s, STWBRX | RS (data_reg2) | RA (0) | RB (r1));
- }
- else {
- tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
- tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
- }
- break;
- }
-
-#ifdef CONFIG_SOFTMMU
- reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-void tcg_target_qemu_prologue (TCGContext *s)
-{
- int i, frame_size;
-
- frame_size = 0
- + LINKAGE_AREA_SIZE
- + TCG_STATIC_CALL_ARGS_SIZE
- + ARRAY_SIZE (tcg_target_callee_save_regs) * 4
- ;
- frame_size = (frame_size + 15) & ~15;
-
- tcg_out32 (s, MFSPR | RT (0) | LR);
- tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff));
- for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
- tcg_out32 (s, (STW
- | RS (tcg_target_callee_save_regs[i])
- | RA (1)
- | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
- )
- );
- tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + BACK_CHAIN_OFFSET));
-
- tcg_out32 (s, MTSPR | RS (3) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS);
- tb_ret_addr = s->code_ptr;
-
- for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
- tcg_out32 (s, (LWZ
- | RT (tcg_target_callee_save_regs[i])
- | RA (1)
- | (i * 4 + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE)
- )
- );
- tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + BACK_CHAIN_OFFSET));
- tcg_out32 (s, MTSPR | RS (0) | LR);
- tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
- tcg_out32 (s, BCLR | BO_ALWAYS);
-}
-
-static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
- tcg_target_long arg2)
-{
- tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
-}
-
-static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
- tcg_target_long arg2)
-{
- tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
-}
-
-static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
-{
- if (!si && rt == ra)
- return;
-
- if (si == (int16_t) si)
- tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
- else {
- uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
- tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
- tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
- }
-}
-
-static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- ppc_addi (s, reg, reg, val);
-}
-
-static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
- int const_arg2, int cr)
-{
- int imm;
- uint32_t op;
-
- switch (cond) {
- case TCG_COND_EQ:
- case TCG_COND_NE:
- if (const_arg2) {
- if ((int16_t) arg2 == arg2) {
- op = CMPI;
- imm = 1;
- break;
- }
- else if ((uint16_t) arg2 == arg2) {
- op = CMPLI;
- imm = 1;
- break;
- }
- }
- op = CMPL;
- imm = 0;
- break;
-
- case TCG_COND_LT:
- case TCG_COND_GE:
- case TCG_COND_LE:
- case TCG_COND_GT:
- if (const_arg2) {
- if ((int16_t) arg2 == arg2) {
- op = CMPI;
- imm = 1;
- break;
- }
- }
- op = CMP;
- imm = 0;
- break;
-
- case TCG_COND_LTU:
- case TCG_COND_GEU:
- case TCG_COND_LEU:
- case TCG_COND_GTU:
- if (const_arg2) {
- if ((uint16_t) arg2 == arg2) {
- op = CMPLI;
- imm = 1;
- break;
- }
- }
- op = CMPL;
- imm = 0;
- break;
-
- default:
- tcg_abort ();
- }
- op |= BF (cr);
-
- if (imm)
- tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
- else {
- if (const_arg2) {
- tcg_out_movi (s, TCG_TYPE_I32, 0, arg2);
- tcg_out32 (s, op | RA (arg1) | RB (0));
- }
- else
- tcg_out32 (s, op | RA (arg1) | RB (arg2));
- }
-
-}
-
-static void tcg_out_bc (TCGContext *s, int bc, int label_index)
-{
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value)
- tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
- else {
- uint16_t val = *(uint16_t *) &s->code_ptr[2];
-
- /* Thanks to Andrzej Zaborowski */
- tcg_out32 (s, bc | (val & 0xfffc));
- tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
- }
-}
-
-static void tcg_out_brcond (TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index)
-{
- tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
- tcg_out_bc (s, tcg_to_bc[cond], label_index);
-}
-
-/* XXX: we implement it at the target level to avoid having to
- handle cross basic blocks temporaries */
-static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
- const int *const_args)
-{
- int cond = args[4], label_index = args[5], op;
- struct { int bit1; int bit2; int cond2; } bits[] = {
- [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT },
- [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT },
- [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT },
- [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT },
- [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU },
- [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU },
- [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU },
- [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU },
- }, *b = &bits[cond];
-
- switch (cond) {
- case TCG_COND_EQ:
- case TCG_COND_NE:
- op = (cond == TCG_COND_EQ) ? CRAND : CRNAND;
- tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 6);
- tcg_out_cmp (s, cond, args[1], args[3], const_args[3], 7);
- tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
- break;
- case TCG_COND_LT:
- case TCG_COND_LE:
- case TCG_COND_GT:
- case TCG_COND_GE:
- case TCG_COND_LTU:
- case TCG_COND_LEU:
- case TCG_COND_GTU:
- case TCG_COND_GEU:
- op = (b->bit1 != b->bit2) ? CRANDC : CRAND;
- tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5);
- tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6);
- tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 7);
- tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2));
- tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ));
- break;
- default:
- tcg_abort();
- }
-
- tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), label_index);
-}
-
-void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
-{
- uint32_t *ptr;
- long disp = addr - jmp_addr;
- unsigned long patch_size;
-
- ptr = (uint32_t *)jmp_addr;
-
- if ((disp << 6) >> 6 != disp) {
- ptr[0] = 0x3c000000 | (addr >> 16); /* lis 0,addr@ha */
- ptr[1] = 0x60000000 | (addr & 0xffff); /* la 0,addr@l(0) */
- ptr[2] = 0x7c0903a6; /* mtctr 0 */
- ptr[3] = 0x4e800420; /* brctr */
- patch_size = 16;
- } else {
- /* patch the branch destination */
- if (disp != 16) {
- *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */
- patch_size = 4;
- } else {
- ptr[0] = 0x60000000; /* nop */
- ptr[1] = 0x60000000;
- ptr[2] = 0x60000000;
- ptr[3] = 0x60000000;
- patch_size = 16;
- }
- }
- /* flush icache */
- flush_icache_range(jmp_addr, jmp_addr + patch_size);
-}
-
-static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
- const int *const_args)
-{
- switch (opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi (s, TCG_TYPE_I32, TCG_REG_R3, args[0]);
- tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
-
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- s->code_ptr += 16;
- }
- else {
- tcg_abort ();
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_br:
- {
- TCGLabel *l = &s->labels[args[0]];
-
- if (l->has_value) {
- tcg_out_b (s, 0, l->u.value);
- }
- else {
- uint32_t val = *(uint32_t *) s->code_ptr;
-
- /* Thanks to Andrzej Zaborowski */
- tcg_out32 (s, B | (val & 0x3fffffc));
- tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
- }
- }
- break;
- case INDEX_op_call:
- if (const_args[0]) {
- tcg_out_b (s, LK, args[0]);
- }
- else {
- tcg_out32 (s, MTSPR | RS (args[0]) | LR);
- tcg_out32 (s, BCLR | BO_ALWAYS | LK);
- }
- break;
- case INDEX_op_jmp:
- if (const_args[0]) {
- tcg_out_b (s, 0, args[0]);
- }
- else {
- tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS);
- }
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
- break;
- case INDEX_op_ld8u_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
- break;
- case INDEX_op_ld8s_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
- tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
- break;
- case INDEX_op_ld16u_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
- break;
- case INDEX_op_ld16s_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
- break;
- case INDEX_op_ld_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
- break;
- case INDEX_op_st8_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
- break;
- case INDEX_op_st16_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
- break;
- case INDEX_op_st_i32:
- tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
- break;
-
- case INDEX_op_add_i32:
- if (const_args[2])
- ppc_addi (s, args[0], args[1], args[2]);
- else
- tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
- break;
- case INDEX_op_sub_i32:
- if (const_args[2])
- ppc_addi (s, args[0], args[1], -args[2]);
- else
- tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
- break;
-
- case INDEX_op_and_i32:
- if (const_args[2]) {
- if ((args[2] & 0xffff) == args[2])
- tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
- else if ((args[2] & 0xffff0000) == args[2])
- tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- else {
- tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
- tcg_out32 (s, AND | SAB (args[1], args[0], 0));
- }
- }
- else
- tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_or_i32:
- if (const_args[2]) {
- if (args[2] & 0xffff) {
- tcg_out32 (s, ORI | RS (args[1]) | RA (args[0])
- | (args[2] & 0xffff));
- if (args[2] >> 16)
- tcg_out32 (s, ORIS | RS (args[0]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- }
- else {
- tcg_out32 (s, ORIS | RS (args[1]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- }
- }
- else
- tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_xor_i32:
- if (const_args[2]) {
- if ((args[2] & 0xffff) == args[2])
- tcg_out32 (s, XORI | RS (args[1]) | RA (args[0])
- | (args[2] & 0xffff));
- else if ((args[2] & 0xffff0000) == args[2])
- tcg_out32 (s, XORIS | RS (args[1]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- else {
- tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
- tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
- }
- }
- else
- tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
- break;
-
- case INDEX_op_mul_i32:
- if (const_args[2]) {
- if (args[2] == (int16_t) args[2])
- tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
- | (args[2] & 0xffff));
- else {
- tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
- tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
- }
- }
- else
- tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
- break;
-
- case INDEX_op_div_i32:
- tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
- break;
-
- case INDEX_op_divu_i32:
- tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
- break;
-
- case INDEX_op_rem_i32:
- tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
- tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
- tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
- break;
-
- case INDEX_op_remu_i32:
- tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
- tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
- tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
- break;
-
- case INDEX_op_mulu2_i32:
- if (args[0] == args[2] || args[0] == args[3]) {
- tcg_out32 (s, MULLW | TAB (0, args[2], args[3]));
- tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
- tcg_out_mov (s, args[0], 0);
- }
- else {
- tcg_out32 (s, MULLW | TAB (args[0], args[2], args[3]));
- tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3]));
- }
- break;
-
- case INDEX_op_shl_i32:
- if (const_args[2]) {
- tcg_out32 (s, (RLWINM
- | RA (args[0])
- | RS (args[1])
- | SH (args[2])
- | MB (0)
- | ME (31 - args[2])
- )
- );
- }
- else
- tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_shr_i32:
- if (const_args[2]) {
- tcg_out32 (s, (RLWINM
- | RA (args[0])
- | RS (args[1])
- | SH (32 - args[2])
- | MB (args[2])
- | ME (31)
- )
- );
- }
- else
- tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_sar_i32:
- if (const_args[2])
- tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
- else
- tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
- break;
-
- case INDEX_op_add2_i32:
- if (args[0] == args[3] || args[0] == args[5]) {
- tcg_out32 (s, ADDC | TAB (0, args[2], args[4]));
- tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
- tcg_out_mov (s, args[0], 0);
- }
- else {
- tcg_out32 (s, ADDC | TAB (args[0], args[2], args[4]));
- tcg_out32 (s, ADDE | TAB (args[1], args[3], args[5]));
- }
- break;
- case INDEX_op_sub2_i32:
- if (args[0] == args[3] || args[0] == args[5]) {
- tcg_out32 (s, SUBFC | TAB (0, args[4], args[2]));
- tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
- tcg_out_mov (s, args[0], 0);
- }
- else {
- tcg_out32 (s, SUBFC | TAB (args[0], args[4], args[2]));
- tcg_out32 (s, SUBFE | TAB (args[1], args[5], args[3]));
- }
- break;
-
- case INDEX_op_brcond_i32:
- /*
- args[0] = r0
- args[1] = r1
- args[2] = cond
- args[3] = r1 is const
- args[4] = label_index
- */
- tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3]);
- break;
- case INDEX_op_brcond2_i32:
- tcg_out_brcond2(s, args, const_args);
- break;
-
- case INDEX_op_neg_i32:
- tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, args, 2);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, args, 3);
- break;
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, args, 2);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, args, 3);
- break;
-
- case INDEX_op_ext8s_i32:
- tcg_out32 (s, EXTSB | RS (args[1]) | RA (args[0]));
- break;
- case INDEX_op_ext16s_i32:
- tcg_out32 (s, EXTSH | RS (args[1]) | RA (args[0]));
- break;
-
- default:
- tcg_dump_ops (s, stderr);
- tcg_abort ();
- }
-}
-
-static const TCGTargetOpDef ppc_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } },
- { INDEX_op_jmp, { "ri" } },
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "r", "ri" } },
- { INDEX_op_mul_i32, { "r", "r", "ri" } },
- { INDEX_op_div_i32, { "r", "r", "r" } },
- { INDEX_op_divu_i32, { "r", "r", "r" } },
- { INDEX_op_rem_i32, { "r", "r", "r" } },
- { INDEX_op_remu_i32, { "r", "r", "r" } },
- { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
- { INDEX_op_sub_i32, { "r", "r", "ri" } },
- { INDEX_op_and_i32, { "r", "r", "ri" } },
- { INDEX_op_or_i32, { "r", "r", "ri" } },
- { INDEX_op_xor_i32, { "r", "r", "ri" } },
-
- { INDEX_op_shl_i32, { "r", "r", "ri" } },
- { INDEX_op_shr_i32, { "r", "r", "ri" } },
- { INDEX_op_sar_i32, { "r", "r", "ri" } },
-
- { INDEX_op_brcond_i32, { "r", "ri" } },
-
- { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
- { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
- { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
-
- { INDEX_op_neg_i32, { "r", "r" } },
-
-#if TARGET_LONG_BITS == 32
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L" } },
- { INDEX_op_qemu_ld64, { "r", "r", "L" } },
-
- { INDEX_op_qemu_st8, { "K", "K" } },
- { INDEX_op_qemu_st16, { "K", "K" } },
- { INDEX_op_qemu_st32, { "K", "K" } },
- { INDEX_op_qemu_st64, { "M", "M", "M" } },
-#else
- { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L", "L" } },
- { INDEX_op_qemu_ld64, { "r", "L", "L", "L" } },
-
- { INDEX_op_qemu_st8, { "K", "K", "K" } },
- { INDEX_op_qemu_st16, { "K", "K", "K" } },
- { INDEX_op_qemu_st32, { "K", "K", "K" } },
- { INDEX_op_qemu_st64, { "M", "M", "M", "M" } },
-#endif
-
- { INDEX_op_ext8s_i32, { "r", "r" } },
- { INDEX_op_ext16s_i32, { "r", "r" } },
-
- { -1 },
-};
-
-void tcg_target_init(TCGContext *s)
-{
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_R0) |
-#ifdef __APPLE__
- (1 << TCG_REG_R2) |
-#endif
- (1 << TCG_REG_R3) |
- (1 << TCG_REG_R4) |
- (1 << TCG_REG_R5) |
- (1 << TCG_REG_R6) |
- (1 << TCG_REG_R7) |
- (1 << TCG_REG_R8) |
- (1 << TCG_REG_R9) |
- (1 << TCG_REG_R10) |
- (1 << TCG_REG_R11) |
- (1 << TCG_REG_R12)
- );
-
- tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
-#ifndef __APPLE__
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
-#endif
-
- tcg_add_target_add_op_defs(ppc_op_defs);
-}
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
deleted file mode 100644
index d46c19d..0000000
--- a/tcg/ppc/tcg-target.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_PPC 1
-
-#define TCG_TARGET_REG_BITS 32
-#define TCG_TARGET_WORDS_BIGENDIAN
-#define TCG_TARGET_NB_REGS 32
-
-enum {
- TCG_REG_R0 = 0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R24,
- TCG_REG_R25,
- TCG_REG_R26,
- TCG_REG_R27,
- TCG_REG_R28,
- TCG_REG_R29,
- TCG_REG_R30,
- TCG_REG_R31
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_R1
-#define TCG_TARGET_STACK_ALIGN 16
-#ifdef __APPLE__
-#define TCG_TARGET_CALL_STACK_OFFSET 24
-#else
-#define TCG_TARGET_CALL_ALIGN_ARGS 1
-#define TCG_TARGET_CALL_STACK_OFFSET 8
-#endif
-
-/* optional instructions */
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_div_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-
-#define TCG_AREG0 TCG_REG_R27
-#define TCG_AREG1 TCG_REG_R24
-#define TCG_AREG2 TCG_REG_R25
-#define TCG_AREG3 TCG_REG_R26
-
-/* taken directly from tcg-dyngen.c */
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
deleted file mode 100644
index 6b16efa..0000000
--- a/tcg/ppc64/tcg-target.c
+++ /dev/null
@@ -1,1491 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#define TCG_CT_CONST_U32 0x100
-
-static uint8_t *tb_ret_addr;
-
-#define FAST_PATH
-
-#if TARGET_PHYS_ADDR_BITS == 32
-#define LD_ADDEND LWZ
-#else
-#define LD_ADDEND LD
-#endif
-
-#if TARGET_LONG_BITS == 32
-#define LD_ADDR LWZU
-#define CMP_L 0
-#else
-#define LD_ADDR LDU
-#define CMP_L (1<<21)
-#endif
-
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "r0",
- "r1",
- "rp",
- "r3",
- "r4",
- "r5",
- "r6",
- "r7",
- "r8",
- "r9",
- "r10",
- "r11",
- "r12",
- "r13",
- "r14",
- "r15",
- "r16",
- "r17",
- "r18",
- "r19",
- "r20",
- "r21",
- "r22",
- "r23",
- "r24",
- "r25",
- "r26",
- "r27",
- "r28",
- "r29",
- "r30",
- "r31"
-};
-
-static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R28,
- TCG_REG_R29,
- TCG_REG_R30,
- TCG_REG_R31,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R24,
- TCG_REG_R25,
- TCG_REG_R26,
- TCG_REG_R27
-};
-
-static const int tcg_target_call_iarg_regs[] = {
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_R3
-};
-
-static const int tcg_target_callee_save_regs[] = {
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R28,
- TCG_REG_R29,
- TCG_REG_R30,
- TCG_REG_R31
-};
-
-static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
-{
- tcg_target_long disp;
-
- disp = target - (tcg_target_long) pc;
- if ((disp << 38) >> 38 != disp)
- tcg_abort ();
-
- return disp & 0x3fffffc;
-}
-
-static void reloc_pc24 (void *pc, tcg_target_long target)
-{
- *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
- | reloc_pc24_val (pc, target);
-}
-
-static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
-{
- tcg_target_long disp;
-
- disp = target - (tcg_target_long) pc;
- if (disp != (int16_t) disp)
- tcg_abort ();
-
- return disp & 0xfffc;
-}
-
-static void reloc_pc14 (void *pc, tcg_target_long target)
-{
- *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
- | reloc_pc14_val (pc, target);
-}
-
-static void patch_reloc (uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- value += addend;
- switch (type) {
- case R_PPC_REL14:
- reloc_pc14 (code_ptr, value);
- break;
- case R_PPC_REL24:
- reloc_pc24 (code_ptr, value);
- break;
- default:
- tcg_abort ();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static int tcg_target_get_call_iarg_regs_count (int flags)
-{
- return sizeof (tcg_target_call_iarg_regs) / sizeof (tcg_target_call_iarg_regs[0]);
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch (ct_str[0]) {
- case 'A': case 'B': case 'C': case 'D':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
- break;
- case 'r':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
- break;
- case 'L': /* qemu_ld constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
-#ifdef CONFIG_SOFTMMU
- tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
-#endif
- break;
- case 'S': /* qemu_st constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
- tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
-#ifdef CONFIG_SOFTMMU
- tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
- tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
-#endif
- break;
- case 'Z':
- ct->ct |= TCG_CT_CONST_U32;
- break;
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static int tcg_target_const_match (tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
-
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val))
- return 1;
- return 0;
-}
-
-#define OPCD(opc) ((opc)<<26)
-#define XO19(opc) (OPCD(19)|((opc)<<1))
-#define XO30(opc) (OPCD(30)|((opc)<<2))
-#define XO31(opc) (OPCD(31)|((opc)<<1))
-#define XO58(opc) (OPCD(58)|(opc))
-#define XO62(opc) (OPCD(62)|(opc))
-
-#define B OPCD( 18)
-#define BC OPCD( 16)
-#define LBZ OPCD( 34)
-#define LHZ OPCD( 40)
-#define LHA OPCD( 42)
-#define LWZ OPCD( 32)
-#define STB OPCD( 38)
-#define STH OPCD( 44)
-#define STW OPCD( 36)
-
-#define STD XO62( 0)
-#define STDU XO62( 1)
-#define STDX XO31(149)
-
-#define LD XO58( 0)
-#define LDX XO31( 21)
-#define LDU XO58( 1)
-#define LWA XO58( 2)
-#define LWAX XO31(341)
-
-#define ADDI OPCD( 14)
-#define ADDIS OPCD( 15)
-#define ORI OPCD( 24)
-#define ORIS OPCD( 25)
-#define XORI OPCD( 26)
-#define XORIS OPCD( 27)
-#define ANDI OPCD( 28)
-#define ANDIS OPCD( 29)
-#define MULLI OPCD( 7)
-#define CMPLI OPCD( 10)
-#define CMPI OPCD( 11)
-
-#define LWZU OPCD( 33)
-#define STWU OPCD( 37)
-
-#define RLWINM OPCD( 21)
-
-#define RLDICL XO30( 0)
-#define RLDICR XO30( 1)
-
-#define BCLR XO19( 16)
-#define BCCTR XO19(528)
-#define CRAND XO19(257)
-#define CRANDC XO19(129)
-#define CRNAND XO19(225)
-#define CROR XO19(449)
-
-#define EXTSB XO31(954)
-#define EXTSH XO31(922)
-#define EXTSW XO31(986)
-#define ADD XO31(266)
-#define ADDE XO31(138)
-#define ADDC XO31( 10)
-#define AND XO31( 28)
-#define SUBF XO31( 40)
-#define SUBFC XO31( 8)
-#define SUBFE XO31(136)
-#define OR XO31(444)
-#define XOR XO31(316)
-#define MULLW XO31(235)
-#define MULHWU XO31( 11)
-#define DIVW XO31(491)
-#define DIVWU XO31(459)
-#define CMP XO31( 0)
-#define CMPL XO31( 32)
-#define LHBRX XO31(790)
-#define LWBRX XO31(534)
-#define STHBRX XO31(918)
-#define STWBRX XO31(662)
-#define MFSPR XO31(339)
-#define MTSPR XO31(467)
-#define SRAWI XO31(824)
-#define NEG XO31(104)
-
-#define MULLD XO31(233)
-#define MULHD XO31( 73)
-#define MULHDU XO31( 9)
-#define DIVD XO31(489)
-#define DIVDU XO31(457)
-
-#define LBZX XO31( 87)
-#define LHZX XO31(276)
-#define LHAX XO31(343)
-#define LWZX XO31( 23)
-#define STBX XO31(215)
-#define STHX XO31(407)
-#define STWX XO31(151)
-
-#define SPR(a,b) ((((a)<<5)|(b))<<11)
-#define LR SPR(8, 0)
-#define CTR SPR(9, 0)
-
-#define SLW XO31( 24)
-#define SRW XO31(536)
-#define SRAW XO31(792)
-
-#define SLD XO31( 27)
-#define SRD XO31(539)
-#define SRAD XO31(794)
-#define SRADI XO31(413<<1)
-
-#define LMW OPCD( 46)
-#define STMW OPCD( 47)
-
-#define TW XO31( 4)
-#define TRAP (TW | TO (31))
-
-#define RT(r) ((r)<<21)
-#define RS(r) ((r)<<21)
-#define RA(r) ((r)<<16)
-#define RB(r) ((r)<<11)
-#define TO(t) ((t)<<21)
-#define SH(s) ((s)<<11)
-#define MB(b) ((b)<<6)
-#define ME(e) ((e)<<1)
-#define BO(o) ((o)<<21)
-#define MB64(b) ((b)<<5)
-
-#define LK 1
-
-#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
-#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
-
-#define BF(n) ((n)<<23)
-#define BI(n, c) (((c)+((n)*4))<<16)
-#define BT(n, c) (((c)+((n)*4))<<21)
-#define BA(n, c) (((c)+((n)*4))<<16)
-#define BB(n, c) (((c)+((n)*4))<<11)
-
-#define BO_COND_TRUE BO (12)
-#define BO_COND_FALSE BO ( 4)
-#define BO_ALWAYS BO (20)
-
-enum {
- CR_LT,
- CR_GT,
- CR_EQ,
- CR_SO
-};
-
-static const uint32_t tcg_to_bc[10] = {
- [TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE,
- [TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE,
- [TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE,
- [TCG_COND_GE] = BC | BI (7, CR_LT) | BO_COND_FALSE,
- [TCG_COND_LE] = BC | BI (7, CR_GT) | BO_COND_FALSE,
- [TCG_COND_GT] = BC | BI (7, CR_GT) | BO_COND_TRUE,
- [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
- [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
- [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
- [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
-};
-
-static void tcg_out_mov (TCGContext *s, int ret, int arg)
-{
- tcg_out32 (s, OR | SAB (arg, ret, arg));
-}
-
-static void tcg_out_rld (TCGContext *s, int op, int ra, int rs, int sh, int mb)
-{
- sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
- mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
- tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
-}
-
-static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg)
-{
- if (arg == (int16_t) arg)
- tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
- else {
- tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
- if (arg & 0xffff)
- tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
- }
-}
-
-static void tcg_out_movi (TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
- int32_t arg32 = arg;
-
- if (type == TCG_TYPE_I32 || arg == arg32) {
- tcg_out_movi32 (s, ret, arg32);
- }
- else {
- if ((uint64_t) arg >> 32) {
- uint16_t h16 = arg >> 16;
- uint16_t l16 = arg;
-
- tcg_out_movi32 (s, ret, arg >> 32);
- tcg_out_rld (s, RLDICR, ret, ret, 32, 31);
- if (h16) tcg_out32 (s, ORIS | RS (ret) | RA (ret) | h16);
- if (l16) tcg_out32 (s, ORI | RS (ret) | RA (ret) | l16);
- }
- else {
- tcg_out_movi32 (s, ret, arg32);
- if (arg32 < 0)
- tcg_out_rld (s, RLDICL, ret, ret, 0, 32);
- }
- }
-}
-
-static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
-{
- int reg;
-
- if (const_arg) {
- reg = 2;
- tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
- }
- else reg = arg;
-
- tcg_out32 (s, LD | RT (0) | RA (reg));
- tcg_out32 (s, MTSPR | RA (0) | CTR);
- tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
- tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
- tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
-}
-
-static void tcg_out_ldst (TCGContext *s, int ret, int addr,
- int offset, int op1, int op2)
-{
- if (offset == (int16_t) offset)
- tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
- else {
- tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
- tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
- }
-}
-
-static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
-{
- tcg_target_long disp;
-
- disp = target - (tcg_target_long) s->code_ptr;
- if ((disp << 38) >> 38 == disp)
- tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
- else {
- tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
- tcg_out32 (s, MTSPR | RS (0) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
- }
-}
-
-#if defined (CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-
-static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
- int addr_reg, int s_bits, int offset)
-{
-#if TARGET_LONG_BITS == 32
- tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
-
- tcg_out32 (s, (RLWINM
- | RA (r0)
- | RS (addr_reg)
- | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
- | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
- | ME (31 - CPU_TLB_ENTRY_BITS)
- )
- );
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
- tcg_out32 (s, (LWZU | RT (r1) | RA (r0) | offset));
- tcg_out32 (s, (RLWINM
- | RA (r2)
- | RS (addr_reg)
- | SH (0)
- | MB ((32 - s_bits) & 31)
- | ME (31 - TARGET_PAGE_BITS)
- )
- );
-#else
- tcg_out_rld (s, RLDICL, r0, addr_reg,
- 64 - TARGET_PAGE_BITS,
- 64 - CPU_TLB_BITS);
- tcg_out_rld (s, RLDICR, r0, r0,
- CPU_TLB_ENTRY_BITS,
- 63 - CPU_TLB_ENTRY_BITS);
-
- tcg_out32 (s, ADD | TAB (r0, r0, TCG_AREG0));
- tcg_out32 (s, LD_ADDR | RT (r1) | RA (r0) | offset);
-
- if (!s_bits) {
- tcg_out_rld (s, RLDICR, r2, addr_reg, 0, 63 - TARGET_PAGE_BITS);
- }
- else {
- tcg_out_rld (s, RLDICL, r2, addr_reg,
- 64 - TARGET_PAGE_BITS,
- TARGET_PAGE_BITS - s_bits);
- tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
- }
-#endif
-}
-#endif
-
-static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
-{
- int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap;
-#ifdef CONFIG_SOFTMMU
- int r2;
- void *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
- s_bits = opc & 3;
-
-#ifdef CONFIG_SOFTMMU
- r0 = 3;
- r1 = 4;
- r2 = 0;
-
- tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
- offsetof (CPUState, tlb_table[mem_index][0].addr_read));
-
- tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
-
- label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
- tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
- /* slow path */
- tcg_out_mov (s, 3, addr_reg);
- tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
-
- tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
-
- switch (opc) {
- case 0|4:
- tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
- break;
- case 1|4:
- tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
- break;
- case 2|4:
- tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
- break;
- case 0:
- case 1:
- case 2:
- case 3:
- if (data_reg != 3)
- tcg_out_mov (s, data_reg, 3);
- break;
- }
- label2_ptr = s->code_ptr;
- tcg_out32 (s, B);
-
- /* label1: fast path */
-#ifdef FAST_PATH
- reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
- /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
- tcg_out32 (s, (LD_ADDEND
- | RT (r0)
- | RA (r0)
- | (offsetof (CPUTLBEntry, addend)
- - offsetof (CPUTLBEntry, addr_read))
- ));
- /* r0 = env->tlb_table[mem_index][index].addend */
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
- /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else /* !CONFIG_SOFTMMU */
-#if TARGET_LONG_BITS == 32
- tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
-#endif
- r0 = addr_reg;
- r1 = 3;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 0;
-#else
- bswap = 1;
-#endif
- switch (opc) {
- default:
- case 0:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
- break;
- case 0|4:
- tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
- tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
- break;
- case 1:
- if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
- break;
- case 1|4:
- if (bswap) {
- tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
- tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
- }
- else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
- break;
- case 2:
- if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
- break;
- case 2|4:
- if (bswap) {
- tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
- tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
- }
- else tcg_out32 (s, LWA | RT (data_reg)| RA (r0));
- break;
- case 3:
- if (bswap) {
- tcg_out32 (s, LWBRX | RT (0) | RB (r0));
- tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
- tcg_out32 (s, LWBRX | RT (data_reg) | RB (r1));
- tcg_out_rld (s, RLDICR, data_reg, data_reg, 32, 31);
- tcg_out32 (s, OR | SAB (0, data_reg, data_reg));
- }
- else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
- break;
- }
-
-#ifdef CONFIG_SOFTMMU
- reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
-{
- int addr_reg, r0, r1, data_reg, mem_index, bswap;
-#ifdef CONFIG_SOFTMMU
- int r2;
- void *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
-
-#ifdef CONFIG_SOFTMMU
- r0 = 3;
- r1 = 4;
- r2 = 0;
-
- tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
- offsetof (CPUState, tlb_table[mem_index][0].addr_write));
-
- tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
-
- label1_ptr = s->code_ptr;
-#ifdef FAST_PATH
- tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
-#endif
-
- /* slow path */
- tcg_out_mov (s, 3, addr_reg);
- tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
- tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
-
- tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
-
- label2_ptr = s->code_ptr;
- tcg_out32 (s, B);
-
- /* label1: fast path */
-#ifdef FAST_PATH
- reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
-#endif
-
- tcg_out32 (s, (LD_ADDEND
- | RT (r0)
- | RA (r0)
- | (offsetof (CPUTLBEntry, addend)
- - offsetof (CPUTLBEntry, addr_write))
- ));
- /* r0 = env->tlb_table[mem_index][index].addend */
- tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
- /* r0 = env->tlb_table[mem_index][index].addend + addr */
-
-#else /* !CONFIG_SOFTMMU */
-#if TARGET_LONG_BITS == 32
- tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
-#endif
- r1 = 3;
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 0;
-#else
- bswap = 1;
-#endif
- switch (opc) {
- case 0:
- tcg_out32 (s, STB | RS (data_reg) | RA (r0));
- break;
- case 1:
- if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
- break;
- case 2:
- if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
- break;
- case 3:
- if (bswap) {
- tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
- tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
- tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
- tcg_out32 (s, STWBRX | RS (0) | RA (0) | RB (r1));
- }
- else tcg_out32 (s, STD | RS (data_reg) | RA (r0));
- break;
- }
-
-#ifdef CONFIG_SOFTMMU
- reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
-#endif
-}
-
-void tcg_target_qemu_prologue (TCGContext *s)
-{
- int i, frame_size;
- uint64_t addr;
-
- frame_size = 0
- + 8 /* back chain */
- + 8 /* CR */
- + 8 /* LR */
- + 8 /* compiler doubleword */
- + 8 /* link editor doubleword */
- + 8 /* TOC save area */
- + TCG_STATIC_CALL_ARGS_SIZE
- + ARRAY_SIZE (tcg_target_callee_save_regs) * 8
- ;
- frame_size = (frame_size + 15) & ~15;
-
- /* First emit adhoc function descriptor */
- addr = (uint64_t) s->code_ptr + 24;
- tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
- s->code_ptr += 16; /* skip TOC and environment pointer */
-
- /* Prologue */
- tcg_out32 (s, MFSPR | RT (0) | LR);
- tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
- for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
- tcg_out32 (s, (STD
- | RS (tcg_target_callee_save_regs[i])
- | RA (1)
- | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
- )
- );
- tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
-
- tcg_out32 (s, MTSPR | RS (3) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS);
-
- /* Epilogue */
- tb_ret_addr = s->code_ptr;
-
- for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
- tcg_out32 (s, (LD
- | RT (tcg_target_callee_save_regs[i])
- | RA (1)
- | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
- )
- );
- tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 16));
- tcg_out32 (s, MTSPR | RS (0) | LR);
- tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
- tcg_out32 (s, BCLR | BO_ALWAYS);
-}
-
-static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
- tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
- else
- tcg_out_ldst (s, ret, arg1, arg2, LD, LDX);
-}
-
-static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
- tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
- else
- tcg_out_ldst (s, arg, arg1, arg2, STD, STDX);
-}
-
-static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
-{
- if (!si && rt == ra)
- return;
-
- if (si == (int16_t) si)
- tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
- else {
- uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
- tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
- tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
- }
-}
-
-static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
-{
- /* XXX: suboptimal */
- if (si == (int16_t) si
- || (((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0)
- ppc_addi32 (s, rt, ra, si);
- else {
- tcg_out_movi (s, TCG_TYPE_I64, 0, si);
- tcg_out32 (s, ADD | RT (rt) | RA (ra));
- }
-}
-
-static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val)
-{
- ppc_addi64 (s, reg, reg, val);
-}
-
-static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
- int const_arg2, int cr, int arch64)
-{
- int imm;
- uint32_t op;
-
- switch (cond) {
- case TCG_COND_EQ:
- case TCG_COND_NE:
- if (const_arg2) {
- if ((int16_t) arg2 == arg2) {
- op = CMPI;
- imm = 1;
- break;
- }
- else if ((uint16_t) arg2 == arg2) {
- op = CMPLI;
- imm = 1;
- break;
- }
- }
- op = CMPL;
- imm = 0;
- break;
-
- case TCG_COND_LT:
- case TCG_COND_GE:
- case TCG_COND_LE:
- case TCG_COND_GT:
- if (const_arg2) {
- if ((int16_t) arg2 == arg2) {
- op = CMPI;
- imm = 1;
- break;
- }
- }
- op = CMP;
- imm = 0;
- break;
-
- case TCG_COND_LTU:
- case TCG_COND_GEU:
- case TCG_COND_LEU:
- case TCG_COND_GTU:
- if (const_arg2) {
- if ((uint16_t) arg2 == arg2) {
- op = CMPLI;
- imm = 1;
- break;
- }
- }
- op = CMPL;
- imm = 0;
- break;
-
- default:
- tcg_abort ();
- }
- op |= BF (cr) | (arch64 << 21);
-
- if (imm)
- tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
- else {
- if (const_arg2) {
- tcg_out_movi (s, TCG_TYPE_I64, 0, arg2);
- tcg_out32 (s, op | RA (arg1) | RB (0));
- }
- else
- tcg_out32 (s, op | RA (arg1) | RB (arg2));
- }
-
-}
-
-static void tcg_out_bc (TCGContext *s, int bc, int label_index)
-{
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value)
- tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
- else {
- uint16_t val = *(uint16_t *) &s->code_ptr[2];
-
- /* Thanks to Andrzej Zaborowski */
- tcg_out32 (s, bc | (val & 0xfffc));
- tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
- }
-}
-
-static void tcg_out_brcond (TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index, int arch64)
-{
- tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, arch64);
- tcg_out_bc (s, tcg_to_bc[cond], label_index);
-}
-
-void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
-{
- TCGContext s;
- unsigned long patch_size;
-
- s.code_ptr = (uint8_t *) jmp_addr;
- tcg_out_b (&s, 0, addr);
- patch_size = s.code_ptr - (uint8_t *) jmp_addr;
- flush_icache_range (jmp_addr, jmp_addr + patch_size);
-}
-
-static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
- const int *const_args)
-{
- int c;
-
- switch (opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi (s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
- tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
-
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- s->code_ptr += 28;
- }
- else {
- tcg_abort ();
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_br:
- {
- TCGLabel *l = &s->labels[args[0]];
-
- if (l->has_value) {
- tcg_out_b (s, 0, l->u.value);
- }
- else {
- uint32_t val = *(uint32_t *) s->code_ptr;
-
- /* Thanks to Andrzej Zaborowski */
- tcg_out32 (s, B | (val & 0x3fffffc));
- tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
- }
- }
- break;
- case INDEX_op_call:
- tcg_out_call (s, args[0], const_args[0]);
- break;
- case INDEX_op_jmp:
- if (const_args[0]) {
- tcg_out_b (s, 0, args[0]);
- }
- else {
- tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
- tcg_out32 (s, BCCTR | BO_ALWAYS);
- }
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]);
- break;
- case INDEX_op_movi_i64:
- tcg_out_movi (s, TCG_TYPE_I64, args[0], args[1]);
- break;
- case INDEX_op_ld8u_i32:
- case INDEX_op_ld8u_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
- break;
- case INDEX_op_ld8s_i32:
- case INDEX_op_ld8s_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
- tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
- break;
- case INDEX_op_ld16u_i32:
- case INDEX_op_ld16u_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
- break;
- case INDEX_op_ld16s_i32:
- case INDEX_op_ld16s_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
- break;
- case INDEX_op_ld_i32:
- case INDEX_op_ld32u_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
- break;
- case INDEX_op_ld32s_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LWA, LWAX);
- break;
- case INDEX_op_ld_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], LD, LDX);
- break;
- case INDEX_op_st8_i32:
- case INDEX_op_st8_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
- break;
- case INDEX_op_st16_i32:
- case INDEX_op_st16_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
- break;
- case INDEX_op_st_i32:
- case INDEX_op_st32_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
- break;
- case INDEX_op_st_i64:
- tcg_out_ldst (s, args[0], args[1], args[2], STD, STDX);
- break;
-
- case INDEX_op_add_i32:
- if (const_args[2])
- ppc_addi32 (s, args[0], args[1], args[2]);
- else
- tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
- break;
- case INDEX_op_sub_i32:
- if (const_args[2])
- ppc_addi32 (s, args[0], args[1], -args[2]);
- else
- tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
- break;
-
- case INDEX_op_and_i64:
- case INDEX_op_and_i32:
- if (const_args[2]) {
- if ((args[2] & 0xffff) == args[2])
- tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
- else if ((args[2] & 0xffff0000) == args[2])
- tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- else {
- tcg_out_movi (s, (opc == INDEX_op_and_i32
- ? TCG_TYPE_I32
- : TCG_TYPE_I64),
- 0, args[2]);
- tcg_out32 (s, AND | SAB (args[1], args[0], 0));
- }
- }
- else
- tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_or_i64:
- case INDEX_op_or_i32:
- if (const_args[2]) {
- if (args[2] & 0xffff) {
- tcg_out32 (s, ORI | RS (args[1]) | RA (args[0])
- | (args[2] & 0xffff));
- if (args[2] >> 16)
- tcg_out32 (s, ORIS | RS (args[0]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- }
- else {
- tcg_out32 (s, ORIS | RS (args[1]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- }
- }
- else
- tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_xor_i64:
- case INDEX_op_xor_i32:
- if (const_args[2]) {
- if ((args[2] & 0xffff) == args[2])
- tcg_out32 (s, XORI | RS (args[1]) | RA (args[0])
- | (args[2] & 0xffff));
- else if ((args[2] & 0xffff0000) == args[2])
- tcg_out32 (s, XORIS | RS (args[1]) | RA (args[0])
- | ((args[2] >> 16) & 0xffff));
- else {
- tcg_out_movi (s, (opc == INDEX_op_and_i32
- ? TCG_TYPE_I32
- : TCG_TYPE_I64),
- 0, args[2]);
- tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
- }
- }
- else
- tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
- break;
-
- case INDEX_op_mul_i32:
- if (const_args[2]) {
- if (args[2] == (int16_t) args[2])
- tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
- | (args[2] & 0xffff));
- else {
- tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
- tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
- }
- }
- else
- tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
- break;
-
- case INDEX_op_div_i32:
- tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
- break;
-
- case INDEX_op_divu_i32:
- tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
- break;
-
- case INDEX_op_rem_i32:
- tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
- tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
- tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
- break;
-
- case INDEX_op_remu_i32:
- tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
- tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
- tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
- break;
-
- case INDEX_op_shl_i32:
- if (const_args[2]) {
- tcg_out32 (s, (RLWINM
- | RA (args[0])
- | RS (args[1])
- | SH (args[2])
- | MB (0)
- | ME (31 - args[2])
- )
- );
- }
- else
- tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_shr_i32:
- if (const_args[2]) {
- tcg_out32 (s, (RLWINM
- | RA (args[0])
- | RS (args[1])
- | SH (32 - args[2])
- | MB (args[2])
- | ME (31)
- )
- );
- }
- else
- tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_sar_i32:
- if (const_args[2])
- tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
- else
- tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
- break;
-
- case INDEX_op_brcond_i32:
- tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 0);
- break;
-
- case INDEX_op_brcond_i64:
- tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 1);
- break;
-
- case INDEX_op_neg_i32:
- case INDEX_op_neg_i64:
- tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
- break;
-
- case INDEX_op_add_i64:
- if (const_args[2])
- ppc_addi64 (s, args[0], args[1], args[2]);
- else
- tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
- break;
- case INDEX_op_sub_i64:
- if (const_args[2])
- ppc_addi64 (s, args[0], args[1], -args[2]);
- else
- tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
- break;
-
- case INDEX_op_shl_i64:
- if (const_args[2])
- tcg_out_rld (s, RLDICR, args[0], args[1], args[2], 63 - args[2]);
- else
- tcg_out32 (s, SLD | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_shr_i64:
- if (const_args[2])
- tcg_out_rld (s, RLDICL, args[0], args[1], 64 - args[2], args[2]);
- else
- tcg_out32 (s, SRD | SAB (args[1], args[0], args[2]));
- break;
- case INDEX_op_sar_i64:
- if (const_args[2]) {
- int sh = SH (args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
- tcg_out32 (s, SRADI | RA (args[0]) | RS (args[1]) | sh);
- }
- else
- tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2]));
- break;
-
- case INDEX_op_mul_i64:
- tcg_out32 (s, MULLD | TAB (args[0], args[1], args[2]));
- break;
- case INDEX_op_div_i64:
- tcg_out32 (s, DIVD | TAB (args[0], args[1], args[2]));
- break;
- case INDEX_op_divu_i64:
- tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
- break;
- case INDEX_op_rem_i64:
- tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
- tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
- tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
- break;
- case INDEX_op_remu_i64:
- tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
- tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
- tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld (s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld (s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld (s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld (s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld (s, args, 2);
- break;
- case INDEX_op_qemu_ld32s:
- tcg_out_qemu_ld (s, args, 2 | 4);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld (s, args, 3);
- break;
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st (s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st (s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st (s, args, 2);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st (s, args, 3);
- break;
-
- case INDEX_op_ext8s_i32:
- case INDEX_op_ext8s_i64:
- c = EXTSB;
- goto gen_ext;
- case INDEX_op_ext16s_i32:
- case INDEX_op_ext16s_i64:
- c = EXTSH;
- goto gen_ext;
- case INDEX_op_ext32s_i64:
- c = EXTSW;
- goto gen_ext;
- gen_ext:
- tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
- break;
-
- default:
- tcg_dump_ops (s, stderr);
- tcg_abort ();
- }
-}
-
-static const TCGTargetOpDef ppc_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } },
- { INDEX_op_jmp, { "ri" } },
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_mov_i64, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_movi_i64, { "r" } },
-
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_ld_i64, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st8_i64, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st16_i64, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
- { INDEX_op_st_i64, { "r", "r" } },
- { INDEX_op_st32_i64, { "r", "r" } },
-
- { INDEX_op_ld8u_i64, { "r", "r" } },
- { INDEX_op_ld8s_i64, { "r", "r" } },
- { INDEX_op_ld16u_i64, { "r", "r" } },
- { INDEX_op_ld16s_i64, { "r", "r" } },
- { INDEX_op_ld32u_i64, { "r", "r" } },
- { INDEX_op_ld32s_i64, { "r", "r" } },
- { INDEX_op_ld_i64, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "r", "ri" } },
- { INDEX_op_mul_i32, { "r", "r", "ri" } },
- { INDEX_op_div_i32, { "r", "r", "r" } },
- { INDEX_op_divu_i32, { "r", "r", "r" } },
- { INDEX_op_rem_i32, { "r", "r", "r" } },
- { INDEX_op_remu_i32, { "r", "r", "r" } },
- { INDEX_op_sub_i32, { "r", "r", "ri" } },
- { INDEX_op_and_i32, { "r", "r", "ri" } },
- { INDEX_op_or_i32, { "r", "r", "ri" } },
- { INDEX_op_xor_i32, { "r", "r", "ri" } },
-
- { INDEX_op_shl_i32, { "r", "r", "ri" } },
- { INDEX_op_shr_i32, { "r", "r", "ri" } },
- { INDEX_op_sar_i32, { "r", "r", "ri" } },
-
- { INDEX_op_brcond_i32, { "r", "ri" } },
- { INDEX_op_brcond_i64, { "r", "ri" } },
-
- { INDEX_op_neg_i32, { "r", "r" } },
-
- { INDEX_op_add_i64, { "r", "r", "ri" } },
- { INDEX_op_sub_i64, { "r", "r", "ri" } },
- { INDEX_op_and_i64, { "r", "r", "rZ" } },
- { INDEX_op_or_i64, { "r", "r", "rZ" } },
- { INDEX_op_xor_i64, { "r", "r", "rZ" } },
-
- { INDEX_op_shl_i64, { "r", "r", "ri" } },
- { INDEX_op_shr_i64, { "r", "r", "ri" } },
- { INDEX_op_sar_i64, { "r", "r", "ri" } },
-
- { INDEX_op_mul_i64, { "r", "r", "r" } },
- { INDEX_op_div_i64, { "r", "r", "r" } },
- { INDEX_op_divu_i64, { "r", "r", "r" } },
- { INDEX_op_rem_i64, { "r", "r", "r" } },
- { INDEX_op_remu_i64, { "r", "r", "r" } },
-
- { INDEX_op_neg_i64, { "r", "r" } },
-
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L" } },
- { INDEX_op_qemu_ld64, { "r", "L" } },
-
- { INDEX_op_qemu_st8, { "S", "S" } },
- { INDEX_op_qemu_st16, { "S", "S" } },
- { INDEX_op_qemu_st32, { "S", "S" } },
- { INDEX_op_qemu_st64, { "S", "S", "S" } },
-
- { INDEX_op_ext8s_i32, { "r", "r" } },
- { INDEX_op_ext16s_i32, { "r", "r" } },
- { INDEX_op_ext8s_i64, { "r", "r" } },
- { INDEX_op_ext16s_i64, { "r", "r" } },
- { INDEX_op_ext32s_i64, { "r", "r" } },
-
- { -1 },
-};
-
-void tcg_target_init (TCGContext *s)
-{
- tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
- tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
- tcg_regset_set32 (tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_R0) |
- (1 << TCG_REG_R3) |
- (1 << TCG_REG_R4) |
- (1 << TCG_REG_R5) |
- (1 << TCG_REG_R6) |
- (1 << TCG_REG_R7) |
- (1 << TCG_REG_R8) |
- (1 << TCG_REG_R9) |
- (1 << TCG_REG_R10) |
- (1 << TCG_REG_R11) |
- (1 << TCG_REG_R12)
- );
-
- tcg_regset_clear (s->reserved_regs);
- tcg_regset_set_reg (s->reserved_regs, TCG_REG_R0);
- tcg_regset_set_reg (s->reserved_regs, TCG_REG_R1);
- tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
- tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
-
- tcg_add_target_add_op_defs (ppc_op_defs);
-}
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
deleted file mode 100644
index 2174db2..0000000
--- a/tcg/ppc64/tcg-target.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_PPC64 1
-
-#define TCG_TARGET_REG_BITS 64
-#define TCG_TARGET_WORDS_BIGENDIAN
-#define TCG_TARGET_NB_REGS 32
-
-enum {
- TCG_REG_R0 = 0,
- TCG_REG_R1,
- TCG_REG_R2,
- TCG_REG_R3,
- TCG_REG_R4,
- TCG_REG_R5,
- TCG_REG_R6,
- TCG_REG_R7,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
- TCG_REG_R16,
- TCG_REG_R17,
- TCG_REG_R18,
- TCG_REG_R19,
- TCG_REG_R20,
- TCG_REG_R21,
- TCG_REG_R22,
- TCG_REG_R23,
- TCG_REG_R24,
- TCG_REG_R25,
- TCG_REG_R26,
- TCG_REG_R27,
- TCG_REG_R28,
- TCG_REG_R29,
- TCG_REG_R30,
- TCG_REG_R31
-};
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_R1
-#define TCG_TARGET_STACK_ALIGN 16
-#define TCG_TARGET_CALL_STACK_OFFSET 48
-
-/* optional instructions */
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_div_i32
-#define TCG_TARGET_HAS_neg_i64
-#define TCG_TARGET_HAS_div_i64
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-
-#define TCG_AREG0 TCG_REG_R27
-#define TCG_AREG1 TCG_REG_R24
-#define TCG_AREG2 TCG_REG_R25
-#define TCG_AREG3 TCG_REG_R26
-
-/* taken directly from tcg-dyngen.c */
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
deleted file mode 100644
index f36796d..0000000
--- a/tcg/sparc/tcg-target.c
+++ /dev/null
@@ -1,1206 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%g0",
- "%g1",
- "%g2",
- "%g3",
- "%g4",
- "%g5",
- "%g6",
- "%g7",
- "%o0",
- "%o1",
- "%o2",
- "%o3",
- "%o4",
- "%o5",
- "%o6",
- "%o7",
- "%l0",
- "%l1",
- "%l2",
- "%l3",
- "%l4",
- "%l5",
- "%l6",
- "%l7",
- "%i0",
- "%i1",
- "%i2",
- "%i3",
- "%i4",
- "%i5",
- "%i6",
- "%i7",
-};
-
-static const int tcg_target_reg_alloc_order[] = {
- TCG_REG_L0,
- TCG_REG_L1,
- TCG_REG_L2,
- TCG_REG_L3,
- TCG_REG_L4,
- TCG_REG_L5,
- TCG_REG_L6,
- TCG_REG_L7,
- TCG_REG_I0,
- TCG_REG_I1,
- TCG_REG_I2,
- TCG_REG_I3,
- TCG_REG_I4,
-};
-
-static const int tcg_target_call_iarg_regs[6] = {
- TCG_REG_O0,
- TCG_REG_O1,
- TCG_REG_O2,
- TCG_REG_O3,
- TCG_REG_O4,
- TCG_REG_O5,
-};
-
-static const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_O0,
- TCG_REG_O1,
-};
-
-static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
-{
- return (val << ((sizeof(tcg_target_long) * 8 - bits))
- >> (sizeof(tcg_target_long) * 8 - bits)) == val;
-}
-
-static inline int check_fit_i32(uint32_t val, unsigned int bits)
-{
- return ((val << (32 - bits)) >> (32 - bits)) == val;
-}
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- value += addend;
- switch (type) {
- case R_SPARC_32:
- if (value != (uint32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- case R_SPARC_WDISP22:
- value -= (long)code_ptr;
- value >>= 2;
- if (!check_fit_tl(value, 22))
- tcg_abort();
- *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
- break;
- default:
- tcg_abort();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
- return 6;
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch (ct_str[0]) {
- case 'r':
- case 'L': /* qemu_ld/st constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
- // Helper args
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
- break;
- case 'I':
- ct->ct |= TCG_CT_CONST_S11;
- break;
- case 'J':
- ct->ct |= TCG_CT_CONST_S13;
- break;
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
-
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11))
- return 1;
- else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13))
- return 1;
- else
- return 0;
-}
-
-#define INSN_OP(x) ((x) << 30)
-#define INSN_OP2(x) ((x) << 22)
-#define INSN_OP3(x) ((x) << 19)
-#define INSN_OPF(x) ((x) << 5)
-#define INSN_RD(x) ((x) << 25)
-#define INSN_RS1(x) ((x) << 14)
-#define INSN_RS2(x) (x)
-#define INSN_ASI(x) ((x) << 5)
-
-#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
-#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
-
-#define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
-#define COND_N 0x0
-#define COND_E 0x1
-#define COND_LE 0x2
-#define COND_L 0x3
-#define COND_LEU 0x4
-#define COND_CS 0x5
-#define COND_NEG 0x6
-#define COND_VS 0x7
-#define COND_A 0x8
-#define COND_NE 0x9
-#define COND_G 0xa
-#define COND_GE 0xb
-#define COND_GU 0xc
-#define COND_CC 0xd
-#define COND_POS 0xe
-#define COND_VC 0xf
-#define BA (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
-
-#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00))
-#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01))
-#define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02))
-#define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
-#define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03))
-#define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04))
-#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
-#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
-#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
-#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
-#define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
-#define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
-#define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
-#define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
-#define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
-
-#define SHIFT_SLL (INSN_OP(2) | INSN_OP3(0x25))
-#define SHIFT_SRL (INSN_OP(2) | INSN_OP3(0x26))
-#define SHIFT_SRA (INSN_OP(2) | INSN_OP3(0x27))
-
-#define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
-#define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
-#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
-
-#define WRY (INSN_OP(2) | INSN_OP3(0x30))
-#define JMPL (INSN_OP(2) | INSN_OP3(0x38))
-#define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
-#define RESTORE (INSN_OP(2) | INSN_OP3(0x3d))
-#define SETHI (INSN_OP(0) | INSN_OP2(0x4))
-#define CALL INSN_OP(1)
-#define LDUB (INSN_OP(3) | INSN_OP3(0x01))
-#define LDSB (INSN_OP(3) | INSN_OP3(0x09))
-#define LDUH (INSN_OP(3) | INSN_OP3(0x02))
-#define LDSH (INSN_OP(3) | INSN_OP3(0x0a))
-#define LDUW (INSN_OP(3) | INSN_OP3(0x00))
-#define LDSW (INSN_OP(3) | INSN_OP3(0x08))
-#define LDX (INSN_OP(3) | INSN_OP3(0x0b))
-#define STB (INSN_OP(3) | INSN_OP3(0x05))
-#define STH (INSN_OP(3) | INSN_OP3(0x06))
-#define STW (INSN_OP(3) | INSN_OP3(0x04))
-#define STX (INSN_OP(3) | INSN_OP3(0x0e))
-#define LDUBA (INSN_OP(3) | INSN_OP3(0x11))
-#define LDSBA (INSN_OP(3) | INSN_OP3(0x19))
-#define LDUHA (INSN_OP(3) | INSN_OP3(0x12))
-#define LDSHA (INSN_OP(3) | INSN_OP3(0x1a))
-#define LDUWA (INSN_OP(3) | INSN_OP3(0x10))
-#define LDSWA (INSN_OP(3) | INSN_OP3(0x18))
-#define LDXA (INSN_OP(3) | INSN_OP3(0x1b))
-#define STBA (INSN_OP(3) | INSN_OP3(0x15))
-#define STHA (INSN_OP(3) | INSN_OP3(0x16))
-#define STWA (INSN_OP(3) | INSN_OP3(0x14))
-#define STXA (INSN_OP(3) | INSN_OP3(0x1e))
-
-#ifndef ASI_PRIMARY_LITTLE
-#define ASI_PRIMARY_LITTLE 0x88
-#endif
-
-static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
- int op)
-{
- tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
- INSN_RS2(rs2));
-}
-
-static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
- uint32_t offset, int op)
-{
- tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
- INSN_IMM13(offset));
-}
-
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
-}
-
-static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
-{
- tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
-}
-
-static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
-{
- tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
-}
-
-static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
-{
- if (check_fit_tl(arg, 12))
- tcg_out_movi_imm13(s, ret, arg);
- else {
- tcg_out_sethi(s, ret, arg);
- if (arg & 0x3ff)
- tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
- }
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- if (!check_fit_tl(arg, 32) && (arg & ~0xffffffffULL) != 0) {
- tcg_out_movi_imm32(s, TCG_REG_I4, arg >> 32);
- tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
- tcg_out_movi_imm32(s, ret, arg);
- tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
- } else if (check_fit_tl(arg, 12))
- tcg_out_movi_imm13(s, ret, arg);
- else {
- tcg_out_sethi(s, ret, arg);
- if (arg & 0x3ff)
- tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
- }
-#else
- tcg_out_movi_imm32(s, ret, arg);
-#endif
-}
-
-static inline void tcg_out_ld_raw(TCGContext *s, int ret,
- tcg_target_long arg)
-{
- tcg_out_sethi(s, ret, arg);
- tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
- INSN_IMM13(arg & 0x3ff));
-}
-
-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
- tcg_target_long arg)
-{
- if (!check_fit_tl(arg, 10))
- tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
- INSN_IMM13(arg & 0x3ff));
-#else
- tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
- INSN_IMM13(arg & 0x3ff));
-#endif
-}
-
-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
-{
- if (check_fit_tl(offset, 13))
- tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
- INSN_IMM13(offset));
- else {
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
- tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
- INSN_RS2(addr));
- }
-}
-
-static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
- int offset, int op, int asi)
-{
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
- tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
- INSN_ASI(asi) | INSN_RS2(addr));
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
- int arg1, tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_ldst(s, ret, arg1, arg2, LDUW);
- else
- tcg_out_ldst(s, ret, arg1, arg2, LDX);
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
- int arg1, tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_ldst(s, arg, arg1, arg2, STW);
- else
- tcg_out_ldst(s, arg, arg1, arg2, STX);
-}
-
-static inline void tcg_out_sety(TCGContext *s, tcg_target_long val)
-{
- if (val == 0 || val == -1)
- tcg_out32(s, WRY | INSN_IMM13(val));
- else
- fprintf(stderr, "unimplemented sety %ld\n", (long)val);
-}
-
-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val != 0) {
- if (check_fit_tl(val, 13))
- tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
- else {
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
- tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
- }
- }
-}
-
-static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val != 0) {
- if (check_fit_tl(val, 13))
- tcg_out_arithi(s, reg, reg, val, ARITH_AND);
- else {
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
- tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
- }
- }
-}
-
-static inline void tcg_out_nop(TCGContext *s)
-{
- tcg_out_sethi(s, TCG_REG_G0, 0);
-}
-
-static void tcg_out_branch(TCGContext *s, int opc, int label_index)
-{
- int32_t val;
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value) {
- val = l->u.value - (tcg_target_long)s->code_ptr;
- tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
- | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
- } else {
- tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
- tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
- }
-}
-
-static const uint8_t tcg_cond_to_bcond[10] = {
- [TCG_COND_EQ] = COND_E,
- [TCG_COND_NE] = COND_NE,
- [TCG_COND_LT] = COND_L,
- [TCG_COND_GE] = COND_GE,
- [TCG_COND_LE] = COND_LE,
- [TCG_COND_GT] = COND_G,
- [TCG_COND_LTU] = COND_CS,
- [TCG_COND_GEU] = COND_CC,
- [TCG_COND_LEU] = COND_LEU,
- [TCG_COND_GTU] = COND_GU,
-};
-
-static void tcg_out_brcond(TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index)
-{
- if (const_arg2 && arg2 == 0)
- /* orcc %g0, r, %g0 */
- tcg_out_arith(s, TCG_REG_G0, TCG_REG_G0, arg1, ARITH_ORCC);
- else
- /* subcc r1, r2, %g0 */
- tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC);
- tcg_out_branch(s, tcg_cond_to_bcond[cond], label_index);
- tcg_out_nop(s);
-}
-
-/* Generate global QEMU prologue and epilogue code */
-void tcg_target_qemu_prologue(TCGContext *s)
-{
- tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
- INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
- INSN_RS2(TCG_REG_G0));
- tcg_out_nop(s);
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static const void * const qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static const void * const qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-#if TARGET_LONG_BITS == 32
-#define TARGET_LD_OP LDUW
-#else
-#define TARGET_LD_OP LDX
-#endif
-
-#if TARGET_PHYS_ADDR_BITS == 32
-#define TARGET_ADDEND_LD_OP LDUW
-#else
-#define TARGET_ADDEND_LD_OP LDX
-#endif
-
-#ifdef __arch64__
-#define HOST_LD_OP LDX
-#define HOST_ST_OP STX
-#define HOST_SLL_OP SHIFT_SLLX
-#define HOST_SRA_OP SHIFT_SRAX
-#else
-#define HOST_LD_OP LDUW
-#define HOST_ST_OP STW
-#define HOST_SLL_OP SHIFT_SLL
-#define HOST_SRA_OP SHIFT_SRA
-#endif
-
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
-#if defined(CONFIG_SOFTMMU)
- uint32_t *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
- s_bits = opc & 3;
-
- arg0 = TCG_REG_O0;
- arg1 = TCG_REG_O1;
- arg2 = TCG_REG_O2;
-
-#if defined(CONFIG_SOFTMMU)
- /* srl addr_reg, x, arg1 */
- tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
- SHIFT_SRL);
- /* and addr_reg, x, arg0 */
- tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
- ARITH_AND);
-
- /* and arg1, x, arg1 */
- tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- /* add arg1, x, arg1 */
- tcg_out_addi(s, arg1, offsetof(CPUState,
- tlb_table[mem_index][0].addr_read));
-
- /* add env, arg1, arg1 */
- tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
-
- /* ld [arg1], arg2 */
- tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
- INSN_RS2(TCG_REG_G0));
-
- /* subcc arg0, arg2, %g0 */
- tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
-
- /* will become:
- be label1 */
- label1_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, 0);
-
- /* mov (delay slot) */
- tcg_out_mov(s, arg0, addr_reg);
-
- /* mov */
- tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
-
- /* XXX: move that code at the end of the TB */
- /* qemu_ld_helper[s_bits](arg0, arg1) */
- tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
- - (tcg_target_ulong)s->code_ptr) >> 2)
- & 0x3fffffff));
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
- global registers */
- // delay slot
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
-
- /* data_reg = sign_extend(arg0) */
- switch(opc) {
- case 0 | 4:
- /* sll arg0, 24/56, data_reg */
- tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
- HOST_SLL_OP);
- /* sra data_reg, 24/56, data_reg */
- tcg_out_arithi(s, data_reg, data_reg,
- (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
- break;
- case 1 | 4:
- /* sll arg0, 16/48, data_reg */
- tcg_out_arithi(s, data_reg, arg0,
- (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
- /* sra data_reg, 16/48, data_reg */
- tcg_out_arithi(s, data_reg, data_reg,
- (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
- break;
- case 2 | 4:
- /* sll arg0, 32, data_reg */
- tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
- /* sra data_reg, 32, data_reg */
- tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
- break;
- case 0:
- case 1:
- case 2:
- case 3:
- default:
- /* mov */
- tcg_out_mov(s, data_reg, arg0);
- break;
- }
-
- /* will become:
- ba label2 */
- label2_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, 0);
-
- /* nop (delay slot */
- tcg_out_nop(s);
-
- /* label1: */
- *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
- INSN_OFF22((unsigned long)s->code_ptr -
- (unsigned long)label1_ptr));
-
- /* ld [arg1 + x], arg1 */
- tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
-
-#if TARGET_LONG_BITS == 32
- /* and addr_reg, x, arg0 */
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
- tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
- /* add arg0, arg1, arg0 */
- tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
-#else
- /* add addr_reg, arg1, arg0 */
- tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
-#endif
-
-#else
- arg0 = addr_reg;
-#endif
-
- switch(opc) {
- case 0:
- /* ldub [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
- break;
- case 0 | 4:
- /* ldsb [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
- break;
- case 1:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* lduh [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
-#else
- /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- case 1 | 4:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* ldsh [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
-#else
- /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- case 2:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* lduw [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
-#else
- /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- case 2 | 4:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* ldsw [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
-#else
- /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- case 3:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* ldx [arg0], data_reg */
- tcg_out_ldst(s, data_reg, arg0, 0, LDX);
-#else
- /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
- INSN_OFF22((unsigned long)s->code_ptr -
- (unsigned long)label2_ptr));
-#endif
-}
-
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
-#if defined(CONFIG_SOFTMMU)
- uint32_t *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
-
- s_bits = opc;
-
- arg0 = TCG_REG_O0;
- arg1 = TCG_REG_O1;
- arg2 = TCG_REG_O2;
-
-#if defined(CONFIG_SOFTMMU)
- /* srl addr_reg, x, arg1 */
- tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
- SHIFT_SRL);
-
- /* and addr_reg, x, arg0 */
- tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
- ARITH_AND);
-
- /* and arg1, x, arg1 */
- tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- /* add arg1, x, arg1 */
- tcg_out_addi(s, arg1, offsetof(CPUState,
- tlb_table[mem_index][0].addr_write));
-
- /* add env, arg1, arg1 */
- tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
-
- /* ld [arg1], arg2 */
- tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
- INSN_RS2(TCG_REG_G0));
-
- /* subcc arg0, arg2, %g0 */
- tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
-
- /* will become:
- be label1 */
- label1_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, 0);
-
- /* mov (delay slot) */
- tcg_out_mov(s, arg0, addr_reg);
-
- /* mov */
- tcg_out_mov(s, arg1, data_reg);
-
- /* mov */
- tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
-
- /* XXX: move that code at the end of the TB */
- /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
- tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
- - (tcg_target_ulong)s->code_ptr) >> 2)
- & 0x3fffffff));
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
- global registers */
- // delay slot
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
-
- /* will become:
- ba label2 */
- label2_ptr = (uint32_t *)s->code_ptr;
- tcg_out32(s, 0);
-
- /* nop (delay slot) */
- tcg_out_nop(s);
-
- /* label1: */
- *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
- INSN_OFF22((unsigned long)s->code_ptr -
- (unsigned long)label1_ptr));
-
- /* ld [arg1 + x], arg1 */
- tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
-
-#if TARGET_LONG_BITS == 32
- /* and addr_reg, x, arg0 */
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
- tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
- /* add arg0, arg1, arg0 */
- tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
-#else
- /* add addr_reg, arg1, arg0 */
- tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
-#endif
-
-#else
- arg0 = addr_reg;
-#endif
-
- switch(opc) {
- case 0:
- /* stb data_reg, [arg0] */
- tcg_out_ldst(s, data_reg, arg0, 0, STB);
- break;
- case 1:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* sth data_reg, [arg0] */
- tcg_out_ldst(s, data_reg, arg0, 0, STH);
-#else
- /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- case 2:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* stw data_reg, [arg0] */
- tcg_out_ldst(s, data_reg, arg0, 0, STW);
-#else
- /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- case 3:
-#ifdef TARGET_WORDS_BIGENDIAN
- /* stx data_reg, [arg0] */
- tcg_out_ldst(s, data_reg, arg0, 0, STX);
-#else
- /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
- tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
-#endif
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
- INSN_OFF22((unsigned long)s->code_ptr -
- (unsigned long)label2_ptr));
-#endif
-}
-
-static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
- const int *const_args)
-{
- int c;
-
- switch (opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
- INSN_IMM13(8));
- tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
- INSN_RS2(TCG_REG_G0));
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
- tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
- INSN_IMM13((args[0] & 0x1fff)));
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- } else {
- /* indirect jump method */
- tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
- INSN_RS2(TCG_REG_G0));
- }
- tcg_out_nop(s);
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_call:
- if (const_args[0])
- tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
- - (tcg_target_ulong)s->code_ptr) >> 2)
- & 0x3fffffff));
- else {
- tcg_out_ld_ptr(s, TCG_REG_I5,
- (tcg_target_long)(s->tb_next + args[0]));
- tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
- INSN_RS2(TCG_REG_G0));
- }
- /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
- global registers */
- // delay slot
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
- tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
- TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
- break;
- case INDEX_op_jmp:
- case INDEX_op_br:
- tcg_out_branch(s, COND_A, args[0]);
- tcg_out_nop(s);
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
- break;
-
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
-#define OP_32_64(x) \
- glue(glue(case INDEX_op_, x), _i32:) \
- glue(glue(case INDEX_op_, x), _i64:)
-#else
-#define OP_32_64(x) \
- glue(glue(case INDEX_op_, x), _i32:)
-#endif
- OP_32_64(ld8u);
- tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
- break;
- OP_32_64(ld8s);
- tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
- break;
- OP_32_64(ld16u);
- tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
- break;
- OP_32_64(ld16s);
- tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
- break;
- case INDEX_op_ld_i32:
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- case INDEX_op_ld32u_i64:
-#endif
- tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
- break;
- OP_32_64(st8);
- tcg_out_ldst(s, args[0], args[1], args[2], STB);
- break;
- OP_32_64(st16);
- tcg_out_ldst(s, args[0], args[1], args[2], STH);
- break;
- case INDEX_op_st_i32:
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- case INDEX_op_st32_i64:
-#endif
- tcg_out_ldst(s, args[0], args[1], args[2], STW);
- break;
- OP_32_64(add);
- c = ARITH_ADD;
- goto gen_arith32;
- OP_32_64(sub);
- c = ARITH_SUB;
- goto gen_arith32;
- OP_32_64(and);
- c = ARITH_AND;
- goto gen_arith32;
- OP_32_64(or);
- c = ARITH_OR;
- goto gen_arith32;
- OP_32_64(xor);
- c = ARITH_XOR;
- goto gen_arith32;
- case INDEX_op_shl_i32:
- c = SHIFT_SLL;
- goto gen_arith32;
- case INDEX_op_shr_i32:
- c = SHIFT_SRL;
- goto gen_arith32;
- case INDEX_op_sar_i32:
- c = SHIFT_SRA;
- goto gen_arith32;
- case INDEX_op_mul_i32:
- c = ARITH_UMUL;
- goto gen_arith32;
- case INDEX_op_div2_i32:
-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
- c = ARITH_SDIVX;
- goto gen_arith32;
-#else
- tcg_out_sety(s, 0);
- c = ARITH_SDIV;
- goto gen_arith32;
-#endif
- case INDEX_op_divu2_i32:
-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
- c = ARITH_UDIVX;
- goto gen_arith32;
-#else
- tcg_out_sety(s, 0);
- c = ARITH_UDIV;
- goto gen_arith32;
-#endif
-
- case INDEX_op_brcond_i32:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
- args[3]);
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, args, 2);
- break;
- case INDEX_op_qemu_ld32s:
- tcg_out_qemu_ld(s, args, 2 | 4);
- break;
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, args, 2);
- break;
-
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- case INDEX_op_movi_i64:
- tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
- break;
- case INDEX_op_ld32s_i64:
- tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
- break;
- case INDEX_op_ld_i64:
- tcg_out_ldst(s, args[0], args[1], args[2], LDX);
- break;
- case INDEX_op_st_i64:
- tcg_out_ldst(s, args[0], args[1], args[2], STX);
- break;
- case INDEX_op_shl_i64:
- c = SHIFT_SLLX;
- goto gen_arith32;
- case INDEX_op_shr_i64:
- c = SHIFT_SRLX;
- goto gen_arith32;
- case INDEX_op_sar_i64:
- c = SHIFT_SRAX;
- goto gen_arith32;
- case INDEX_op_mul_i64:
- c = ARITH_MULX;
- goto gen_arith32;
- case INDEX_op_div2_i64:
- c = ARITH_SDIVX;
- goto gen_arith32;
- case INDEX_op_divu2_i64:
- c = ARITH_UDIVX;
- goto gen_arith32;
-
- case INDEX_op_brcond_i64:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
- args[3]);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, args, 3);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, args, 3);
- break;
-
-#endif
- gen_arith32:
- if (const_args[2]) {
- tcg_out_arithi(s, args[0], args[1], args[2], c);
- } else {
- tcg_out_arith(s, args[0], args[1], args[2], c);
- }
- break;
-
- default:
- fprintf(stderr, "unknown opcode 0x%x\n", opc);
- tcg_abort();
- }
-}
-
-static const TCGTargetOpDef sparc_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } },
- { INDEX_op_jmp, { "ri" } },
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "r", "rJ" } },
- { INDEX_op_mul_i32, { "r", "r", "rJ" } },
- { INDEX_op_div2_i32, { "r", "r", "0", "1", "r" } },
- { INDEX_op_divu2_i32, { "r", "r", "0", "1", "r" } },
- { INDEX_op_sub_i32, { "r", "r", "rJ" } },
- { INDEX_op_and_i32, { "r", "r", "rJ" } },
- { INDEX_op_or_i32, { "r", "r", "rJ" } },
- { INDEX_op_xor_i32, { "r", "r", "rJ" } },
-
- { INDEX_op_shl_i32, { "r", "r", "rJ" } },
- { INDEX_op_shr_i32, { "r", "r", "rJ" } },
- { INDEX_op_sar_i32, { "r", "r", "rJ" } },
-
- { INDEX_op_brcond_i32, { "r", "ri" } },
-
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L" } },
-
- { INDEX_op_qemu_st8, { "L", "L" } },
- { INDEX_op_qemu_st16, { "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L" } },
-
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- { INDEX_op_mov_i64, { "r", "r" } },
- { INDEX_op_movi_i64, { "r" } },
- { INDEX_op_ld8u_i64, { "r", "r" } },
- { INDEX_op_ld8s_i64, { "r", "r" } },
- { INDEX_op_ld16u_i64, { "r", "r" } },
- { INDEX_op_ld16s_i64, { "r", "r" } },
- { INDEX_op_ld32u_i64, { "r", "r" } },
- { INDEX_op_ld32s_i64, { "r", "r" } },
- { INDEX_op_ld_i64, { "r", "r" } },
- { INDEX_op_st8_i64, { "r", "r" } },
- { INDEX_op_st16_i64, { "r", "r" } },
- { INDEX_op_st32_i64, { "r", "r" } },
- { INDEX_op_st_i64, { "r", "r" } },
- { INDEX_op_qemu_ld64, { "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L" } },
-
- { INDEX_op_add_i64, { "r", "r", "rJ" } },
- { INDEX_op_mul_i64, { "r", "r", "rJ" } },
- { INDEX_op_div2_i64, { "r", "r", "0", "1", "r" } },
- { INDEX_op_divu2_i64, { "r", "r", "0", "1", "r" } },
- { INDEX_op_sub_i64, { "r", "r", "rJ" } },
- { INDEX_op_and_i64, { "r", "r", "rJ" } },
- { INDEX_op_or_i64, { "r", "r", "rJ" } },
- { INDEX_op_xor_i64, { "r", "r", "rJ" } },
-
- { INDEX_op_shl_i64, { "r", "r", "rJ" } },
- { INDEX_op_shr_i64, { "r", "r", "rJ" } },
- { INDEX_op_sar_i64, { "r", "r", "rJ" } },
-
- { INDEX_op_brcond_i64, { "r", "ri" } },
-#endif
- { -1 },
-};
-
-void tcg_target_init(TCGContext *s)
-{
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
-#endif
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_G1) |
- (1 << TCG_REG_G2) |
- (1 << TCG_REG_G3) |
- (1 << TCG_REG_G4) |
- (1 << TCG_REG_G5) |
- (1 << TCG_REG_G6) |
- (1 << TCG_REG_G7) |
- (1 << TCG_REG_O0) |
- (1 << TCG_REG_O1) |
- (1 << TCG_REG_O2) |
- (1 << TCG_REG_O3) |
- (1 << TCG_REG_O4) |
- (1 << TCG_REG_O5) |
- (1 << TCG_REG_O7));
-
- tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
-#endif
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
- tcg_add_target_add_op_defs(sparc_op_defs);
-}
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
deleted file mode 100644
index 8dc07d3..0000000
--- a/tcg/sparc/tcg-target.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_SPARC 1
-
-#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
-#define TCG_TARGET_REG_BITS 64
-#else
-#define TCG_TARGET_REG_BITS 32
-#endif
-
-#define TCG_TARGET_WORDS_BIGENDIAN
-
-#define TCG_TARGET_NB_REGS 32
-
-enum {
- TCG_REG_G0 = 0,
- TCG_REG_G1,
- TCG_REG_G2,
- TCG_REG_G3,
- TCG_REG_G4,
- TCG_REG_G5,
- TCG_REG_G6,
- TCG_REG_G7,
- TCG_REG_O0,
- TCG_REG_O1,
- TCG_REG_O2,
- TCG_REG_O3,
- TCG_REG_O4,
- TCG_REG_O5,
- TCG_REG_O6,
- TCG_REG_O7,
- TCG_REG_L0,
- TCG_REG_L1,
- TCG_REG_L2,
- TCG_REG_L3,
- TCG_REG_L4,
- TCG_REG_L5,
- TCG_REG_L6,
- TCG_REG_L7,
- TCG_REG_I0,
- TCG_REG_I1,
- TCG_REG_I2,
- TCG_REG_I3,
- TCG_REG_I4,
- TCG_REG_I5,
- TCG_REG_I6,
- TCG_REG_I7,
-};
-
-#define TCG_CT_CONST_S11 0x100
-#define TCG_CT_CONST_S13 0x200
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_I6
-#ifdef __arch64__
-// Reserve space for AREG0
-#define TCG_TARGET_STACK_MINFRAME (176 + 2 * (int)sizeof(long))
-#define TCG_TARGET_CALL_STACK_OFFSET (2047 + TCG_TARGET_STACK_MINFRAME)
-#define TCG_TARGET_STACK_ALIGN 16
-#else
-// AREG0 + one word for alignment
-#define TCG_TARGET_STACK_MINFRAME (92 + (2 + 1) * (int)sizeof(long))
-#define TCG_TARGET_CALL_STACK_OFFSET TCG_TARGET_STACK_MINFRAME
-#define TCG_TARGET_STACK_ALIGN 8
-#endif
-
-/* optional instructions */
-//#define TCG_TARGET_HAS_bswap_i32
-//#define TCG_TARGET_HAS_bswap_i64
-//#define TCG_TARGET_HAS_neg_i32
-//#define TCG_TARGET_HAS_neg_i64
-
-
-/* Note: must be synced with dyngen-exec.h and Makefile.target */
-#ifdef HOST_SOLARIS
-#define TCG_AREG0 TCG_REG_G2
-#define TCG_AREG1 TCG_REG_G3
-#define TCG_AREG2 TCG_REG_G4
-#define TCG_AREG3 TCG_REG_G5
-#define TCG_AREG4 TCG_REG_G6
-#elif defined(__sparc_v9__)
-#define TCG_AREG0 TCG_REG_G5
-#define TCG_AREG1 TCG_REG_G6
-#define TCG_AREG2 TCG_REG_G7
-#else
-#define TCG_AREG0 TCG_REG_G6
-#define TCG_AREG1 TCG_REG_G1
-#define TCG_AREG2 TCG_REG_G2
-#define TCG_AREG3 TCG_REG_G3
-#endif
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- p = start & ~(8UL - 1UL);
- stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
- for (; p < stop; p += 8)
- __asm__ __volatile__("flush\t%0" : : "r" (p));
-}
diff --git a/tcg/tcg-dyngen.c b/tcg/tcg-dyngen.c
deleted file mode 100644
index b4ceb5e..0000000
--- a/tcg/tcg-dyngen.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <assert.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-#include "osdep.h"
-
-#include "tcg.h"
-
-int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
- void __op_gen_label1(){}
- void __op_gen_label2(){}
- void __op_gen_label3(){}
-#else
- int __op_gen_label1, __op_gen_label2, __op_gen_label3;
-#endif
-int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if 0
-#if defined(__s390__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
-#elif defined(__ia64__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- while (start < stop) {
- asm volatile ("fc %0" :: "r"(start));
- start += 32;
- }
- asm volatile (";;sync.i;;srlz.i;;");
-}
-#elif defined(__powerpc__)
-
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- start &= ~(MIN_CACHE_LINE_SIZE - 1);
- stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
- asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
- }
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
-#elif defined(__alpha__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- asm ("imb");
-}
-#elif defined(__sparc__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- unsigned long p;
-
- p = start & ~(8UL - 1UL);
- stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
- for (; p < stop; p += 8)
- __asm__ __volatile__("flush\t%0" : : "r" (p));
-}
-#elif defined(__arm__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- register unsigned long _beg __asm ("a1") = start;
- register unsigned long _end __asm ("a2") = stop;
- register unsigned long _flg __asm ("a3") = 0;
- __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-}
-#elif defined(__mc68000)
-
-# include <asm/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- cacheflush(start,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,stop-start+16);
-}
-#elif defined(__mips__)
-
-#include <sys/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
- _flush_cache ((void *)start, stop - start, BCACHE);
-}
-#else
-#error unsupported CPU
-#endif
-
-#ifdef __alpha__
-
-register int gp asm("$29");
-
-static inline void immediate_ldah(void *p, int val) {
- uint32_t *dest = p;
- long high = ((val >> 16) + ((val >> 15) & 1)) & 0xffff;
-
- *dest &= ~0xffff;
- *dest |= high;
- *dest |= 31 << 16;
-}
-static inline void immediate_lda(void *dest, int val) {
- *(uint16_t *) dest = val;
-}
-void fix_bsr(void *p, int offset) {
- uint32_t *dest = p;
- *dest &= ~((1 << 21) - 1);
- *dest |= (offset >> 2) & ((1 << 21) - 1);
-}
-
-#endif /* __alpha__ */
-
-#ifdef __ia64
-
-/* Patch instruction with "val" where "mask" has 1 bits. */
-static inline void ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
-{
- uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16);
-# define insn_mask ((1UL << 41) - 1)
- unsigned long shift;
-
- b0 = b[0]; b1 = b[1];
- shift = 5 + 41 * (insn_addr % 16); /* 5 template, 3 x 41-bit insns */
- if (shift >= 64) {
- m1 = mask << (shift - 64);
- v1 = val << (shift - 64);
- } else {
- m0 = mask << shift; m1 = mask >> (64 - shift);
- v0 = val << shift; v1 = val >> (64 - shift);
- b[0] = (b0 & ~m0) | (v0 & m0);
- }
- b[1] = (b1 & ~m1) | (v1 & m1);
-}
-
-static inline void ia64_patch_imm60 (uint64_t insn_addr, uint64_t val)
-{
- ia64_patch(insn_addr,
- 0x011ffffe000UL,
- ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
- | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
- ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
-}
-
-static inline void ia64_imm64 (void *insn, uint64_t val)
-{
- /* Ignore the slot number of the relocation; GCC and Intel
- toolchains differed for some time on whether IMM64 relocs are
- against slot 1 (Intel) or slot 2 (GCC). */
- uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
- ia64_patch(insn_addr + 2,
- 0x01fffefe000UL,
- ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
- | ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */
- | ((val & 0x00000000001f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x000000000000ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x000000000000007fUL) << 13) /* bit 0 -> 13 */)
- );
- ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
-}
-
-static inline void ia64_imm60b (void *insn, uint64_t val)
-{
- /* Ignore the slot number of the relocation; GCC and Intel
- toolchains differed for some time on whether IMM64 relocs are
- against slot 1 (Intel) or slot 2 (GCC). */
- uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
- if (val + ((uint64_t) 1 << 59) >= (1UL << 60))
- fprintf(stderr, "%s: value %ld out of IMM60 range\n",
- __FUNCTION__, (int64_t) val);
- ia64_patch_imm60(insn_addr + 2, val);
-}
-
-static inline void ia64_imm22 (void *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22))
- fprintf(stderr, "%s: value %li out of IMM22 range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x01fffcfe000UL,
- ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
-}
-
-/* Like ia64_imm22(), but also clear bits 20-21. For addl, this has
- the effect of turning "addl rX=imm22,rY" into "addl
- rX=imm22,r0". */
-static inline void ia64_imm22_r0 (void *insn, uint64_t val)
-{
- if (val + (1 << 21) >= (1 << 22))
- fprintf(stderr, "%s: value %li out of IMM22 range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x01fffcfe000UL | (0x3UL << 20),
- ( ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
- | ((val & 0x1f0000UL) << 6) /* bit 16 -> 22 */
- | ((val & 0x00ff80UL) << 20) /* bit 7 -> 27 */
- | ((val & 0x00007fUL) << 13) /* bit 0 -> 13 */));
-}
-
-static inline void ia64_imm21b (void *insn, uint64_t val)
-{
- if (val + (1 << 20) >= (1 << 21))
- fprintf(stderr, "%s: value %li out of IMM21b range\n",
- __FUNCTION__, (int64_t)val);
- ia64_patch((uint64_t) insn, 0x11ffffe000UL,
- ( ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
- | ((val & 0x0fffffUL) << 13) /* bit 0 -> 13 */));
-}
-
-static inline void ia64_nop_b (void *insn)
-{
- ia64_patch((uint64_t) insn, (1UL << 41) - 1, 2UL << 37);
-}
-
-static inline void ia64_ldxmov(void *insn, uint64_t val)
-{
- if (val + (1 << 21) < (1 << 22))
- ia64_patch((uint64_t) insn, 0x1fff80fe000UL, 8UL << 37);
-}
-
-static inline int ia64_patch_ltoff(void *insn, uint64_t val,
- int relaxable)
-{
- if (relaxable && (val + (1 << 21) < (1 << 22))) {
- ia64_imm22_r0(insn, val);
- return 0;
- }
- return 1;
-}
-
-struct ia64_fixup {
- struct ia64_fixup *next;
- void *addr; /* address that needs to be patched */
- long value;
-};
-
-#define IA64_PLT(insn, plt_index) \
-do { \
- struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
- fixup->next = plt_fixes; \
- plt_fixes = fixup; \
- fixup->addr = (insn); \
- fixup->value = (plt_index); \
- plt_offset[(plt_index)] = 1; \
-} while (0)
-
-#define IA64_LTOFF(insn, val, relaxable) \
-do { \
- if (ia64_patch_ltoff(insn, val, relaxable)) { \
- struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
- fixup->next = ltoff_fixes; \
- ltoff_fixes = fixup; \
- fixup->addr = (insn); \
- fixup->value = (val); \
- } \
-} while (0)
-
-static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
- struct ia64_fixup *ltoff_fixes,
- uint64_t gp,
- struct ia64_fixup *plt_fixes,
- int num_plts,
- unsigned long *plt_target,
- unsigned int *plt_offset)
-{
- static const uint8_t plt_bundle[] = {
- 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; movl r1=GP */
- 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
-
- 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
- };
- uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start;
- uint64_t *vp;
- struct ia64_fixup *fixup;
- unsigned int offset = 0;
- struct fdesc {
- long ip;
- long gp;
- } *fdesc;
- int i;
-
- if (plt_fixes) {
- plt_start = gen_code_ptr;
-
- for (i = 0; i < num_plts; ++i) {
- if (plt_offset[i]) {
- plt_offset[i] = offset;
- offset += sizeof(plt_bundle);
-
- fdesc = (struct fdesc *) plt_target[i];
- memcpy(gen_code_ptr, plt_bundle, sizeof(plt_bundle));
- ia64_imm64 (gen_code_ptr + 0x02, fdesc->gp);
- ia64_imm60b(gen_code_ptr + 0x12,
- (fdesc->ip - (long) (gen_code_ptr + 0x10)) >> 4);
- gen_code_ptr += sizeof(plt_bundle);
- }
- }
-
- for (fixup = plt_fixes; fixup; fixup = fixup->next)
- ia64_imm21b(fixup->addr,
- ((long) plt_start + plt_offset[fixup->value]
- - ((long) fixup->addr & ~0xf)) >> 4);
- }
-
- got_start = gen_code_ptr;
-
- /* First, create the GOT: */
- for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
- /* first check if we already have this value in the GOT: */
- for (vp = (uint64_t *) got_start; vp < (uint64_t *) gen_code_ptr; ++vp)
- if (*vp == fixup->value)
- break;
- if (vp == (uint64_t *) gen_code_ptr) {
- /* Nope, we need to put the value in the GOT: */
- *vp = fixup->value;
- gen_code_ptr += 8;
- }
- ia64_imm22(fixup->addr, (long) vp - gp);
- }
- /* Keep code ptr aligned. */
- if ((long) gen_code_ptr & 15)
- gen_code_ptr += 8;
- *gen_code_pp = gen_code_ptr;
-}
-#endif
-#endif
-
-#ifdef CONFIG_DYNGEN_OP
-
-#if defined __hppa__
-struct hppa_branch_stub {
- uint32_t *location;
- long target;
- struct hppa_branch_stub *next;
-};
-
-#define HPPA_RECORD_BRANCH(LIST, LOC, TARGET) \
-do { \
- struct hppa_branch_stub *stub = alloca(sizeof(struct hppa_branch_stub)); \
- stub->location = LOC; \
- stub->target = TARGET; \
- stub->next = LIST; \
- LIST = stub; \
-} while (0)
-
-static inline void hppa_process_stubs(struct hppa_branch_stub *stub,
- uint8_t **gen_code_pp)
-{
- uint32_t *s = (uint32_t *)*gen_code_pp;
- uint32_t *p = s + 1;
-
- if (!stub) return;
-
- for (; stub != NULL; stub = stub->next) {
- unsigned long l = (unsigned long)p;
- /* stub:
- * ldil L'target, %r1
- * be,n R'target(%sr4,%r1)
- */
- *p++ = 0x20200000 | reassemble_21(lrsel(stub->target, 0));
- *p++ = 0xe0202002 | (reassemble_17(rrsel(stub->target, 0) >> 2));
- hppa_patch17f(stub->location, l, 0);
- }
- /* b,l,n stub,%r0 */
- *s = 0xe8000002 | reassemble_17((p - s) - 2);
- *gen_code_pp = (uint8_t *)p;
-}
-#endif /* __hppa__ */
-
-const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr)
-{
- uint8_t *gen_code_ptr;
-
-#ifdef __hppa__
- struct hppa_branch_stub *hppa_stubs = NULL;
-#endif
-
- gen_code_ptr = s->code_ptr;
- switch(opc) {
-
-/* op.h is dynamically generated by dyngen.c from op.c */
-#include "op.h"
-
- default:
- tcg_abort();
- }
-
-#ifdef __hppa__
- hppa_process_stubs(hppa_stubs, &gen_code_ptr);
-#endif
-
- s->code_ptr = gen_code_ptr;
- return opparam_ptr;
-}
-#endif
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
deleted file mode 100644
index bc6be85..0000000
--- a/tcg/tcg-op.h
+++ /dev/null
@@ -1,1713 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "tcg.h"
-
-#ifdef CONFIG_DYNGEN_OP
-/* legacy dyngen operations */
-#include "gen-op.h"
-#endif
-
-int gen_new_label(void);
-
-static inline void tcg_gen_op1(int opc, TCGv arg1)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
-}
-
-static inline void tcg_gen_op1i(int opc, TCGArg arg1)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = arg1;
-}
-
-static inline void tcg_gen_op2(int opc, TCGv arg1, TCGv arg2)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
-}
-
-static inline void tcg_gen_op2i(int opc, TCGv arg1, TCGArg arg2)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = arg2;
-}
-
-static inline void tcg_gen_op2ii(int opc, TCGArg arg1, TCGArg arg2)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = arg1;
- *gen_opparam_ptr++ = arg2;
-}
-
-static inline void tcg_gen_op3(int opc, TCGv arg1, TCGv arg2, TCGv arg3)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
-}
-
-static inline void tcg_gen_op3i(int opc, TCGv arg1, TCGv arg2, TCGArg arg3)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = arg3;
-}
-
-static inline void tcg_gen_op4(int opc, TCGv arg1, TCGv arg2, TCGv arg3,
- TCGv arg4)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
-}
-
-static inline void tcg_gen_op4i(int opc, TCGv arg1, TCGv arg2, TCGv arg3,
- TCGArg arg4)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = arg4;
-}
-
-static inline void tcg_gen_op4ii(int opc, TCGv arg1, TCGv arg2, TCGArg arg3,
- TCGArg arg4)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = arg3;
- *gen_opparam_ptr++ = arg4;
-}
-
-static inline void tcg_gen_op5(int opc, TCGv arg1, TCGv arg2,
- TCGv arg3, TCGv arg4,
- TCGv arg5)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
- *gen_opparam_ptr++ = GET_TCGV(arg5);
-}
-
-static inline void tcg_gen_op5i(int opc, TCGv arg1, TCGv arg2,
- TCGv arg3, TCGv arg4,
- TCGArg arg5)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
- *gen_opparam_ptr++ = arg5;
-}
-
-static inline void tcg_gen_op6(int opc, TCGv arg1, TCGv arg2,
- TCGv arg3, TCGv arg4,
- TCGv arg5, TCGv arg6)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
- *gen_opparam_ptr++ = GET_TCGV(arg5);
- *gen_opparam_ptr++ = GET_TCGV(arg6);
-}
-
-static inline void tcg_gen_op6ii(int opc, TCGv arg1, TCGv arg2,
- TCGv arg3, TCGv arg4,
- TCGArg arg5, TCGArg arg6)
-{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV(arg1);
- *gen_opparam_ptr++ = GET_TCGV(arg2);
- *gen_opparam_ptr++ = GET_TCGV(arg3);
- *gen_opparam_ptr++ = GET_TCGV(arg4);
- *gen_opparam_ptr++ = arg5;
- *gen_opparam_ptr++ = arg6;
-}
-
-static inline void gen_set_label(int n)
-{
- tcg_gen_op1i(INDEX_op_set_label, n);
-}
-
-static inline void tcg_gen_br(int label)
-{
- tcg_gen_op1i(INDEX_op_br, label);
-}
-
-static inline void tcg_gen_mov_i32(TCGv ret, TCGv arg)
-{
- if (GET_TCGV(ret) != GET_TCGV(arg))
- tcg_gen_op2(INDEX_op_mov_i32, ret, arg);
-}
-
-static inline void tcg_gen_movi_i32(TCGv ret, int32_t arg)
-{
- tcg_gen_op2i(INDEX_op_movi_i32, ret, arg);
-}
-
-/* helper calls */
-#define TCG_HELPER_CALL_FLAGS 0
-
-static inline void tcg_gen_helper_0_0(void *func)
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 0, NULL);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_0_1(void *func, TCGv arg)
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 1, &arg);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2)
-{
- TCGv args[2];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 2, args);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_0_3(void *func,
- TCGv arg1, TCGv arg2, TCGv arg3)
-{
- TCGv args[3];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 3, args);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
- TCGv arg3, TCGv arg4)
-{
- TCGv args[4];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- args[3] = arg4;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 0, NULL, 4, args);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_1_0(void *func, TCGv ret)
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 0, NULL);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1)
-{
- TCGv t0;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 1, &arg1);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_1_2(void *func, TCGv ret,
- TCGv arg1, TCGv arg2)
-{
- TCGv args[2];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 2, args);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_1_3(void *func, TCGv ret,
- TCGv arg1, TCGv arg2, TCGv arg3)
-{
- TCGv args[3];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 3, args);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_helper_1_4(void *func, TCGv ret,
- TCGv arg1, TCGv arg2, TCGv arg3,
- TCGv arg4)
-{
- TCGv args[4];
- TCGv t0;
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
- args[3] = arg4;
- t0 = tcg_const_ptr((tcg_target_long)func);
- tcg_gen_call(&tcg_ctx,
- t0, TCG_HELPER_CALL_FLAGS,
- 1, &ret, 4, args);
- tcg_temp_free(t0);
-}
-
-/* 32 bit ops */
-
-static inline void tcg_gen_ld8u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld8u_i32, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld8s_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld8s_i32, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld16u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld16u_i32, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld16s_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld16s_i32, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld_i32, ret, arg2, offset);
-}
-
-static inline void tcg_gen_st8_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st8_i32, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st16_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st16_i32, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st_i32(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st_i32, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_add_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_add_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- /* some cases can be optimized here */
- if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_add_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_sub_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_sub_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_subi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- /* some cases can be optimized here */
- if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_sub_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_and_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_and_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- /* some cases can be optimized here */
- if (arg2 == 0) {
- tcg_gen_movi_i32(ret, 0);
- } else if (arg2 == 0xffffffff) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_and_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_or_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_or_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- /* some cases can be optimized here */
- if (arg2 == 0xffffffff) {
- tcg_gen_movi_i32(ret, 0xffffffff);
- } else if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_or_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_xor_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_xor_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_xori_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- /* some cases can be optimized here */
- if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_xor_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_shl_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_shl_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_shli_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_shl_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_shr_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_shr_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_shri_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_shr_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_sar_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_sar_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_sari_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- if (arg2 == 0) {
- tcg_gen_mov_i32(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_sar_i32(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_brcond_i32(int cond, TCGv arg1, TCGv arg2,
- int label_index)
-{
- tcg_gen_op4ii(INDEX_op_brcond_i32, arg1, arg2, cond, label_index);
-}
-
-static inline void tcg_gen_brcondi_i32(int cond, TCGv arg1, int32_t arg2,
- int label_index)
-{
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_brcond_i32(cond, arg1, t0, label_index);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_mul_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_mul_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_muli_i32(TCGv ret, TCGv arg1, int32_t arg2)
-{
- TCGv t0 = tcg_const_i32(arg2);
- tcg_gen_mul_i32(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-#ifdef TCG_TARGET_HAS_div_i32
-static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_div_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_rem_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_divu_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_remu_i32, ret, arg1, arg2);
-}
-#else
-static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- tcg_gen_sari_i32(t0, arg1, 31);
- tcg_gen_op5(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- tcg_gen_sari_i32(t0, arg1, 31);
- tcg_gen_op5(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- tcg_gen_movi_i32(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- tcg_gen_movi_i32(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-#endif
-
-#if TCG_TARGET_REG_BITS == 32
-
-static inline void tcg_gen_mov_i64(TCGv ret, TCGv arg)
-{
- if (GET_TCGV(ret) != GET_TCGV(arg)) {
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
- }
-}
-
-static inline void tcg_gen_movi_i64(TCGv ret, int64_t arg)
-{
- tcg_gen_movi_i32(ret, arg);
- tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
-}
-
-static inline void tcg_gen_ld8u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_ld8u_i32(ret, arg2, offset);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_ld8s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_ld8s_i32(ret, arg2, offset);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_ld16u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_ld16u_i32(ret, arg2, offset);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_ld16s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_ld16s_i32(ret, arg2, offset);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_ld32u_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_ld_i32(ret, arg2, offset);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_ld32s_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_ld_i32(ret, arg2, offset);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_ld_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- /* since arg2 and ret have different types, they cannot be the
- same temporary */
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
- tcg_gen_ld_i32(ret, arg2, offset + 4);
-#else
- tcg_gen_ld_i32(ret, arg2, offset);
- tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
-#endif
-}
-
-static inline void tcg_gen_st8_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_st8_i32(arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st16_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_st16_i32(arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st32_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_st_i32(arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
- tcg_gen_st_i32(arg1, arg2, offset + 4);
-#else
- tcg_gen_st_i32(arg1, arg2, offset);
- tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
-#endif
-}
-
-static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op6(INDEX_op_add2_i32, ret, TCGV_HIGH(ret),
- arg1, TCGV_HIGH(arg1), arg2, TCGV_HIGH(arg2));
-}
-
-static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_add_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op6(INDEX_op_sub2_i32, ret, TCGV_HIGH(ret),
- arg1, TCGV_HIGH(arg1), arg2, TCGV_HIGH(arg2));
-}
-
-static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_sub_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_and_i32(ret, arg1, arg2);
- tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-}
-
-static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- tcg_gen_andi_i32(ret, arg1, arg2);
- tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
-}
-
-static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_or_i32(ret, arg1, arg2);
- tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-}
-
-static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- tcg_gen_ori_i32(ret, arg1, arg2);
- tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
-}
-
-static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_xor_i32(ret, arg1, arg2);
- tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-}
-
-static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- tcg_gen_xori_i32(ret, arg1, arg2);
- tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
-}
-
-/* XXX: use generic code when basic block handling is OK or CPU
- specific code (x86) */
-static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_shl_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
-}
-
-static inline void tcg_gen_shr_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_shr_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
-}
-
-static inline void tcg_gen_sar_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_sar_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
-}
-
-static inline void tcg_gen_brcond_i64(int cond, TCGv arg1, TCGv arg2,
- int label_index)
-{
- tcg_gen_op6ii(INDEX_op_brcond2_i32,
- arg1, TCGV_HIGH(arg1), arg2, TCGV_HIGH(arg2),
- cond, label_index);
-}
-
-static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0, t1;
-
- t0 = tcg_temp_new(TCG_TYPE_I64);
- t1 = tcg_temp_new(TCG_TYPE_I32);
-
- tcg_gen_op4(INDEX_op_mulu2_i32, t0, TCGV_HIGH(t0), arg1, arg2);
-
- tcg_gen_mul_i32(t1, arg1, TCGV_HIGH(arg2));
- tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
- tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), arg2);
- tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
-
- tcg_gen_mov_i64(ret, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-}
-
-static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_mul_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_div_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_rem_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_divu_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_helper_1_2(tcg_helper_remu_i64, ret, arg1, arg2);
-}
-
-#else
-
-static inline void tcg_gen_mov_i64(TCGv ret, TCGv arg)
-{
- if (GET_TCGV(ret) != GET_TCGV(arg))
- tcg_gen_op2(INDEX_op_mov_i64, ret, arg);
-}
-
-static inline void tcg_gen_movi_i64(TCGv ret, int64_t arg)
-{
- tcg_gen_op2i(INDEX_op_movi_i64, ret, arg);
-}
-
-static inline void tcg_gen_ld8u_i64(TCGv ret, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld8u_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld8s_i64(TCGv ret, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld8s_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld16u_i64(TCGv ret, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld16u_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld16s_i64(TCGv ret, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld16s_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld32u_i64(TCGv ret, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld32u_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld32s_i64(TCGv ret, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld32s_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_ld_i64(TCGv ret, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_ld_i64, ret, arg2, offset);
-}
-
-static inline void tcg_gen_st8_i64(TCGv arg1, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st8_i64, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st16_i64(TCGv arg1, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st16_i64, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st32_i64(TCGv arg1, TCGv arg2,
- tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st32_i64, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_st_i64(TCGv arg1, TCGv arg2, tcg_target_long offset)
-{
- tcg_gen_op3i(INDEX_op_st_i64, arg1, arg2, offset);
-}
-
-static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_add_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_add_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_sub_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_sub_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_and_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_and_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_or_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_or_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_xor_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_xor_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_shl_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- if (arg2 == 0) {
- tcg_gen_mov_i64(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_shl_i64(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_shr_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_shr_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- if (arg2 == 0) {
- tcg_gen_mov_i64(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_shr_i64(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_sar_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_sar_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- if (arg2 == 0) {
- tcg_gen_mov_i64(ret, arg1);
- } else {
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_sar_i64(ret, arg1, t0);
- tcg_temp_free(t0);
- }
-}
-
-static inline void tcg_gen_brcond_i64(int cond, TCGv arg1, TCGv arg2,
- int label_index)
-{
- tcg_gen_op4ii(INDEX_op_brcond_i64, arg1, arg2, cond, label_index);
-}
-
-static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_mul_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_mul_i64(ret, arg1, t0);
- tcg_temp_free(t0);
-}
-
-#ifdef TCG_TARGET_HAS_div_i64
-static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_div_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_rem_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_divu_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- tcg_gen_op3(INDEX_op_remu_i64, ret, arg1, arg2);
-}
-#else
-static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_sari_i64(t0, arg1, 63);
- tcg_gen_op5(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_sari_i64(t0, arg1, 63);
- tcg_gen_op5(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_movi_i64(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-
-static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_movi_i64(t0, 0);
- tcg_gen_op5(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
- tcg_temp_free(t0);
-}
-#endif
-
-#endif
-
-static inline void tcg_gen_brcondi_i64(int cond, TCGv arg1, int64_t arg2,
- int label_index)
-{
- TCGv t0 = tcg_const_i64(arg2);
- tcg_gen_brcond_i64(cond, arg1, t0, label_index);
- tcg_temp_free(t0);
-}
-
-/***************************************/
-/* optional operations */
-
-static inline void tcg_gen_ext8s_i32(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_ext8s_i32
- tcg_gen_op2(INDEX_op_ext8s_i32, ret, arg);
-#else
- tcg_gen_shli_i32(ret, arg, 24);
- tcg_gen_sari_i32(ret, ret, 24);
-#endif
-}
-
-static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_ext16s_i32
- tcg_gen_op2(INDEX_op_ext16s_i32, ret, arg);
-#else
- tcg_gen_shli_i32(ret, arg, 16);
- tcg_gen_sari_i32(ret, ret, 16);
-#endif
-}
-
-/* These are currently just for convenience.
- We assume a target will recognise these automatically . */
-static inline void tcg_gen_ext8u_i32(TCGv ret, TCGv arg)
-{
- tcg_gen_andi_i32(ret, arg, 0xffu);
-}
-
-static inline void tcg_gen_ext16u_i32(TCGv ret, TCGv arg)
-{
- tcg_gen_andi_i32(ret, arg, 0xffffu);
-}
-
-/* Note: we assume the two high bytes are set to zero */
-static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_bswap16_i32
- tcg_gen_op2(INDEX_op_bswap16_i32, ret, arg);
-#else
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
-
- tcg_gen_shri_i32(t0, arg, 8);
- tcg_gen_andi_i32(t1, arg, 0x000000ff);
- tcg_gen_shli_i32(t1, t1, 8);
- tcg_gen_or_i32(ret, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-#endif
-}
-
-static inline void tcg_gen_bswap_i32(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_bswap_i32
- tcg_gen_op2(INDEX_op_bswap_i32, ret, arg);
-#else
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
-
- tcg_gen_shli_i32(t0, arg, 24);
-
- tcg_gen_andi_i32(t1, arg, 0x0000ff00);
- tcg_gen_shli_i32(t1, t1, 8);
- tcg_gen_or_i32(t0, t0, t1);
-
- tcg_gen_shri_i32(t1, arg, 8);
- tcg_gen_andi_i32(t1, t1, 0x0000ff00);
- tcg_gen_or_i32(t0, t0, t1);
-
- tcg_gen_shri_i32(t1, arg, 24);
- tcg_gen_or_i32(ret, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-#endif
-}
-
-#if TCG_TARGET_REG_BITS == 32
-static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_ext8s_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_ext16s_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_ext8u_i32(ret, arg);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_ext16u_i32(ret, arg);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
-{
- tcg_gen_mov_i32(ret, arg);
-}
-
-static inline void tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-}
-
-static inline void tcg_gen_ext_i32_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_mov_i32(ret, arg);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-}
-
-static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
-{
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
-
- tcg_gen_bswap_i32(t0, arg);
- tcg_gen_bswap_i32(t1, TCGV_HIGH(arg));
- tcg_gen_mov_i32(ret, t1);
- tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-}
-#else
-
-static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_ext8s_i64
- tcg_gen_op2(INDEX_op_ext8s_i64, ret, arg);
-#else
- tcg_gen_shli_i64(ret, arg, 56);
- tcg_gen_sari_i64(ret, ret, 56);
-#endif
-}
-
-static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_ext16s_i64
- tcg_gen_op2(INDEX_op_ext16s_i64, ret, arg);
-#else
- tcg_gen_shli_i64(ret, arg, 48);
- tcg_gen_sari_i64(ret, ret, 48);
-#endif
-}
-
-static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_ext32s_i64
- tcg_gen_op2(INDEX_op_ext32s_i64, ret, arg);
-#else
- tcg_gen_shli_i64(ret, arg, 32);
- tcg_gen_sari_i64(ret, ret, 32);
-#endif
-}
-
-static inline void tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_andi_i64(ret, arg, 0xffu);
-}
-
-static inline void tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_andi_i64(ret, arg, 0xffffu);
-}
-
-static inline void tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_andi_i64(ret, arg, 0xffffffffu);
-}
-
-/* Note: we assume the target supports move between 32 and 64 bit
- registers. This will probably break MIPS64 targets. */
-static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
-{
- tcg_gen_mov_i32(ret, arg);
-}
-
-/* Note: we assume the target supports move between 32 and 64 bit
- registers */
-static inline void tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_andi_i64(ret, arg, 0xffffffffu);
-}
-
-/* Note: we assume the target supports move between 32 and 64 bit
- registers */
-static inline void tcg_gen_ext_i32_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_ext32s_i64(ret, arg);
-}
-
-static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_bswap_i64
- tcg_gen_op2(INDEX_op_bswap_i64, ret, arg);
-#else
- TCGv t0, t1;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
-
- tcg_gen_shli_i64(t0, arg, 56);
-
- tcg_gen_andi_i64(t1, arg, 0x0000ff00);
- tcg_gen_shli_i64(t1, t1, 40);
- tcg_gen_or_i64(t0, t0, t1);
-
- tcg_gen_andi_i64(t1, arg, 0x00ff0000);
- tcg_gen_shli_i64(t1, t1, 24);
- tcg_gen_or_i64(t0, t0, t1);
-
- tcg_gen_andi_i64(t1, arg, 0xff000000);
- tcg_gen_shli_i64(t1, t1, 8);
- tcg_gen_or_i64(t0, t0, t1);
-
- tcg_gen_shri_i64(t1, arg, 8);
- tcg_gen_andi_i64(t1, t1, 0xff000000);
- tcg_gen_or_i64(t0, t0, t1);
-
- tcg_gen_shri_i64(t1, arg, 24);
- tcg_gen_andi_i64(t1, t1, 0x00ff0000);
- tcg_gen_or_i64(t0, t0, t1);
-
- tcg_gen_shri_i64(t1, arg, 40);
- tcg_gen_andi_i64(t1, t1, 0x0000ff00);
- tcg_gen_or_i64(t0, t0, t1);
-
- tcg_gen_shri_i64(t1, arg, 56);
- tcg_gen_or_i64(ret, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-#endif
-}
-
-#endif
-
-static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_neg_i32
- tcg_gen_op2(INDEX_op_neg_i32, ret, arg);
-#else
- TCGv t0 = tcg_const_i32(0);
- tcg_gen_sub_i32(ret, t0, arg);
- tcg_temp_free(t0);
-#endif
-}
-
-static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg)
-{
-#ifdef TCG_TARGET_HAS_neg_i64
- tcg_gen_op2(INDEX_op_neg_i64, ret, arg);
-#else
- TCGv t0 = tcg_const_i64(0);
- tcg_gen_sub_i64(ret, t0, arg);
- tcg_temp_free(t0);
-#endif
-}
-
-static inline void tcg_gen_not_i32(TCGv ret, TCGv arg)
-{
- tcg_gen_xori_i32(ret, arg, -1);
-}
-
-static inline void tcg_gen_not_i64(TCGv ret, TCGv arg)
-{
- tcg_gen_xori_i64(ret, arg, -1);
-}
-
-static inline void tcg_gen_discard_i32(TCGv arg)
-{
- tcg_gen_op1(INDEX_op_discard, arg);
-}
-
-#if TCG_TARGET_REG_BITS == 32
-static inline void tcg_gen_discard_i64(TCGv arg)
-{
- tcg_gen_discard_i32(arg);
- tcg_gen_discard_i32(TCGV_HIGH(arg));
-}
-#else
-static inline void tcg_gen_discard_i64(TCGv arg)
-{
- tcg_gen_op1(INDEX_op_discard, arg);
-}
-#endif
-
-/***************************************/
-/* QEMU specific operations. Their type depend on the QEMU CPU
- type. */
-#ifndef TARGET_LONG_BITS
-#error must include QEMU headers
-#endif
-
-/* debug info: write the PC of the corresponding QEMU CPU instruction */
-static inline void tcg_gen_debug_insn_start(uint64_t pc)
-{
- /* XXX: must really use a 32 bit size for TCGArg in all cases */
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
- tcg_gen_op2ii(INDEX_op_debug_insn_start,
- (uint32_t)(pc), (uint32_t)(pc >> 32));
-#else
- tcg_gen_op1i(INDEX_op_debug_insn_start, pc);
-#endif
-}
-
-static inline void tcg_gen_exit_tb(tcg_target_long val)
-{
- tcg_gen_op1i(INDEX_op_exit_tb, val);
-}
-
-static inline void tcg_gen_goto_tb(int idx)
-{
- tcg_gen_op1i(INDEX_op_goto_tb, idx);
-}
-
-#if TCG_TARGET_REG_BITS == 32
-static inline void tcg_gen_qemu_ld8u(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld8u, ret, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_ld8u, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-#endif
-}
-
-static inline void tcg_gen_qemu_ld8s(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld8s, ret, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_ld8s, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-#endif
-}
-
-static inline void tcg_gen_qemu_ld16u(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld16u, ret, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_ld16u, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-#endif
-}
-
-static inline void tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld16s, ret, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_ld16s, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-#endif
-}
-
-static inline void tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld32u, ret, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_ld32u, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
-#endif
-}
-
-static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_ld32u, ret, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_ld32u, ret, addr, TCGV_HIGH(addr), mem_index);
- tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
-#endif
-}
-
-static inline void tcg_gen_qemu_ld64(TCGv ret, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op4i(INDEX_op_qemu_ld64, ret, TCGV_HIGH(ret), addr, mem_index);
-#else
- tcg_gen_op5i(INDEX_op_qemu_ld64, ret, TCGV_HIGH(ret),
- addr, TCGV_HIGH(addr), mem_index);
-#endif
-}
-
-static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_st8, arg, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_st8, arg, addr, TCGV_HIGH(addr), mem_index);
-#endif
-}
-
-static inline void tcg_gen_qemu_st16(TCGv arg, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_st16, arg, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_st16, arg, addr, TCGV_HIGH(addr), mem_index);
-#endif
-}
-
-static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op3i(INDEX_op_qemu_st32, arg, addr, mem_index);
-#else
- tcg_gen_op4i(INDEX_op_qemu_st32, arg, addr, TCGV_HIGH(addr), mem_index);
-#endif
-}
-
-static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
-{
-#if TARGET_LONG_BITS == 32
- tcg_gen_op4i(INDEX_op_qemu_st64, arg, TCGV_HIGH(arg), addr, mem_index);
-#else
- tcg_gen_op5i(INDEX_op_qemu_st64, arg, TCGV_HIGH(arg),
- addr, TCGV_HIGH(addr), mem_index);
-#endif
-}
-
-#define tcg_gen_ld_ptr tcg_gen_ld_i32
-#define tcg_gen_discard_ptr tcg_gen_discard_i32
-
-#else /* TCG_TARGET_REG_BITS == 32 */
-
-static inline void tcg_gen_qemu_ld8u(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld8u, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_ld8s(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld8s, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_ld16u(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld16u, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_ld16s(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld16s, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_ld32u(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld32u, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_ld32s(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld32s, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_ld64(TCGv ret, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_ld64, ret, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_st8(TCGv arg, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_st8, arg, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_st16(TCGv arg, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_st16, arg, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_st32(TCGv arg, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_st32, arg, addr, mem_index);
-}
-
-static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
-{
- tcg_gen_op3i(INDEX_op_qemu_st64, arg, addr, mem_index);
-}
-
-#define tcg_gen_ld_ptr tcg_gen_ld_i64
-#define tcg_gen_discard_ptr tcg_gen_discard_i64
-
-#endif /* TCG_TARGET_REG_BITS != 32 */
-
-#if TARGET_LONG_BITS == 64
-#define TCG_TYPE_TL TCG_TYPE_I64
-#define tcg_gen_movi_tl tcg_gen_movi_i64
-#define tcg_gen_mov_tl tcg_gen_mov_i64
-#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
-#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
-#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
-#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
-#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
-#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
-#define tcg_gen_ld_tl tcg_gen_ld_i64
-#define tcg_gen_st8_tl tcg_gen_st8_i64
-#define tcg_gen_st16_tl tcg_gen_st16_i64
-#define tcg_gen_st32_tl tcg_gen_st32_i64
-#define tcg_gen_st_tl tcg_gen_st_i64
-#define tcg_gen_add_tl tcg_gen_add_i64
-#define tcg_gen_addi_tl tcg_gen_addi_i64
-#define tcg_gen_sub_tl tcg_gen_sub_i64
-#define tcg_gen_neg_tl tcg_gen_neg_i64
-#define tcg_gen_subi_tl tcg_gen_subi_i64
-#define tcg_gen_and_tl tcg_gen_and_i64
-#define tcg_gen_andi_tl tcg_gen_andi_i64
-#define tcg_gen_or_tl tcg_gen_or_i64
-#define tcg_gen_ori_tl tcg_gen_ori_i64
-#define tcg_gen_xor_tl tcg_gen_xor_i64
-#define tcg_gen_xori_tl tcg_gen_xori_i64
-#define tcg_gen_not_tl tcg_gen_not_i64
-#define tcg_gen_shl_tl tcg_gen_shl_i64
-#define tcg_gen_shli_tl tcg_gen_shli_i64
-#define tcg_gen_shr_tl tcg_gen_shr_i64
-#define tcg_gen_shri_tl tcg_gen_shri_i64
-#define tcg_gen_sar_tl tcg_gen_sar_i64
-#define tcg_gen_sari_tl tcg_gen_sari_i64
-#define tcg_gen_brcond_tl tcg_gen_brcond_i64
-#define tcg_gen_brcondi_tl tcg_gen_brcondi_i64
-#define tcg_gen_mul_tl tcg_gen_mul_i64
-#define tcg_gen_muli_tl tcg_gen_muli_i64
-#define tcg_gen_discard_tl tcg_gen_discard_i64
-#define tcg_gen_trunc_tl_i32 tcg_gen_trunc_i64_i32
-#define tcg_gen_trunc_i64_tl tcg_gen_mov_i64
-#define tcg_gen_extu_i32_tl tcg_gen_extu_i32_i64
-#define tcg_gen_ext_i32_tl tcg_gen_ext_i32_i64
-#define tcg_gen_extu_tl_i64 tcg_gen_mov_i64
-#define tcg_gen_ext_tl_i64 tcg_gen_mov_i64
-#define tcg_gen_ext8u_tl tcg_gen_ext8u_i64
-#define tcg_gen_ext8s_tl tcg_gen_ext8s_i64
-#define tcg_gen_ext16u_tl tcg_gen_ext16u_i64
-#define tcg_gen_ext16s_tl tcg_gen_ext16s_i64
-#define tcg_gen_ext32u_tl tcg_gen_ext32u_i64
-#define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
-#define tcg_const_tl tcg_const_i64
-#else
-#define TCG_TYPE_TL TCG_TYPE_I32
-#define tcg_gen_movi_tl tcg_gen_movi_i32
-#define tcg_gen_mov_tl tcg_gen_mov_i32
-#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
-#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
-#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
-#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
-#define tcg_gen_ld32u_tl tcg_gen_ld_i32
-#define tcg_gen_ld32s_tl tcg_gen_ld_i32
-#define tcg_gen_ld_tl tcg_gen_ld_i32
-#define tcg_gen_st8_tl tcg_gen_st8_i32
-#define tcg_gen_st16_tl tcg_gen_st16_i32
-#define tcg_gen_st32_tl tcg_gen_st_i32
-#define tcg_gen_st_tl tcg_gen_st_i32
-#define tcg_gen_add_tl tcg_gen_add_i32
-#define tcg_gen_addi_tl tcg_gen_addi_i32
-#define tcg_gen_sub_tl tcg_gen_sub_i32
-#define tcg_gen_neg_tl tcg_gen_neg_i32
-#define tcg_gen_subi_tl tcg_gen_subi_i32
-#define tcg_gen_and_tl tcg_gen_and_i32
-#define tcg_gen_andi_tl tcg_gen_andi_i32
-#define tcg_gen_or_tl tcg_gen_or_i32
-#define tcg_gen_ori_tl tcg_gen_ori_i32
-#define tcg_gen_xor_tl tcg_gen_xor_i32
-#define tcg_gen_xori_tl tcg_gen_xori_i32
-#define tcg_gen_not_tl tcg_gen_not_i32
-#define tcg_gen_shl_tl tcg_gen_shl_i32
-#define tcg_gen_shli_tl tcg_gen_shli_i32
-#define tcg_gen_shr_tl tcg_gen_shr_i32
-#define tcg_gen_shri_tl tcg_gen_shri_i32
-#define tcg_gen_sar_tl tcg_gen_sar_i32
-#define tcg_gen_sari_tl tcg_gen_sari_i32
-#define tcg_gen_brcond_tl tcg_gen_brcond_i32
-#define tcg_gen_brcondi_tl tcg_gen_brcondi_i32
-#define tcg_gen_mul_tl tcg_gen_mul_i32
-#define tcg_gen_muli_tl tcg_gen_muli_i32
-#define tcg_gen_discard_tl tcg_gen_discard_i32
-#define tcg_gen_trunc_tl_i32 tcg_gen_mov_i32
-#define tcg_gen_trunc_i64_tl tcg_gen_trunc_i64_i32
-#define tcg_gen_extu_i32_tl tcg_gen_mov_i32
-#define tcg_gen_ext_i32_tl tcg_gen_mov_i32
-#define tcg_gen_extu_tl_i64 tcg_gen_extu_i32_i64
-#define tcg_gen_ext_tl_i64 tcg_gen_ext_i32_i64
-#define tcg_gen_ext8u_tl tcg_gen_ext8u_i32
-#define tcg_gen_ext8s_tl tcg_gen_ext8s_i32
-#define tcg_gen_ext16u_tl tcg_gen_ext16u_i32
-#define tcg_gen_ext16s_tl tcg_gen_ext16s_i32
-#define tcg_gen_ext32u_tl tcg_gen_mov_i32
-#define tcg_gen_ext32s_tl tcg_gen_mov_i32
-#define tcg_const_tl tcg_const_i32
-#endif
-
-#if TCG_TARGET_REG_BITS == 32
-#define tcg_gen_add_ptr tcg_gen_add_i32
-#define tcg_gen_addi_ptr tcg_gen_addi_i32
-#define tcg_gen_ext_i32_ptr tcg_gen_mov_i32
-#else /* TCG_TARGET_REG_BITS == 32 */
-#define tcg_gen_add_ptr tcg_gen_add_i64
-#define tcg_gen_addi_ptr tcg_gen_addi_i64
-#define tcg_gen_ext_i32_ptr tcg_gen_ext_i32_i64
-#endif /* TCG_TARGET_REG_BITS != 32 */
-
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
deleted file mode 100644
index 31ae550..0000000
--- a/tcg/tcg-opc.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifdef CONFIG_DYNGEN_OP
-#include "dyngen-opc.h"
-#endif
-
-#ifndef DEF2
-#define DEF2(name, oargs, iargs, cargs, flags) DEF(name, oargs + iargs + cargs, 0)
-#endif
-
-/* predefined ops */
-DEF2(end, 0, 0, 0, 0) /* must be kept first */
-DEF2(nop, 0, 0, 0, 0)
-DEF2(nop1, 0, 0, 1, 0)
-DEF2(nop2, 0, 0, 2, 0)
-DEF2(nop3, 0, 0, 3, 0)
-DEF2(nopn, 0, 0, 1, 0) /* variable number of parameters */
-
-DEF2(discard, 1, 0, 0, 0)
-
-DEF2(set_label, 0, 0, 1, 0)
-DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
-DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-
-DEF2(mov_i32, 1, 1, 0, 0)
-DEF2(movi_i32, 1, 0, 1, 0)
-/* load/store */
-DEF2(ld8u_i32, 1, 1, 1, 0)
-DEF2(ld8s_i32, 1, 1, 1, 0)
-DEF2(ld16u_i32, 1, 1, 1, 0)
-DEF2(ld16s_i32, 1, 1, 1, 0)
-DEF2(ld_i32, 1, 1, 1, 0)
-DEF2(st8_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st16_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-/* arith */
-DEF2(add_i32, 1, 2, 0, 0)
-DEF2(sub_i32, 1, 2, 0, 0)
-DEF2(mul_i32, 1, 2, 0, 0)
-#ifdef TCG_TARGET_HAS_div_i32
-DEF2(div_i32, 1, 2, 0, 0)
-DEF2(divu_i32, 1, 2, 0, 0)
-DEF2(rem_i32, 1, 2, 0, 0)
-DEF2(remu_i32, 1, 2, 0, 0)
-#else
-DEF2(div2_i32, 2, 3, 0, 0)
-DEF2(divu2_i32, 2, 3, 0, 0)
-#endif
-DEF2(and_i32, 1, 2, 0, 0)
-DEF2(or_i32, 1, 2, 0, 0)
-DEF2(xor_i32, 1, 2, 0, 0)
-/* shifts */
-DEF2(shl_i32, 1, 2, 0, 0)
-DEF2(shr_i32, 1, 2, 0, 0)
-DEF2(sar_i32, 1, 2, 0, 0)
-
-DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-#if TCG_TARGET_REG_BITS == 32
-DEF2(add2_i32, 2, 4, 0, 0)
-DEF2(sub2_i32, 2, 4, 0, 0)
-DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(mulu2_i32, 2, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext8s_i32
-DEF2(ext8s_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i32
-DEF2(ext16s_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_bswap_i32
-DEF2(bswap_i32, 1, 1, 0, 0)
-#endif
-
-#if TCG_TARGET_REG_BITS == 64
-DEF2(mov_i64, 1, 1, 0, 0)
-DEF2(movi_i64, 1, 0, 1, 0)
-/* load/store */
-DEF2(ld8u_i64, 1, 1, 1, 0)
-DEF2(ld8s_i64, 1, 1, 1, 0)
-DEF2(ld16u_i64, 1, 1, 1, 0)
-DEF2(ld16s_i64, 1, 1, 1, 0)
-DEF2(ld32u_i64, 1, 1, 1, 0)
-DEF2(ld32s_i64, 1, 1, 1, 0)
-DEF2(ld_i64, 1, 1, 1, 0)
-DEF2(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF2(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-/* arith */
-DEF2(add_i64, 1, 2, 0, 0)
-DEF2(sub_i64, 1, 2, 0, 0)
-DEF2(mul_i64, 1, 2, 0, 0)
-#ifdef TCG_TARGET_HAS_div_i64
-DEF2(div_i64, 1, 2, 0, 0)
-DEF2(divu_i64, 1, 2, 0, 0)
-DEF2(rem_i64, 1, 2, 0, 0)
-DEF2(remu_i64, 1, 2, 0, 0)
-#else
-DEF2(div2_i64, 2, 3, 0, 0)
-DEF2(divu2_i64, 2, 3, 0, 0)
-#endif
-DEF2(and_i64, 1, 2, 0, 0)
-DEF2(or_i64, 1, 2, 0, 0)
-DEF2(xor_i64, 1, 2, 0, 0)
-/* shifts */
-DEF2(shl_i64, 1, 2, 0, 0)
-DEF2(shr_i64, 1, 2, 0, 0)
-DEF2(sar_i64, 1, 2, 0, 0)
-
-DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-#ifdef TCG_TARGET_HAS_ext8s_i64
-DEF2(ext8s_i64, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i64
-DEF2(ext16s_i64, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext32s_i64
-DEF2(ext32s_i64, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_bswap_i64
-DEF2(bswap_i64, 1, 1, 0, 0)
-#endif
-#endif
-#ifdef TCG_TARGET_HAS_neg_i32
-DEF2(neg_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_neg_i64
-DEF2(neg_i64, 1, 1, 0, 0)
-#endif
-
-/* QEMU specific */
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
-DEF2(debug_insn_start, 0, 0, 2, 0)
-#else
-DEF2(debug_insn_start, 0, 0, 1, 0)
-#endif
-DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF2(goto_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-/* Note: even if TARGET_LONG_BITS is not defined, the INDEX_op
- constants must be defined */
-#if TCG_TARGET_REG_BITS == 32
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld32s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-#if TARGET_LONG_BITS == 32
-DEF2(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#else
-DEF2(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-#endif
-
-#else /* TCG_TARGET_REG_BITS == 32 */
-
-DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-
-DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF2(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-
-#endif /* TCG_TARGET_REG_BITS != 32 */
-
-#undef DEF2
diff --git a/tcg/tcg-runtime.c b/tcg/tcg-runtime.c
deleted file mode 100644
index 575da43..0000000
--- a/tcg/tcg-runtime.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-#include "osdep.h"
-#include "tcg.h"
-
-int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2)
-{
- return arg1 << arg2;
-}
-
-int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2)
-{
- return (uint64_t)arg1 >> arg2;
-}
-
-int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2)
-{
- return arg1 >> arg2;
-}
-
-int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2)
-{
- return arg1 / arg2;
-}
-
-int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2)
-{
- return arg1 % arg2;
-}
-
-uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2)
-{
- return arg1 / arg2;
-}
-
-uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2)
-{
- return arg1 % arg2;
-}
-
diff --git a/tcg/tcg.c b/tcg/tcg.c
deleted file mode 100644
index 1b7bf5c..0000000
--- a/tcg/tcg.c
+++ /dev/null
@@ -1,2081 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* define it to suppress various consistency checks (faster) */
-#define NDEBUG
-
-/* define it to use liveness analysis (better code) */
-#define USE_LIVENESS_ANALYSIS
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#ifdef _WIN32
-#include <malloc.h>
-#endif
-
-#include "config.h"
-#include "qemu-common.h"
-
-/* Note: the long term plan is to reduce the dependancies on the QEMU
- CPU definitions. Currently they are used for qemu_ld/st
- instructions */
-#define NO_CPU_IO_DEFS
-#include "cpu.h"
-#include "exec-all.h"
-
-#include "tcg-op.h"
-#include "elf.h"
-
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend);
-
-TCGOpDef tcg_op_defs[] = {
-#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
-#define DEF2(s, iargs, oargs, cargs, flags) { #s, iargs, oargs, cargs, iargs + oargs + cargs, flags, 0 },
-#include "tcg-opc.h"
-#undef DEF
-#undef DEF2
-};
-
-TCGRegSet tcg_target_available_regs[2];
-TCGRegSet tcg_target_call_clobber_regs;
-
-/* XXX: move that inside the context */
-uint16_t *gen_opc_ptr;
-TCGArg *gen_opparam_ptr;
-
-static inline void tcg_out8(TCGContext *s, uint8_t v)
-{
- *s->code_ptr++ = v;
-}
-
-static inline void tcg_out16(TCGContext *s, uint16_t v)
-{
- *(uint16_t *)s->code_ptr = v;
- s->code_ptr += 2;
-}
-
-static inline void tcg_out32(TCGContext *s, uint32_t v)
-{
- *(uint32_t *)s->code_ptr = v;
- s->code_ptr += 4;
-}
-
-/* label relocation processing */
-
-void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
- int label_index, long addend)
-{
- TCGLabel *l;
- TCGRelocation *r;
-
- l = &s->labels[label_index];
- if (l->has_value) {
- /* FIXME: This may break relocations on RISC targets that
- modify instruction fields in place. The caller may not have
- written the initial value. */
- patch_reloc(code_ptr, type, l->u.value, addend);
- } else {
- /* add a new relocation entry */
- r = tcg_malloc(sizeof(TCGRelocation));
- r->type = type;
- r->ptr = code_ptr;
- r->addend = addend;
- r->next = l->u.first_reloc;
- l->u.first_reloc = r;
- }
-}
-
-static void tcg_out_label(TCGContext *s, int label_index,
- tcg_target_long value)
-{
- TCGLabel *l;
- TCGRelocation *r;
-
- l = &s->labels[label_index];
- if (l->has_value)
- tcg_abort();
- r = l->u.first_reloc;
- while (r != NULL) {
- patch_reloc(r->ptr, r->type, value, r->addend);
- r = r->next;
- }
- l->has_value = 1;
- l->u.value = value;
-}
-
-int gen_new_label(void)
-{
- TCGContext *s = &tcg_ctx;
- int idx;
- TCGLabel *l;
-
- if (s->nb_labels >= TCG_MAX_LABELS)
- tcg_abort();
- idx = s->nb_labels++;
- l = &s->labels[idx];
- l->has_value = 0;
- l->u.first_reloc = NULL;
- return idx;
-}
-
-#include "tcg-target.c"
-
-/* pool based memory allocation */
-void *tcg_malloc_internal(TCGContext *s, int size)
-{
- TCGPool *p;
- int pool_size;
-
- if (size > TCG_POOL_CHUNK_SIZE) {
- /* big malloc: insert a new pool (XXX: could optimize) */
- p = qemu_malloc(sizeof(TCGPool) + size);
- p->size = size;
- if (s->pool_current)
- s->pool_current->next = p;
- else
- s->pool_first = p;
- p->next = s->pool_current;
- } else {
- p = s->pool_current;
- if (!p) {
- p = s->pool_first;
- if (!p)
- goto new_pool;
- } else {
- if (!p->next) {
- new_pool:
- pool_size = TCG_POOL_CHUNK_SIZE;
- p = qemu_malloc(sizeof(TCGPool) + pool_size);
- p->size = pool_size;
- p->next = NULL;
- if (s->pool_current)
- s->pool_current->next = p;
- else
- s->pool_first = p;
- } else {
- p = p->next;
- }
- }
- }
- s->pool_current = p;
- s->pool_cur = p->data + size;
- s->pool_end = p->data + p->size;
- return p->data;
-}
-
-void tcg_pool_reset(TCGContext *s)
-{
- s->pool_cur = s->pool_end = NULL;
- s->pool_current = NULL;
-}
-
-void tcg_context_init(TCGContext *s)
-{
- int op, total_args, n;
- TCGOpDef *def;
- TCGArgConstraint *args_ct;
- int *sorted_args;
-
- memset(s, 0, sizeof(*s));
- s->temps = s->static_temps;
- s->nb_globals = 0;
-
- /* Count total number of arguments and allocate the corresponding
- space */
- total_args = 0;
- for(op = 0; op < NB_OPS; op++) {
- def = &tcg_op_defs[op];
- n = def->nb_iargs + def->nb_oargs;
- total_args += n;
- }
-
- args_ct = qemu_malloc(sizeof(TCGArgConstraint) * total_args);
- sorted_args = qemu_malloc(sizeof(int) * total_args);
-
- for(op = 0; op < NB_OPS; op++) {
- def = &tcg_op_defs[op];
- def->args_ct = args_ct;
- def->sorted_args = sorted_args;
- n = def->nb_iargs + def->nb_oargs;
- sorted_args += n;
- args_ct += n;
- }
-
- tcg_target_init(s);
-
- /* init global prologue and epilogue */
- s->code_buf = code_gen_prologue;
- s->code_ptr = s->code_buf;
- tcg_target_qemu_prologue(s);
- flush_icache_range((unsigned long)s->code_buf,
- (unsigned long)s->code_ptr);
-}
-
-void tcg_set_frame(TCGContext *s, int reg,
- tcg_target_long start, tcg_target_long size)
-{
- s->frame_start = start;
- s->frame_end = start + size;
- s->frame_reg = reg;
-}
-
-void tcg_func_start(TCGContext *s)
-{
- int i;
- tcg_pool_reset(s);
- s->nb_temps = s->nb_globals;
- for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
- s->first_free_temp[i] = -1;
- s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
- s->nb_labels = 0;
- s->current_frame_offset = s->frame_start;
-
- gen_opc_ptr = gen_opc_buf;
- gen_opparam_ptr = gen_opparam_buf;
-}
-
-static inline void tcg_temp_alloc(TCGContext *s, int n)
-{
- if (n > TCG_MAX_TEMPS)
- tcg_abort();
-}
-
-TCGv tcg_global_reg_new(TCGType type, int reg, const char *name)
-{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx;
-
-#if TCG_TARGET_REG_BITS == 32
- if (type != TCG_TYPE_I32)
- tcg_abort();
-#endif
- if (tcg_regset_test_reg(s->reserved_regs, reg))
- tcg_abort();
- idx = s->nb_globals;
- tcg_temp_alloc(s, s->nb_globals + 1);
- ts = &s->temps[s->nb_globals];
- ts->base_type = type;
- ts->type = type;
- ts->fixed_reg = 1;
- ts->reg = reg;
- ts->name = name;
- s->nb_globals++;
- tcg_regset_set_reg(s->reserved_regs, reg);
- return MAKE_TCGV(idx);
-}
-
-#if TCG_TARGET_REG_BITS == 32
-/* temporary hack to avoid register shortage for tcg_qemu_st64() */
-TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
- const char *name)
-{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx;
- char buf[64];
-
- if (type != TCG_TYPE_I64)
- tcg_abort();
- idx = s->nb_globals;
- tcg_temp_alloc(s, s->nb_globals + 2);
- ts = &s->temps[s->nb_globals];
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 1;
- ts->reg = reg1;
- pstrcpy(buf, sizeof(buf), name);
- pstrcat(buf, sizeof(buf), "_0");
- ts->name = strdup(buf);
-
- ts++;
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 1;
- ts->reg = reg2;
- pstrcpy(buf, sizeof(buf), name);
- pstrcat(buf, sizeof(buf), "_1");
- ts->name = strdup(buf);
-
- s->nb_globals += 2;
- return MAKE_TCGV(idx);
-}
-#endif
-
-TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
- const char *name)
-{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx;
-
- idx = s->nb_globals;
-#if TCG_TARGET_REG_BITS == 32
- if (type == TCG_TYPE_I64) {
- char buf[64];
- tcg_temp_alloc(s, s->nb_globals + 2);
- ts = &s->temps[s->nb_globals];
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 0;
- ts->mem_allocated = 1;
- ts->mem_reg = reg;
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- ts->mem_offset = offset + 4;
-#else
- ts->mem_offset = offset;
-#endif
- pstrcpy(buf, sizeof(buf), name);
- pstrcat(buf, sizeof(buf), "_0");
- ts->name = strdup(buf);
- ts++;
-
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->fixed_reg = 0;
- ts->mem_allocated = 1;
- ts->mem_reg = reg;
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- ts->mem_offset = offset;
-#else
- ts->mem_offset = offset + 4;
-#endif
- pstrcpy(buf, sizeof(buf), name);
- pstrcat(buf, sizeof(buf), "_1");
- ts->name = strdup(buf);
-
- s->nb_globals += 2;
- } else
-#endif
- {
- tcg_temp_alloc(s, s->nb_globals + 1);
- ts = &s->temps[s->nb_globals];
- ts->base_type = type;
- ts->type = type;
- ts->fixed_reg = 0;
- ts->mem_allocated = 1;
- ts->mem_reg = reg;
- ts->mem_offset = offset;
- ts->name = name;
- s->nb_globals++;
- }
- return MAKE_TCGV(idx);
-}
-
-TCGv tcg_temp_new_internal(TCGType type, int temp_local)
-{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx, k;
-
- k = type;
- if (temp_local)
- k += TCG_TYPE_COUNT;
- idx = s->first_free_temp[k];
- if (idx != -1) {
- /* There is already an available temp with the
- right type */
- ts = &s->temps[idx];
- s->first_free_temp[k] = ts->next_free_temp;
- ts->temp_allocated = 1;
- assert(ts->temp_local == temp_local);
- } else {
- idx = s->nb_temps;
-#if TCG_TARGET_REG_BITS == 32
- if (type == TCG_TYPE_I64) {
- tcg_temp_alloc(s, s->nb_temps + 2);
- ts = &s->temps[s->nb_temps];
- ts->base_type = type;
- ts->type = TCG_TYPE_I32;
- ts->temp_allocated = 1;
- ts->temp_local = temp_local;
- ts->name = NULL;
- ts++;
- ts->base_type = TCG_TYPE_I32;
- ts->type = TCG_TYPE_I32;
- ts->temp_allocated = 1;
- ts->temp_local = temp_local;
- ts->name = NULL;
- s->nb_temps += 2;
- } else
-#endif
- {
- tcg_temp_alloc(s, s->nb_temps + 1);
- ts = &s->temps[s->nb_temps];
- ts->base_type = type;
- ts->type = type;
- ts->temp_allocated = 1;
- ts->temp_local = temp_local;
- ts->name = NULL;
- s->nb_temps++;
- }
- }
- return MAKE_TCGV(idx);
-}
-
-void tcg_temp_free(TCGv arg)
-{
- TCGContext *s = &tcg_ctx;
- TCGTemp *ts;
- int idx = GET_TCGV(arg);
- int k;
-
- assert(idx >= s->nb_globals && idx < s->nb_temps);
- ts = &s->temps[idx];
- assert(ts->temp_allocated != 0);
- ts->temp_allocated = 0;
- k = ts->base_type;
- if (ts->temp_local)
- k += TCG_TYPE_COUNT;
- ts->next_free_temp = s->first_free_temp[k];
- s->first_free_temp[k] = idx;
-}
-
-
-TCGv tcg_const_i32(int32_t val)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I32);
- tcg_gen_movi_i32(t0, val);
- return t0;
-}
-
-TCGv tcg_const_i64(int64_t val)
-{
- TCGv t0;
- t0 = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_movi_i64(t0, val);
- return t0;
-}
-
-void tcg_register_helper(void *func, const char *name)
-{
- TCGContext *s = &tcg_ctx;
- int n;
- if ((s->nb_helpers + 1) > s->allocated_helpers) {
- n = s->allocated_helpers;
- if (n == 0) {
- n = 4;
- } else {
- n *= 2;
- }
- s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
- s->allocated_helpers = n;
- }
- s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
- s->helpers[s->nb_helpers].name = name;
- s->nb_helpers++;
-}
-
-static inline TCGType tcg_get_base_type(TCGContext *s, TCGv arg)
-{
- return s->temps[GET_TCGV(arg)].base_type;
-}
-
-static void tcg_gen_call_internal(TCGContext *s, TCGv func,
- unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *params)
-{
- int i;
- *gen_opc_ptr++ = INDEX_op_call;
- *gen_opparam_ptr++ = (nb_rets << 16) | (nb_params + 1);
- for(i = 0; i < nb_rets; i++) {
- *gen_opparam_ptr++ = GET_TCGV(rets[i]);
- }
- for(i = 0; i < nb_params; i++) {
- *gen_opparam_ptr++ = GET_TCGV(params[i]);
- }
- *gen_opparam_ptr++ = GET_TCGV(func);
-
- *gen_opparam_ptr++ = flags;
- /* total parameters, needed to go backward in the instruction stream */
- *gen_opparam_ptr++ = 1 + nb_rets + nb_params + 3;
-}
-
-
-#if TCG_TARGET_REG_BITS < 64
-/* Note: we convert the 64 bit args to 32 bit and do some alignment
- and endian swap. Maybe it would be better to do the alignment
- and endian swap in tcg_reg_alloc_call(). */
-void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *args1)
-{
- TCGv ret, *args2, rets_2[2], arg;
- int j, i, call_type;
-
- if (nb_rets == 1) {
- ret = rets[0];
- if (tcg_get_base_type(s, ret) == TCG_TYPE_I64) {
- nb_rets = 2;
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- rets_2[0] = TCGV_HIGH(ret);
- rets_2[1] = ret;
-#else
- rets_2[0] = ret;
- rets_2[1] = TCGV_HIGH(ret);
-#endif
- rets = rets_2;
- }
- }
- args2 = alloca((nb_params * 3) * sizeof(TCGv));
- j = 0;
- call_type = (flags & TCG_CALL_TYPE_MASK);
- for(i = 0; i < nb_params; i++) {
- arg = args1[i];
- if (tcg_get_base_type(s, arg) == TCG_TYPE_I64) {
-#ifdef TCG_TARGET_I386
- /* REGPARM case: if the third parameter is 64 bit, it is
- allocated on the stack */
- if (j == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
- call_type = TCG_CALL_TYPE_REGPARM_2;
- flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
- }
- args2[j++] = arg;
- args2[j++] = TCGV_HIGH(arg);
-#else
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
- /* some targets want aligned 64 bit args */
- if (j & 1) {
- args2[j++] = TCG_CALL_DUMMY_ARG;
- }
-#endif
-#ifdef TCG_TARGET_WORDS_BIGENDIAN
- args2[j++] = TCGV_HIGH(arg);
- args2[j++] = arg;
-#else
- args2[j++] = arg;
- args2[j++] = TCGV_HIGH(arg);
-#endif
-#endif
- } else {
- args2[j++] = arg;
- }
- }
- tcg_gen_call_internal(s, func, flags,
- nb_rets, rets, j, args2);
-}
-#else
-void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *args1)
-{
- tcg_gen_call_internal(s, func, flags,
- nb_rets, rets, nb_params, args1);
-}
-#endif
-
-#if TCG_TARGET_REG_BITS == 32
-void tcg_gen_shifti_i64(TCGv ret, TCGv arg1,
- int c, int right, int arith)
-{
- if (c == 0) {
- tcg_gen_mov_i32(ret, arg1);
- tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
- } else if (c >= 32) {
- c -= 32;
- if (right) {
- if (arith) {
- tcg_gen_sari_i32(ret, TCGV_HIGH(arg1), c);
- tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
- } else {
- tcg_gen_shri_i32(ret, TCGV_HIGH(arg1), c);
- tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
- }
- } else {
- tcg_gen_shli_i32(TCGV_HIGH(ret), arg1, c);
- tcg_gen_movi_i32(ret, 0);
- }
- } else {
- TCGv t0, t1;
-
- t0 = tcg_temp_new(TCG_TYPE_I32);
- t1 = tcg_temp_new(TCG_TYPE_I32);
- if (right) {
- tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
- if (arith)
- tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
- else
- tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
- tcg_gen_shri_i32(ret, arg1, c);
- tcg_gen_or_i32(ret, ret, t0);
- tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
- } else {
- tcg_gen_shri_i32(t0, arg1, 32 - c);
- /* Note: ret can be the same as arg1, so we use t1 */
- tcg_gen_shli_i32(t1, arg1, c);
- tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
- tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
- tcg_gen_mov_i32(ret, t1);
- }
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- }
-}
-#endif
-
-static void tcg_reg_alloc_start(TCGContext *s)
-{
- int i;
- TCGTemp *ts;
- for(i = 0; i < s->nb_globals; i++) {
- ts = &s->temps[i];
- if (ts->fixed_reg) {
- ts->val_type = TEMP_VAL_REG;
- } else {
- ts->val_type = TEMP_VAL_MEM;
- }
- }
- for(i = s->nb_globals; i < s->nb_temps; i++) {
- ts = &s->temps[i];
- ts->val_type = TEMP_VAL_DEAD;
- ts->mem_allocated = 0;
- ts->fixed_reg = 0;
- }
- for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
- s->reg_to_temp[i] = -1;
- }
-}
-
-static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
- int idx)
-{
- TCGTemp *ts;
-
- ts = &s->temps[idx];
- if (idx < s->nb_globals) {
- pstrcpy(buf, buf_size, ts->name);
- } else {
- if (ts->temp_local)
- snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
- else
- snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
- }
- return buf;
-}
-
-char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg)
-{
- return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV(arg));
-}
-
-static int helper_cmp(const void *p1, const void *p2)
-{
- const TCGHelperInfo *th1 = p1;
- const TCGHelperInfo *th2 = p2;
- if (th1->func < th2->func)
- return -1;
- else if (th1->func == th2->func)
- return 0;
- else
- return 1;
-}
-
-/* find helper definition (Note: A hash table would be better) */
-static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
-{
- int m, m_min, m_max;
- TCGHelperInfo *th;
- tcg_target_ulong v;
-
- if (unlikely(!s->helpers_sorted)) {
- qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
- helper_cmp);
- s->helpers_sorted = 1;
- }
-
- /* binary search */
- m_min = 0;
- m_max = s->nb_helpers - 1;
- while (m_min <= m_max) {
- m = (m_min + m_max) >> 1;
- th = &s->helpers[m];
- v = th->func;
- if (v == val)
- return th;
- else if (val < v) {
- m_max = m - 1;
- } else {
- m_min = m + 1;
- }
- }
- return NULL;
-}
-
-static const char * const cond_name[] =
-{
- [TCG_COND_EQ] = "eq",
- [TCG_COND_NE] = "ne",
- [TCG_COND_LT] = "lt",
- [TCG_COND_GE] = "ge",
- [TCG_COND_LE] = "le",
- [TCG_COND_GT] = "gt",
- [TCG_COND_LTU] = "ltu",
- [TCG_COND_GEU] = "geu",
- [TCG_COND_LEU] = "leu",
- [TCG_COND_GTU] = "gtu"
-};
-
-void tcg_dump_ops(TCGContext *s, FILE *outfile)
-{
- const uint16_t *opc_ptr;
- const TCGArg *args;
- TCGArg arg;
- int c, i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
- const TCGOpDef *def;
- char buf[128];
-
- first_insn = 1;
- opc_ptr = gen_opc_buf;
- args = gen_opparam_buf;
- while (opc_ptr < gen_opc_ptr) {
- c = *opc_ptr++;
- def = &tcg_op_defs[c];
- if (c == INDEX_op_debug_insn_start) {
- uint64_t pc;
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
- pc = ((uint64_t)args[1] << 32) | args[0];
-#else
- pc = args[0];
-#endif
- if (!first_insn)
- fprintf(outfile, "\n");
- fprintf(outfile, " ---- 0x%" PRIx64, pc);
- first_insn = 0;
- nb_oargs = def->nb_oargs;
- nb_iargs = def->nb_iargs;
- nb_cargs = def->nb_cargs;
- } else if (c == INDEX_op_call) {
- TCGArg arg;
-
- /* variable number of arguments */
- arg = *args++;
- nb_oargs = arg >> 16;
- nb_iargs = arg & 0xffff;
- nb_cargs = def->nb_cargs;
-
- fprintf(outfile, " %s ", def->name);
-
- /* function name */
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
- /* flags */
- fprintf(outfile, ",$0x%" TCG_PRIlx,
- args[nb_oargs + nb_iargs]);
- /* nb out args */
- fprintf(outfile, ",$%d", nb_oargs);
- for(i = 0; i < nb_oargs; i++) {
- fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
- }
- for(i = 0; i < (nb_iargs - 1); i++) {
- fprintf(outfile, ",");
- if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
- fprintf(outfile, "<dummy>");
- } else {
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
- }
- }
- } else if (c == INDEX_op_movi_i32
-#if TCG_TARGET_REG_BITS == 64
- || c == INDEX_op_movi_i64
-#endif
- ) {
- tcg_target_ulong val;
- TCGHelperInfo *th;
-
- nb_oargs = def->nb_oargs;
- nb_iargs = def->nb_iargs;
- nb_cargs = def->nb_cargs;
- fprintf(outfile, " %s %s,$", def->name,
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
- val = args[1];
- th = tcg_find_helper(s, val);
- if (th) {
- fprintf(outfile, th->name);
- } else {
- if (c == INDEX_op_movi_i32)
- fprintf(outfile, "0x%x", (uint32_t)val);
- else
- fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
- }
- } else {
- fprintf(outfile, " %s ", def->name);
- if (c == INDEX_op_nopn) {
- /* variable number of arguments */
- nb_cargs = *args;
- nb_oargs = 0;
- nb_iargs = 0;
- } else {
- nb_oargs = def->nb_oargs;
- nb_iargs = def->nb_iargs;
- nb_cargs = def->nb_cargs;
- }
-
- k = 0;
- for(i = 0; i < nb_oargs; i++) {
- if (k != 0)
- fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
- }
- for(i = 0; i < nb_iargs; i++) {
- if (k != 0)
- fprintf(outfile, ",");
- fprintf(outfile, "%s",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
- }
- if (c == INDEX_op_brcond_i32
-#if TCG_TARGET_REG_BITS == 32
- || c == INDEX_op_brcond2_i32
-#elif TCG_TARGET_REG_BITS == 64
- || c == INDEX_op_brcond_i64
-#endif
- ) {
- if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
- fprintf(outfile, ",%s", cond_name[args[k++]]);
- else
- fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
- i = 1;
- }
- else
- i = 0;
- for(; i < nb_cargs; i++) {
- if (k != 0)
- fprintf(outfile, ",");
- arg = args[k++];
- fprintf(outfile, "$0x%" TCG_PRIlx, arg);
- }
- }
- fprintf(outfile, "\n");
- args += nb_iargs + nb_oargs + nb_cargs;
- }
-}
-
-/* we give more priority to constraints with less registers */
-static int get_constraint_priority(const TCGOpDef *def, int k)
-{
- const TCGArgConstraint *arg_ct;
-
- int i, n;
- arg_ct = &def->args_ct[k];
- if (arg_ct->ct & TCG_CT_ALIAS) {
- /* an alias is equivalent to a single register */
- n = 1;
- } else {
- if (!(arg_ct->ct & TCG_CT_REG))
- return 0;
- n = 0;
- for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
- if (tcg_regset_test_reg(arg_ct->u.regs, i))
- n++;
- }
- }
- return TCG_TARGET_NB_REGS - n + 1;
-}
-
-/* sort from highest priority to lowest */
-static void sort_constraints(TCGOpDef *def, int start, int n)
-{
- int i, j, p1, p2, tmp;
-
- for(i = 0; i < n; i++)
- def->sorted_args[start + i] = start + i;
- if (n <= 1)
- return;
- for(i = 0; i < n - 1; i++) {
- for(j = i + 1; j < n; j++) {
- p1 = get_constraint_priority(def, def->sorted_args[start + i]);
- p2 = get_constraint_priority(def, def->sorted_args[start + j]);
- if (p1 < p2) {
- tmp = def->sorted_args[start + i];
- def->sorted_args[start + i] = def->sorted_args[start + j];
- def->sorted_args[start + j] = tmp;
- }
- }
- }
-}
-
-void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
-{
- int op;
- TCGOpDef *def;
- const char *ct_str;
- int i, nb_args;
-
- for(;;) {
- if (tdefs->op < 0)
- break;
- op = tdefs->op;
- assert(op >= 0 && op < NB_OPS);
- def = &tcg_op_defs[op];
- nb_args = def->nb_iargs + def->nb_oargs;
- for(i = 0; i < nb_args; i++) {
- ct_str = tdefs->args_ct_str[i];
- tcg_regset_clear(def->args_ct[i].u.regs);
- def->args_ct[i].ct = 0;
- if (ct_str[0] >= '0' && ct_str[0] <= '9') {
- int oarg;
- oarg = ct_str[0] - '0';
- assert(oarg < def->nb_oargs);
- assert(def->args_ct[oarg].ct & TCG_CT_REG);
- /* TCG_CT_ALIAS is for the output arguments. The input
- argument is tagged with TCG_CT_IALIAS. */
- def->args_ct[i] = def->args_ct[oarg];
- def->args_ct[oarg].ct = TCG_CT_ALIAS;
- def->args_ct[oarg].alias_index = i;
- def->args_ct[i].ct |= TCG_CT_IALIAS;
- def->args_ct[i].alias_index = oarg;
- } else {
- for(;;) {
- if (*ct_str == '\0')
- break;
- switch(*ct_str) {
- case 'i':
- def->args_ct[i].ct |= TCG_CT_CONST;
- ct_str++;
- break;
- default:
- if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
- fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
- ct_str, i, def->name);
- exit(1);
- }
- }
- }
- }
- }
-
- /* sort the constraints (XXX: this is just an heuristic) */
- sort_constraints(def, 0, def->nb_oargs);
- sort_constraints(def, def->nb_oargs, def->nb_iargs);
-
-#if 0
- {
- int i;
-
- printf("%s: sorted=", def->name);
- for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
- printf(" %d", def->sorted_args[i]);
- printf("\n");
- }
-#endif
- tdefs++;
- }
-
-}
-
-#ifdef USE_LIVENESS_ANALYSIS
-
-/* set a nop for an operation using 'nb_args' */
-static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
- TCGArg *args, int nb_args)
-{
- if (nb_args == 0) {
- *opc_ptr = INDEX_op_nop;
- } else {
- *opc_ptr = INDEX_op_nopn;
- args[0] = nb_args;
- args[nb_args - 1] = nb_args;
- }
-}
-
-/* liveness analysis: end of function: globals are live, temps are
- dead. */
-/* XXX: at this stage, not used as there would be little gains because
- most TBs end with a conditional jump. */
-static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
-{
- memset(dead_temps, 0, s->nb_globals);
- memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
-}
-
-/* liveness analysis: end of basic block: globals are live, temps are
- dead, local temps are live. */
-static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
-{
- int i;
- TCGTemp *ts;
-
- memset(dead_temps, 0, s->nb_globals);
- ts = &s->temps[s->nb_globals];
- for(i = s->nb_globals; i < s->nb_temps; i++) {
- if (ts->temp_local)
- dead_temps[i] = 0;
- else
- dead_temps[i] = 1;
- ts++;
- }
-}
-
-/* Liveness analysis : update the opc_dead_iargs array to tell if a
- given input arguments is dead. Instructions updating dead
- temporaries are removed. */
-static void tcg_liveness_analysis(TCGContext *s)
-{
- int i, op_index, op, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
- TCGArg *args;
- const TCGOpDef *def;
- uint8_t *dead_temps;
- unsigned int dead_iargs;
-
- gen_opc_ptr++; /* skip end */
-
- nb_ops = gen_opc_ptr - gen_opc_buf;
-
- /* XXX: make it really dynamic */
- s->op_dead_iargs = tcg_malloc(OPC_BUF_SIZE * sizeof(uint16_t));
-
- dead_temps = tcg_malloc(s->nb_temps);
- memset(dead_temps, 1, s->nb_temps);
-
- args = gen_opparam_ptr;
- op_index = nb_ops - 1;
- while (op_index >= 0) {
- op = gen_opc_buf[op_index];
- def = &tcg_op_defs[op];
- switch(op) {
- case INDEX_op_call:
- {
- int call_flags;
-
- nb_args = args[-1];
- args -= nb_args;
- nb_iargs = args[0] & 0xffff;
- nb_oargs = args[0] >> 16;
- args++;
- call_flags = args[nb_oargs + nb_iargs];
-
- /* pure functions can be removed if their result is not
- used */
- if (call_flags & TCG_CALL_PURE) {
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- if (!dead_temps[arg])
- goto do_not_remove_call;
- }
- tcg_set_nop(s, gen_opc_buf + op_index,
- args - 1, nb_args);
- } else {
- do_not_remove_call:
-
- /* output args are dead */
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- dead_temps[arg] = 1;
- }
-
- /* globals are live (they may be used by the call) */
- memset(dead_temps, 0, s->nb_globals);
-
- /* input args are live */
- dead_iargs = 0;
- for(i = 0; i < nb_iargs; i++) {
- arg = args[i + nb_oargs];
- if (arg != TCG_CALL_DUMMY_ARG) {
- if (dead_temps[arg]) {
- dead_iargs |= (1 << i);
- }
- dead_temps[arg] = 0;
- }
- }
- s->op_dead_iargs[op_index] = dead_iargs;
- }
- args--;
- }
- break;
- case INDEX_op_set_label:
- args--;
- /* mark end of basic block */
- tcg_la_bb_end(s, dead_temps);
- break;
- case INDEX_op_debug_insn_start:
- args -= def->nb_args;
- break;
- case INDEX_op_nopn:
- nb_args = args[-1];
- args -= nb_args;
- break;
- case INDEX_op_discard:
- args--;
- /* mark the temporary as dead */
- dead_temps[args[0]] = 1;
- break;
- case INDEX_op_end:
- break;
- /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
- default:
- if (op > INDEX_op_end) {
- args -= def->nb_args;
- nb_iargs = def->nb_iargs;
- nb_oargs = def->nb_oargs;
-
- /* Test if the operation can be removed because all
- its outputs are dead. We assume that nb_oargs == 0
- implies side effects */
- if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- if (!dead_temps[arg])
- goto do_not_remove;
- }
- tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
-#ifdef CONFIG_PROFILER
- s->del_op_count++;
-#endif
- } else {
- do_not_remove:
-
- /* output args are dead */
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- dead_temps[arg] = 1;
- }
-
- /* if end of basic block, update */
- if (def->flags & TCG_OPF_BB_END) {
- tcg_la_bb_end(s, dead_temps);
- } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
- /* globals are live */
- memset(dead_temps, 0, s->nb_globals);
- }
-
- /* input args are live */
- dead_iargs = 0;
- for(i = 0; i < nb_iargs; i++) {
- arg = args[i + nb_oargs];
- if (dead_temps[arg]) {
- dead_iargs |= (1 << i);
- }
- dead_temps[arg] = 0;
- }
- s->op_dead_iargs[op_index] = dead_iargs;
- }
- } else {
- /* legacy dyngen operations */
- args -= def->nb_args;
- /* mark end of basic block */
- tcg_la_bb_end(s, dead_temps);
- }
- break;
- }
- op_index--;
- }
-
- if (args != gen_opparam_buf)
- tcg_abort();
-}
-#else
-/* dummy liveness analysis */
-void tcg_liveness_analysis(TCGContext *s)
-{
- int nb_ops;
- nb_ops = gen_opc_ptr - gen_opc_buf;
-
- s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
- memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
-}
-#endif
-
-#ifndef NDEBUG
-static void dump_regs(TCGContext *s)
-{
- TCGTemp *ts;
- int i;
- char buf[64];
-
- for(i = 0; i < s->nb_temps; i++) {
- ts = &s->temps[i];
- printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
- switch(ts->val_type) {
- case TEMP_VAL_REG:
- printf("%s", tcg_target_reg_names[ts->reg]);
- break;
- case TEMP_VAL_MEM:
- printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
- break;
- case TEMP_VAL_CONST:
- printf("$0x%" TCG_PRIlx, ts->val);
- break;
- case TEMP_VAL_DEAD:
- printf("D");
- break;
- default:
- printf("???");
- break;
- }
- printf("\n");
- }
-
- for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
- if (s->reg_to_temp[i] >= 0) {
- printf("%s: %s\n",
- tcg_target_reg_names[i],
- tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
- }
- }
-}
-
-static void check_regs(TCGContext *s)
-{
- int reg, k;
- TCGTemp *ts;
- char buf[64];
-
- for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
- k = s->reg_to_temp[reg];
- if (k >= 0) {
- ts = &s->temps[k];
- if (ts->val_type != TEMP_VAL_REG ||
- ts->reg != reg) {
- printf("Inconsistency for register %s:\n",
- tcg_target_reg_names[reg]);
- goto fail;
- }
- }
- }
- for(k = 0; k < s->nb_temps; k++) {
- ts = &s->temps[k];
- if (ts->val_type == TEMP_VAL_REG &&
- !ts->fixed_reg &&
- s->reg_to_temp[ts->reg] != k) {
- printf("Inconsistency for temp %s:\n",
- tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
- fail:
- printf("reg state:\n");
- dump_regs(s);
- tcg_abort();
- }
- }
-}
-#endif
-
-static void temp_allocate_frame(TCGContext *s, int temp)
-{
- TCGTemp *ts;
- ts = &s->temps[temp];
- s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
- if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
- tcg_abort();
- ts->mem_offset = s->current_frame_offset;
- ts->mem_reg = s->frame_reg;
- ts->mem_allocated = 1;
- s->current_frame_offset += sizeof(tcg_target_long);
-}
-
-/* free register 'reg' by spilling the corresponding temporary if necessary */
-static void tcg_reg_free(TCGContext *s, int reg)
-{
- TCGTemp *ts;
- int temp;
-
- temp = s->reg_to_temp[reg];
- if (temp != -1) {
- ts = &s->temps[temp];
- assert(ts->val_type == TEMP_VAL_REG);
- if (!ts->mem_coherent) {
- if (!ts->mem_allocated)
- temp_allocate_frame(s, temp);
- tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- }
- ts->val_type = TEMP_VAL_MEM;
- s->reg_to_temp[reg] = -1;
- }
-}
-
-/* Allocate a register belonging to reg1 & ~reg2 */
-static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
-{
- int i, reg;
- TCGRegSet reg_ct;
-
- tcg_regset_andnot(reg_ct, reg1, reg2);
-
- /* first try free registers */
- for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
- reg = tcg_target_reg_alloc_order[i];
- if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
- return reg;
- }
-
- /* XXX: do better spill choice */
- for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
- reg = tcg_target_reg_alloc_order[i];
- if (tcg_regset_test_reg(reg_ct, reg)) {
- tcg_reg_free(s, reg);
- return reg;
- }
- }
-
- tcg_abort();
-}
-
-/* save a temporary to memory. 'allocated_regs' is used in case a
- temporary registers needs to be allocated to store a constant. */
-static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
-{
- TCGTemp *ts;
- int reg;
-
- ts = &s->temps[temp];
- if (!ts->fixed_reg) {
- switch(ts->val_type) {
- case TEMP_VAL_REG:
- tcg_reg_free(s, ts->reg);
- break;
- case TEMP_VAL_DEAD:
- ts->val_type = TEMP_VAL_MEM;
- break;
- case TEMP_VAL_CONST:
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- allocated_regs);
- if (!ts->mem_allocated)
- temp_allocate_frame(s, temp);
- tcg_out_movi(s, ts->type, reg, ts->val);
- tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- ts->val_type = TEMP_VAL_MEM;
- break;
- case TEMP_VAL_MEM:
- break;
- default:
- tcg_abort();
- }
- }
-}
-
-/* save globals to their cannonical location and assume they can be
- modified be the following code. 'allocated_regs' is used in case a
- temporary registers needs to be allocated to store a constant. */
-static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
-{
- int i;
-
- for(i = 0; i < s->nb_globals; i++) {
- temp_save(s, i, allocated_regs);
- }
-}
-
-/* at the end of a basic block, we assume all temporaries are dead and
- all globals are stored at their canonical location. */
-static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
-{
- TCGTemp *ts;
- int i;
-
- for(i = s->nb_globals; i < s->nb_temps; i++) {
- ts = &s->temps[i];
- if (ts->temp_local) {
- temp_save(s, i, allocated_regs);
- } else {
- if (ts->val_type == TEMP_VAL_REG) {
- s->reg_to_temp[ts->reg] = -1;
- }
- ts->val_type = TEMP_VAL_DEAD;
- }
- }
-
- save_globals(s, allocated_regs);
-}
-
-#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
-
-static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
-{
- TCGTemp *ots;
- tcg_target_ulong val;
-
- ots = &s->temps[args[0]];
- val = args[1];
-
- if (ots->fixed_reg) {
- /* for fixed registers, we do not do any constant
- propagation */
- tcg_out_movi(s, ots->type, ots->reg, val);
- } else {
- /* The movi is not explicitly generated here */
- if (ots->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ots->reg] = -1;
- ots->val_type = TEMP_VAL_CONST;
- ots->val = val;
- }
-}
-
-static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
- const TCGArg *args,
- unsigned int dead_iargs)
-{
- TCGTemp *ts, *ots;
- int reg;
- const TCGArgConstraint *arg_ct;
-
- ots = &s->temps[args[0]];
- ts = &s->temps[args[1]];
- arg_ct = &def->args_ct[0];
-
- /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
- if (ts->val_type == TEMP_VAL_REG) {
- if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
- /* the mov can be suppressed */
- if (ots->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ots->reg] = -1;
- reg = ts->reg;
- s->reg_to_temp[reg] = -1;
- ts->val_type = TEMP_VAL_DEAD;
- } else {
- if (ots->val_type == TEMP_VAL_REG) {
- reg = ots->reg;
- } else {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
- }
- if (ts->reg != reg) {
- tcg_out_mov(s, reg, ts->reg);
- }
- }
- } else if (ts->val_type == TEMP_VAL_MEM) {
- if (ots->val_type == TEMP_VAL_REG) {
- reg = ots->reg;
- } else {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
- }
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- if (ots->fixed_reg) {
- reg = ots->reg;
- tcg_out_movi(s, ots->type, reg, ts->val);
- } else {
- /* propagate constant */
- if (ots->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ots->reg] = -1;
- ots->val_type = TEMP_VAL_CONST;
- ots->val = ts->val;
- return;
- }
- } else {
- tcg_abort();
- }
- s->reg_to_temp[reg] = args[0];
- ots->reg = reg;
- ots->val_type = TEMP_VAL_REG;
- ots->mem_coherent = 0;
-}
-
-static void tcg_reg_alloc_op(TCGContext *s,
- const TCGOpDef *def, int opc,
- const TCGArg *args,
- unsigned int dead_iargs)
-{
- TCGRegSet allocated_regs;
- int i, k, nb_iargs, nb_oargs, reg;
- TCGArg arg;
- const TCGArgConstraint *arg_ct;
- TCGTemp *ts;
- TCGArg new_args[TCG_MAX_OP_ARGS];
- int const_args[TCG_MAX_OP_ARGS];
-
- nb_oargs = def->nb_oargs;
- nb_iargs = def->nb_iargs;
-
- /* copy constants */
- memcpy(new_args + nb_oargs + nb_iargs,
- args + nb_oargs + nb_iargs,
- sizeof(TCGArg) * def->nb_cargs);
-
- /* satisfy input constraints */
- tcg_regset_set(allocated_regs, s->reserved_regs);
- for(k = 0; k < nb_iargs; k++) {
- i = def->sorted_args[nb_oargs + k];
- arg = args[i];
- arg_ct = &def->args_ct[i];
- ts = &s->temps[arg];
- if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- ts->mem_coherent = 1;
- s->reg_to_temp[reg] = arg;
- } else if (ts->val_type == TEMP_VAL_CONST) {
- if (tcg_target_const_match(ts->val, arg_ct)) {
- /* constant is OK for instruction */
- const_args[i] = 1;
- new_args[i] = ts->val;
- goto iarg_end;
- } else {
- /* need to move to a register */
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_movi(s, ts->type, reg, ts->val);
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
- }
- }
- assert(ts->val_type == TEMP_VAL_REG);
- if (arg_ct->ct & TCG_CT_IALIAS) {
- if (ts->fixed_reg) {
- /* if fixed register, we must allocate a new register
- if the alias is not the same register */
- if (arg != args[arg_ct->alias_index])
- goto allocate_in_reg;
- } else {
- /* if the input is aliased to an output and if it is
- not dead after the instruction, we must allocate
- a new register and move it */
- if (!IS_DEAD_IARG(i - nb_oargs))
- goto allocate_in_reg;
- }
- }
- reg = ts->reg;
- if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
- /* nothing to do : the constraint is satisfied */
- } else {
- allocate_in_reg:
- /* allocate a new register matching the constraint
- and move the temporary register into it */
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_mov(s, reg, ts->reg);
- }
- new_args[i] = reg;
- const_args[i] = 0;
- tcg_regset_set_reg(allocated_regs, reg);
- iarg_end: ;
- }
-
- if (def->flags & TCG_OPF_BB_END) {
- tcg_reg_alloc_bb_end(s, allocated_regs);
- } else {
- /* mark dead temporaries and free the associated registers */
- for(i = 0; i < nb_iargs; i++) {
- arg = args[nb_oargs + i];
- if (IS_DEAD_IARG(i)) {
- ts = &s->temps[arg];
- if (!ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_DEAD;
- }
- }
- }
-
- if (def->flags & TCG_OPF_CALL_CLOBBER) {
- /* XXX: permit generic clobber register list ? */
- for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
- if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
- tcg_reg_free(s, reg);
- }
- }
- /* XXX: for load/store we could do that only for the slow path
- (i.e. when a memory callback is called) */
-
- /* store globals and free associated registers (we assume the insn
- can modify any global. */
- save_globals(s, allocated_regs);
- }
-
- /* satisfy the output constraints */
- tcg_regset_set(allocated_regs, s->reserved_regs);
- for(k = 0; k < nb_oargs; k++) {
- i = def->sorted_args[k];
- arg = args[i];
- arg_ct = &def->args_ct[i];
- ts = &s->temps[arg];
- if (arg_ct->ct & TCG_CT_ALIAS) {
- reg = new_args[arg_ct->alias_index];
- } else {
- /* if fixed register, we try to use it */
- reg = ts->reg;
- if (ts->fixed_reg &&
- tcg_regset_test_reg(arg_ct->u.regs, reg)) {
- goto oarg_end;
- }
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- }
- tcg_regset_set_reg(allocated_regs, reg);
- /* if a fixed register is used, then a move will be done afterwards */
- if (!ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- /* temp value is modified, so the value kept in memory is
- potentially not the same */
- ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
- }
- oarg_end:
- new_args[i] = reg;
- }
- }
-
- /* emit instruction */
- tcg_out_op(s, opc, new_args, const_args);
-
- /* move the outputs in the correct register if needed */
- for(i = 0; i < nb_oargs; i++) {
- ts = &s->temps[args[i]];
- reg = new_args[i];
- if (ts->fixed_reg && ts->reg != reg) {
- tcg_out_mov(s, ts->reg, reg);
- }
- }
-}
-
-#ifdef TCG_TARGET_STACK_GROWSUP
-#define STACK_DIR(x) (-(x))
-#else
-#define STACK_DIR(x) (x)
-#endif
-
-static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
- int opc, const TCGArg *args,
- unsigned int dead_iargs)
-{
- int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
- TCGArg arg, func_arg;
- TCGTemp *ts;
- tcg_target_long stack_offset, call_stack_size, func_addr;
- int const_func_arg, allocate_args;
- TCGRegSet allocated_regs;
- const TCGArgConstraint *arg_ct;
-
- arg = *args++;
-
- nb_oargs = arg >> 16;
- nb_iargs = arg & 0xffff;
- nb_params = nb_iargs - 1;
-
- flags = args[nb_oargs + nb_iargs];
-
- nb_regs = tcg_target_get_call_iarg_regs_count(flags);
- if (nb_regs > nb_params)
- nb_regs = nb_params;
-
- /* assign stack slots first */
- /* XXX: preallocate call stack */
- call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
- call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
- ~(TCG_TARGET_STACK_ALIGN - 1);
- allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
- if (allocate_args) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
- }
-
- stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
- for(i = nb_regs; i < nb_params; i++) {
- arg = args[nb_oargs + i];
-#ifdef TCG_TARGET_STACK_GROWSUP
- stack_offset -= sizeof(tcg_target_long);
-#endif
- if (arg != TCG_CALL_DUMMY_ARG) {
- ts = &s->temps[arg];
- if (ts->val_type == TEMP_VAL_REG) {
- tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
- } else if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- s->reserved_regs);
- /* XXX: not correct if reading values from the stack */
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
- s->reserved_regs);
- /* XXX: sign extend may be needed on some targets */
- tcg_out_movi(s, ts->type, reg, ts->val);
- tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
- } else {
- tcg_abort();
- }
- }
-#ifndef TCG_TARGET_STACK_GROWSUP
- stack_offset += sizeof(tcg_target_long);
-#endif
- }
-
- /* assign input registers */
- tcg_regset_set(allocated_regs, s->reserved_regs);
- for(i = 0; i < nb_regs; i++) {
- arg = args[nb_oargs + i];
- if (arg != TCG_CALL_DUMMY_ARG) {
- ts = &s->temps[arg];
- reg = tcg_target_call_iarg_regs[i];
- tcg_reg_free(s, reg);
- if (ts->val_type == TEMP_VAL_REG) {
- if (ts->reg != reg) {
- tcg_out_mov(s, reg, ts->reg);
- }
- } else if (ts->val_type == TEMP_VAL_MEM) {
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- /* XXX: sign extend ? */
- tcg_out_movi(s, ts->type, reg, ts->val);
- } else {
- tcg_abort();
- }
- tcg_regset_set_reg(allocated_regs, reg);
- }
- }
-
- /* assign function address */
- func_arg = args[nb_oargs + nb_iargs - 1];
- arg_ct = &def->args_ct[0];
- ts = &s->temps[func_arg];
- func_addr = ts->val;
- const_func_arg = 0;
- if (ts->val_type == TEMP_VAL_MEM) {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
- func_arg = reg;
- tcg_regset_set_reg(allocated_regs, reg);
- } else if (ts->val_type == TEMP_VAL_REG) {
- reg = ts->reg;
- if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_mov(s, reg, ts->reg);
- }
- func_arg = reg;
- tcg_regset_set_reg(allocated_regs, reg);
- } else if (ts->val_type == TEMP_VAL_CONST) {
- if (tcg_target_const_match(func_addr, arg_ct)) {
- const_func_arg = 1;
- func_arg = func_addr;
- } else {
- reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
- tcg_out_movi(s, ts->type, reg, func_addr);
- func_arg = reg;
- tcg_regset_set_reg(allocated_regs, reg);
- }
- } else {
- tcg_abort();
- }
-
-
- /* mark dead temporaries and free the associated registers */
- for(i = 0; i < nb_iargs; i++) {
- arg = args[nb_oargs + i];
- if (IS_DEAD_IARG(i)) {
- ts = &s->temps[arg];
- if (!ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_DEAD;
- }
- }
- }
-
- /* clobber call registers */
- for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
- if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
- tcg_reg_free(s, reg);
- }
- }
-
- /* store globals and free associated registers (we assume the call
- can modify any global. */
- save_globals(s, allocated_regs);
-
- tcg_out_op(s, opc, &func_arg, &const_func_arg);
-
- if (allocate_args) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
- }
-
- /* assign output registers and emit moves if needed */
- for(i = 0; i < nb_oargs; i++) {
- arg = args[i];
- ts = &s->temps[arg];
- reg = tcg_target_call_oarg_regs[i];
- assert(s->reg_to_temp[reg] == -1);
- if (ts->fixed_reg) {
- if (ts->reg != reg) {
- tcg_out_mov(s, ts->reg, reg);
- }
- } else {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_REG;
- ts->reg = reg;
- ts->mem_coherent = 0;
- s->reg_to_temp[reg] = arg;
- }
- }
-
- return nb_iargs + nb_oargs + def->nb_cargs + 1;
-}
-
-#ifdef CONFIG_PROFILER
-
-static int64_t dyngen_table_op_count[NB_OPS];
-
-void dump_op_count(void)
-{
- int i;
- FILE *f;
- f = fopen("/tmp/op1.log", "w");
- for(i = 0; i < INDEX_op_end; i++) {
- fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
- }
- fclose(f);
- f = fopen("/tmp/op2.log", "w");
- for(i = INDEX_op_end; i < NB_OPS; i++) {
- fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
- }
- fclose(f);
-}
-#endif
-
-
-static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
- long search_pc)
-{
- int opc, op_index;
- const TCGOpDef *def;
- unsigned int dead_iargs;
- const TCGArg *args;
-
-#ifdef DEBUG_DISAS
- if (unlikely(loglevel & CPU_LOG_TB_OP)) {
- fprintf(logfile, "OP:\n");
- tcg_dump_ops(s, logfile);
- fprintf(logfile, "\n");
- }
-#endif
-
-#ifdef CONFIG_PROFILER
- s->la_time -= profile_getclock();
-#endif
- tcg_liveness_analysis(s);
-#ifdef CONFIG_PROFILER
- s->la_time += profile_getclock();
-#endif
-
-#ifdef DEBUG_DISAS
- if (unlikely(loglevel & CPU_LOG_TB_OP_OPT)) {
- fprintf(logfile, "OP after la:\n");
- tcg_dump_ops(s, logfile);
- fprintf(logfile, "\n");
- }
-#endif
-
- tcg_reg_alloc_start(s);
-
- s->code_buf = gen_code_buf;
- s->code_ptr = gen_code_buf;
-
- args = gen_opparam_buf;
- op_index = 0;
-
- for(;;) {
- opc = gen_opc_buf[op_index];
-#ifdef CONFIG_PROFILER
- dyngen_table_op_count[opc]++;
-#endif
- def = &tcg_op_defs[opc];
-#if 0
- printf("%s: %d %d %d\n", def->name,
- def->nb_oargs, def->nb_iargs, def->nb_cargs);
- // dump_regs(s);
-#endif
- switch(opc) {
- case INDEX_op_mov_i32:
-#if TCG_TARGET_REG_BITS == 64
- case INDEX_op_mov_i64:
-#endif
- dead_iargs = s->op_dead_iargs[op_index];
- tcg_reg_alloc_mov(s, def, args, dead_iargs);
- break;
- case INDEX_op_movi_i32:
-#if TCG_TARGET_REG_BITS == 64
- case INDEX_op_movi_i64:
-#endif
- tcg_reg_alloc_movi(s, args);
- break;
- case INDEX_op_debug_insn_start:
- /* debug instruction */
- break;
- case INDEX_op_nop:
- case INDEX_op_nop1:
- case INDEX_op_nop2:
- case INDEX_op_nop3:
- break;
- case INDEX_op_nopn:
- args += args[0];
- goto next;
- case INDEX_op_discard:
- {
- TCGTemp *ts;
- ts = &s->temps[args[0]];
- /* mark the temporary as dead */
- if (!ts->fixed_reg) {
- if (ts->val_type == TEMP_VAL_REG)
- s->reg_to_temp[ts->reg] = -1;
- ts->val_type = TEMP_VAL_DEAD;
- }
- }
- break;
- case INDEX_op_set_label:
- tcg_reg_alloc_bb_end(s, s->reserved_regs);
- tcg_out_label(s, args[0], (long)s->code_ptr);
- break;
- case INDEX_op_call:
- dead_iargs = s->op_dead_iargs[op_index];
- args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
- goto next;
- case INDEX_op_end:
- goto the_end;
-
-#ifdef CONFIG_DYNGEN_OP
- case 0 ... INDEX_op_end - 1:
- /* legacy dyngen ops */
-#ifdef CONFIG_PROFILER
- s->old_op_count++;
-#endif
- tcg_reg_alloc_bb_end(s, s->reserved_regs);
- if (search_pc >= 0) {
- s->code_ptr += def->copy_size;
- args += def->nb_args;
- } else {
- args = dyngen_op(s, opc, args);
- }
- goto next;
-#endif
- default:
- /* Note: in order to speed up the code, it would be much
- faster to have specialized register allocator functions for
- some common argument patterns */
- dead_iargs = s->op_dead_iargs[op_index];
- tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
- break;
- }
- args += def->nb_args;
- next:
- if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
- return op_index;
- }
- op_index++;
-#ifndef NDEBUG
- check_regs(s);
-#endif
- }
- the_end:
- return -1;
-}
-
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
-{
-#ifdef CONFIG_PROFILER
- {
- int n;
- n = (gen_opc_ptr - gen_opc_buf);
- s->op_count += n;
- if (n > s->op_count_max)
- s->op_count_max = n;
-
- s->temp_count += s->nb_temps;
- if (s->nb_temps > s->temp_count_max)
- s->temp_count_max = s->nb_temps;
- }
-#endif
-
- tcg_gen_code_common(s, gen_code_buf, -1);
-
- /* flush instruction cache */
- flush_icache_range((unsigned long)gen_code_buf,
- (unsigned long)s->code_ptr);
- return s->code_ptr - gen_code_buf;
-}
-
-/* Return the index of the micro operation such as the pc after is <
- offset bytes from the start of the TB. The contents of gen_code_buf must
- not be changed, though writing the same values is ok.
- Return -1 if not found. */
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
-{
- return tcg_gen_code_common(s, gen_code_buf, offset);
-}
-
-#ifdef CONFIG_PROFILER
-void tcg_dump_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
- TCGContext *s = &tcg_ctx;
- int64_t tot;
-
- tot = s->interm_time + s->code_time;
- cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
- tot, tot / 2.4e9);
- cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
- s->tb_count,
- s->tb_count1 - s->tb_count,
- s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
- cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
- s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
- cpu_fprintf(f, "old ops/total ops %0.1f%%\n",
- s->op_count ? (double)s->old_op_count / s->op_count * 100.0 : 0);
- cpu_fprintf(f, "deleted ops/TB %0.2f\n",
- s->tb_count ?
- (double)s->del_op_count / s->tb_count : 0);
- cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
- s->tb_count ?
- (double)s->temp_count / s->tb_count : 0,
- s->temp_count_max);
-
- cpu_fprintf(f, "cycles/op %0.1f\n",
- s->op_count ? (double)tot / s->op_count : 0);
- cpu_fprintf(f, "cycles/in byte %0.1f\n",
- s->code_in_len ? (double)tot / s->code_in_len : 0);
- cpu_fprintf(f, "cycles/out byte %0.1f\n",
- s->code_out_len ? (double)tot / s->code_out_len : 0);
- if (tot == 0)
- tot = 1;
- cpu_fprintf(f, " gen_interm time %0.1f%%\n",
- (double)s->interm_time / tot * 100.0);
- cpu_fprintf(f, " gen_code time %0.1f%%\n",
- (double)s->code_time / tot * 100.0);
- cpu_fprintf(f, "liveness/code time %0.1f%%\n",
- (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
- cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
- s->restore_count);
- cpu_fprintf(f, " avg cycles %0.1f\n",
- s->restore_count ? (double)s->restore_time / s->restore_count : 0);
- {
- extern void dump_op_count(void);
- dump_op_count();
- }
-}
-#else
-void tcg_dump_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
-{
- cpu_fprintf(f, "[TCG profiler not compiled]\n");
-}
-#endif
diff --git a/tcg/tcg.h b/tcg/tcg.h
deleted file mode 100644
index bc5b902..0000000
--- a/tcg/tcg.h
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "tcg-target.h"
-
-#if TCG_TARGET_REG_BITS == 32
-typedef int32_t tcg_target_long;
-typedef uint32_t tcg_target_ulong;
-#define TCG_PRIlx PRIx32
-#define TCG_PRIld PRId32
-#elif TCG_TARGET_REG_BITS == 64
-typedef int64_t tcg_target_long;
-typedef uint64_t tcg_target_ulong;
-#define TCG_PRIlx PRIx64
-#define TCG_PRIld PRId64
-#else
-#error unsupported
-#endif
-
-#if TCG_TARGET_NB_REGS <= 32
-typedef uint32_t TCGRegSet;
-#elif TCG_TARGET_NB_REGS <= 64
-typedef uint64_t TCGRegSet;
-#else
-#error unsupported
-#endif
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "tcg-opc.h"
-#undef DEF
- NB_OPS,
-};
-
-#define tcg_regset_clear(d) (d) = 0
-#define tcg_regset_set(d, s) (d) = (s)
-#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
-#define tcg_regset_set_reg(d, r) (d) |= 1 << (r)
-#define tcg_regset_reset_reg(d, r) (d) &= ~(1 << (r))
-#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
-#define tcg_regset_or(d, a, b) (d) = (a) | (b)
-#define tcg_regset_and(d, a, b) (d) = (a) & (b)
-#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
-#define tcg_regset_not(d, a) (d) = ~(a)
-
-typedef struct TCGRelocation {
- struct TCGRelocation *next;
- int type;
- uint8_t *ptr;
- tcg_target_long addend;
-} TCGRelocation;
-
-typedef struct TCGLabel {
- int has_value;
- union {
- tcg_target_ulong value;
- TCGRelocation *first_reloc;
- } u;
-} TCGLabel;
-
-typedef struct TCGPool {
- struct TCGPool *next;
- int size;
- uint8_t data[0] __attribute__ ((aligned));
-} TCGPool;
-
-#define TCG_POOL_CHUNK_SIZE 32768
-
-#define TCG_MAX_LABELS 512
-
-#define TCG_MAX_TEMPS 512
-
-/* when the size of the arguments of a called function is smaller than
- this value, they are statically allocated in the TB stack frame */
-#define TCG_STATIC_CALL_ARGS_SIZE 128
-
-typedef int TCGType;
-
-#define TCG_TYPE_I32 0
-#define TCG_TYPE_I64 1
-#define TCG_TYPE_COUNT 2 /* number of different types */
-
-#if TCG_TARGET_REG_BITS == 32
-#define TCG_TYPE_PTR TCG_TYPE_I32
-#else
-#define TCG_TYPE_PTR TCG_TYPE_I64
-#endif
-
-typedef tcg_target_ulong TCGArg;
-
-/* Define a type and accessor macros for varables. Using a struct is
- nice because it gives some level of type safely. Ideally the compiler
- be able to see through all this. However in practice this is not true,
- expecially on targets with braindamaged ABIs (e.g. i386).
- We use plain int by default to avoid this runtime overhead.
- Users of tcg_gen_* don't need to know about any of this, and should
- treat TCGv as an opaque type. */
-
-//#define DEBUG_TCGV 1
-
-#ifdef DEBUG_TCGV
-
-typedef struct
-{
- int n;
-} TCGv;
-
-#define MAKE_TCGV(i) __extension__ \
- ({ TCGv make_tcgv_tmp = {i}; make_tcgv_tmp;})
-#define GET_TCGV(t) ((t).n)
-#if TCG_TARGET_REG_BITS == 32
-#define TCGV_HIGH(t) MAKE_TCGV(GET_TCGV(t) + 1)
-#endif
-
-#else /* !DEBUG_TCGV */
-
-typedef int TCGv;
-#define MAKE_TCGV(x) (x)
-#define GET_TCGV(t) (t)
-#if TCG_TARGET_REG_BITS == 32
-#define TCGV_HIGH(t) ((t) + 1)
-#endif
-
-#endif /* DEBUG_TCGV */
-
-/* Dummy definition to avoid compiler warnings. */
-#define TCGV_UNUSED(x) x = MAKE_TCGV(-1)
-
-/* call flags */
-#define TCG_CALL_TYPE_MASK 0x000f
-#define TCG_CALL_TYPE_STD 0x0000 /* standard C call */
-#define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
-#define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
-#define TCG_CALL_TYPE_REGPARM 0x0003 /* i386 style regparm call (3 regs) */
-/* A pure function only reads its arguments and globals variables and
- cannot raise exceptions. Hence a call to a pure function can be
- safely suppressed if the return value is not used. */
-#define TCG_CALL_PURE 0x0010
-
-/* used to align parameters */
-#define TCG_CALL_DUMMY_TCGV MAKE_TCGV(-1)
-#define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
-
-typedef enum {
- TCG_COND_EQ,
- TCG_COND_NE,
- TCG_COND_LT,
- TCG_COND_GE,
- TCG_COND_LE,
- TCG_COND_GT,
- /* unsigned */
- TCG_COND_LTU,
- TCG_COND_GEU,
- TCG_COND_LEU,
- TCG_COND_GTU,
-} TCGCond;
-
-#define TEMP_VAL_DEAD 0
-#define TEMP_VAL_REG 1
-#define TEMP_VAL_MEM 2
-#define TEMP_VAL_CONST 3
-
-/* XXX: optimize memory layout */
-typedef struct TCGTemp {
- TCGType base_type;
- TCGType type;
- int val_type;
- int reg;
- tcg_target_long val;
- int mem_reg;
- tcg_target_long mem_offset;
- unsigned int fixed_reg:1;
- unsigned int mem_coherent:1;
- unsigned int mem_allocated:1;
- unsigned int temp_local:1; /* If true, the temp is saved accross
- basic blocks. Otherwise, it is not
- preserved accross basic blocks. */
- unsigned int temp_allocated:1; /* never used for code gen */
- /* index of next free temp of same base type, -1 if end */
- int next_free_temp;
- const char *name;
-} TCGTemp;
-
-typedef struct TCGHelperInfo {
- tcg_target_ulong func;
- const char *name;
-} TCGHelperInfo;
-
-typedef struct TCGContext TCGContext;
-
-struct TCGContext {
- uint8_t *pool_cur, *pool_end;
- TCGPool *pool_first, *pool_current;
- TCGLabel *labels;
- int nb_labels;
- TCGTemp *temps; /* globals first, temps after */
- int nb_globals;
- int nb_temps;
- /* index of free temps, -1 if none */
- int first_free_temp[TCG_TYPE_COUNT * 2];
-
- /* goto_tb support */
- uint8_t *code_buf;
- unsigned long *tb_next;
- uint16_t *tb_next_offset;
- uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
-
- /* liveness analysis */
- uint16_t *op_dead_iargs; /* for each operation, each bit tells if the
- corresponding input argument is dead */
-
- /* tells in which temporary a given register is. It does not take
- into account fixed registers */
- int reg_to_temp[TCG_TARGET_NB_REGS];
- TCGRegSet reserved_regs;
- tcg_target_long current_frame_offset;
- tcg_target_long frame_start;
- tcg_target_long frame_end;
- int frame_reg;
-
- uint8_t *code_ptr;
- TCGTemp static_temps[TCG_MAX_TEMPS];
-
- TCGHelperInfo *helpers;
- int nb_helpers;
- int allocated_helpers;
- int helpers_sorted;
-
-#ifdef CONFIG_PROFILER
- /* profiling info */
- int64_t tb_count1;
- int64_t tb_count;
- int64_t op_count; /* total insn count */
- int op_count_max; /* max insn per TB */
- int64_t temp_count;
- int temp_count_max;
- int64_t old_op_count;
- int64_t del_op_count;
- int64_t code_in_len;
- int64_t code_out_len;
- int64_t interm_time;
- int64_t code_time;
- int64_t la_time;
- int64_t restore_count;
- int64_t restore_time;
-#endif
-};
-
-extern TCGContext tcg_ctx;
-extern uint16_t *gen_opc_ptr;
-extern TCGArg *gen_opparam_ptr;
-extern uint16_t gen_opc_buf[];
-extern TCGArg gen_opparam_buf[];
-
-/* pool based memory allocation */
-
-void *tcg_malloc_internal(TCGContext *s, int size);
-void tcg_pool_reset(TCGContext *s);
-void tcg_pool_delete(TCGContext *s);
-
-static inline void *tcg_malloc(int size)
-{
- TCGContext *s = &tcg_ctx;
- uint8_t *ptr, *ptr_end;
- size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
- ptr = s->pool_cur;
- ptr_end = ptr + size;
- if (unlikely(ptr_end > s->pool_end)) {
- return tcg_malloc_internal(&tcg_ctx, size);
- } else {
- s->pool_cur = ptr_end;
- return ptr;
- }
-}
-
-void tcg_context_init(TCGContext *s);
-void tcg_func_start(TCGContext *s);
-
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
-
-void tcg_set_frame(TCGContext *s, int reg,
- tcg_target_long start, tcg_target_long size);
-TCGv tcg_global_reg_new(TCGType type, int reg, const char *name);
-TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
- const char *name);
-TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
- const char *name);
-TCGv tcg_temp_new_internal(TCGType type, int temp_local);
-static inline TCGv tcg_temp_new(TCGType type)
-{
- return tcg_temp_new_internal(type, 0);
-}
-static inline TCGv tcg_temp_local_new(TCGType type)
-{
- return tcg_temp_new_internal(type, 1);
-}
-void tcg_temp_free(TCGv arg);
-char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
-void tcg_dump_info(FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
-
-#define TCG_CT_ALIAS 0x80
-#define TCG_CT_IALIAS 0x40
-#define TCG_CT_REG 0x01
-#define TCG_CT_CONST 0x02 /* any constant of register size */
-
-typedef struct TCGArgConstraint {
- uint16_t ct;
- uint8_t alias_index;
- union {
- TCGRegSet regs;
- } u;
-} TCGArgConstraint;
-
-#define TCG_MAX_OP_ARGS 16
-
-#define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
- block */
-#define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers
- and potentially update globals. */
-#define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it
- cannot be removed if its output
- are not used */
-
-typedef struct TCGOpDef {
- const char *name;
- uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
- uint8_t flags;
- uint16_t copy_size;
- TCGArgConstraint *args_ct;
- int *sorted_args;
-} TCGOpDef;
-
-typedef struct TCGTargetOpDef {
- int op;
- const char *args_ct_str[TCG_MAX_OP_ARGS];
-} TCGTargetOpDef;
-
-extern TCGOpDef tcg_op_defs[];
-
-void tcg_target_init(TCGContext *s);
-void tcg_target_qemu_prologue(TCGContext *s);
-
-#define tcg_abort() \
-do {\
- fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
- abort();\
-} while (0)
-
-void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
-
-void tcg_gen_call(TCGContext *s, TCGv func, unsigned int flags,
- unsigned int nb_rets, const TCGv *rets,
- unsigned int nb_params, const TCGv *args1);
-void tcg_gen_shifti_i64(TCGv ret, TCGv arg1,
- int c, int right, int arith);
-
-/* only used for debugging purposes */
-void tcg_register_helper(void *func, const char *name);
-#define TCG_HELPER(func) tcg_register_helper(func, #func)
-const char *tcg_helper_get_name(TCGContext *s, void *func);
-void tcg_dump_ops(TCGContext *s, FILE *outfile);
-
-void dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
-TCGv tcg_const_i32(int32_t val);
-TCGv tcg_const_i64(int64_t val);
-
-#if TCG_TARGET_REG_BITS == 32
-#define tcg_const_ptr tcg_const_i32
-#define tcg_add_ptr tcg_add_i32
-#define tcg_sub_ptr tcg_sub_i32
-#else
-#define tcg_const_ptr tcg_const_i64
-#define tcg_add_ptr tcg_add_i64
-#define tcg_sub_ptr tcg_sub_i64
-#endif
-
-void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
- int label_index, long addend);
-const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
- unsigned int dead_iargs);
-
-const TCGArg *dyngen_op(TCGContext *s, int opc, const TCGArg *opparam_ptr);
-
-/* tcg-runtime.c */
-int64_t tcg_helper_shl_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_shr_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2);
-int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2);
-uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2);
-uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2);
-
-extern uint8_t code_gen_prologue[];
-#if defined(__powerpc__) && !defined(__powerpc64__)
-#define tcg_qemu_tb_exec(tb_ptr) \
- ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
-#else
-#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
-#endif
diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c
deleted file mode 100644
index 304a0c3..0000000
--- a/tcg/x86_64/tcg-target.c
+++ /dev/null
@@ -1,1307 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-const char *tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
- "%rax",
- "%rcx",
- "%rdx",
- "%rbx",
- "%rsp",
- "%rbp",
- "%rsi",
- "%rdi",
- "%r8",
- "%r9",
- "%r10",
- "%r11",
- "%r12",
- "%r13",
- "%r14",
- "%r15",
-};
-
-int tcg_target_reg_alloc_order[] = {
- TCG_REG_RDI,
- TCG_REG_RSI,
- TCG_REG_RDX,
- TCG_REG_RCX,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_RAX,
- TCG_REG_R10,
- TCG_REG_R11,
-
- TCG_REG_RBP,
- TCG_REG_RBX,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
-};
-
-const int tcg_target_call_iarg_regs[6] = {
- TCG_REG_RDI,
- TCG_REG_RSI,
- TCG_REG_RDX,
- TCG_REG_RCX,
- TCG_REG_R8,
- TCG_REG_R9,
-};
-
-const int tcg_target_call_oarg_regs[2] = {
- TCG_REG_RAX,
- TCG_REG_RDX
-};
-
-static uint8_t *tb_ret_addr;
-
-static void patch_reloc(uint8_t *code_ptr, int type,
- tcg_target_long value, tcg_target_long addend)
-{
- value += addend;
- switch(type) {
- case R_X86_64_32:
- if (value != (uint32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- case R_X86_64_32S:
- if (value != (int32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- case R_386_PC32:
- value -= (long)code_ptr;
- if (value != (int32_t)value)
- tcg_abort();
- *(uint32_t *)code_ptr = value;
- break;
- default:
- tcg_abort();
- }
-}
-
-/* maximum number of register used for input function arguments */
-static inline int tcg_target_get_call_iarg_regs_count(int flags)
-{
- return 6;
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
- const char *ct_str;
-
- ct_str = *pct_str;
- switch(ct_str[0]) {
- case 'a':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RAX);
- break;
- case 'b':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RBX);
- break;
- case 'c':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RCX);
- break;
- case 'd':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RDX);
- break;
- case 'S':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RSI);
- break;
- case 'D':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set_reg(ct->u.regs, TCG_REG_RDI);
- break;
- case 'q':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xf);
- break;
- case 'r':
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffff);
- break;
- case 'L': /* qemu_ld/st constraint */
- ct->ct |= TCG_CT_REG;
- tcg_regset_set32(ct->u.regs, 0, 0xffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
- break;
- case 'e':
- ct->ct |= TCG_CT_CONST_S32;
- break;
- case 'Z':
- ct->ct |= TCG_CT_CONST_U32;
- break;
- default:
- return -1;
- }
- ct_str++;
- *pct_str = ct_str;
- return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
- const TCGArgConstraint *arg_ct)
-{
- int ct;
- ct = arg_ct->ct;
- if (ct & TCG_CT_CONST)
- return 1;
- else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val)
- return 1;
- else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val)
- return 1;
- else
- return 0;
-}
-
-#define ARITH_ADD 0
-#define ARITH_OR 1
-#define ARITH_ADC 2
-#define ARITH_SBB 3
-#define ARITH_AND 4
-#define ARITH_SUB 5
-#define ARITH_XOR 6
-#define ARITH_CMP 7
-
-#define SHIFT_SHL 4
-#define SHIFT_SHR 5
-#define SHIFT_SAR 7
-
-#define JCC_JMP (-1)
-#define JCC_JO 0x0
-#define JCC_JNO 0x1
-#define JCC_JB 0x2
-#define JCC_JAE 0x3
-#define JCC_JE 0x4
-#define JCC_JNE 0x5
-#define JCC_JBE 0x6
-#define JCC_JA 0x7
-#define JCC_JS 0x8
-#define JCC_JNS 0x9
-#define JCC_JP 0xa
-#define JCC_JNP 0xb
-#define JCC_JL 0xc
-#define JCC_JGE 0xd
-#define JCC_JLE 0xe
-#define JCC_JG 0xf
-
-#define P_EXT 0x100 /* 0x0f opcode prefix */
-#define P_REXW 0x200 /* set rex.w = 1 */
-#define P_REXB 0x400 /* force rex use for byte registers */
-
-static const uint8_t tcg_cond_to_jcc[10] = {
- [TCG_COND_EQ] = JCC_JE,
- [TCG_COND_NE] = JCC_JNE,
- [TCG_COND_LT] = JCC_JL,
- [TCG_COND_GE] = JCC_JGE,
- [TCG_COND_LE] = JCC_JLE,
- [TCG_COND_GT] = JCC_JG,
- [TCG_COND_LTU] = JCC_JB,
- [TCG_COND_GEU] = JCC_JAE,
- [TCG_COND_LEU] = JCC_JBE,
- [TCG_COND_GTU] = JCC_JA,
-};
-
-static inline void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
-{
- int rex;
- rex = ((opc >> 6) & 0x8) | ((r >> 1) & 0x4) |
- ((x >> 2) & 2) | ((rm >> 3) & 1);
- if (rex || (opc & P_REXB)) {
- tcg_out8(s, rex | 0x40);
- }
- if (opc & P_EXT)
- tcg_out8(s, 0x0f);
- tcg_out8(s, opc);
-}
-
-static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
-{
- tcg_out_opc(s, opc, r, rm, 0);
- tcg_out8(s, 0xc0 | ((r & 7) << 3) | (rm & 7));
-}
-
-/* rm < 0 means no register index plus (-rm - 1 immediate bytes) */
-static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm,
- tcg_target_long offset)
-{
- if (rm < 0) {
- tcg_target_long val;
- tcg_out_opc(s, opc, r, 0, 0);
- val = offset - ((tcg_target_long)s->code_ptr + 5 + (-rm - 1));
- if (val == (int32_t)val) {
- /* eip relative */
- tcg_out8(s, 0x05 | ((r & 7) << 3));
- tcg_out32(s, val);
- } else if (offset == (int32_t)offset) {
- tcg_out8(s, 0x04 | ((r & 7) << 3));
- tcg_out8(s, 0x25); /* sib */
- tcg_out32(s, offset);
- } else {
- tcg_abort();
- }
- } else if (offset == 0 && (rm & 7) != TCG_REG_RBP) {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, 0x04 | ((r & 7) << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x00 | ((r & 7) << 3) | (rm & 7));
- }
- } else if ((int8_t)offset == offset) {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, 0x44 | ((r & 7) << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x40 | ((r & 7) << 3) | (rm & 7));
- }
- tcg_out8(s, offset);
- } else {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, 0x84 | ((r & 7) << 3));
- tcg_out8(s, 0x24);
- } else {
- tcg_out8(s, 0x80 | ((r & 7) << 3) | (rm & 7));
- }
- tcg_out32(s, offset);
- }
-}
-
-#if defined(CONFIG_SOFTMMU)
-/* XXX: incomplete. index must be different from ESP */
-static void tcg_out_modrm_offset2(TCGContext *s, int opc, int r, int rm,
- int index, int shift,
- tcg_target_long offset)
-{
- int mod;
- if (rm == -1)
- tcg_abort();
- if (offset == 0 && (rm & 7) != TCG_REG_RBP) {
- mod = 0;
- } else if (offset == (int8_t)offset) {
- mod = 0x40;
- } else if (offset == (int32_t)offset) {
- mod = 0x80;
- } else {
- tcg_abort();
- }
- if (index == -1) {
- tcg_out_opc(s, opc, r, rm, 0);
- if ((rm & 7) == TCG_REG_RSP) {
- tcg_out8(s, mod | ((r & 7) << 3) | 0x04);
- tcg_out8(s, 0x04 | (rm & 7));
- } else {
- tcg_out8(s, mod | ((r & 7) << 3) | (rm & 7));
- }
- } else {
- tcg_out_opc(s, opc, r, rm, index);
- tcg_out8(s, mod | ((r & 7) << 3) | 0x04);
- tcg_out8(s, (shift << 6) | ((index & 7) << 3) | (rm & 7));
- }
- if (mod == 0x40) {
- tcg_out8(s, offset);
- } else if (mod == 0x80) {
- tcg_out32(s, offset);
- }
-}
-#endif
-
-static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
-{
- tcg_out_modrm(s, 0x8b | P_REXW, ret, arg);
-}
-
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
- int ret, tcg_target_long arg)
-{
- if (arg == 0) {
- tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret); /* xor r0,r0 */
- } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
- tcg_out_opc(s, 0xb8 + (ret & 7), 0, ret, 0);
- tcg_out32(s, arg);
- } else if (arg == (int32_t)arg) {
- tcg_out_modrm(s, 0xc7 | P_REXW, 0, ret);
- tcg_out32(s, arg);
- } else {
- tcg_out_opc(s, (0xb8 + (ret & 7)) | P_REXW, 0, ret, 0);
- tcg_out32(s, arg);
- tcg_out32(s, arg >> 32);
- }
-}
-
-static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
- int arg1, tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_modrm_offset(s, 0x8b, ret, arg1, arg2); /* movl */
- else
- tcg_out_modrm_offset(s, 0x8b | P_REXW, ret, arg1, arg2); /* movq */
-}
-
-static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
- int arg1, tcg_target_long arg2)
-{
- if (type == TCG_TYPE_I32)
- tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2); /* movl */
- else
- tcg_out_modrm_offset(s, 0x89 | P_REXW, arg, arg1, arg2); /* movq */
-}
-
-static inline void tgen_arithi32(TCGContext *s, int c, int r0, int32_t val)
-{
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83, c, r0);
- tcg_out8(s, val);
- } else if (c == ARITH_AND && val == 0xffu) {
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, r0, r0);
- } else if (c == ARITH_AND && val == 0xffffu) {
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, r0, r0);
- } else {
- tcg_out_modrm(s, 0x81, c, r0);
- tcg_out32(s, val);
- }
-}
-
-static inline void tgen_arithi64(TCGContext *s, int c, int r0, int64_t val)
-{
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x83 | P_REXW, c, r0);
- tcg_out8(s, val);
- } else if (c == ARITH_AND && val == 0xffu) {
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT | P_REXW, r0, r0);
- } else if (c == ARITH_AND && val == 0xffffu) {
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT | P_REXW, r0, r0);
- } else if (c == ARITH_AND && val == 0xffffffffu) {
- /* 32-bit mov zero extends */
- tcg_out_modrm(s, 0x8b, r0, r0);
- } else if (val == (int32_t)val) {
- tcg_out_modrm(s, 0x81 | P_REXW, c, r0);
- tcg_out32(s, val);
- } else if (c == ARITH_AND && val == (uint32_t)val) {
- tcg_out_modrm(s, 0x81, c, r0);
- tcg_out32(s, val);
- } else {
- tcg_abort();
- }
-}
-
-static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
- if (val != 0)
- tgen_arithi64(s, ARITH_ADD, reg, val);
-}
-
-static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
-{
- int32_t val, val1;
- TCGLabel *l = &s->labels[label_index];
-
- if (l->has_value) {
- val = l->u.value - (tcg_target_long)s->code_ptr;
- val1 = val - 2;
- if ((int8_t)val1 == val1) {
- if (opc == -1)
- tcg_out8(s, 0xeb);
- else
- tcg_out8(s, 0x70 + opc);
- tcg_out8(s, val1);
- } else {
- if (opc == -1) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, val - 5);
- } else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
- tcg_out32(s, val - 6);
- }
- }
- } else {
- if (opc == -1) {
- tcg_out8(s, 0xe9);
- } else {
- tcg_out8(s, 0x0f);
- tcg_out8(s, 0x80 + opc);
- }
- tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
- s->code_ptr += 4;
- }
-}
-
-static void tcg_out_brcond(TCGContext *s, int cond,
- TCGArg arg1, TCGArg arg2, int const_arg2,
- int label_index, int rexw)
-{
- if (const_arg2) {
- if (arg2 == 0) {
- /* test r, r */
- tcg_out_modrm(s, 0x85 | rexw, arg1, arg1);
- } else {
- if (rexw)
- tgen_arithi64(s, ARITH_CMP, arg1, arg2);
- else
- tgen_arithi32(s, ARITH_CMP, arg1, arg2);
- }
- } else {
- tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3) | rexw, arg2, arg1);
- }
- tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
-}
-
-#if defined(CONFIG_SOFTMMU)
-
-#include "../../softmmu_defs.h"
-
-static void *qemu_ld_helpers[4] = {
- __ldb_mmu,
- __ldw_mmu,
- __ldl_mmu,
- __ldq_mmu,
-};
-
-static void *qemu_st_helpers[4] = {
- __stb_mmu,
- __stw_mmu,
- __stl_mmu,
- __stq_mmu,
-};
-#endif
-
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
- s_bits = opc & 3;
-
- r0 = TCG_REG_RDI;
- r1 = TCG_REG_RSI;
-
-#if TARGET_LONG_BITS == 32
- rexw = 0;
-#else
- rexw = P_REXW;
-#endif
-#if defined(CONFIG_SOFTMMU)
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- /* lea offset(r1, env), r1 */
- tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
- offsetof(CPUState, tlb_table[mem_index][0].addr_read));
-
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* XXX: move that code at the end of the TB */
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RSI, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-
- switch(opc) {
- case 0 | 4:
- /* movsbq */
- tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
- break;
- case 1 | 4:
- /* movswq */
- tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
- break;
- case 2 | 4:
- /* movslq */
- tcg_out_modrm(s, 0x63 | P_REXW, data_reg, TCG_REG_RAX);
- break;
- case 0:
- case 1:
- case 2:
- default:
- /* movl */
- tcg_out_modrm(s, 0x8b, data_reg, TCG_REG_RAX);
- break;
- case 3:
- tcg_out_mov(s, data_reg, TCG_REG_RAX);
- break;
- }
-
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_read));
-#else
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
-#else
- bswap = 0;
-#endif
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
- break;
- case 0 | 4:
- /* movsbX */
- tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
- if (bswap) {
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
- }
- break;
- case 1 | 4:
- if (bswap) {
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
- /* rolw $8, data_reg */
- tcg_out8(s, 0x66);
- tcg_out_modrm(s, 0xc1, 0, data_reg);
- tcg_out8(s, 8);
-
- /* movswX data_reg, data_reg */
- tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg);
- } else {
- /* movswX */
- tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0);
- }
- break;
- case 2:
- /* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- if (bswap) {
- /* bswap */
- tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
- }
- break;
- case 2 | 4:
- if (bswap) {
- /* movl (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
- /* bswap */
- tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
- /* movslq */
- tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg);
- } else {
- /* movslq */
- tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0);
- }
- break;
- case 3:
- /* movq (r0), data_reg */
- tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0);
- if (bswap) {
- /* bswap */
- tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0);
- }
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-#endif
-}
-
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
- int opc)
-{
- int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
-#if defined(CONFIG_SOFTMMU)
- uint8_t *label1_ptr, *label2_ptr;
-#endif
-
- data_reg = *args++;
- addr_reg = *args++;
- mem_index = *args;
-
- s_bits = opc;
-
- r0 = TCG_REG_RDI;
- r1 = TCG_REG_RSI;
-
-#if TARGET_LONG_BITS == 32
- rexw = 0;
-#else
- rexw = P_REXW;
-#endif
-#if defined(CONFIG_SOFTMMU)
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */
- tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
- tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */
- tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
- tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
- tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-
- /* lea offset(r1, env), r1 */
- tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
- offsetof(CPUState, tlb_table[mem_index][0].addr_write));
-
- /* cmp 0(r1), r0 */
- tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
-
- /* mov */
- tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
-
- /* je label1 */
- tcg_out8(s, 0x70 + JCC_JE);
- label1_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* XXX: move that code at the end of the TB */
- switch(opc) {
- case 0:
- /* movzbl */
- tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, TCG_REG_RSI, data_reg);
- break;
- case 1:
- /* movzwl */
- tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_RSI, data_reg);
- break;
- case 2:
- /* movl */
- tcg_out_modrm(s, 0x8b, TCG_REG_RSI, data_reg);
- break;
- default:
- case 3:
- tcg_out_mov(s, TCG_REG_RSI, data_reg);
- break;
- }
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
- tcg_out8(s, 0xe8);
- tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
- (tcg_target_long)s->code_ptr - 4);
-
- /* jmp label2 */
- tcg_out8(s, 0xeb);
- label2_ptr = s->code_ptr;
- s->code_ptr++;
-
- /* label1: */
- *label1_ptr = s->code_ptr - label1_ptr - 1;
-
- /* add x(r1), r0 */
- tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) -
- offsetof(CPUTLBEntry, addr_write));
-#else
- r0 = addr_reg;
-#endif
-
-#ifdef TARGET_WORDS_BIGENDIAN
- bswap = 1;
-#else
- bswap = 0;
-#endif
- switch(opc) {
- case 0:
- /* movb */
- tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0);
- break;
- case 1:
- if (bswap) {
- tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */
- tcg_out8(s, 0x66); /* rolw $8, %ecx */
- tcg_out_modrm(s, 0xc1, 0, r1);
- tcg_out8(s, 8);
- data_reg = r1;
- }
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 2:
- if (bswap) {
- tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT, 0, r1, 0);
- data_reg = r1;
- }
- /* movl */
- tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
- break;
- case 3:
- if (bswap) {
- tcg_out_mov(s, r1, data_reg);
- /* bswap data_reg */
- tcg_out_opc(s, (0xc8 + r1) | P_EXT | P_REXW, 0, r1, 0);
- data_reg = r1;
- }
- /* movq */
- tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0);
- break;
- default:
- tcg_abort();
- }
-
-#if defined(CONFIG_SOFTMMU)
- /* label2: */
- *label2_ptr = s->code_ptr - label2_ptr - 1;
-#endif
-}
-
-static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
- const int *const_args)
-{
- int c;
-
- switch(opc) {
- case INDEX_op_exit_tb:
- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, args[0]);
- tcg_out8(s, 0xe9); /* jmp tb_ret_addr */
- tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
- break;
- case INDEX_op_goto_tb:
- if (s->tb_jmp_offset) {
- /* direct jump method */
- tcg_out8(s, 0xe9); /* jmp im */
- s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
- tcg_out32(s, 0);
- } else {
- /* indirect jump method */
- /* jmp Ev */
- tcg_out_modrm_offset(s, 0xff, 4, -1,
- (tcg_target_long)(s->tb_next +
- args[0]));
- }
- s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
- break;
- case INDEX_op_call:
- if (const_args[0]) {
- tcg_out8(s, 0xe8);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
- } else {
- tcg_out_modrm(s, 0xff, 2, args[0]);
- }
- break;
- case INDEX_op_jmp:
- if (const_args[0]) {
- tcg_out8(s, 0xe9);
- tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
- } else {
- tcg_out_modrm(s, 0xff, 4, args[0]);
- }
- break;
- case INDEX_op_br:
- tcg_out_jxx(s, JCC_JMP, args[0]);
- break;
- case INDEX_op_movi_i32:
- tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
- break;
- case INDEX_op_movi_i64:
- tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
- break;
- case INDEX_op_ld8u_i32:
- case INDEX_op_ld8u_i64:
- /* movzbl */
- tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld8s_i32:
- /* movsbl */
- tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld8s_i64:
- /* movsbq */
- tcg_out_modrm_offset(s, 0xbe | P_EXT | P_REXW, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16u_i32:
- case INDEX_op_ld16u_i64:
- /* movzwl */
- tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16s_i32:
- /* movswl */
- tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld16s_i64:
- /* movswq */
- tcg_out_modrm_offset(s, 0xbf | P_EXT | P_REXW, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld_i32:
- case INDEX_op_ld32u_i64:
- /* movl */
- tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld32s_i64:
- /* movslq */
- tcg_out_modrm_offset(s, 0x63 | P_REXW, args[0], args[1], args[2]);
- break;
- case INDEX_op_ld_i64:
- /* movq */
- tcg_out_modrm_offset(s, 0x8b | P_REXW, args[0], args[1], args[2]);
- break;
-
- case INDEX_op_st8_i32:
- case INDEX_op_st8_i64:
- /* movb */
- tcg_out_modrm_offset(s, 0x88 | P_REXB, args[0], args[1], args[2]);
- break;
- case INDEX_op_st16_i32:
- case INDEX_op_st16_i64:
- /* movw */
- tcg_out8(s, 0x66);
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
- break;
- case INDEX_op_st_i32:
- case INDEX_op_st32_i64:
- /* movl */
- tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
- break;
- case INDEX_op_st_i64:
- /* movq */
- tcg_out_modrm_offset(s, 0x89 | P_REXW, args[0], args[1], args[2]);
- break;
-
- case INDEX_op_sub_i32:
- c = ARITH_SUB;
- goto gen_arith32;
- case INDEX_op_and_i32:
- c = ARITH_AND;
- goto gen_arith32;
- case INDEX_op_or_i32:
- c = ARITH_OR;
- goto gen_arith32;
- case INDEX_op_xor_i32:
- c = ARITH_XOR;
- goto gen_arith32;
- case INDEX_op_add_i32:
- c = ARITH_ADD;
- gen_arith32:
- if (const_args[2]) {
- tgen_arithi32(s, c, args[0], args[2]);
- } else {
- tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
- }
- break;
-
- case INDEX_op_sub_i64:
- c = ARITH_SUB;
- goto gen_arith64;
- case INDEX_op_and_i64:
- c = ARITH_AND;
- goto gen_arith64;
- case INDEX_op_or_i64:
- c = ARITH_OR;
- goto gen_arith64;
- case INDEX_op_xor_i64:
- c = ARITH_XOR;
- goto gen_arith64;
- case INDEX_op_add_i64:
- c = ARITH_ADD;
- gen_arith64:
- if (const_args[2]) {
- tgen_arithi64(s, c, args[0], args[2]);
- } else {
- tcg_out_modrm(s, 0x01 | (c << 3) | P_REXW, args[2], args[0]);
- }
- break;
-
- case INDEX_op_mul_i32:
- if (const_args[2]) {
- int32_t val;
- val = args[2];
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b, args[0], args[0]);
- tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x69, args[0], args[0]);
- tcg_out32(s, val);
- }
- } else {
- tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
- }
- break;
- case INDEX_op_mul_i64:
- if (const_args[2]) {
- int32_t val;
- val = args[2];
- if (val == (int8_t)val) {
- tcg_out_modrm(s, 0x6b | P_REXW, args[0], args[0]);
- tcg_out8(s, val);
- } else {
- tcg_out_modrm(s, 0x69 | P_REXW, args[0], args[0]);
- tcg_out32(s, val);
- }
- } else {
- tcg_out_modrm(s, 0xaf | P_EXT | P_REXW, args[0], args[2]);
- }
- break;
- case INDEX_op_div2_i32:
- tcg_out_modrm(s, 0xf7, 7, args[4]);
- break;
- case INDEX_op_divu2_i32:
- tcg_out_modrm(s, 0xf7, 6, args[4]);
- break;
- case INDEX_op_div2_i64:
- tcg_out_modrm(s, 0xf7 | P_REXW, 7, args[4]);
- break;
- case INDEX_op_divu2_i64:
- tcg_out_modrm(s, 0xf7 | P_REXW, 6, args[4]);
- break;
-
- case INDEX_op_shl_i32:
- c = SHIFT_SHL;
- gen_shift32:
- if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1, c, args[0]);
- tcg_out8(s, args[2]);
- }
- } else {
- tcg_out_modrm(s, 0xd3, c, args[0]);
- }
- break;
- case INDEX_op_shr_i32:
- c = SHIFT_SHR;
- goto gen_shift32;
- case INDEX_op_sar_i32:
- c = SHIFT_SAR;
- goto gen_shift32;
-
- case INDEX_op_shl_i64:
- c = SHIFT_SHL;
- gen_shift64:
- if (const_args[2]) {
- if (args[2] == 1) {
- tcg_out_modrm(s, 0xd1 | P_REXW, c, args[0]);
- } else {
- tcg_out_modrm(s, 0xc1 | P_REXW, c, args[0]);
- tcg_out8(s, args[2]);
- }
- } else {
- tcg_out_modrm(s, 0xd3 | P_REXW, c, args[0]);
- }
- break;
- case INDEX_op_shr_i64:
- c = SHIFT_SHR;
- goto gen_shift64;
- case INDEX_op_sar_i64:
- c = SHIFT_SAR;
- goto gen_shift64;
-
- case INDEX_op_brcond_i32:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
- args[3], 0);
- break;
- case INDEX_op_brcond_i64:
- tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
- args[3], P_REXW);
- break;
-
- case INDEX_op_bswap_i32:
- tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT, 0, args[0], 0);
- break;
- case INDEX_op_bswap_i64:
- tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0);
- break;
-
- case INDEX_op_neg_i32:
- tcg_out_modrm(s, 0xf7, 3, args[0]);
- break;
- case INDEX_op_neg_i64:
- tcg_out_modrm(s, 0xf7 | P_REXW, 3, args[0]);
- break;
-
- case INDEX_op_ext8s_i32:
- tcg_out_modrm(s, 0xbe | P_EXT | P_REXB, args[0], args[1]);
- break;
- case INDEX_op_ext16s_i32:
- tcg_out_modrm(s, 0xbf | P_EXT, args[0], args[1]);
- break;
- case INDEX_op_ext8s_i64:
- tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, args[0], args[1]);
- break;
- case INDEX_op_ext16s_i64:
- tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, args[0], args[1]);
- break;
- case INDEX_op_ext32s_i64:
- tcg_out_modrm(s, 0x63 | P_REXW, args[0], args[1]);
- break;
-
- case INDEX_op_qemu_ld8u:
- tcg_out_qemu_ld(s, args, 0);
- break;
- case INDEX_op_qemu_ld8s:
- tcg_out_qemu_ld(s, args, 0 | 4);
- break;
- case INDEX_op_qemu_ld16u:
- tcg_out_qemu_ld(s, args, 1);
- break;
- case INDEX_op_qemu_ld16s:
- tcg_out_qemu_ld(s, args, 1 | 4);
- break;
- case INDEX_op_qemu_ld32u:
- tcg_out_qemu_ld(s, args, 2);
- break;
- case INDEX_op_qemu_ld32s:
- tcg_out_qemu_ld(s, args, 2 | 4);
- break;
- case INDEX_op_qemu_ld64:
- tcg_out_qemu_ld(s, args, 3);
- break;
-
- case INDEX_op_qemu_st8:
- tcg_out_qemu_st(s, args, 0);
- break;
- case INDEX_op_qemu_st16:
- tcg_out_qemu_st(s, args, 1);
- break;
- case INDEX_op_qemu_st32:
- tcg_out_qemu_st(s, args, 2);
- break;
- case INDEX_op_qemu_st64:
- tcg_out_qemu_st(s, args, 3);
- break;
-
- default:
- tcg_abort();
- }
-}
-
-static int tcg_target_callee_save_regs[] = {
- TCG_REG_RBP,
- TCG_REG_RBX,
- TCG_REG_R12,
- TCG_REG_R13,
- /* TCG_REG_R14, */ /* currently used for the global env, so no
- need to save */
- TCG_REG_R15,
-};
-
-static inline void tcg_out_push(TCGContext *s, int reg)
-{
- tcg_out_opc(s, (0x50 + (reg & 7)), 0, reg, 0);
-}
-
-static inline void tcg_out_pop(TCGContext *s, int reg)
-{
- tcg_out_opc(s, (0x58 + (reg & 7)), 0, reg, 0);
-}
-
-/* Generate global QEMU prologue and epilogue code */
-void tcg_target_qemu_prologue(TCGContext *s)
-{
- int i, frame_size, push_size, stack_addend;
-
- /* TB prologue */
- /* save all callee saved registers */
- for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
- tcg_out_push(s, tcg_target_callee_save_regs[i]);
-
- }
- /* reserve some stack space */
- push_size = 8 + ARRAY_SIZE(tcg_target_callee_save_regs) * 8;
- frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
- frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
- ~(TCG_TARGET_STACK_ALIGN - 1);
- stack_addend = frame_size - push_size;
- tcg_out_addi(s, TCG_REG_RSP, -stack_addend);
-
- tcg_out_modrm(s, 0xff, 4, TCG_REG_RDI); /* jmp *%rdi */
-
- /* TB epilogue */
- tb_ret_addr = s->code_ptr;
- tcg_out_addi(s, TCG_REG_RSP, stack_addend);
- for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
- tcg_out_pop(s, tcg_target_callee_save_regs[i]);
- }
- tcg_out8(s, 0xc3); /* ret */
-}
-
-static const TCGTargetOpDef x86_64_op_defs[] = {
- { INDEX_op_exit_tb, { } },
- { INDEX_op_goto_tb, { } },
- { INDEX_op_call, { "ri" } }, /* XXX: might need a specific constant constraint */
- { INDEX_op_jmp, { "ri" } }, /* XXX: might need a specific constant constraint */
- { INDEX_op_br, { } },
-
- { INDEX_op_mov_i32, { "r", "r" } },
- { INDEX_op_movi_i32, { "r" } },
- { INDEX_op_ld8u_i32, { "r", "r" } },
- { INDEX_op_ld8s_i32, { "r", "r" } },
- { INDEX_op_ld16u_i32, { "r", "r" } },
- { INDEX_op_ld16s_i32, { "r", "r" } },
- { INDEX_op_ld_i32, { "r", "r" } },
- { INDEX_op_st8_i32, { "r", "r" } },
- { INDEX_op_st16_i32, { "r", "r" } },
- { INDEX_op_st_i32, { "r", "r" } },
-
- { INDEX_op_add_i32, { "r", "0", "ri" } },
- { INDEX_op_mul_i32, { "r", "0", "ri" } },
- { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
- { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
- { INDEX_op_sub_i32, { "r", "0", "ri" } },
- { INDEX_op_and_i32, { "r", "0", "ri" } },
- { INDEX_op_or_i32, { "r", "0", "ri" } },
- { INDEX_op_xor_i32, { "r", "0", "ri" } },
-
- { INDEX_op_shl_i32, { "r", "0", "ci" } },
- { INDEX_op_shr_i32, { "r", "0", "ci" } },
- { INDEX_op_sar_i32, { "r", "0", "ci" } },
-
- { INDEX_op_brcond_i32, { "r", "ri" } },
-
- { INDEX_op_mov_i64, { "r", "r" } },
- { INDEX_op_movi_i64, { "r" } },
- { INDEX_op_ld8u_i64, { "r", "r" } },
- { INDEX_op_ld8s_i64, { "r", "r" } },
- { INDEX_op_ld16u_i64, { "r", "r" } },
- { INDEX_op_ld16s_i64, { "r", "r" } },
- { INDEX_op_ld32u_i64, { "r", "r" } },
- { INDEX_op_ld32s_i64, { "r", "r" } },
- { INDEX_op_ld_i64, { "r", "r" } },
- { INDEX_op_st8_i64, { "r", "r" } },
- { INDEX_op_st16_i64, { "r", "r" } },
- { INDEX_op_st32_i64, { "r", "r" } },
- { INDEX_op_st_i64, { "r", "r" } },
-
- { INDEX_op_add_i64, { "r", "0", "re" } },
- { INDEX_op_mul_i64, { "r", "0", "re" } },
- { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
- { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
- { INDEX_op_sub_i64, { "r", "0", "re" } },
- { INDEX_op_and_i64, { "r", "0", "reZ" } },
- { INDEX_op_or_i64, { "r", "0", "re" } },
- { INDEX_op_xor_i64, { "r", "0", "re" } },
-
- { INDEX_op_shl_i64, { "r", "0", "ci" } },
- { INDEX_op_shr_i64, { "r", "0", "ci" } },
- { INDEX_op_sar_i64, { "r", "0", "ci" } },
-
- { INDEX_op_brcond_i64, { "r", "re" } },
-
- { INDEX_op_bswap_i32, { "r", "0" } },
- { INDEX_op_bswap_i64, { "r", "0" } },
-
- { INDEX_op_neg_i32, { "r", "0" } },
- { INDEX_op_neg_i64, { "r", "0" } },
-
- { INDEX_op_ext8s_i32, { "r", "r"} },
- { INDEX_op_ext16s_i32, { "r", "r"} },
- { INDEX_op_ext8s_i64, { "r", "r"} },
- { INDEX_op_ext16s_i64, { "r", "r"} },
- { INDEX_op_ext32s_i64, { "r", "r"} },
-
- { INDEX_op_qemu_ld8u, { "r", "L" } },
- { INDEX_op_qemu_ld8s, { "r", "L" } },
- { INDEX_op_qemu_ld16u, { "r", "L" } },
- { INDEX_op_qemu_ld16s, { "r", "L" } },
- { INDEX_op_qemu_ld32u, { "r", "L" } },
- { INDEX_op_qemu_ld32s, { "r", "L" } },
- { INDEX_op_qemu_ld64, { "r", "L" } },
-
- { INDEX_op_qemu_st8, { "L", "L" } },
- { INDEX_op_qemu_st16, { "L", "L" } },
- { INDEX_op_qemu_st32, { "L", "L" } },
- { INDEX_op_qemu_st64, { "L", "L", "L" } },
-
- { -1 },
-};
-
-void tcg_target_init(TCGContext *s)
-{
- /* fail safe */
- if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
- tcg_abort();
-
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
- tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
- tcg_regset_set32(tcg_target_call_clobber_regs, 0,
- (1 << TCG_REG_RDI) |
- (1 << TCG_REG_RSI) |
- (1 << TCG_REG_RDX) |
- (1 << TCG_REG_RCX) |
- (1 << TCG_REG_R8) |
- (1 << TCG_REG_R9) |
- (1 << TCG_REG_RAX) |
- (1 << TCG_REG_R10) |
- (1 << TCG_REG_R11));
-
- tcg_regset_clear(s->reserved_regs);
- tcg_regset_set_reg(s->reserved_regs, TCG_REG_RSP);
-
- tcg_add_target_add_op_defs(x86_64_op_defs);
-}
diff --git a/tcg/x86_64/tcg-target.h b/tcg/x86_64/tcg-target.h
deleted file mode 100644
index 9a0cca0..0000000
--- a/tcg/x86_64/tcg-target.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Tiny Code Generator for QEMU
- *
- * Copyright (c) 2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define TCG_TARGET_X86_64 1
-
-#define TCG_TARGET_REG_BITS 64
-//#define TCG_TARGET_WORDS_BIGENDIAN
-
-#define TCG_TARGET_NB_REGS 16
-
-enum {
- TCG_REG_RAX = 0,
- TCG_REG_RCX,
- TCG_REG_RDX,
- TCG_REG_RBX,
- TCG_REG_RSP,
- TCG_REG_RBP,
- TCG_REG_RSI,
- TCG_REG_RDI,
- TCG_REG_R8,
- TCG_REG_R9,
- TCG_REG_R10,
- TCG_REG_R11,
- TCG_REG_R12,
- TCG_REG_R13,
- TCG_REG_R14,
- TCG_REG_R15,
-};
-
-#define TCG_CT_CONST_S32 0x100
-#define TCG_CT_CONST_U32 0x200
-
-/* used for function call generation */
-#define TCG_REG_CALL_STACK TCG_REG_RSP
-#define TCG_TARGET_STACK_ALIGN 16
-#define TCG_TARGET_CALL_STACK_OFFSET 0
-
-/* optional instructions */
-#define TCG_TARGET_HAS_bswap_i32
-#define TCG_TARGET_HAS_bswap_i64
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_neg_i64
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-
-/* Note: must be synced with dyngen-exec.h */
-#define TCG_AREG0 TCG_REG_R14
-#define TCG_AREG1 TCG_REG_R15
-#define TCG_AREG2 TCG_REG_R12
-#define TCG_AREG3 TCG_REG_R13
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
diff --git a/tcpdump.c b/tcpdump.c
deleted file mode 100644
index e562253..0000000
--- a/tcpdump.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "tcpdump.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-int qemu_tcpdump_active;
-
-static FILE* capture_file;
-static uint64_t capture_count;
-static uint64_t capture_size;
-static int capture_init;
-
-static void
-capture_atexit(void)
-{
- if (qemu_tcpdump_active) {
- fclose(capture_file);
- qemu_tcpdump_active = 0;
- }
-}
-
-/* See http://wiki.wireshark.org/Development/LibpcapFileFormat for
- * the complete description of the packet capture file format
- */
-
-#define PCAP_MAGIC 0xa1b2c3d4
-#define PCAP_MAJOR 2
-#define PCAP_MINOR 4
-#define PCAP_SNAPLEN 65535
-#define PCAP_ETHERNET 1
-
-static int
-pcap_write_header( FILE* out )
-{
- typedef struct {
- uint32_t magic;
- uint16_t version_major;
- uint16_t version_minor;
- int32_t this_zone;
- uint32_t sigfigs;
- uint32_t snaplen;
- uint32_t network;
- } PcapHeader;
-
- PcapHeader h;
-
- h.magic = PCAP_MAGIC;
- h.version_major = PCAP_MAJOR;
- h.version_minor = PCAP_MINOR;
- h.this_zone = 0;
- h.sigfigs = 0; /* all tools set it to 0 in practice */
- h.snaplen = PCAP_SNAPLEN;
- h.network = PCAP_ETHERNET;
-
- if (fwrite(&h, sizeof(h), 1, out) != 1) {
- return -1;
- }
- return 0;
-}
-
-int
-qemu_tcpdump_start( const char* filepath )
-{
- if (!capture_init) {
- capture_init = 1;
- atexit(capture_atexit);
- }
-
- qemu_tcpdump_stop();
-
- if (filepath == NULL)
- return -1;
-
- capture_file = fopen(filepath, "wb");
- if (capture_file == NULL)
- return -1;
-
- if (pcap_write_header(capture_file) < 0)
- return -1;
-
- qemu_tcpdump_active = 1;
- return 0;
-}
-
-void
-qemu_tcpdump_stop( void )
-{
- if (!qemu_tcpdump_active)
- return;
-
- qemu_tcpdump_active = 0;
-
- capture_count = 0;
- capture_size = 0;
-
- fclose(capture_file);
- capture_file = NULL;
-}
-
-void
-qemu_tcpdump_packet( const void* base, int len )
-{
- typedef struct {
- uint32_t ts_sec;
- uint32_t ts_usec;
- uint32_t incl_len;
- uint32_t orig_len;
- } PacketHeader;
-
- PacketHeader h;
- struct timeval now;
- int len2 = len;
-
- if (len2 > PCAP_SNAPLEN)
- len2 = PCAP_SNAPLEN;
-
- gettimeofday(&now, NULL);
- h.ts_sec = (uint32_t) now.tv_sec;
- h.ts_usec = (uint32_t) now.tv_usec;
- h.incl_len = (uint32_t) len2;
- h.orig_len = (uint32_t) len;
-
- fwrite( &h, sizeof(h), 1, capture_file );
- fwrite( base, 1, len2, capture_file );
-
- capture_count += 1;
- capture_size += len2;
-}
-
-void
-qemu_tcpdump_stats( uint64_t *pcount, uint64_t* psize )
-{
- *pcount = capture_count;
- *psize = capture_size;
-}
-
diff --git a/tcpdump.h b/tcpdump.h
deleted file mode 100644
index fc23d3f..0000000
--- a/tcpdump.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _QEMU_TCPDUMP_H
-#define _QEMU_TCPDUMP_H
-
-#include <stdint.h>
-
-/* global flag, set to 1 when packet captupe is active */
-extern int qemu_tcpdump_active;
-
-/* start a new packet capture, close the current one if any.
- * returns 0 on success, and -1 on failure (see errno then) */
-extern int qemu_tcpdump_start( const char* filepath );
-
-/* stop the current packet capture, if any */
-extern void qemu_tcpdump_stop( void );
-
-/* send an ethernet packet to the packet capture file, if any */
-extern void qemu_tcpdump_packet( const void* base, int len );
-
-/* returns interesting stats, like the number of packets captures,
- * and the total size of these packets. Note: the file will be larger
- * due to global and packet headers.
- */
-extern void qemu_tcpdump_stats( uint64_t *pcount, uint64_t* psize );
-
-#endif /* _QEMU_TCPDUMP_H */
diff --git a/telephony/Jamfile b/telephony/Jamfile
deleted file mode 100644
index 0f2b7b9..0000000
--- a/telephony/Jamfile
+++ /dev/null
@@ -1,13 +0,0 @@
-Main telephony : telephony.c ;
-
-Library sysdeps : sysdeps_posix.c ;
-Library android_modem : android_modem.c sim_card.c ;
-
-for prog in test1 test2 {
- Main $(prog) : $(prog).c ;
- LinkLibraries $(prog) : sysdeps ;
-}
-
-Main simulator : simulator.c ;
-LinkLibraries simulator : sysdeps android_modem ;
-
diff --git a/telephony/android_modem.c b/telephony/android_modem.c
deleted file mode 100644
index 79e93b2..0000000
--- a/telephony/android_modem.c
+++ /dev/null
@@ -1,1870 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android/android.h"
-#include "android_modem.h"
-#include "android/utils/debug.h"
-#include "android/utils/timezone.h"
-#include "android/utils/system.h"
-#include "sim_card.h"
-#include "sysdeps.h"
-#include <memory.h>
-#include <stdarg.h>
-#include <time.h>
-#include <assert.h>
-#include <stdio.h>
-#include "sms.h"
-#include "remote_call.h"
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(modem)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if 1
-# define R_ACTIVE VERBOSE_CHECK(radio)
-#else
-# define R_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) do { if (D_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-# define R(...) do { if (R_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-#else
-# define D(...) ((void)0)
-# define R(...) ((void)0)
-#endif
-
-#define CALL_DELAY_DIAL 1000
-#define CALL_DELAY_ALERT 1000
-
-/* the Android GSM stack checks that the operator's name has changed
- * when roaming is on. If not, it will not update the Roaming status icon
- *
- * this means that we need to emulate two distinct operators:
- * - the first one for the 'home' registration state, must also correspond
- * to the emulated user's IMEI
- *
- * - the second one for the 'roaming' registration state, must have a
- * different name and MCC/MNC
- */
-
-#define OPERATOR_HOME_INDEX 0
-#define OPERATOR_HOME_MCC 310
-#define OPERATOR_HOME_MNC 260
-#define OPERATOR_HOME_NAME "Android"
-#define OPERATOR_HOME_MCCMNC STRINGIFY(OPERATOR_HOME_MCC) \
- STRINGIFY(OPERATOR_HOME_MNC)
-
-#define OPERATOR_ROAMING_INDEX 1
-#define OPERATOR_ROAMING_MCC 310
-#define OPERATOR_ROAMING_MNC 295
-#define OPERATOR_ROAMING_NAME "TelKila"
-#define OPERATOR_ROAMING_MCCMNC STRINGIFY(OPERATOR_ROAMING_MCC) \
- STRINGIFY(OPERATOR_ROAMING_MNC)
-
-#if DEBUG
-static const char* quote( const char* line )
-{
- static char temp[1024];
- const char* hexdigits = "0123456789abcdef";
- char* p = temp;
- int c;
-
- while ((c = *line++) != 0) {
- c &= 255;
- if (c >= 32 && c < 127) {
- *p++ = c;
- }
- else if (c == '\r') {
- memcpy( p, "<CR>", 4 );
- p += 4;
- }
- else if (c == '\n') {
- memcpy( p, "<LF>", 4 );strcat( p, "<LF>" );
- p += 4;
- }
- else {
- p[0] = '\\';
- p[1] = 'x';
- p[2] = hexdigits[ (c) >> 4 ];
- p[3] = hexdigits[ (c) & 15 ];
- p += 4;
- }
- }
- *p = 0;
- return temp;
-}
-#endif
-
-extern AGprsNetworkType
-android_parse_network_type( const char* speed )
-{
- const struct { const char* name; AGprsNetworkType type; } types[] = {
- { "gprs", A_GPRS_NETWORK_GPRS },
- { "edge", A_GPRS_NETWORK_EDGE },
- { "umts", A_GPRS_NETWORK_UMTS },
- { "hsdpa", A_GPRS_NETWORK_UMTS }, /* not handled yet by Android GSM framework */
- { "full", A_GPRS_NETWORK_UMTS },
- { NULL, 0 }
- };
- int nn;
-
- for (nn = 0; types[nn].name; nn++) {
- if ( !strcmp(speed, types[nn].name) )
- return types[nn].type;
- }
- /* not found, be conservative */
- return A_GPRS_NETWORK_GPRS;
-}
-
-/* 'mode' for +CREG/+CGREG commands */
-typedef enum {
- A_REGISTRATION_UNSOL_DISABLED = 0,
- A_REGISTRATION_UNSOL_ENABLED = 1,
- A_REGISTRATION_UNSOL_ENABLED_FULL = 2
-} ARegistrationUnsolMode;
-
-/* Operator selection mode, see +COPS commands */
-typedef enum {
- A_SELECTION_AUTOMATIC,
- A_SELECTION_MANUAL,
- A_SELECTION_DEREGISTRATION,
- A_SELECTION_SET_FORMAT,
- A_SELECTION_MANUAL_AUTOMATIC
-} AOperatorSelection;
-
-/* Operator status, see +COPS commands */
-typedef enum {
- A_STATUS_UNKNOWN = 0,
- A_STATUS_AVAILABLE,
- A_STATUS_CURRENT,
- A_STATUS_DENIED
-} AOperatorStatus;
-
-typedef struct {
- AOperatorStatus status;
- char name[3][16];
-} AOperatorRec, *AOperator;
-
-typedef struct AVoiceCallRec {
- ACallRec call;
- SysTimer timer;
- AModem modem;
- char is_remote;
-} AVoiceCallRec, *AVoiceCall;
-
-#define MAX_OPERATORS 4
-
-typedef enum {
- A_DATA_IP = 0,
- A_DATA_PPP
-} ADataType;
-
-#define A_DATA_APN_SIZE 32
-
-typedef struct {
- int id;
- int active;
- ADataType type;
- char apn[ A_DATA_APN_SIZE ];
-
-} ADataContextRec, *ADataContext;
-
-/* the spec says that there can only be a max of 4 contexts */
-#define MAX_DATA_CONTEXTS 4
-#define MAX_CALLS 4
-
-#define A_MODEM_SELF_SIZE 3
-
-typedef struct AModemRec_
-{
- /* Radio state */
- ARadioState radio_state;
- int area_code;
- int cell_id;
- int base_port;
-
- /* SMS */
- int wait_sms;
-
- /* SIM card */
- ASimCard sim;
-
- /* voice and data network registration */
- ARegistrationUnsolMode voice_mode;
- ARegistrationState voice_state;
- ARegistrationUnsolMode data_mode;
- ARegistrationState data_state;
- AGprsNetworkType data_network;
-
- /* operator names */
- AOperatorSelection oper_selection_mode;
- ANameIndex oper_name_index;
- int oper_index;
- int oper_count;
- AOperatorRec operators[ MAX_OPERATORS ];
-
- /* data connection contexts */
- ADataContextRec data_contexts[ MAX_DATA_CONTEXTS ];
-
- /* active calls */
- AVoiceCallRec calls[ MAX_CALLS ];
- int call_count;
-
- /* unsolicited callback */ /* XXX: TODO: use this */
- AModemUnsolFunc unsol_func;
- void* unsol_opaque;
-
- SmsReceiver sms_receiver;
-
- int out_size;
- char out_buff[1024];
-
-} AModemRec;
-
-
-static void
-amodem_unsol( AModem modem, const char* format, ... )
-{
- if (modem->unsol_func) {
- va_list args;
- va_start(args, format);
- vsnprintf( modem->out_buff, sizeof(modem->out_buff), format, args );
- va_end(args);
-
- modem->unsol_func( modem->unsol_opaque, modem->out_buff );
- }
-}
-
-void
-amodem_receive_sms( AModem modem, SmsPDU sms )
-{
-#define SMS_UNSOL_HEADER "+CMT: 0\r\n"
-
- if (modem->unsol_func) {
- int len, max;
- char* p;
-
- strcpy( modem->out_buff, SMS_UNSOL_HEADER );
- p = modem->out_buff + (sizeof(SMS_UNSOL_HEADER)-1);
- max = sizeof(modem->out_buff) - 3 - (sizeof(SMS_UNSOL_HEADER)-1);
- len = smspdu_to_hex( sms, p, max );
- if (len > max) /* too long */
- return;
- p[len] = '\r';
- p[len+1] = '\n';
- p[len+2] = 0;
-
- R( "SMS>> %s\n", p );
-
- modem->unsol_func( modem->unsol_opaque, modem->out_buff );
- }
-}
-
-static const char*
-amodem_printf( AModem modem, const char* format, ... )
-{
- va_list args;
- va_start(args, format);
- vsnprintf( modem->out_buff, sizeof(modem->out_buff), format, args );
- va_end(args);
-
- return modem->out_buff;
-}
-
-static void
-amodem_begin_line( AModem modem )
-{
- modem->out_size = 0;
-}
-
-static void
-amodem_add_line( AModem modem, const char* format, ... )
-{
- va_list args;
- va_start(args, format);
- modem->out_size += vsnprintf( modem->out_buff + modem->out_size,
- sizeof(modem->out_buff) - modem->out_size,
- format, args );
- va_end(args);
-}
-
-static const char*
-amodem_end_line( AModem modem )
-{
- modem->out_buff[ modem->out_size ] = 0;
- return modem->out_buff;
-}
-
-static void
-amodem_reset( AModem modem )
-{
- modem->radio_state = A_RADIO_STATE_OFF;
- modem->wait_sms = 0;
-
- modem->oper_name_index = 2;
- modem->oper_selection_mode = A_SELECTION_AUTOMATIC;
- modem->oper_index = 0;
- modem->oper_count = 2;
-
- modem->area_code = -1;
- modem->cell_id = -1;
-
- strcpy( modem->operators[0].name[0], OPERATOR_HOME_NAME );
- strcpy( modem->operators[0].name[1], OPERATOR_HOME_NAME );
- strcpy( modem->operators[0].name[2], OPERATOR_HOME_MCCMNC );
-
- modem->operators[0].status = A_STATUS_AVAILABLE;
-
- strcpy( modem->operators[1].name[0], OPERATOR_ROAMING_NAME );
- strcpy( modem->operators[1].name[1], OPERATOR_ROAMING_NAME );
- strcpy( modem->operators[1].name[2], OPERATOR_ROAMING_MCCMNC );
-
- modem->operators[1].status = A_STATUS_AVAILABLE;
-
- modem->voice_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- modem->voice_state = A_REGISTRATION_HOME;
- modem->data_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- modem->data_state = A_REGISTRATION_HOME;
- modem->data_network = A_GPRS_NETWORK_UMTS;
-}
-
-static AModemRec _android_modem[1];
-
-AModem
-amodem_create( int base_port, AModemUnsolFunc unsol_func, void* unsol_opaque )
-{
- AModem modem = _android_modem;
-
- amodem_reset( modem );
- modem->base_port = base_port;
- modem->unsol_func = unsol_func;
- modem->unsol_opaque = unsol_opaque;
-
- modem->sim = asimcard_create();
-
- return modem;
-}
-
-void
-amodem_destroy( AModem modem )
-{
- asimcard_destroy( modem->sim );
- modem->sim = NULL;
-}
-
-
-static int
-amodem_has_network( AModem modem )
-{
- return !(modem->radio_state == A_RADIO_STATE_OFF ||
- modem->oper_index < 0 ||
- modem->oper_index >= modem->oper_count ||
- modem->oper_selection_mode == A_SELECTION_DEREGISTRATION );
-}
-
-
-ARadioState
-amodem_get_radio_state( AModem modem )
-{
- return modem->radio_state;
-}
-
-void
-amodem_set_radio_state( AModem modem, ARadioState state )
-{
- modem->radio_state = state;
-}
-
-ASimCard
-amodem_get_sim( AModem modem )
-{
- return modem->sim;
-}
-
-ARegistrationState
-amodem_get_voice_registration( AModem modem )
-{
- return modem->voice_state;
-}
-
-void
-amodem_set_voice_registration( AModem modem, ARegistrationState state )
-{
- modem->voice_state = state;
-
- if (state == A_REGISTRATION_HOME)
- modem->oper_index = OPERATOR_HOME_INDEX;
- else if (state == A_REGISTRATION_ROAMING)
- modem->oper_index = OPERATOR_ROAMING_INDEX;
-
- switch (modem->voice_mode) {
- case A_REGISTRATION_UNSOL_ENABLED:
- amodem_unsol( modem, "+CREG: %d,%d\r",
- modem->voice_mode, modem->voice_state );
- break;
-
- case A_REGISTRATION_UNSOL_ENABLED_FULL:
- amodem_unsol( modem, "+CREG: %d,%d, \"%04x\", \"%04x\"\r",
- modem->voice_mode, modem->voice_state,
- modem->area_code, modem->cell_id );
- break;
- default:
- ;
- }
-}
-
-ARegistrationState
-amodem_get_data_registration( AModem modem )
-{
- return modem->data_state;
-}
-
-void
-amodem_set_data_registration( AModem modem, ARegistrationState state )
-{
- modem->data_state = state;
-
- switch (modem->data_mode) {
- case A_REGISTRATION_UNSOL_ENABLED:
- amodem_unsol( modem, "+CGREG: %d,%d\r",
- modem->data_mode, modem->data_state );
- break;
-
- case A_REGISTRATION_UNSOL_ENABLED_FULL:
- amodem_unsol( modem, "+CGREG: %d,%d,\"%04x\",\"%04x\",\"%04x\"\r",
- modem->data_mode, modem->data_state,
- modem->area_code, modem->cell_id,
- modem->data_network );
- break;
-
- default:
- ;
- }
-}
-
-void
-amodem_set_data_network_type( AModem modem, AGprsNetworkType type )
-{
- modem->data_network = type;
- amodem_set_data_registration( modem, modem->data_state );
-}
-
-int
-amodem_get_operator_name ( AModem modem, ANameIndex index, char* buffer, int buffer_size )
-{
- AOperator oper;
- int len;
-
- if ( (unsigned)modem->oper_index >= (unsigned)modem->oper_count ||
- (unsigned)index > 2 )
- return 0;
-
- oper = modem->operators + modem->oper_index;
- len = strlen(oper->name[index]) + 1;
-
- if (buffer_size > len)
- buffer_size = len;
-
- if (buffer_size > 0) {
- memcpy( buffer, oper->name[index], buffer_size-1 );
- buffer[buffer_size] = 0;
- }
- return len;
-}
-
-/* reset one operator name from a user-provided buffer, set buffer_size to -1 for zero-terminated strings */
-void
-amodem_set_operator_name( AModem modem, ANameIndex index, const char* buffer, int buffer_size )
-{
- AOperator oper;
- int avail;
-
- if ( (unsigned)modem->oper_index >= (unsigned)modem->oper_count ||
- (unsigned)index > 2 )
- return;
-
- oper = modem->operators + modem->oper_index;
-
- avail = sizeof(oper->name[0]);
- if (buffer_size < 0)
- buffer_size = strlen(buffer);
- if (buffer_size > avail-1)
- buffer_size = avail-1;
- memcpy( oper->name[index], buffer, buffer_size );
- oper->name[index][buffer_size] = 0;
-}
-
-/** CALLS
- **/
-int
-amodem_get_call_count( AModem modem )
-{
- return modem->call_count;
-}
-
-ACall
-amodem_get_call( AModem modem, int index )
-{
- if ((unsigned)index >= (unsigned)modem->call_count)
- return NULL;
-
- return &modem->calls[index].call;
-}
-
-static AVoiceCall
-amodem_alloc_call( AModem modem )
-{
- AVoiceCall call = NULL;
- int count = modem->call_count;
-
- if (count < MAX_CALLS) {
- int id;
-
- /* find a valid id for this call */
- for (id = 0; id < modem->call_count; id++) {
- int found = 0;
- int nn;
- for (nn = 0; nn < count; nn++) {
- if ( modem->calls[nn].call.id == (id+1) ) {
- found = 1;
- break;
- }
- }
- if (!found)
- break;
- }
- call = modem->calls + count;
- call->call.id = id + 1;
- call->modem = modem;
-
- modem->call_count += 1;
- }
- return call;
-}
-
-
-static void
-amodem_free_call( AModem modem, AVoiceCall call )
-{
- int nn;
-
- if (call->timer) {
- sys_timer_destroy( call->timer );
- call->timer = NULL;
- }
-
- if (call->is_remote) {
- remote_call_cancel( call->call.number, modem->base_port );
- call->is_remote = 0;
- }
-
- for (nn = 0; nn < modem->call_count; nn++) {
- if ( modem->calls + nn == call )
- break;
- }
- assert( nn < modem->call_count );
-
- memmove( modem->calls + nn,
- modem->calls + nn + 1,
- (modem->call_count - 1 - nn)*sizeof(*call) );
-
- modem->call_count -= 1;
-}
-
-
-static AVoiceCall
-amodem_find_call( AModem modem, int id )
-{
- int nn;
-
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall call = modem->calls + nn;
- if (call->call.id == id)
- return call;
- }
- return NULL;
-}
-
-static void
-amodem_send_calls_update( AModem modem )
-{
- /* despite its name, this really tells the system that the call
- * state has changed */
- amodem_unsol( modem, "RING\r" );
-}
-
-
-int
-amodem_add_inbound_call( AModem modem, const char* number )
-{
- AVoiceCall vcall = amodem_alloc_call( modem );
- ACall call = &vcall->call;
- int len;
-
- if (call == NULL)
- return -1;
-
- call->dir = A_CALL_INBOUND;
- call->state = A_CALL_INCOMING;
- call->mode = A_CALL_VOICE;
- call->multi = 0;
-
- vcall->is_remote = (remote_number_string_to_port(number) > 0);
-
- len = strlen(number);
- if (len >= sizeof(call->number))
- len = sizeof(call->number)-1;
-
- memcpy( call->number, number, len );
- call->number[len] = 0;
-
- amodem_send_calls_update( modem );
- return 0;
-}
-
-ACall
-amodem_find_call_by_number( AModem modem, const char* number )
-{
- AVoiceCall vcall = modem->calls;
- AVoiceCall vend = vcall + modem->call_count;
-
- if (!number)
- return NULL;
-
- for ( ; vcall < vend; vcall++ )
- if ( !strcmp(vcall->call.number, number) )
- return &vcall->call;
-
- return NULL;
-}
-
-
-static void
-acall_set_state( AVoiceCall call, ACallState state )
-{
- if (state != call->call.state)
- {
- if (call->is_remote)
- {
- const char* number = call->call.number;
- int port = call->modem->base_port;
-
- switch (state) {
- case A_CALL_HELD:
- remote_call_other( number, port, REMOTE_CALL_HOLD );
- break;
-
- case A_CALL_ACTIVE:
- remote_call_other( number, port, REMOTE_CALL_ACCEPT );
- break;
-
- default: ;
- }
- }
- call->call.state = state;
- }
-}
-
-
-int
-amodem_update_call( AModem modem, const char* fromNumber, ACallState state )
-{
- AVoiceCall vcall = (AVoiceCall) amodem_find_call_by_number(modem, fromNumber);
-
- if (vcall == NULL)
- return -1;
-
- acall_set_state( vcall, state );
- amodem_send_calls_update(modem);
- return 0;
-}
-
-
-int
-amodem_disconnect_call( AModem modem, const char* number )
-{
- AVoiceCall vcall = (AVoiceCall) amodem_find_call_by_number(modem, number);
-
- if (!vcall)
- return -1;
-
- amodem_free_call( modem, vcall );
- amodem_send_calls_update(modem);
- return 0;
-}
-
-/** COMMAND HANDLERS
- **/
-
-static const char*
-unknownCommand( const char* cmd, AModem modem )
-{
- modem=modem;
- fprintf(stderr, ">>> unknown command '%s'\n", cmd );
- return "ERROR: unknown command\r";
-}
-
-static const char*
-handleRadioPower( const char* cmd, AModem modem )
-{
- if ( !strcmp( cmd, "+CFUN=0" ) )
- {
- /* turn radio off */
- modem->radio_state = A_RADIO_STATE_OFF;
- }
- else if ( !strcmp( cmd, "+CFUN=1" ) )
- {
- /* turn radio on */
- modem->radio_state = A_RADIO_STATE_ON;
- }
- return NULL;
-}
-
-static const char*
-handleRadioPowerReq( const char* cmd, AModem modem )
-{
- if (modem->radio_state != A_RADIO_STATE_OFF)
- return "+CFUN=1";
- else
- return "+CFUN=0";
-}
-
-static const char*
-handleSIMStatusReq( const char* cmd, AModem modem )
-{
- const char* answer = NULL;
-
- switch (asimcard_get_status(modem->sim)) {
- case A_SIM_STATUS_ABSENT: answer = "+CPIN: ABSENT"; break;
- case A_SIM_STATUS_READY: answer = "+CPIN: READY"; break;
- case A_SIM_STATUS_NOT_READY: answer = "+CMERROR: NOT READY"; break;
- case A_SIM_STATUS_PIN: answer = "+CPIN: SIM PIN"; break;
- case A_SIM_STATUS_PUK: answer = "+CPIN: SIM PUK"; break;
- case A_SIM_STATUS_NETWORK_PERSONALIZATION: answer = "+CPIN: PH-NET PIN"; break;
- default:
- answer = "ERROR: internal error";
- }
- return answer;
-}
-
-static const char*
-handleNetworkRegistration( const char* cmd, AModem modem )
-{
- if ( !memcmp( cmd, "+CREG", 5 ) ) {
- cmd += 5;
- if (cmd[0] == '?') {
- return amodem_printf( modem, "+CREG: %d,%d, \"%04x\", \"%04x\"",
- modem->voice_mode, modem->voice_state,
- modem->area_code, modem->cell_id );
- } else if (cmd[0] == '=') {
- switch (cmd[1]) {
- case '0':
- modem->voice_mode = A_REGISTRATION_UNSOL_DISABLED;
- break;
-
- case '1':
- modem->voice_mode = A_REGISTRATION_UNSOL_ENABLED;
- break;
-
- case '2':
- modem->voice_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- break;
-
- case '?':
- return "+CREG: (0-2)";
-
- default:
- return "ERROR: BAD COMMAND";
- }
- } else {
- assert( 0 && "unreachable" );
- }
- } else if ( !memcmp( cmd, "+CGREG", 6 ) ) {
- cmd += 6;
- if (cmd[0] == '?') {\
- return amodem_printf( modem, "+CGREG: %d,%d,\"%04x\",\"%04x\",\"%04x\"",
- modem->data_mode, modem->data_state,
- modem->area_code, modem->cell_id,
- modem->data_network );
- } else if (cmd[0] == '=') {
- switch (cmd[1]) {
- case '0':
- modem->data_mode = A_REGISTRATION_UNSOL_DISABLED;
- break;
-
- case '1':
- modem->data_mode = A_REGISTRATION_UNSOL_ENABLED;
- break;
-
- case '2':
- modem->data_mode = A_REGISTRATION_UNSOL_ENABLED_FULL;
- break;
-
- case '?':
- return "+CGREG: (0-2)";
-
- default:
- return "ERROR: BAD COMMAND";
- }
- } else {
- assert( 0 && "unreachable" );
- }
- }
- return NULL;
-}
-
-static const char*
-handleSetDialTone( const char* cmd, AModem modem )
-{
- /* XXX: TODO */
- return NULL;
-}
-
-static const char*
-handleDeleteSMSonSIM( const char* cmd, AModem modem )
-{
- /* XXX: TODO */
- return NULL;
-}
-
-static const char*
-handleSIM_IO( const char* cmd, AModem modem )
-{
- return asimcard_io( modem->sim, cmd );
-}
-
-
-static const char*
-handleOperatorSelection( const char* cmd, AModem modem )
-{
- assert( !memcmp( "+COPS", cmd, 5 ) );
- cmd += 5;
- if (cmd[0] == '?') { /* ask for current operator */
- AOperator oper = &modem->operators[ modem->oper_index ];
-
- if ( !amodem_has_network( modem ) )
- {
- /* this error code means "no network" */
- return amodem_printf( modem, "+CME ERROR: 30" );
- }
-
- oper = &modem->operators[ modem->oper_index ];
-
- if ( modem->oper_name_index == 2 )
- return amodem_printf( modem, "+COPS: %d,2,%s",
- modem->oper_selection_mode,
- oper->name[2] );
-
- return amodem_printf( modem, "+COPS: %d,%d,\"%s\"",
- modem->oper_selection_mode,
- modem->oper_name_index,
- oper->name[ modem->oper_name_index ] );
- }
- else if (cmd[0] == '=' && cmd[1] == '?') { /* ask for all available operators */
- const char* comma = "+COPS: ";
- int nn;
- amodem_begin_line( modem );
- for (nn = 0; nn < modem->oper_count; nn++) {
- AOperator oper = &modem->operators[nn];
- amodem_add_line( modem, "%s(%d,\"%s\",\"%s\",\"%s\")", comma,
- oper->status, oper->name[0], oper->name[1], oper->name[2] );
- comma = ", ";
- }
- return amodem_end_line( modem );
- }
- else if (cmd[0] == '=') {
- switch (cmd[1]) {
- case '0':
- modem->oper_selection_mode = A_SELECTION_AUTOMATIC;
- return NULL;
-
- case '1':
- {
- int format, nn, len, found = -1;
-
- if (cmd[2] != ',')
- goto BadCommand;
- format = cmd[3] - '0';
- if ( (unsigned)format > 2 )
- goto BadCommand;
- if (cmd[4] != ',')
- goto BadCommand;
- cmd += 5;
- len = strlen(cmd);
- if (*cmd == '"') {
- cmd++;
- len -= 2;
- }
- if (len <= 0)
- goto BadCommand;
-
- for (nn = 0; nn < modem->oper_count; nn++) {
- AOperator oper = modem->operators + nn;
- char* name = oper->name[ format ];
-
- if ( !memcpy( name, cmd, len ) && name[len] == 0 ) {
- found = nn;
- break;
- }
- }
-
- if (found < 0) {
- /* Selection failed */
- return "+CME ERROR: 529";
- } else if (modem->operators[found].status == A_STATUS_DENIED) {
- /* network not allowed */
- return "+CME ERROR: 32";
- }
- modem->oper_index = found;
-
- /* set the voice and data registration states to home or roaming
- * depending on the operator index
- */
- if (found == OPERATOR_HOME_INDEX) {
- modem->voice_state = A_REGISTRATION_HOME;
- modem->data_state = A_REGISTRATION_HOME;
- } else if (found == OPERATOR_ROAMING_INDEX) {
- modem->voice_state = A_REGISTRATION_ROAMING;
- modem->data_state = A_REGISTRATION_ROAMING;
- }
- return NULL;
- }
-
- case '2':
- modem->oper_selection_mode = A_SELECTION_DEREGISTRATION;
- return NULL;
-
- case '3':
- {
- int format;
-
- if (cmd[2] != ',')
- goto BadCommand;
-
- format = cmd[3] - '0';
- if ( (unsigned)format > 2 )
- goto BadCommand;
-
- modem->oper_name_index = format;
- return NULL;
- }
- default:
- ;
- }
- }
-BadCommand:
- return unknownCommand(cmd,modem);
-}
-
-static const char*
-handleRequestOperator( const char* cmd, AModem modem )
-{
- AOperator oper;
- cmd=cmd;
-
- if ( !amodem_has_network(modem) )
- return "+CME ERROR: 30";
-
- oper = modem->operators + modem->oper_index;
- modem->oper_name_index = 2;
- return amodem_printf( modem, "+COPS: 0,0,\"%s\"\r"
- "+COPS: 0,1,\"%s\"\r"
- "+COPS: 0,2,\"%s\"",
- oper->name[0], oper->name[1], oper->name[2] );
-}
-
-static const char*
-handleSendSMStoSIM( const char* cmd, AModem modem )
-{
- /* XXX: TODO */
- return "ERROR: unimplemented";
-}
-
-static const char*
-handleSendSMS( const char* cmd, AModem modem )
-{
- modem->wait_sms = 1;
- return "> ";
-}
-
-#if 0
-static void
-sms_address_dump( SmsAddress address, FILE* out )
-{
- int nn, len = address->len;
-
- if (address->toa == 0x91) {
- fprintf( out, "+" );
- }
- for (nn = 0; nn < len; nn += 2)
- {
- static const char dialdigits[16] = "0123456789*#,N%";
- int c = address->data[nn/2];
-
- fprintf( out, "%c", dialdigits[c & 0xf] );
- if (nn+1 >= len)
- break;
-
- fprintf( out, "%c", dialdigits[(c >> 4) & 0xf] );
- }
-}
-
-static void
-smspdu_dump( SmsPDU pdu, FILE* out )
-{
- SmsAddressRec address;
- unsigned char temp[256];
- int len;
-
- if (pdu == NULL) {
- fprintf( out, "SMS PDU is (null)\n" );
- return;
- }
-
- fprintf( out, "SMS PDU type: " );
- switch (smspdu_get_type(pdu)) {
- case SMS_PDU_DELIVER: fprintf(out, "DELIVER"); break;
- case SMS_PDU_SUBMIT: fprintf(out, "SUBMIT"); break;
- case SMS_PDU_STATUS_REPORT: fprintf(out, "STATUS_REPORT"); break;
- default: fprintf(out, "UNKNOWN");
- }
- fprintf( out, "\n sender: " );
- if (smspdu_get_sender_address(pdu, &address) < 0)
- fprintf( out, "(N/A)" );
- else
- sms_address_dump(&address, out);
- fprintf( out, "\n receiver: " );
- if (smspdu_get_receiver_address(pdu, &address) < 0)
- fprintf(out, "(N/A)");
- else
- sms_address_dump(&address, out);
- fprintf( out, "\n text: " );
- len = smspdu_get_text_message( pdu, temp, sizeof(temp)-1 );
- if (len > sizeof(temp)-1 )
- len = sizeof(temp)-1;
- fprintf( out, "'%.*s'\n", len, temp );
-}
-#endif
-
-static const char*
-handleSendSMSText( const char* cmd, AModem modem )
-{
-#if 1
- SmsAddressRec address;
- char number[16];
- int numlen;
- int len = strlen(cmd);
- SmsPDU pdu;
-
- /* get rid of trailing escape */
- if (len > 0 && cmd[len-1] == 0x1a)
- len -= 1;
-
- pdu = smspdu_create_from_hex( cmd, len );
- if (pdu == NULL) {
- D("%s: invalid SMS PDU ?: '%s'\n", __FUNCTION__, cmd);
- return "+CMS ERROR: INVALID SMS PDU";
- }
- if (smspdu_get_receiver_address(pdu, &address) < 0) {
- D("%s: could not get SMS receiver address from '%s'\n",
- __FUNCTION__, cmd);
- return "+CMS ERROR: BAD SMS RECEIVER ADDRESS";
- }
-
- do {
- int index;
-
- numlen = sms_address_to_str( &address, number, sizeof(number) );
- if (numlen > sizeof(number)-1)
- break;
-
- number[numlen] = 0;
- if ( remote_number_string_to_port( number ) < 0 )
- break;
-
- if (modem->sms_receiver == NULL) {
- modem->sms_receiver = sms_receiver_create();
- if (modem->sms_receiver == NULL) {
- D( "%s: could not create SMS receiver\n", __FUNCTION__ );
- break;
- }
- }
-
- index = sms_receiver_add_submit_pdu( modem->sms_receiver, pdu );
- if (index < 0) {
- D( "%s: could not add submit PDU\n", __FUNCTION__ );
- break;
- }
- /* the PDU is now owned by the receiver */
- pdu = NULL;
-
- if (index > 0) {
- SmsAddressRec from[1];
- char temp[10];
- SmsPDU* deliver;
- int nn;
-
- sprintf( temp, "%d", modem->base_port );
- sms_address_from_str( from, temp, strlen(temp) );
-
- deliver = sms_receiver_create_deliver( modem->sms_receiver, index, from );
- if (deliver == NULL) {
- D( "%s: could not create deliver PDUs for SMS index %d\n",
- __FUNCTION__, index );
- break;
- }
-
- for (nn = 0; deliver[nn] != NULL; nn++) {
- if ( remote_call_sms( number, modem->base_port, deliver[nn] ) < 0 ) {
- D( "%s: could not send SMS PDU to remote emulator\n",
- __FUNCTION__ );
- break;
- }
- }
-
- smspdu_free_list(deliver);
- }
-
- } while (0);
-
- if (pdu != NULL)
- smspdu_free(pdu);
-
-#elif 1
- SmsAddressRec address;
- char number[16];
- int numlen;
- int len = strlen(cmd);
- SmsPDU pdu;
-
- /* get rid of trailing escape */
- if (len > 0 && cmd[len-1] == 0x1a)
- len -= 1;
-
- pdu = smspdu_create_from_hex( cmd, len );
- if (pdu == NULL) {
- D("%s: invalid SMS PDU ?: '%s'\n", __FUNCTION__, cmd);
- return "+CMS ERROR: INVALID SMS PDU";
- }
- if (smspdu_get_receiver_address(pdu, &address) < 0) {
- D("%s: could not get SMS receiver address from '%s'\n",
- __FUNCTION__, cmd);
- return "+CMS ERROR: BAD SMS RECEIVER ADDRESS";
- }
- do {
- numlen = sms_address_to_str( &address, number, sizeof(number) );
- if (numlen > sizeof(number)-1)
- break;
-
- number[numlen] = 0;
- if ( remote_number_string_to_port( number ) < 0 )
- break;
-
- if ( remote_call_sms( number, modem->base_port, pdu ) < 0 )
- {
- D("%s: could not send SMS PDU to remote emulator\n",
- __FUNCTION__);
- return "+CMS ERROR: NO EMULATOR RECEIVER";
- }
- } while (0);
-#else
- fprintf(stderr, "SMS<< %s\n", cmd);
- SmsPDU pdu = smspdu_create_from_hex( cmd, strlen(cmd) );
- if (pdu == NULL) {
- fprintf(stderr, "invalid SMS PDU ?: '%s'\n", cmd);
- } else {
- smspdu_dump(pdu, stderr);
- }
-#endif
- return "+CMGS: 0\rOK\r";
-}
-
-static const char*
-handleChangeOrEnterPIN( const char* cmd, AModem modem )
-{
- assert( !memcmp( cmd, "+CPIN=", 6 ) );
- cmd += 6;
-
- switch (asimcard_get_status(modem->sim)) {
- case A_SIM_STATUS_ABSENT:
- return "+CME ERROR: SIM ABSENT";
-
- case A_SIM_STATUS_NOT_READY:
- return "+CME ERROR: SIM NOT READY";
-
- case A_SIM_STATUS_READY:
- /* this may be a request to change the PIN */
- {
- if (strlen(cmd) == 9 && cmd[4] == ',') {
- char pin[5];
- memcpy( pin, cmd, 4 ); pin[4] = 0;
-
- if ( !asimcard_check_pin( modem->sim, pin ) )
- return "+CME ERROR: BAD PIN";
-
- memcpy( pin, cmd+5, 4 );
- asimcard_set_pin( modem->sim, pin );
- return "+CPIN: READY";
- }
- }
- break;
-
- case A_SIM_STATUS_PIN: /* waiting for PIN */
- if ( asimcard_check_pin( modem->sim, cmd ) )
- return "+CPIN: READY";
- else
- return "+CME ERROR: BAD PIN";
-
- case A_SIM_STATUS_PUK:
- if (strlen(cmd) == 9 && cmd[4] == ',') {
- char puk[5];
- memcpy( puk, cmd, 4 );
- puk[4] = 0;
- if ( asimcard_check_puk( modem->sim, puk, cmd+5 ) )
- return "+CPIN: READY";
- else
- return "+CME ERROR: BAD PUK";
- }
- return "+CME ERROR: BAD PUK";
-
- default:
- return "+CPIN: PH-NET PIN";
- }
-
- return "+CME ERROR: BAD FORMAT";
-}
-
-
-static const char*
-handleListCurrentCalls( const char* cmd, AModem modem )
-{
- int nn;
- amodem_begin_line( modem );
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode == A_CALL_VOICE)
- amodem_add_line( modem, "+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
- call->id, call->dir, call->state, call->mode,
- call->multi, call->number, 129 );
- }
- return amodem_end_line( modem );
-}
-
-/* retrieve the current time and zone in a format suitable
- * for %CTZV: unsolicited message
- * "yy/mm/dd,hh:mm:ss(+/-)tz"
- * mm is 0-based
- * tz is in number of quarter-hours
- *
- * it seems reference-ril doesn't parse the comma (,) as anything else than a token
- * separator, so use a column (:) instead, the Java parsing code won't see a difference
- *
- */
-static const char*
-handleEndOfInit( const char* cmd, AModem modem )
-{
- time_t now = time(NULL);
- struct tm utc, local;
- long e_local, e_utc;
- long tzdiff;
- char tzname[64];
-
- tzset();
-
- utc = *gmtime( &now );
- local = *localtime( &now );
-
- e_local = local.tm_min + 60*(local.tm_hour + 24*local.tm_yday);
- e_utc = utc.tm_min + 60*(utc.tm_hour + 24*utc.tm_yday);
-
- if ( utc.tm_year < local.tm_year )
- e_local += 24*60;
- else if ( utc.tm_year > local.tm_year )
- e_utc += 24*60;
-
- tzdiff = e_local - e_utc; /* timezone offset in minutes */
-
- /* retrieve a zoneinfo-compatible name for the host timezone
- */
- {
- char* end = tzname + sizeof(tzname);
- char* p = bufprint_zoneinfo_timezone( tzname, end );
- if (p >= end)
- strcpy(tzname, "Unknown/Unknown");
-
- /* now replace every / in the timezone name by a "!"
- * that's because the code that reads the CTZV line is
- * dumb and treats a / as a field separator...
- */
- p = tzname;
- while (1) {
- p = strchr(p, '/');
- if (p == NULL)
- break;
- *p = '!';
- p += 1;
- }
- }
-
- /* as a special extension, we append the name of the host's time zone to the
- * string returned with %CTZ. the system should contain special code to detect
- * and deal with this case (since it normally relied on the operator's country code
- * which is hard to simulate on a general-purpose computer
- */
- return amodem_printf( modem, "%%CTZV: %02d/%02d/%02d:%02d:%02d:%02d%c%d:%d:%s",
- (utc.tm_year + 1900) % 100, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec,
- (tzdiff >= 0) ? '+' : '-', (tzdiff >= 0 ? tzdiff : -tzdiff) / 15,
- (local.tm_isdst > 0),
- tzname );
-}
-
-
-static const char*
-handleListPDPContexts( const char* cmd, AModem modem )
-{
- int nn;
- assert( !memcmp( cmd, "+CGACT?", 7 ) );
- amodem_begin_line( modem );
- for (nn = 0; nn < MAX_DATA_CONTEXTS; nn++) {
- ADataContext data = modem->data_contexts + nn;
- if (!data->active)
- continue;
- amodem_add_line( modem, "+CGACT: %d,%d\r", data->id, data->active );
- }
- return amodem_end_line( modem );
-}
-
-static const char*
-handleDefinePDPContext( const char* cmd, AModem modem )
-{
- assert( !memcmp( cmd, "+CGDCONT=", 9 ) );
- cmd += 9;
- if (cmd[0] == '?') {
- int nn;
- amodem_begin_line(modem);
- for (nn = 0; nn < MAX_DATA_CONTEXTS; nn++) {
- ADataContext data = modem->data_contexts + nn;
- if (!data->active)
- continue;
- amodem_add_line( modem, "+CGDCONT: %d,%s,\"%s\",,0,0\r\n",
- data->id,
- data->type == A_DATA_IP ? "IP" : "PPP",
- data->apn );
- }
- return amodem_end_line(modem);
- } else {
- /* template is +CGDCONT=<id>,"<type>","<apn>",,0,0 */
- int id = cmd[0] - '1';
- ADataType type;
- char apn[32];
- ADataContext data;
-
- if ((unsigned)id > 3)
- goto BadCommand;
-
- if ( !memcmp( cmd+1, ",\"IP\",\"", 7 ) ) {
- type = A_DATA_IP;
- cmd += 8;
- } else if ( !memcmp( cmd+1, ",\"PPP\",\"", 8 ) ) {
- type = A_DATA_PPP;
- cmd += 9;
- } else
- goto BadCommand;
-
- {
- const char* p = strchr( cmd, '"' );
- int len;
- if (p == NULL)
- goto BadCommand;
- len = (int)( p - cmd );
- if (len > sizeof(apn)-1 )
- len = sizeof(apn)-1;
- memcpy( apn, cmd, len );
- apn[len] = 0;
- }
-
- data = modem->data_contexts + id;
-
- data->id = id + 1;
- data->active = 1;
- data->type = type;
- memcpy( data->apn, apn, sizeof(data->apn) );
- }
- return NULL;
-BadCommand:
- return "ERROR: BAD COMMAND";
-}
-
-
-static const char*
-handleStartPDPContext( const char* cmd, AModem modem )
-{
- /* XXX: TODO: handle PDP start appropriately */
- /* for the moment, always return success */
-#if 0
- AVoiceCall vcall = amodem_alloc_call( modem );
- ACall call = (ACall) vcall;
- if (call == NULL) {
- return "ERROR: TOO MANY CALLS";
- }
- call->id = 1;
- call->dir = A_CALL_OUTBOUND;
- /* XXX: it would be better to delay this */
- call->state = A_CALL_ACTIVE;
- call->mode = A_CALL_DATA;
- call->multi = 0;
- strcpy( call->number, "012345" );
-#endif
- return NULL;
-}
-
-
-static void
-remote_voice_call_event( void* _vcall, int success )
-{
- AVoiceCall vcall = _vcall;
- AModem modem = vcall->modem;
-
- /* NOTE: success only means we could send the "gsm in new" command
- * to the remote emulator, nothing more */
-
- if (!success) {
- /* aargh, the remote emulator probably quitted at that point */
- amodem_free_call(modem, vcall);
- amodem_send_calls_update(modem);
- }
-}
-
-
-static void
-voice_call_event( void* _vcall )
-{
- AVoiceCall vcall = _vcall;
- ACall call = &vcall->call;
-
- switch (call->state) {
- case A_CALL_DIALING:
- call->state = A_CALL_ALERTING;
-
- if (vcall->is_remote) {
- if ( remote_call_dial( call->number,
- vcall->modem->base_port,
- remote_voice_call_event, vcall ) < 0 )
- {
- /* we could not connect, probably because the corresponding
- * emulator is not running, so simply destroy this call.
- * XXX: should we send some sort of message to indicate BAD NUMBER ? */
- /* it seems the Android code simply waits for changes in the list */
- amodem_free_call( vcall->modem, vcall );
- }
- } else {
- /* this is not a remote emulator number, so just simulate
- * a small ringing delay */
- sys_timer_set( vcall->timer, sys_time_ms() + CALL_DELAY_ALERT,
- voice_call_event, vcall );
- }
- break;
-
- case A_CALL_ALERTING:
- call->state = A_CALL_ACTIVE;
- break;
-
- default:
- assert( 0 && "unreachable event call state" );
- }
- amodem_send_calls_update(vcall->modem);
-}
-
-
-static const char*
-handleDial( const char* cmd, AModem modem )
-{
- AVoiceCall vcall = amodem_alloc_call( modem );
- ACall call = &vcall->call;
- int len;
-
- if (call == NULL)
- return "ERROR: TOO MANY CALLS";
-
- assert( cmd[0] == 'D' );
- call->dir = A_CALL_OUTBOUND;
- call->state = A_CALL_DIALING;
- call->mode = A_CALL_VOICE;
- call->multi = 0;
-
- cmd += 1;
- len = strlen(cmd);
- if (len > 0 && cmd[len-1] == ';')
- len--;
- if (len >= sizeof(call->number))
- len = sizeof(call->number)-1;
-
- memcpy( call->number, cmd, len );
- call->number[len] = 0;
-
- vcall->is_remote = (remote_number_string_to_port(call->number) > 0);
-
- vcall->timer = sys_timer_create();
- sys_timer_set( vcall->timer, sys_time_ms() + CALL_DELAY_DIAL,
- voice_call_event, vcall );
-
- return NULL;
-}
-
-
-static const char*
-handleAnswer( const char* cmd, AModem modem )
-{
- int nn;
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
-
- if (cmd[0] == 'A') {
- if (call->state == A_CALL_INCOMING) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- }
- else if (call->state == A_CALL_ACTIVE) {
- acall_set_state( vcall, A_CALL_HELD );
- }
- } else if (cmd[0] == 'H') {
- /* ATH: hangup, since user is busy */
- if (call->state == A_CALL_INCOMING) {
- amodem_free_call( modem, vcall );
- break;
- }
- }
- }
- return NULL;
-}
-
-static const char*
-handleHangup( const char* cmd, AModem modem )
-{
- if ( !memcmp(cmd, "+CHLD=", 6) ) {
- int nn;
- cmd += 6;
- switch (cmd[0]) {
- case '0': /* release all held, and set busy for waiting calls */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_HELD ||
- call->state == A_CALL_WAITING ||
- call->state == A_CALL_INCOMING) {
- amodem_free_call(modem, vcall);
- nn--;
- }
- }
- break;
-
- case '1':
- if (cmd[1] == 0) { /* release all active, accept held one */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_ACTIVE) {
- amodem_free_call(modem, vcall);
- nn--;
- }
- else if (call->state == A_CALL_HELD ||
- call->state == A_CALL_WAITING) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- }
- }
- } else { /* release specific call */
- int id = cmd[1] - '0';
- AVoiceCall vcall = amodem_find_call( modem, id );
- if (vcall != NULL)
- amodem_free_call( modem, vcall );
- }
- break;
-
- case '2':
- if (cmd[1] == 0) { /* place all active on hold, accept held or waiting one */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_ACTIVE) {
- acall_set_state( vcall, A_CALL_HELD );
- }
- else if (call->state == A_CALL_HELD ||
- call->state == A_CALL_WAITING) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- }
- }
- } else { /* place all active on hold, except a specific one */
- int id = cmd[1] - '0';
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_ACTIVE && call->id != id) {
- acall_set_state( vcall, A_CALL_HELD );
- }
- }
- }
- break;
-
- case '3': /* add a held call to the conversation */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_HELD) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- break;
- }
- }
- break;
-
- case '4': /* connect the two calls */
- for (nn = 0; nn < modem->call_count; nn++) {
- AVoiceCall vcall = modem->calls + nn;
- ACall call = &vcall->call;
- if (call->mode != A_CALL_VOICE)
- continue;
- if (call->state == A_CALL_HELD) {
- acall_set_state( vcall, A_CALL_ACTIVE );
- break;
- }
- }
- break;
- }
- }
- else
- return "ERROR: BAD COMMAND";
-
- return NULL;
-}
-
-
-/* a function used to deal with a non-trivial request */
-typedef const char* (*ResponseHandler)(const char* cmd, AModem modem);
-
-static const struct {
- const char* cmd; /* command coming from libreference-ril.so, if first
- character is '!', then the rest is a prefix only */
-
- const char* answer; /* default answer, NULL if needs specific handling or
- if OK is good enough */
-
- ResponseHandler handler; /* specific handler, ignored if 'answer' is not NULL,
- NULL if OK is good enough */
-} sDefaultResponses[] =
-{
- /* see onRadioPowerOn() */
- { "%CPHS=1", NULL, NULL },
- { "%CTZV=1", NULL, NULL },
-
- /* see onSIMReady() */
- { "+CSMS=1", "+CSMS: 1, 1, 1", NULL },
- { "+CNMI=1,2,2,1,1", NULL, NULL },
-
- /* see requestRadioPower() */
- { "+CFUN=0", NULL, handleRadioPower },
- { "+CFUN=1", NULL, handleRadioPower },
-
- /* see requestOrSendPDPContextList() */
- { "+CGACT?", "", handleListPDPContexts },
-
- /* see requestOperator() */
- { "+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?", NULL, handleRequestOperator },
-
- /* see requestQueryNetworkSelectionMode() */
- { "!+COPS", NULL, handleOperatorSelection },
-
- /* see requestGetCurrentCalls() */
- { "+CLCC", NULL, handleListCurrentCalls },
-
- /* see requestWriteSmsToSim() */
- { "!+CMGW=", NULL, handleSendSMStoSIM },
-
- /* see requestHangup() */
- { "!+CHLD=", NULL, handleHangup },
-
- /* see requestSignalStrength() */
- { "+CSQ", "+CSQ: 7,99", NULL }, /* XXX: TODO: implement variable signal strength and error rates */
-
- /* see requestRegistrationState() */
- { "!+CREG", NULL, handleNetworkRegistration },
- { "!+CGREG", NULL, handleNetworkRegistration },
-
- /* see requestSendSMS() */
- { "!+CMGS=", NULL, handleSendSMS },
-
- /* see requestSetupDefaultPDP() */
- { "%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"", NULL, NULL },
- { "%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL, NULL },
-
- { "!+CGDCONT=", NULL, handleDefinePDPContext },
-
- { "+CGQREQ=1", NULL, NULL },
- { "+CGQMIN=1", NULL, NULL },
- { "+CGEREP=1,0", NULL, NULL },
- { "+CGACT=1,0", NULL, NULL },
- { "D*99***1#", NULL, handleStartPDPContext },
-
- /* see requestDial() */
- { "!D", NULL, handleDial }, /* the code says that success/error is ignored, the call state will
- be polled through +CLCC instead */
-
- /* see requestSMSAcknowledge() */
- { "+CNMA=1", NULL, NULL },
- { "+CNMA=2", NULL, NULL },
-
- /* see requestSIM_IO() */
- { "!+CRSM=", NULL, handleSIM_IO },
-
- /* see onRequest() */
- { "+CHLD=0", NULL, handleHangup },
- { "+CHLD=1", NULL, handleHangup },
- { "+CHLD=2", NULL, handleHangup },
- { "+CHLD=3", NULL, handleHangup },
- { "A", NULL, handleAnswer }, /* answer the call */
- { "H", NULL, handleAnswer }, /* user is busy */
- { "!+VTS=", NULL, handleSetDialTone },
- { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */
- { "+CGSN", "000000000000000", NULL }, /* request model version */
- { "+CUSD=2",NULL, NULL }, /* Cancel USSD */
- { "+COPS=0", NULL, handleOperatorSelection }, /* set network selection to automatic */
- { "!+CMGD=", NULL, handleDeleteSMSonSIM }, /* delete SMS on SIM */
- { "!+CPIN=", NULL, handleChangeOrEnterPIN },
-
- /* see getSIMStatus() */
- { "+CPIN?", NULL, handleSIMStatusReq },
- { "+CNMI?", "+CNMI: 1,2,2,1,1", NULL },
-
- /* see isRadioOn() */
- { "+CFUN?", NULL, handleRadioPowerReq },
-
- /* see initializeCallback() */
- { "E0Q0V1", NULL, NULL },
- { "S0=0", NULL, NULL },
- { "+CMEE=1", NULL, NULL },
- { "+CREG=2", NULL, handleNetworkRegistration },
- { "+CREG=1", NULL, handleNetworkRegistration },
- { "+CGREG=1", NULL, handleNetworkRegistration },
- { "+CCWA=1", NULL, NULL },
- { "+CMOD=0", NULL, NULL },
- { "+CMUT=0", NULL, NULL },
- { "+CSSN=0,1", NULL, NULL },
- { "+COLP=0", NULL, NULL },
- { "+CSCS=\"HEX\"", NULL, NULL },
- { "+CUSD=1", NULL, NULL },
- { "+CGEREP=1,0", NULL, NULL },
- { "+CMGF=0", NULL, handleEndOfInit }, /* now is a goof time to send the current tme and timezone */
- { "%CPI=3", NULL, NULL },
- { "%CSTAT=1", NULL, NULL },
-
- /* end of list */
- {NULL, NULL, NULL}
-};
-
-
-#define REPLY(str) do { const char* s = (str); R(">> %s\n", quote(s)); return s; } while (0)
-
-const char* amodem_send( AModem modem, const char* cmd )
-{
- const char* answer;
-
- if ( modem->wait_sms != 0 ) {
- modem->wait_sms = 0;
- R( "SMS<< %s\n", quote(cmd) );
- answer = handleSendSMSText( cmd, modem );
- REPLY(answer);
- }
-
- /* everything that doesn't start with 'AT' is not a command, right ? */
- if ( cmd[0] != 'A' || cmd[1] != 'T' || cmd[2] == 0 ) {
- /* R( "-- %s\n", quote(cmd) ); */
- return NULL;
- }
- R( "<< %s\n", quote(cmd) );
-
- cmd += 2;
-
- /* TODO: implement command handling */
- {
- int nn, found = 0;
-
- for (nn = 0; ; nn++) {
- const char* scmd = sDefaultResponses[nn].cmd;
-
- if (!scmd) /* end of list */
- break;
-
- if (scmd[0] == '!') { /* prefix match */
- int len = strlen(++scmd);
-
- if ( !memcmp( scmd, cmd, len ) ) {
- found = 1;
- break;
- }
- } else { /* full match */
- if ( !strcmp( scmd, cmd ) ) {
- found = 1;
- break;
- }
- }
- }
-
- if ( !found )
- {
- D( "** UNSUPPORTED COMMAND **\n" );
- REPLY( "ERROR: UNSUPPORTED" );
- }
- else
- {
- const char* answer = sDefaultResponses[nn].answer;
- ResponseHandler handler = sDefaultResponses[nn].handler;
-
- if ( answer != NULL ) {
- REPLY( amodem_printf( modem, "%s\rOK", answer ) );
- }
-
- if (handler == NULL) {
- REPLY( "OK" );
- }
-
- answer = handler( cmd, modem );
- if (answer == NULL)
- REPLY( "OK" );
-
- if ( !memcmp( answer, "> ", 2 ) ||
- !memcmp( answer, "ERROR", 5 ) ||
- !memcmp( answer, "+CME ERROR", 6 ) )
- {
- REPLY( answer );
- }
-
- if (answer != modem->out_buff)
- REPLY( amodem_printf( modem, "%s\rOK", answer ) );
-
- strcat( modem->out_buff, "\rOK" );
- REPLY( answer );
- }
- }
-}
diff --git a/telephony/android_modem.h b/telephony/android_modem.h
deleted file mode 100644
index 80d22c5..0000000
--- a/telephony/android_modem.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_modem_h_
-#define _android_modem_h_
-
-#include "sim_card.h"
-#include "sms.h"
-
-/** MODEM OBJECT
- **/
-typedef struct AModemRec_* AModem;
-
-/* a function used by the modem to send unsolicited messages to the channel controller */
-typedef void (*AModemUnsolFunc)( void* opaque, const char* message );
-
-extern AModem amodem_create( int base_port, AModemUnsolFunc unsol_func, void* unsol_opaque );
-extern void amodem_destroy( AModem modem );
-
-/* send a command to the modem */
-extern const char* amodem_send( AModem modem, const char* cmd );
-
-/* simulate the receipt on an incoming SMS message */
-extern void amodem_receive_sms( AModem modem, SmsPDU pdu );
-
-/** RADIO STATE
- **/
-typedef enum {
- A_RADIO_STATE_OFF = 0, /* Radio explictly powered off (eg CFUN=0) */
- A_RADIO_STATE_ON, /* Radio on */
-} ARadioState;
-
-extern ARadioState amodem_get_radio_state( AModem modem );
-extern void amodem_set_radio_state( AModem modem, ARadioState state );
-
-/** SIM CARD STATUS
- **/
-extern ASimCard amodem_get_sim( AModem modem );
-
-/** VOICE AND DATA NETWORK REGISTRATION
- **/
-
-/* 'stat' for +CREG/+CGREG commands */
-typedef enum {
- A_REGISTRATION_UNREGISTERED = 0,
- A_REGISTRATION_HOME = 1,
- A_REGISTRATION_SEARCHING,
- A_REGISTRATION_DENIED,
- A_REGISTRATION_UNKNOWN,
- A_REGISTRATION_ROAMING
-} ARegistrationState;
-
-typedef enum {
- A_GPRS_NETWORK_UNKNOWN = 0,
- A_GPRS_NETWORK_GPRS,
- A_GPRS_NETWORK_EDGE,
- A_GPRS_NETWORK_UMTS
-} AGprsNetworkType;
-
-extern ARegistrationState amodem_get_voice_registration( AModem modem );
-extern void amodem_set_voice_registration( AModem modem, ARegistrationState state );
-
-extern ARegistrationState amodem_get_data_registration( AModem modem );
-extern void amodem_set_data_registration( AModem modem, ARegistrationState state );
-extern void amodem_set_data_network_type( AModem modem, AGprsNetworkType type );
-
-extern AGprsNetworkType android_parse_network_type( const char* speed );
-
-
-/** OPERATOR NAMES
- **/
-typedef enum {
- A_NAME_LONG = 0,
- A_NAME_SHORT,
- A_NAME_NUMERIC,
- A_NAME_MAX /* don't remove */
-} ANameIndex;
-
-/* retrieve operator name into user-provided buffer. returns number of writes written, including terminating zero */
-extern int amodem_get_operator_name ( AModem modem, ANameIndex index, char* buffer, int buffer_size );
-
-/* reset one operator name from a user-provided buffer, set buffer_size to -1 for zero-terminated strings */
-extern void amodem_set_operator_name( AModem modem, ANameIndex index, const char* buffer, int buffer_size );
-
-/** CALL STATES
- **/
-
-typedef enum {
- A_CALL_OUTBOUND = 0,
- A_CALL_INBOUND = 1,
-} ACallDir;
-
-typedef enum {
- A_CALL_ACTIVE = 0,
- A_CALL_HELD,
- A_CALL_DIALING,
- A_CALL_ALERTING,
- A_CALL_INCOMING,
- A_CALL_WAITING
-} ACallState;
-
-typedef enum {
- A_CALL_VOICE = 0,
- A_CALL_DATA,
- A_CALL_FAX,
- A_CALL_UNKNOWN = 9
-} ACallMode;
-
-#define A_CALL_NUMBER_MAX_SIZE 16
-
-typedef struct {
- int id;
- ACallDir dir;
- ACallState state;
- ACallMode mode;
- int multi;
- char number[ A_CALL_NUMBER_MAX_SIZE+1 ];
-} ACallRec, *ACall;
-
-extern int amodem_get_call_count( AModem modem );
-extern ACall amodem_get_call( AModem modem, int index );
-extern ACall amodem_find_call_by_number( AModem modem, const char* number );
-extern int amodem_add_inbound_call( AModem modem, const char* number );
-extern int amodem_update_call( AModem modem, const char* number, ACallState state );
-extern int amodem_disconnect_call( AModem modem, const char* number );
-
-/**/
-
-#endif /* _android_modem_h_ */
diff --git a/telephony/gsm.c b/telephony/gsm.c
deleted file mode 100644
index b55578d..0000000
--- a/telephony/gsm.c
+++ /dev/null
@@ -1,1220 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "gsm.h"
-#include <stdlib.h>
-#include <string.h>
-
-/** UTILITIES
- **/
-byte_t
-gsm_int_to_bcdi( int value )
-{
- return (byte_t)((value / 10) | ((value % 10) << 4));
-}
-
-int
-gsm_int_from_bcdi( byte_t val )
-{
- int ret = 0;
-
- if ((val & 0xf0) <= 0x90)
- ret = (val >> 4);
-
- if ((val & 0x0f) <= 0x90)
- ret |= (val % 0xf)*10;
-
- return ret;
-}
-
-#if 0
-static int
-gsm_bcdi_to_ascii( cbytes_t bcd, int bcdlen, bytes_t dst )
-{
- static byte_t bcdichars[14] = "0123456789*#,N";
-
- int result = 0;
- int shift = 0;
-
- while (bcdlen > 0) {
- int c = (bcd[0] >> shift) & 0xf;
-
- if (c == 0xf && bcdlen == 1)
- break;
-
- if (c < 14) {
- if (dst) dst[result] = bcdichars[c];
- result += 1;
- }
- bcdlen --;
- shift += 4;
- if (shift == 8) {
- bcd++;
- shift = 0;
- }
- }
- return result;
-}
-#endif
-
-#if 0
-static int
-gsm_bcdi_from_ascii( cbytes_t ascii, int asciilen, bytes_t dst )
-{
- cbytes_t end = ascii + asciilen;
- int result = 0;
- int phase = 0x01;
-
- while (ascii < end) {
- int c = *ascii++;
-
- if (c == '*')
- c = 11;
- else if (c == '#')
- c = 12;
- else if (c == ',')
- c = 13;
- else if (c == 'N')
- c = 14;
- else {
- c -= '0';
- if ((unsigned)c >= 10)
- break;
- }
- phase = (phase << 4) | c;
- if (phase & 0x100) {
- if (dst) dst[result] = (byte_t) phase;
- result += 1;
- phase = 0x01;
- }
- }
- if (phase != 0x01) {
- if (dst) dst[result] = (byte_t)( phase | 0xf0 );
- result += 1;
- }
- return result;
-}
-#endif
-
-int
-gsm_hexchar_to_int( char c )
-{
- if ((unsigned)(c - '0') < 10)
- return c - '0';
- if ((unsigned)(c - 'a') < 6)
- return 10 + (c - 'a');
- if ((unsigned)(c - 'A') < 6)
- return 10 + (c - 'A');
- return -1;
-}
-
-int
-gsm_hexchar_to_int0( char c )
-{
- int ret = gsm_hexchar_to_int(c);
-
- return (ret < 0) ? 0 : ret;
-}
-
-int
-gsm_hex2_to_byte( const char* hex )
-{
- int hi = gsm_hexchar_to_int(hex[0]);
- int lo = gsm_hexchar_to_int(hex[1]);
-
- if (hi < 0 || lo < 0)
- return -1;
-
- return ( (hi << 4) | lo );
-}
-
-int
-gsm_hex4_to_short( const char* hex )
-{
- int hi = gsm_hex2_to_byte(hex);
- int lo = gsm_hex2_to_byte(hex+2);
-
- if (hi < 0 || lo < 0)
- return -1;
-
- return ((hi << 8) | lo);
-}
-
-int
-gsm_hex2_to_byte0( const char* hex )
-{
- int hi = gsm_hexchar_to_int0(hex[0]);
- int lo = gsm_hexchar_to_int0(hex[1]);
-
- return (byte_t)( (hi << 4) | lo );
-}
-
-void
-gsm_hex_from_byte( char* hex, int val )
-{
- static const char hexdigits[] = "0123456789abcdef";
-
- hex[0] = hexdigits[(val >> 4) & 15];
- hex[1] = hexdigits[val & 15];
-}
-
-void
-gsm_hex_from_short( char* hex, int val )
-{
- gsm_hex_from_byte( hex, (val >> 8) );
- gsm_hex_from_byte( hex+2, val );
-}
-
-
-
-/** HEX
- **/
-void
-gsm_hex_to_bytes0( cbytes_t hex, int hexlen, bytes_t dst )
-{
- int nn;
-
- for (nn = 0; nn < hexlen/2; nn++ ) {
- dst[nn] = (byte_t) gsm_hex2_to_byte0( (const char*)hex+2*nn );
- }
- if (hexlen & 1) {
- dst[nn] = gsm_hexchar_to_int0( hex[2*nn] ) << 4;
- }
-}
-
-int
-gsm_hex_to_bytes( cbytes_t hex, int hexlen, bytes_t dst )
-{
- int nn;
-
- if (hexlen & 1) /* must be even */
- return -1;
-
- for (nn = 0; nn < hexlen/2; nn++ ) {
- int c = gsm_hex2_to_byte( (const char*)hex+2*nn );
- if (c < 0) return -1;
- dst[nn] = (byte_t) c;
- }
- return hexlen/2;
-}
-
-void
-gsm_hex_from_bytes( char* hex, cbytes_t src, int srclen )
-{
- int nn;
-
- for (nn = 0; nn < srclen; nn++) {
- gsm_hex_from_byte( hex + 2*nn, src[nn] );
- }
-}
-
-/** ROPES
- **/
-
-void
-gsm_rope_init( GsmRope rope )
-{
- rope->data = NULL;
- rope->pos = 0;
- rope->max = 0;
- rope->error = 0;
-}
-
-void
-gsm_rope_init_alloc( GsmRope rope, int count )
-{
- rope->data = rope->data0;
- rope->pos = 0;
- rope->max = sizeof(rope->data0);
- rope->error = 0;
-
- if (count > 0) {
- rope->data = calloc( count, 1 );
- rope->max = count;
-
- if (rope->data == NULL) {
- rope->error = 1;
- rope->max = 0;
- }
- }
-}
-
-int
-gsm_rope_done( GsmRope rope )
-{
- int result = rope->error;
-
- if (rope->data && rope->data != rope->data0)
- free(rope->data);
-
- rope->data = NULL;
- rope->pos = 0;
- rope->max = 0;
- rope->error = 0;
-
- return result;
-}
-
-
-bytes_t
-gsm_rope_done_acquire( GsmRope rope, int *psize )
-{
- bytes_t result = rope->data;
-
- *psize = rope->pos;
- if (result == rope->data0) {
- result = malloc( rope->pos );
- if (result != NULL)
- memcpy( result, rope->data, rope->pos );
- }
- return result;
-}
-
-
-int
-gsm_rope_ensure( GsmRope rope, int new_count )
-{
- if (rope->data != NULL) {
- int old_max = rope->max;
- bytes_t old_data = rope->data == rope->data0 ? NULL : rope->data;
- int new_max = old_max;
- bytes_t new_data;
-
- while (new_max < new_count) {
- new_max += (new_max >> 1) + 4;
- }
- new_data = realloc( old_data, new_max );
- if (new_data == NULL) {
- rope->error = 1;
- return -1;
- }
- rope->data = new_data;
- rope->max = new_max;
- } else {
- rope->max = new_count;
- }
- return 0;
-}
-
-static int
-gsm_rope_can_grow( GsmRope rope, int count )
-{
- if (!rope->data || rope->error)
- return 0;
-
- if (rope->pos + count > rope->max)
- {
- if (rope->data == NULL)
- rope->max = rope->pos + count;
-
- else if (rope->error ||
- gsm_rope_ensure( rope, rope->pos + count ) < 0)
- return 0;
- }
- return 1;
-}
-
-void
-gsm_rope_add_c( GsmRope rope, char c )
-{
- if (gsm_rope_can_grow(rope, 1)) {
- rope->data[ rope->pos ] = (byte_t) c;
- }
- rope->pos += 1;
-}
-
-void
-gsm_rope_add( GsmRope rope, const void* buf, int buflen )
-{
- if (gsm_rope_can_grow(rope, buflen)) {
- memcpy( rope->data + rope->pos, (const char*)buf, buflen );
- }
- rope->pos += buflen;
-}
-
-void*
-gsm_rope_reserve( GsmRope rope, int count )
-{
- void* result = NULL;
-
- if (gsm_rope_can_grow(rope, count))
- {
- if (rope->data != NULL)
- result = rope->data + rope->pos;
- }
- rope->pos += count;
-
- return result;
-}
-
-/* skip a given number of Unicode characters in a utf-8 byte string */
-cbytes_t
-utf8_skip( cbytes_t utf8,
- cbytes_t utf8end,
- int count)
-{
- cbytes_t p = utf8;
- cbytes_t end = utf8end;
-
- for ( ; count > 0; count-- ) {
- int c;
-
- if (p >= end)
- break;
-
- c = *p++;
- if (c > 128) {
- while (p < end && (p[0] & 0xc0) == 0x80)
- p++;
- }
- }
- return p;
-}
-
-
-static __inline__ int
-utf8_next( cbytes_t *pp, cbytes_t end )
-{
- cbytes_t p = *pp;
- int result = -1;
-
- if (p < end) {
- int c= *p++;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
-
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- p ++;
- }
- }
- result = c;
- *pp = p;
- }
- return result;
-}
-
-
-__inline__ int
-utf8_write( bytes_t utf8, int offset, int v )
-{
- int result;
-
- if (v < 128) {
- result = 1;
- if (utf8)
- utf8[offset] = (byte_t) v;
- } else if (v < 0x800) {
- result = 2;
- if (utf8) {
- utf8[offset+0] = (byte_t)( 0xc0 | (v >> 6) );
- utf8[offset+1] = (byte_t)( 0x80 | (v & 0x3f) );
- }
- } else if (v < 0x10000) {
- result = 3;
- if (utf8) {
- utf8[offset+0] = (byte_t)( 0xe0 | (v >> 12) );
- utf8[offset+1] = (byte_t)( 0x80 | ((v >> 6) & 0x3f) );
- utf8[offset+2] = (byte_t)( 0x80 | (v & 0x3f) );
- }
- } else {
- result = 4;
- if (utf8) {
- utf8[offset+0] = (byte_t)( 0xf0 | ((v >> 18) & 0x7) );
- utf8[offset+1] = (byte_t)( 0x80 | ((v >> 12) & 0x3f) );
- utf8[offset+2] = (byte_t)( 0x80 | ((v >> 6) & 0x3f) );
- utf8[offset+3] = (byte_t)( 0x80 | (v & 0x3f) );
- }
- }
- return result;
-}
-
-static __inline__ int
-ucs2_write( bytes_t ucs2, int offset, int v )
-{
- if (ucs2) {
- ucs2[offset+0] = (byte_t) (v >> 8);
- ucs2[offset+1] = (byte_t) (v);
- }
- return 2;
-}
-
-int
-utf8_check( cbytes_t p, int utf8len )
-{
- cbytes_t end = p + utf8len;
- int result = 0;
-
- if (p) {
- while (p < end) {
- int c = *p++;
- if (c >= 128) {
- int len;
- if ((c & 0xe0) == 0xc0) {
- len = 1;
- }
- else if ((c & 0xf0) == 0xe0) {
- len = 2;
- }
- else if ((c & 0xf8) == 0xf0) {
- len = 3;
- }
- else
- goto Exit; /* malformed utf-8 */
-
- if (p+len > end) /* string too short */
- goto Exit;
-
- for ( ; len > 0; len--, p++ ) {
- if ((p[0] & 0xc0) != 0x80)
- goto Exit;
- }
- }
- }
- result = 1;
- }
-Exit:
- return result;
-}
-
-/** UCS2 to UTF8
- **/
-
-/* convert a UCS2 string into a UTF8 byte string, assumes 'buf' is correctly sized */
-int
-ucs2_to_utf8( cbytes_t ucs2,
- int ucs2len,
- bytes_t buf )
-{
- int nn;
- int result = 0;
-
- for (nn = 0; nn < ucs2len; ucs2 += 2, nn++) {
- int c= (ucs2[0] << 8) | ucs2[1];
- result += utf8_write(buf, result, c);
- }
- return result;
-}
-
-/* count the number of UCS2 chars contained in a utf8 byte string */
-int
-utf8_to_ucs2( cbytes_t utf8,
- int utf8len,
- bytes_t ucs2 )
-{
- cbytes_t p = utf8;
- cbytes_t end = p + utf8len;
- int result = 0;
-
- while (p < end) {
- int c = utf8_next(&p, end);
-
- if (c < 0)
- break;
-
- result += ucs2_write(ucs2, result, c);
- }
- return result/2;
-}
-
-
-
-/** GSM ALPHABET
- **/
-
-#define GSM_7BITS_ESCAPE 0x1b
-#define GSM_7BITS_UNKNOWN 0
-
-static const unsigned short gsm7bits_to_unicode[128] = {
- '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec, 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
-0x394, '_',0x3a6,0x393,0x39b,0x3a9,0x3a0,0x3a8,0x3a3,0x398,0x39e, 0, 0xc6, 0xe6, 0xdf, 0xc9,
- ' ', '!', '"', '#', 0xa4, '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
- 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0xc4, 0xd6,0x147, 0xdc, 0xa7,
- 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0,
-};
-
-static const unsigned short gsm7bits_extend_to_unicode[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\f', 0, 0, 0, 0, 0,
- 0, 0, 0, 0, '^', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, '{', '}', 0, 0, 0, 0, 0,'\\',
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '[', '~', ']', 0,
- '|', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,0x20ac, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-
-static int
-unichar_to_gsm7( int unicode )
-{
- int nn;
- for (nn = 0; nn < 128; nn++) {
- if (gsm7bits_to_unicode[nn] == unicode) {
- return nn;
- }
- }
- return -1;
-}
-
-static int
-unichar_to_gsm7_extend( int unichar )
-{
- int nn;
- for (nn = 0; nn < 128; nn++) {
- if (gsm7bits_extend_to_unicode[nn] == unichar) {
- return nn;
- }
- }
- return -1;
-}
-
-
-/* return the number of septets needed to encode a unicode charcode */
-static int
-unichar_to_gsm7_count( int unicode )
-{
- int nn;
-
- nn = unichar_to_gsm7(unicode);
- if (nn >= 0)
- return 1;
-
- nn = unichar_to_gsm7_extend(unicode);
- if (nn >= 0)
- return 2;
-
- return 0;
-}
-
-
-cbytes_t
-utf8_skip_gsm7( cbytes_t utf8, cbytes_t utf8end, int gsm7len )
-{
- cbytes_t p = utf8;
- cbytes_t end = utf8end;
-
- while (gsm7len >0) {
- cbytes_t q = p;
- int c = utf8_next( &q, end );
- int len;
-
- if (c < 0)
- break;
-
- len = unichar_to_gsm7_count( c );
- if (len == 0) /* unknown chars are replaced by spaces */
- len = 1;
-
- if (len > gsm7len)
- break;
-
- gsm7len -= len;
- p = q;
- }
- return p;
-}
-
-
-int
-utf8_check_gsm7( cbytes_t utf8,
- int utf8len )
-{
- cbytes_t utf8end = utf8 + utf8len;
-
- while (utf8 < utf8end) {
- int c = utf8_next( &utf8, utf8end );
- if (unichar_to_gsm7_count(c) == 0)
- return 0;
- }
- return 1;
-}
-
-
-int
-utf8_from_gsm7( cbytes_t src,
- int septet_offset,
- int septet_count,
- bytes_t utf8 )
-{
- int shift = (septet_offset & 7);
- int escaped = 0;
- int result = 0;
-
- src += (septet_offset >> 3);
- for ( ; septet_count > 0; septet_count-- )
- {
- int c = (src[0] >> shift) & 0x7f;
- int v;
-
- if (shift > 1) {
- c = ((src[1] << (8-shift)) | c) & 0x7f;
- }
-
- if (escaped) {
- v = gsm7bits_extend_to_unicode[c];
- } else if (c == GSM_7BITS_ESCAPE) {
- escaped = 1;
- goto NextSeptet;
- } else {
- v = gsm7bits_to_unicode[c];
- }
-
- result += utf8_write( utf8, result, v );
-
- NextSeptet:
- shift += 7;
- if (shift >= 8) {
- shift -= 8;
- src += 1;
- }
- }
- return result;
-}
-
-
-int
-utf8_from_gsm8( cbytes_t src, int count, bytes_t utf8 )
-{
- int result = 0;
- int escaped = 0;
-
-
- for ( ; count > 0; count-- )
- {
- int c = *src++;
-
- if (c == 0xff)
- break;
-
- if (c == GSM_7BITS_ESCAPE) {
- if (escaped) { /* two escape characters => one space */
- c = 0x20;
- escaped = 0;
- } else {
- escaped = 1;
- continue;
- }
- }
- else
- {
- if (c >= 0x80) {
- c = 0x20;
- escaped = 0;
- } else if (escaped) {
- c = gsm7bits_extend_to_unicode[c];
- } else
- c = gsm7bits_to_unicode[c];
- }
-
- result += utf8_write( utf8, result, c );
- }
- return result;
-}
-
-/* convert a GSM 7-bit message into a unicode character array
- * the 'dst' array must contain at least 160 chars. the function
- * returns the number of characters decoded
- *
- * assumes the 'dst' array has at least septet_count items, returns the
- * number of unichars really written
- */
-int
-ucs2_from_gsm7( bytes_t ucs2,
- cbytes_t src,
- int septet_offset,
- int septet_count )
-{
- const unsigned char* p = src + (septet_offset >> 3);
- int shift = (septet_offset & 7);
- int escaped = 0;
- int result = 0;
-
- for ( ; septet_count > 0; septet_count-- )
- {
- unsigned val = (p[0] >> shift) & 0x7f;
-
- if (shift > 1)
- val = (val | (p[1] << (8-shift))) & 0x7f;
-
- if (escaped) {
- int c = gsm7bits_to_unicode[val];
-
- result += ucs2_write(ucs2, result, c);
- escaped = 0;
- }
- else if (val == GSM_7BITS_ESCAPE) {
- escaped = 1;
- }
- else {
- val = gsm7bits_extend_to_unicode[val];
- if (val == 0)
- val = 0x20;
-
- result += ucs2_write( ucs2, result, val );
- }
- }
- return result/2;
-}
-
-
-/* count the number of septets required to write a utf8 string */
-static int
-utf8_to_gsm7_count( cbytes_t utf8, int utf8len )
-{
- cbytes_t utf8end = utf8 + utf8len;
- int result = 0;
-
- while ( utf8 < utf8end ) {
- int len;
- int c = utf8_next( &utf8, utf8end );
-
- if (c < 0)
- break;
-
- len = unichar_to_gsm7_count(c);
- if (len == 0) /* replace non-representables with space */
- len = 1;
-
- result += len;
- }
- return result;
-}
-
-typedef struct {
- bytes_t dst;
- unsigned pad;
- int bits;
- int offset;
-} BWriterRec, *BWriter;
-
-static void
-bwriter_init( BWriter writer, bytes_t dst, int start )
-{
- int shift = start & 7;
-
- writer->dst = dst + (start >> 3);
- writer->pad = 0;
- writer->bits = shift;
- writer->offset = start;
-
- if (shift > 0) {
- writer->pad = writer->dst[0] & ~(0xFF << shift);
- }
-}
-
-static void
-bwriter_add7( BWriter writer, unsigned value )
-{
- writer->pad |= (unsigned)(value << writer->bits);
- writer->bits += 7;
- if (writer->bits >= 8) {
- writer->dst[0] = (byte_t)writer->pad;
- writer->bits -= 8;
- writer->pad >>= 8;
- writer->dst += 1;
- }
- writer->offset += 7;
-}
-
-static int
-bwriter_done( BWriter writer )
-{
- if (writer->bits > 0) {
- writer->dst[0] = (byte_t)writer->pad;
- writer->pad = 0;
- writer->bits = 0;
- writer->dst += 1;
- }
- return writer->offset;
-}
-
-/* convert a utf8 string to a gsm7 byte string - return the number of septets written */
-int
-utf8_to_gsm7( cbytes_t utf8, int utf8len, bytes_t dst, int offset )
-{
- const unsigned char* utf8end = utf8 + utf8len;
- BWriterRec writer[1];
-
- if (dst == NULL)
- return utf8_to_gsm7_count(utf8, utf8len);
-
- bwriter_init( writer, dst, offset );
- while ( utf8 < utf8end ) {
- int c = utf8_next( &utf8, utf8end );
- int nn;
-
- if (c < 0)
- break;
-
- nn = unichar_to_gsm7(c);
- if (nn >= 0) {
- bwriter_add7( writer, nn );
- continue;
- }
-
- nn = unichar_to_gsm7_extend(c);
- if (nn >= 0) {
- bwriter_add7( writer, GSM_7BITS_ESCAPE );
- bwriter_add7( writer, nn );
- continue;
- }
-
- /* unknown => replaced by space */
- bwriter_add7( writer, 0x20 );
- }
- return bwriter_done( writer );
-}
-
-
-int
-utf8_to_gsm8( cbytes_t utf8, int utf8len, bytes_t dst )
-{
- const unsigned char* utf8end = utf8 + utf8len;
- int result = 0;
-
- while ( utf8 < utf8end ) {
- int c = utf8_next( &utf8, utf8end );
- int nn;
-
- if (c < 0)
- break;
-
- nn = unichar_to_gsm7(c);
- if (nn >= 0) {
- if (dst)
- dst[result] = (byte_t)nn;
- result += 1;
- continue;
- }
-
- nn = unichar_to_gsm7_extend(c);
- if (nn >= 0) {
- if (dst) {
- dst[result+0] = (byte_t) GSM_7BITS_ESCAPE;
- dst[result+1] = (byte_t) nn;
- }
- result += 2;
- continue;
- }
-
- /* unknown => space */
- if (dst)
- dst[result] = 0x20;
- result += 1;
- }
- return result;
-}
-
-
-int
-ucs2_to_gsm7( cbytes_t ucs2, int ucs2len, bytes_t dst, int offset )
-{
- const unsigned char* ucs2end = ucs2 + ucs2len*2;
- BWriterRec writer[1];
-
- bwriter_init( writer, dst, offset );
- while ( ucs2 < ucs2end ) {
- int c = *ucs2++;
- int nn;
-
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_to_unicode[nn] == c ) {
- bwriter_add7( writer, nn );
- goto NextUnicode;
- }
- }
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_extend_to_unicode[nn] == c ) {
- bwriter_add7( writer, GSM_7BITS_ESCAPE );
- bwriter_add7( writer, nn );
- goto NextUnicode;
- }
- }
-
- /* unknown */
- bwriter_add7( writer, 0x20 );
-
- NextUnicode:
- ;
- }
- return bwriter_done( writer );
-}
-
-
-int
-ucs2_to_gsm8( cbytes_t ucs2, int ucs2len, bytes_t dst )
-{
- const unsigned char* ucs2end = ucs2 + ucs2len*2;
- bytes_t dst0 = dst;
-
- while ( ucs2 < ucs2end ) {
- int c = *ucs2++;
- int nn;
-
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_to_unicode[nn] == c ) {
- *dst++ = (byte_t)nn;
- goto NextUnicode;
- }
- }
- for (nn = 0; nn < 128; nn++) {
- if ( gsm7bits_extend_to_unicode[nn] == c ) {
- dst[0] = (byte_t) GSM_7BITS_ESCAPE;
- dst[1] = (byte_t) nn;
- dst += 2;
- goto NextUnicode;
- }
- }
-
- /* unknown */
- *dst++ = 0x20;
-
- NextUnicode:
- ;
- }
- return (dst - dst0);
-}
-
-int
-gsm_bcdnum_to_ascii( cbytes_t bcd, int count, bytes_t dst )
-{
- int result = 0;
- int shift = 0;
-
- while (count > 0) {
- int c = (bcd[0] >> shift) & 0xf;
-
- if (c == 15 && count == 1) /* ignore trailing 0xf */
- break;
-
- if (c >= 14)
- c = 0;
-
- if (dst) dst[result] = "0123456789*#,N"[c];
- result += 1;
-
- shift += 4;
- if (shift == 8) {
- shift = 0;
- bcd += 1;
- }
- }
- return result;
-}
-
-
-int
-gsm_bcdnum_from_ascii( cbytes_t ascii, int asciilen, bytes_t dst )
-{
- cbytes_t end = ascii + asciilen;
- int result = 0;
- int phase = 0x01;
-
- while (ascii < end) {
- int c = *ascii++;
-
- if (c == '*')
- c = 10;
- else if (c == '#')
- c = 11;
- else if (c == ',')
- c = 12;
- else if (c == 'N')
- c = 13;
- else {
- c -= '0';
- if ((unsigned)c >= 10U)
- return -1;
- }
- phase = (phase << 4) | c;
- result += 1;
- if (phase & 0x100) {
- if (dst) dst[result/2] = (byte_t) phase;
- phase = 0x01;
- }
- }
-
- if (result & 1) {
- if (dst) dst[result/2] = (byte_t)(phase | 0xf0);
- }
- return result;
-}
-
-/** ADN: Abbreviated Dialing Number
- **/
-
-#define ADN_FOOTER_SIZE 14
-#define ADN_OFFSET_NUMBER_LENGTH 0
-#define ADN_OFFSET_TON_NPI 1
-#define ADN_OFFSET_NUMBER_START 2
-#define ADN_OFFSET_NUMBER_END 11
-#define ADN_OFFSET_CAPABILITY_ID 12
-#define ADN_OFFSET_EXTENSION_ID 13
-
-/* see 10.5.1 of 3GPP 51.011 */
-static int
-sim_adn_alpha_to_utf8( cbytes_t alpha, cbytes_t end, bytes_t dst )
-{
- int result = 0;
-
- /* ignore trailing 0xff */
- while (alpha < end && end[-1] == 0xff)
- end--;
-
- if (alpha >= end)
- return 0;
-
- if (alpha[0] == 0x80) { /* UCS/2 source encoding */
- alpha += 1;
- result = ucs2_to_utf8( alpha, (end-alpha)/2, dst );
- }
- else
- {
- int is_ucs2 = 0;
- int len = 0, base = 0;
-
- if (alpha+3 <= end && alpha[0] == 0x81) {
- is_ucs2 = 1;
- len = alpha[1];
- base = alpha[2] << 7;
- alpha += 3;
- if (len > end-alpha)
- len = end-alpha;
- } else if (alpha+4 <= end && alpha[0] == 0x82) {
- is_ucs2 = 1;
- len = alpha[1];
- base = (alpha[2] << 8) | alpha[3];
- alpha += 4;
- if (len > end-alpha)
- len = end-alpha;
- }
-
- if (is_ucs2) {
- end = alpha + len;
- while (alpha < end) {
- int c = alpha[0];
- if (c >= 0x80) {
- result += utf8_write(dst, result, base + (c & 0x7f));
- alpha += 1;
- } else {
- /* GSM character set */
- int count;
- for (count = 0; alpha+count < end && alpha[count] < 128; count++)
- ;
- result += utf8_from_gsm8(alpha, count, (dst ? dst+result : NULL));
- alpha += count;
- }
- }
- }
- else {
- result = utf8_from_gsm8(alpha, end-alpha, dst);
- }
- }
- return result;
-}
-
-#if 0
-static int
-sim_adn_alpha_from_utf8( cbytes_t utf8, int utf8len, bytes_t dst )
-{
- int result = 0;
-
- if (utf8_check_gsm7(utf8, utf8len)) {
- /* GSM 7-bit compatible, encode directly as 8-bit string */
- result = utf8_to_gsm8(utf8, utf8len, dst);
- } else {
- /* otherwise, simply try UCS-2 encoding, nothing more serious at the moment */
- if (dst) {
- dst[0] = 0x80;
- }
- result = 1 + utf8_to_ucs2(utf8, utf8len, dst ? (dst+1) : NULL)*2;
- }
- return result;
-}
-#endif
-
-int
-sim_adn_record_from_bytes( SimAdnRecord rec, cbytes_t data, int len )
-{
- cbytes_t end = data + len;
- cbytes_t footer = end - ADN_FOOTER_SIZE;
- int num_len;
-
- rec->adn.alpha[0] = 0;
- rec->adn.number[0] = 0;
- rec->ext_record = 0xff;
-
- if (len < ADN_FOOTER_SIZE)
- return -1;
-
- /* alpha is optional */
- if (len > ADN_FOOTER_SIZE) {
- cbytes_t dataend = data + len - ADN_FOOTER_SIZE;
- int count = sim_adn_alpha_to_utf8(data, dataend, NULL);
-
- if (count > sizeof(rec->adn.alpha)-1) /* too long */
- return -1;
-
- sim_adn_alpha_to_utf8(data, dataend, rec->adn.alpha);
- rec->adn.alpha[count] = 0;
- }
-
- num_len = footer[ADN_OFFSET_NUMBER_LENGTH];
- if (num_len > 11)
- return -1;
-
- /* decode TON and number to ASCII, NOTE: this is lossy !! */
- {
- int ton = footer[ADN_OFFSET_TON_NPI];
- bytes_t number = (bytes_t) rec->adn.number;
- int len = sizeof(rec->adn.number)-1;
- int count;
-
- if (ton != 0x81 && ton != 0x91)
- return -1;
-
- if (ton == 0x91) {
- *number++ = '+';
- len -= 1;
- }
-
- count = gsm_bcdnum_to_ascii( footer + ADN_OFFSET_NUMBER_START,
- num_len*2, number );
- number[count] = 0;
- }
- return 0;
-}
-
-int
-sim_adn_record_to_bytes( SimAdnRecord rec, bytes_t data, int datalen )
-{
- bytes_t end = data + datalen;
- bytes_t footer = end - ADN_FOOTER_SIZE;
- int ton = 0x81;
- cbytes_t number = (cbytes_t) rec->adn.number;
-
- if (number[0] == '+') {
- ton = 0x91;
- number += 1;
- }
- footer[0] = (strlen((const char*)number)+1)/2 + 1;
- /* XXXX: TODO */
- return 0;
-}
diff --git a/telephony/gsm.h b/telephony/gsm.h
deleted file mode 100644
index f799dea..0000000
--- a/telephony/gsm.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_gsm_h
-#define _android_gsm_h
-
-/** USEFUL TYPES
- **/
-
-typedef unsigned char byte_t;
-typedef byte_t* bytes_t;
-typedef const byte_t* cbytes_t;
-
-/** BCD
- **/
-
-/* convert a 8-bit value into the corresponding nibble-bcd byte */
-extern byte_t gsm_int_to_bcdi( int value );
-
-/* convert a nibble-bcd byte into an int, invalid nibbles are silently converted to 0 */
-extern int gsm_int_from_bcdi( byte_t value );
-
-/** HEX
- **/
-
-/* try to convert a hex string into a byte string, assumes 'dst' is properly sized, and hexlen is even.
- * returns the number of bytes on exit, or -1 in case of badly formatted data */
-extern int gsm_hex_to_bytes ( cbytes_t hex, int hexlen, bytes_t dst );
-
-/* convert a hex string into a byte string, assumes 'dst' is properly sized, and hexlen is even.
- * no checks are performed */
-extern void gsm_hex_to_bytes0 ( cbytes_t hex, int hexlen, bytes_t dst );
-
-/* convert a byte string into a hex string, assumes 'hex' is properly sized */
-extern void gsm_hex_from_bytes( char* hex, cbytes_t src, int srclen );
-
-/* convert a hexchar to an int, returns -1 on error */
-extern int gsm_hexchar_to_int( char c );
-
-/* convert a hexchar to an int, returns 0 on error */
-extern int gsm_hexchar_to_int0( char c );
-
-/* convert a 2-char hex value into an int, returns -1 on error */
-extern int gsm_hex2_to_byte( const char* hex );
-
-/* convert a 2-char hex value into an int, returns 0 on error */
-extern int gsm_hex2_to_byte0( const char* hex );
-
-/* convert a 4-char hex value into an int, returns -1 on error */
-extern int gsm_hex4_to_short( const char* hex );
-
-/* convert a 4-char hex value into an int, returns 0 on error */
-extern int gsm_hex4_to_short0( const char* hex );
-
-/* write a byte to a 2-byte hex string */
-extern void gsm_hex_from_byte( char* hex, int val );
-
-extern void gsm_hex_from_short( char* hex, int val );
-
-/** UTF-8 and GSM Alphabet
- **/
-
-/* check that a given utf8 string is well-formed, returns 1 on success, 0 otherwise */
-extern int utf8_check( cbytes_t utf8, int utf8len );
-
-/* check that all characters in a given utf8 string can be encoded into the GSM alphabet.
- returns 1 if TRUE, 0 otherwise */
-extern int utf8_check_gsm7( cbytes_t utf8, int utf8len );
-
-/* try to skip enough utf8 characters to generate gsm7len GSM septets */
-extern cbytes_t utf8_skip_gsm7( cbytes_t utf8, cbytes_t utf8end, int gsm7len );
-
-/* convert a utf-8 string into a GSM septet string, assumes 'dst' is NULL or is properly sized,
- and that all characters are representable. 'offset' is the starting bit offset in 'dst'.
- non-representable characters are replaced by spaces.
- returns the number of septets, */
-extern int utf8_to_gsm7( cbytes_t utf8, int utf8len, bytes_t dst, int offset );
-
-/* convert a utf8 string into an array of 8-bit unpacked GSM septets,
- * assumes 'dst' is NULL or is properly sized, returns the number of GSM bytes */
-extern int utf8_to_gsm8( cbytes_t utf8, int utf8len, bytes_t dst );
-
-/* convert a GSM septets string into a utf-8 byte string. assumes that 'utf8' is NULL or properly
- sized. 'offset' is the starting bit offset in 'src', 'count' is the number of input septets.
- return the number of utf8 bytes. */
-extern int utf8_from_gsm7( cbytes_t src, int offset, int count, bytes_t utf8 );
-
-/* convert an unpacked 8-bit GSM septets string into a utf-8 byte string. assumes that 'utf8'
- is NULL or properly sized. 'count' is the number of input bytes.
- returns the number of utf8 bytes */
-extern int utf8_from_gsm8( cbytes_t src, int count, bytes_t utf8 );
-
-
-/** UCS-2 and GSM Alphabet
- **
- ** Note that here, 'ucs2' really refers to non-aligned UCS2-BE, as used by the GSM standard
- **/
-
-/* check that all characters in a given ucs2 string can be encoded into the GSM alphabet.
- returns 1 if TRUE, 0 otherwise */
-extern int ucs2_check_gsm7( cbytes_t ucs2, int ucs2len );
-
-/* convert a ucs2 string into a GSM septet string, assumes 'dst' is NULL or properly sized,
- 'offset' is the starting bit offset in 'dst'. non-representable characters are replaced
- by spaces. returns the number of septets */
-extern int ucs2_to_gsm7( cbytes_t ucs2, int ucs2len, bytes_t dst, int offset );
-
-/* convert a ucs2 string into a GSM septet string, assumes 'dst' is NULL or properly sized,
- non-representable characters are replaced by spaces. returns the number of bytes */
-extern int ucs2_to_gsm8( cbytes_t ucs2, int ucs2len, bytes_t dst );
-
-/* convert a GSM septets string into a ucs2 string. assumes that 'ucs2' is NULL or
- properly sized. 'offset' is the starting bit offset in 'src', 'count' is the number
- of input septets. return the number of ucs2 characters (not bytes) */
-extern int ucs2_from_gsm7( bytes_t ucs2, cbytes_t src, int offset, int count );
-
-/* convert an 8-bit unpacked GSM septets string into a ucs2 string. assumes that 'ucs2'
- is NULL or properly sized. 'count' is the number of input septets. return the number
- of ucs2 characters (not bytes) */
-extern int ucs2_from_gsm8( bytes_t ucs2, cbytes_t src, int count );
-
-
-/** UCS2 to/from UTF8
- **/
-
-/* convert a ucs2 string into a utf8 byte string, assumes 'utf8' NULL or properly sized.
- returns the number of utf8 bytes*/
-extern int ucs2_to_utf8( cbytes_t ucs2, int ucs2len, bytes_t utf8 );
-
-/* convert a utf8 byte string into a ucs2 string, assumes 'ucs2' NULL or properly sized.
- returns the number of ucs2 chars */
-extern int utf8_to_ucs2( cbytes_t utf8, int utf8len, bytes_t ucs2 );
-
-/* try to skip a given number of characters in a utf-8 byte string, return new position */
-extern cbytes_t utf8_skip( cbytes_t utf8, cbytes_t utf8end, int count);
-
-/** Dial Numbers: TON byte + 'count' bcd numbers
- **/
-
-/* convert a bcd-coded GSM dial number into an ASCII string (not zero-terminated)
- assumes 'dst' is NULL or properly sized, returns 0 in case of success, -1 in case of error.
- 'num_digits' is the number of digits, not input bytes. a trailing 0xf0 is ignored automatically
- return the number of ASCII chars */
-extern int gsm_bcdnum_to_ascii ( cbytes_t bcd, int num_digits, bytes_t dst );
-
-/* convert an ASCII dial-number into a bcd-coded string, returns the number of 4-bit nibbles written, */
-extern int gsm_bcdnum_from_ascii( cbytes_t ascii, int asciilen, bytes_t dst );
-
-/** ADN: Abbreviated Dialing Numbers
- **/
-#define SIM_ADN_MAX_ALPHA 20 /* maximum number of characters in ADN alpha tag */
-#define SIM_ADN_MAX_NUMBER 20 /* maximum digits in ADN number */
-
-typedef struct {
- byte_t alpha [ SIM_ADN_MAX_ALPHA*3+1 ]; /* alpha tag in zero-terminated utf-8 */
- char number[ SIM_ADN_MAX_NUMBER+1 ]; /* dialing number in zero-terminated ASCII */
-}
-SimAdnRec, *SimAdn;
-
-typedef struct {
- SimAdnRec adn;
- byte_t ext_record; /* 0 or 0xFF means no extension */
-}
-SimAdnRecordRec, *SimAdnRecord;
-
-extern int sim_adn_record_from_bytes( SimAdnRecord rec, cbytes_t data, int datalen );
-extern int sim_adn_record_to_bytes ( SimAdnRecord rec, bytes_t data, int datalen );
-
-/** ROPES
- **/
-
-typedef struct {
- bytes_t data;
- int max;
- int pos;
- int error;
- unsigned char data0[16];
-} GsmRopeRec, *GsmRope;
-
-extern void gsm_rope_init( GsmRope rope );
-extern void gsm_rope_init_alloc( GsmRope rope, int alloc );
-extern int gsm_rope_done( GsmRope rope );
-extern bytes_t gsm_rope_done_acquire( GsmRope rope, int *psize );
-extern void gsm_rope_add_c( GsmRope rope, char c );
-extern void gsm_rope_add( GsmRope rope, const void* str, int len );
-extern void* gsm_rope_reserve( GsmRope rope, int len );
-
-#endif /* _android_gsm_h */
diff --git a/telephony/modem_driver.c b/telephony/modem_driver.c
deleted file mode 100644
index 99bbe6c..0000000
--- a/telephony/modem_driver.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-/* implement the modem character device for Android within the QEMU event loop.
- * it communicates through a serial port with "rild" (Radio Interface Layer Daemon)
- * on the emulated device.
- */
-#include "modem_driver.h"
-#include "qemu-char.h"
-
-#define xxDEBUG
-
-#ifdef DEBUG
-# include <stdio.h>
-# define D(...) ( fprintf( stderr, __VA_ARGS__ ) )
-#else
-# define D(...) ((void)0)
-#endif
-
-AModem android_modem;
-CharDriverState* android_modem_cs;
-
-typedef struct {
- CharDriverState* cs;
- AModem modem;
- char in_buff[ 1024 ];
- int in_pos;
- int in_sms;
-} ModemDriver;
-
-/* send unsollicited messages to the device */
-static void
-modem_driver_unsol( void* _md, const char* message)
-{
- ModemDriver* md = _md;
- int len = strlen(message);
-
- qemu_chr_write(md->cs, (const uint8_t*)message, len);
-}
-
-static int
-modem_driver_can_read( void* _md )
-{
- ModemDriver* md = _md;
- int ret = sizeof(md->in_buff) - md->in_pos;
-
- return ret;
-}
-
-/* despite its name, this function is called when the device writes to the modem */
-static void
-modem_driver_read( void* _md, const uint8_t* src, int len )
-{
- ModemDriver* md = _md;
- const uint8_t* end = src + len;
- int nn;
-
- D( "%s: reading %d from %p bytes:", __FUNCTION__, len, src );
- for (nn = 0; nn < len; nn++) {
- int c = src[nn];
- if (c >= 32 && c < 127)
- D( "%c", c );
- else if (c == '\n')
- D( "<LF>" );
- else if (c == '\r')
- D( "<CR>" );
- else
- D( "\\x%02x", c );
- }
- D( "\n" );
-
- for ( ; src < end; src++ ) {
- char c = src[0];
-
- if (md->in_sms) {
- if (c != 26)
- goto AppendChar;
-
- md->in_buff[ md->in_pos ] = c;
- md->in_pos++;
- md->in_sms = 0;
- c = '\n';
- }
-
- if (c == '\n' || c == '\r') {
- const char* answer;
-
- if (md->in_pos == 0) /* skip empty lines */
- continue;
-
- md->in_buff[ md->in_pos ] = 0;
- md->in_pos = 0;
-
- D( "%s: << %s\n", __FUNCTION__, md->in_buff );
- answer = amodem_send(android_modem, md->in_buff);
- if (answer != NULL) {
- D( "%s: >> %s\n", __FUNCTION__, answer );
- len = strlen(answer);
- if (len == 2 && answer[0] == '>' && answer[1] == ' ')
- md->in_sms = 1;
-
- qemu_chr_write(md->cs, (const uint8_t*)answer, len);
- qemu_chr_write(md->cs, (const uint8_t*)"\r", 1);
- } else
- D( "%s: -- NO ANSWER\n", __FUNCTION__ );
-
- continue;
- }
- AppendChar:
- md->in_buff[ md->in_pos++ ] = c;
- if (md->in_pos == sizeof(md->in_buff)) {
- /* input is too long !! */
- md->in_pos = 0;
- }
- }
- D( "%s: done\n", __FUNCTION__ );
-}
-
-
-static void
-modem_driver_init( int base_port, ModemDriver* dm, CharDriverState* cs )
-{
- dm->cs = cs;
- dm->in_pos = 0;
- dm->in_sms = 0;
- dm->modem = amodem_create( base_port, modem_driver_unsol, dm );
-
- qemu_chr_add_handlers( cs, modem_driver_can_read, modem_driver_read, NULL, dm );
-}
-
-
-void android_modem_init( int base_port )
-{
- static ModemDriver modem_driver[1];
-
- if (android_modem_cs != NULL) {
- modem_driver_init( base_port, modem_driver, android_modem_cs );
- android_modem = modem_driver->modem;
- }
-}
diff --git a/telephony/modem_driver.h b/telephony/modem_driver.h
deleted file mode 100644
index d03010f..0000000
--- a/telephony/modem_driver.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _modem_driver_h
-#define _modem_driver_h
-
-#include "android_modem.h"
-#include "qemu-common.h"
-
-/** in telephony/modem_driver.c */
-/* this is the internal character driver used to communicate with the
- * emulated GSM modem. see qemu_chr_open() in vl.c */
-extern CharDriverState* android_modem_cs;
-
-/* the emulated GSM modem itself */
-extern AModem android_modem;
-
-/* must be called before the VM runs if there is a modem to emulate */
-extern void android_modem_init( int base_port );
-
-#endif /* _modem_driver_h */
diff --git a/telephony/remote_call.c b/telephony/remote_call.c
deleted file mode 100644
index 927e11d..0000000
--- a/telephony/remote_call.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "remote_call.h"
-#include "android/utils/bufprint.h"
-#include "android/utils/debug.h"
-#include "sysdeps.h"
-#include "gsm.h"
-#include "android/android.h"
-#include "sockets.h"
-#include <stdlib.h>
-
-#define DEBUG 1
-
-#if 1
-# define D_ACTIVE VERBOSE_CHECK(modem)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if 1
-# define S_ACTIVE VERBOSE_CHECK(socket)
-#else
-# define S_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# include <stdio.h>
-# define D(...) do { if (D_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-# define S(...) do { if (S_ACTIVE) fprintf( stderr, __VA_ARGS__ ); } while (0)
-#else
-# define D(...) ((void)0)
-# define S(...) ((void)0)
-#endif
-
-/** By convention, remote numbers are the console ports, i.e. 5554, 5556, etc...
- **/
-#define REMOTE_NUMBER_BASE 5554
-#define REMOTE_NUMBER_MAX 16
-#define REMOTE_NUMBER_MAX_CHARS 4
-#define REMOTE_CONSOLE_PORT 5554
-
-int
-remote_number_from_port( int port )
-{
- if (port & 1) /* must be even */
- return -1;
-
- port = (port - REMOTE_CONSOLE_PORT) >> 1;
- if ((unsigned)port >= REMOTE_NUMBER_MAX)
- return -1;
-
- return REMOTE_NUMBER_BASE + port*2;
-}
-
-int
-remote_number_to_port( int number )
-{
- if (number & 1) /* must be even */
- return -1;
-
- number = (number - REMOTE_NUMBER_BASE) >> 1;
- if ((unsigned)number >= REMOTE_NUMBER_MAX)
- return -1;
-
- return REMOTE_CONSOLE_PORT + number*2;
-}
-
-int
-remote_number_string_to_port( const char* number )
-{
- char* end;
- long num = strtol( number, &end, 10 );
-
- if (end == NULL || *end || (int)num != num )
- return -1;
-
- return remote_number_to_port( (int)num );
-}
-
-/** REMOTE CALL OBJECTS
- **/
-
-typedef struct RemoteCallRec {
- struct RemoteCallRec* next;
- struct RemoteCallRec** pref;
- RemoteCallType type;
- int to_port;
- int from_port;
- SysChannel channel;
- RemoteResultFunc result_func;
- void* result_opaque;
-
- char quitting;
-
- /* the output buffer */
- char* buff;
- int buff_pos;
- int buff_len;
- int buff_size;
- char buff0[32];
-
-} RemoteCallRec, *RemoteCall;
-
-static void
-remote_call_done( RemoteCall call )
-{
- call->pref[0] = call->next;
- call->next = NULL;
- call->pref = &call->next;
-
- if (call->buff && call->buff != call->buff0) {
- free(call->buff);
- call->buff = call->buff0;
- call->buff_size = (int) sizeof(call->buff0);
- }
-
- if ( call->channel ) {
- sys_channel_close( call->channel );
- call->channel = NULL;
- }
-
- call->buff_pos = 0;
- call->buff_len = 0;
-}
-
-
-static void
-remote_call_free( RemoteCall call )
-{
- if (call) {
- remote_call_done( call );
- free(call);
- }
-}
-
-
-static void remote_call_event( void* opaque, int events ); /* forward */
-
-static RemoteCall
-remote_call_alloc( RemoteCallType type, int to_port, int from_port )
-{
- RemoteCall rcall = calloc( sizeof(*rcall), 1 );
- int from_num = remote_number_from_port(from_port);
-
- if (rcall != NULL) {
- char *p, *end;
-
- rcall->pref = &rcall->next;
- rcall->type = type;
- rcall->to_port = to_port;
- rcall->from_port = from_port;
- rcall->buff = rcall->buff0;
- rcall->buff_size = sizeof(rcall->buff0);
- rcall->buff_pos = 0;
-
- p = rcall->buff;
- end = p + rcall->buff_size;
-
- switch (type) {
- case REMOTE_CALL_DIAL:
- p = bufprint(p, end, "gsm call %d\n", from_num );
- break;
-
- case REMOTE_CALL_BUSY:
- p = bufprint(p, end, "gsm busy %d\n", from_num);
- break;
-
- case REMOTE_CALL_HOLD:
- p = bufprint(p, end, "gsm hold %d\n", from_num);
- break;
-
- case REMOTE_CALL_ACCEPT:
- p = bufprint(p, end, "gsm accept %d\n", from_num);
- break;
-
- case REMOTE_CALL_HANGUP:
- p = bufprint(p, end, "gsm cancel %d\n", from_num );
- break;
-
- default:
- ;
- }
- if (p >= end) {
- D("%s: buffer too short\n", __FUNCTION__ );
- remote_call_free(rcall);
- return NULL;
- }
-
- rcall->buff_len = p - rcall->buff;
-
- rcall->channel = sys_channel_create_tcp_client( "localhost", to_port );
- if (rcall->channel == NULL) {
- D("%s: could not create channel to port %d\n", __FUNCTION__, to_port);
- remote_call_free(rcall);
- return NULL;
- }
-
- sys_channel_on( rcall->channel, SYS_EVENT_WRITE, remote_call_event, rcall );
- }
- return rcall;
-}
-
-
-static int
-remote_call_set_sms_pdu( RemoteCall call,
- SmsPDU pdu )
-{
- char *p, *end;
- int msg2len;
-
- msg2len = 32 + smspdu_to_hex( pdu, NULL, 0 );
- if (msg2len > call->buff_size) {
- char* old_buff = call->buff == call->buff0 ? NULL : call->buff;
- char* new_buff = realloc( old_buff, msg2len );
- if (new_buff == NULL) {
- D("%s: not enough memory to alloc %d bytes", __FUNCTION__, msg2len);
- return -1;
- }
- call->buff = new_buff;
- call->buff_size = msg2len;
- }
-
- p = call->buff;
- end = p + call->buff_size;
-
- p = bufprint(p, end, "sms pdu ");
- p += smspdu_to_hex( pdu, p, end-p );
- *p++ = '\n';
- *p = 0;
-
- call->buff_len = p - call->buff;
- call->buff_pos = 0;
- return 0;
-}
-
-
-static void
-remote_call_add( RemoteCall call,
- RemoteCall *plist )
-{
- RemoteCall first = *plist;
-
- call->next = first;
- call->pref = plist;
-
- if (first)
- first->pref = &call->next;
-}
-
-static void
-remote_call_event( void* opaque, int events )
-{
- RemoteCall call = opaque;
-
- S("%s: called for call (%d,%d), events=%02x\n", __FUNCTION__,
- call->from_port, call->to_port, events);
-
- if (events & SYS_EVENT_READ) {
- /* simply drain the channel */
- char temp[32];
- int n = sys_channel_read( call->channel, temp, sizeof(temp) );
- if (n <= 0) {
- /* remote emulator probably quitted */
- //S("%s: emulator %d quitted with %d: %s\n", __FUNCTION__, call->to_port, errno, errno_str);
- remote_call_free( call );
- return;
- }
- }
-
- if (events & SYS_EVENT_WRITE) {
- int n;
-
- if (S_ACTIVE) {
- int nn;
- S("%s: call (%d,%d) sending %d bytes '", __FUNCTION__,
- call->from_port, call->to_port, call->buff_len - call->buff_pos );
- for (nn = call->buff_pos; nn < call->buff_len; nn++) {
- int c = call->buff[nn];
- if (c < 32) {
- if (c == '\n')
- S("\\n");
- else if (c == '\t')
- S("\\t");
- else if (c == '\r')
- S("\\r");
- else
- S("\\x%02x", c);
- } else
- S("%c", c);
- }
- S("'\n");
- }
-
- n = sys_channel_write( call->channel,
- call->buff + call->buff_pos,
- call->buff_len - call->buff_pos );
- if (n <= 0) {
- /* remote emulator probably quitted */
- S("%s: emulator %d quitted unexpectedly with error %d: %s\n",
- __FUNCTION__, call->to_port, errno, errno_str);
- if (call->result_func)
- call->result_func( call->result_opaque, 0 );
- remote_call_free( call );
- return;
- }
- call->buff_pos += n;
-
- if (call->buff_pos >= call->buff_len) {
- /* cool, we sent everything */
- S("%s: finished sending data to %d\n", __FUNCTION__, call->to_port);
- if (!call->quitting) {
- call->quitting = 1;
- sprintf( call->buff, "quit\n" );
- call->buff_len = strlen(call->buff);
- call->buff_pos = 0;
- } else {
- call->quitting = 0;
- if (call->result_func)
- call->result_func( call->result_opaque, 1 );
-
- sys_channel_on( call->channel, SYS_EVENT_READ, remote_call_event, call );
- }
- }
- }
-}
-
-static RemoteCall _the_remote_calls;
-
-#if 0
-static int
-remote_from_number( const char* from )
-{
- char* end;
- long num = strtol( from, &end, 10 );
-
- if (end == NULL || *end)
- return -1;
-
- if ((unsigned)(num - REMOTE_NUMBER_BASE) >= REMOTE_NUMBER_MAX)
- return -1;
-
- return (int) num;
-}
-#endif
-
-static RemoteCall
-remote_call_generic( RemoteCallType type, const char* to_number, int from_port )
-{
- int to_port = remote_number_string_to_port(to_number);
- RemoteCall call;
-
- if ( remote_number_from_port(from_port) < 0 ) {
- D("%s: from_port value %d is not valid", __FUNCTION__, from_port);
- return NULL;
- }
- if ( to_port < 0 ) {
- D("%s: phone number '%s' is not decimal or remote", __FUNCTION__, to_number);
- return NULL;
- }
- if (to_port == from_port) {
- D("%s: trying to call self\n", __FUNCTION__);
- return NULL;
- }
- call = remote_call_alloc( type, to_port, from_port );
- if (call == NULL) {
- return NULL;
- }
- remote_call_add( call, &_the_remote_calls );
- D("%s: adding new call from port %d to port %d\n", __FUNCTION__, from_port, to_port);
- return call;
-}
-
-
-int
-remote_call_dial( const char* number,
- int from,
- RemoteResultFunc result_func,
- void* result_opaque )
-{
- RemoteCall call = remote_call_generic( REMOTE_CALL_DIAL, number, from );
-
- if (call != NULL) {
- call->result_func = result_func;
- call->result_opaque = result_opaque;
- }
- return call ? 0 : -1;
-}
-
-
-void
-remote_call_other( const char* to_number, int from_port, RemoteCallType type )
-{
- remote_call_generic( type, to_number, from_port );
-}
-
-/* call this function to send a SMS to a remote emulator */
-int
-remote_call_sms( const char* number,
- int from,
- SmsPDU pdu )
-{
- RemoteCall call = remote_call_generic( REMOTE_CALL_SMS, number, from );
-
- if (call == NULL)
- return -1;
-
- if (call != NULL) {
- if ( remote_call_set_sms_pdu( call, pdu ) < 0 ) {
- remote_call_free(call);
- return -1;
- }
- }
- return call ? 0 : -1;
-}
-
-
-void
-remote_call_cancel( const char* to_number, int from_port )
-{
- remote_call_generic( REMOTE_CALL_HANGUP, to_number, from_port );
-}
diff --git a/telephony/remote_call.h b/telephony/remote_call.h
deleted file mode 100644
index c6891b8..0000000
--- a/telephony/remote_call.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _REMOTE_CALL_H
-#define _REMOTE_CALL_H
-
-#include "sms.h"
-
-/* convert a base console port into a remote phone number, -1 on error */
-extern int remote_number_from_port( int port );
-
-/* convert a remote phone number into a remote console port, -1 on error */
-extern int remote_number_to_port( int number );
-
-extern int remote_number_string_to_port( const char* number );
-
-typedef void (*RemoteResultFunc)( void* opaque, int success );
-
-typedef enum {
- REMOTE_CALL_DIAL = 0,
- REMOTE_CALL_BUSY,
- REMOTE_CALL_HANGUP,
- REMOTE_CALL_HOLD,
- REMOTE_CALL_ACCEPT,
- REMOTE_CALL_SMS
-} RemoteCallType;
-
-/* call this function when you need to dial a remote voice call.
- * this will try to connect to a remote emulator. the result function
- * is called to indicate success or failure after some time.
- *
- * returns 0 if the number is to a remote phone, or -1 otherwise
- */
-extern int remote_call_dial( const char* to_number,
- int from_port,
- RemoteResultFunc result_func,
- void* result_opaque );
-
-/* call this function to send a SMS to a remote emulator */
-extern int remote_call_sms( const char* number, int from_port, SmsPDU pdu );
-
-/* call this function to indicate that you're busy to a remote caller */
-extern void remote_call_other( const char* to_number, int from_port, RemoteCallType type );
-
-extern void remote_call_cancel( const char* to_number, int from_port );
-
-#endif /* _REMOTE_CALL_H */
diff --git a/telephony/sim_card.c b/telephony/sim_card.c
deleted file mode 100644
index a5a3249..0000000
--- a/telephony/sim_card.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sim_card.h"
-#include <string.h>
-#include <assert.h>
-
-/* set ENABLE_DYNAMIC_RECORDS to 1 to enable dynamic records
- * for now, this is an experimental feature that needs more testing
- */
-#define ENABLE_DYNAMIC_RECORDS 0
-
-#define A_SIM_PIN_SIZE 4
-#define A_SIM_PUK_SIZE 8
-
-typedef struct ASimCardRec_ {
- ASimStatus status;
- char pin[ A_SIM_PIN_SIZE+1 ];
- char puk[ A_SIM_PUK_SIZE+1 ];
- int pin_retries;
-
- char out_buff[ 256 ];
- int out_size;
-
-} ASimCardRec;
-
-static ASimCardRec _s_card[1];
-
-ASimCard
-asimcard_create( void )
-{
- ASimCard card = _s_card;
- card->status = A_SIM_STATUS_READY;
- card->pin_retries = 0;
- strncpy( card->pin, "0000", sizeof(card->pin) );
- strncpy( card->puk, "12345678", sizeof(card->puk) );
- return card;
-}
-
-void
-asimcard_destroy( ASimCard card )
-{
- /* nothing really */
- card=card;
-}
-
-static __inline__ int
-asimcard_ready( ASimCard card )
-{
- return card->status == A_SIM_STATUS_READY;
-}
-
-ASimStatus
-asimcard_get_status( ASimCard sim )
-{
- return sim->status;
-}
-
-void
-asimcard_set_status( ASimCard sim, ASimStatus status )
-{
- sim->status = status;
-}
-
-const char*
-asimcard_get_pin( ASimCard sim )
-{
- return sim->pin;
-}
-
-const char*
-asimcard_get_puk( ASimCard sim )
-{
- return sim->puk;
-}
-
-void
-asimcard_set_pin( ASimCard sim, const char* pin )
-{
- strncpy( sim->pin, pin, A_SIM_PIN_SIZE );
- sim->pin_retries = 0;
-}
-
-void
-asimcard_set_puk( ASimCard sim, const char* puk )
-{
- strncpy( sim->puk, puk, A_SIM_PUK_SIZE );
- sim->pin_retries = 0;
-}
-
-
-int
-asimcard_check_pin( ASimCard sim, const char* pin )
-{
- if (sim->status != A_SIM_STATUS_PIN &&
- sim->status != A_SIM_STATUS_READY )
- return 0;
-
- if ( !strcmp( sim->pin, pin ) ) {
- sim->status = A_SIM_STATUS_READY;
- sim->pin_retries = 0;
- return 1;
- }
-
- if (sim->status != A_SIM_STATUS_READY) {
- if (++sim->pin_retries == 3)
- sim->status = A_SIM_STATUS_PUK;
- }
- return 0;
-}
-
-
-int
-asimcard_check_puk( ASimCard sim, const char* puk, const char* pin )
-{
- if (sim->status != A_SIM_STATUS_PUK)
- return 0;
-
- if ( !strcmp( sim->puk, puk ) ) {
- strncpy( sim->puk, puk, A_SIM_PUK_SIZE );
- strncpy( sim->pin, pin, A_SIM_PIN_SIZE );
- sim->status = A_SIM_STATUS_READY;
- sim->pin_retries = 0;
- return 1;
- }
-
- if ( ++sim->pin_retries == 6 ) {
- sim->status = A_SIM_STATUS_ABSENT;
- }
- return 0;
-}
-
-typedef enum {
- SIM_FILE_DM = 0,
- SIM_FILE_DF,
- SIM_FILE_EF_DEDICATED,
- SIM_FILE_EF_LINEAR,
- SIM_FILE_EF_CYCLIC
-} SimFileType;
-
-typedef enum {
- SIM_FILE_READ_ONLY = (1 << 0),
- SIM_FILE_NEED_PIN = (1 << 1),
-} SimFileFlags;
-
-/* descriptor for a known SIM File */
-#define SIM_FILE_HEAD \
- SimFileType type; \
- unsigned short id; \
- unsigned short flags;
-
-typedef struct {
- SIM_FILE_HEAD
-} SimFileAnyRec, *SimFileAny;
-
-typedef struct {
- SIM_FILE_HEAD
- cbytes_t data;
- int length;
-} SimFileEFDedicatedRec, *SimFileEFDedicated;
-
-typedef struct {
- SIM_FILE_HEAD
- byte_t rec_count;
- byte_t rec_len;
- cbytes_t records;
-} SimFileEFLinearRec, *SimFileEFLinear;
-
-typedef SimFileEFLinearRec SimFileEFCyclicRec;
-typedef SimFileEFCyclicRec* SimFileEFCyclic;
-
-typedef union {
- SimFileAnyRec any;
- SimFileEFDedicatedRec dedicated;
- SimFileEFLinearRec linear;
- SimFileEFCyclicRec cyclic;
-} SimFileRec, *SimFile;
-
-
-#if ENABLE_DYNAMIC_RECORDS
-/* convert a SIM File descriptor into an ASCII string,
- assumes 'dst' is NULL or properly sized.
- return the number of chars, or -1 on error */
-static int
-sim_file_to_hex( SimFile file, bytes_t dst )
-{
- SimFileType type = file->any.type;
- int result = 0;
-
- /* see 9.2.1 in TS 51.011 */
- switch (type) {
- case SIM_FILE_EF_DEDICATED:
- case SIM_FILE_EF_LINEAR:
- case SIM_FILE_EF_CYCLIC:
- {
- if (dst) {
- int file_size, perm;
-
- memcpy(dst, "0000", 4); /* bytes 1-2 are RFU */
- dst += 4;
-
- /* bytes 3-4 are the file size */
- if (type == SIM_FILE_EF_DEDICATED)
- file_size = file->dedicated.length;
- else
- file_size = file->linear.rec_count * file->linear.rec_len;
-
- gsm_hex_from_short( dst, file_size );
- dst += 4;
-
- /* bytes 5-6 are the file id */
- gsm_hex_from_short( dst, file->any.id );
- dst += 4;
-
- /* byte 7 is the file type - always EF, i.e. 0x04 */
- dst[0] = '0';
- dst[1] = '4';
- dst += 2;
-
- /* byte 8 is RFU, except bit 7 for cyclic files, which indicates
- that INCREASE is allowed. Since we don't support this yet... */
- dst[0] = '0';
- dst[1] = '0';
- dst += 2;
-
- /* byte 9-11 are access conditions */
- if (file->any.flags & SIM_FILE_READ_ONLY) {
- if (file->any.flags & SIM_FILE_NEED_PIN)
- perm = 0x1a;
- else
- perm = 0x0a;
- } else {
- if (file->any.flags & SIM_FILE_NEED_PIN)
- perm = 0x11;
- else
- perm = 0x00;
- }
- gsm_hex_from_byte(dst, perm);
- memcpy( dst+2, "a0aa", 4 );
- dst += 6;
-
- /* byte 12 is file status, we don't support invalidation */
- dst[0] = '0';
- dst[1] = '0';
- dst += 2;
-
- /* byte 13 is length of the following data, always 2 */
- dst[0] = '0';
- dst[1] = '2';
- dst += 2;
-
- /* byte 14 is struct of EF */
- dst[0] = '0';
- if (type == SIM_FILE_EF_DEDICATED)
- dst[1] = '0';
- else if (type == SIM_FILE_EF_LINEAR)
- dst[1] = '1';
- else
- dst[1] = '3';
-
- /* byte 15 is lenght of record, or 0 */
- if (type == SIM_FILE_EF_DEDICATED) {
- dst[0] = '0';
- dst[1] = '0';
- } else
- gsm_hex_from_byte( dst, file->linear.rec_len );
- }
- result = 30;
- }
- break;
-
- default:
- result = -1;
- }
- return result;
-}
-
-
-static const byte_t _const_spn_cphs[20] = {
- 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-static const byte_t _const_voicemail_cphs[1] = {
- 0x55
-};
-
-static const byte_t _const_iccid[10] = {
- 0x98, 0x10, 0x14, 0x30, 0x12, 0x11, 0x81, 0x15, 0x70, 0x02
-};
-
-static const byte_t _const_cff_cphs[1] = {
- 0x55
-};
-
-static SimFileEFDedicatedRec _const_files_dedicated[] =
-{
- { SIM_FILE_EF_DEDICATED, 0x6f14, SIM_FILE_READ_ONLY | SIM_FILE_NEED_PIN,
- _const_spn_cphs, sizeof(_const_spn_cphs) },
-
- { SIM_FILE_EF_DEDICATED, 0x6f11, SIM_FILE_NEED_PIN,
- _const_voicemail_cphs, sizeof(_const_voicemail_cphs) },
-
- { SIM_FILE_EF_DEDICATED, 0x2fe2, SIM_FILE_READ_ONLY,
- _const_iccid, sizeof(_const_iccid) },
-
- { SIM_FILE_EF_DEDICATED, 0x6f13, SIM_FILE_NEED_PIN,
- _const_cff_cphs, sizeof(_const_cff_cphs) },
-
- { 0, 0, 0, NULL, 0 } /* end of list */
-};
-#endif /* ENABLE_DYNAMIC_RECORDS */
-
-const char*
-asimcard_io( ASimCard sim, const char* cmd )
-{
- int nn;
-#if ENABLE_DYNAMIC_RECORDS
- int command, id, p1, p2, p3;
-#endif
- static const struct { const char* cmd; const char* answer; } answers[] =
- {
- { "+CRSM=192,28436,0,0,15", "+CRSM: 144,0,000000146f1404001aa0aa01020000" },
- { "+CRSM=176,28436,0,0,20", "+CRSM: 144,0,416e64726f6964ffffffffffffffffffffffffff" },
-
- { "+CRSM=192,28433,0,0,15", "+CRSM: 144,0,000000016f11040011a0aa01020000" },
- { "+CRSM=176,28433,0,0,1", "+CRSM: 144,0,55" },
-
- { "+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000a2fe204000fa0aa01020000" },
- { "+CRSM=176,12258,0,0,10", "+CRSM: 144,0,98101430121181157002" },
-
- { "+CRSM=192,28435,0,0,15", "+CRSM: 144,0,000000016f13040011a0aa01020000" },
- { "+CRSM=176,28435,0,0,1", "+CRSM: 144,0,55" },
-
- { "+CRSM=192,28472,0,0,15", "+CRSM: 144,0,0000000f6f3804001aa0aa01020000" },
- { "+CRSM=176,28472,0,0,15", "+CRSM: 144,0,ff30ffff3c003c03000c0000f03f00" },
-
- { "+CRSM=192,28617,0,0,15", "+CRSM: 144,0,000000086fc9040011a0aa01020104" },
- { "+CRSM=178,28617,1,4,4", "+CRSM: 144,0,01000000" },
-
- { "+CRSM=192,28618,0,0,15", "+CRSM: 144,0,0000000a6fca040011a0aa01020105" },
- { "+CRSM=178,28618,1,4,5", "+CRSM: 144,0,0000000000" },
-
- { "+CRSM=192,28589,0,0,15", "+CRSM: 144,0,000000046fad04000aa0aa01020000" },
- { "+CRSM=176,28589,0,0,4", "+CRSM: 144,0,00000003" },
-
- { "+CRSM=192,28438,0,0,15", "+CRSM: 144,0,000000026f1604001aa0aa01020000" },
- { "+CRSM=176,28438,0,0,2", "+CRSM: 144,0,0233" },
-
- { "+CRSM=192,28486,0,0,15", "+CRSM: 148,4" },
- { "+CRSM=192,28621,0,0,15", "+CRSM: 148,4" },
-
- { "+CRSM=192,28613,0,0,15", "+CRSM: 144,0,000000f06fc504000aa0aa01020118" },
- { "+CRSM=178,28613,1,4,24", "+CRSM: 144,0,43058441aa890affffffffffffffffffffffffffffffffff" },
-
- { "+CRSM=192,28480,0,0,15", "+CRSM: 144,0,000000806f40040011a0aa01020120" },
- { "+CRSM=178,28480,1,4,32", "+CRSM: 144,0,ffffffffffffffffffffffffffffffffffff07815155258131f5ffffffffffff" },
-
- { "+CRSM=192,28615,0,0,15", "+CRSM: 144,0,000000406fc7040011a0aa01020120" },
- { "+CRSM=178,28615,1,4,32", "+CRSM: 144,0,566f6963656d61696cffffffffffffffffff07915155125740f9ffffffffffff" },
-
- { NULL, NULL }
- };
-
- assert( memcmp( cmd, "+CRSM=", 6 ) == 0 );
-
-#if ENABLE_DYNAMIC_RECORDS
- if ( sscanf(cmd, "+CRSM=%d,%d,%d,%d,%d", &command, &id, &p1, &p2, &p3) == 5 ) {
- switch (command) {
- case A_SIM_CMD_GET_RESPONSE:
- {
- const SimFileEFDedicatedRec* file = _const_files_dedicated;
-
- assert(p1 == 0 && p2 == 0 && p3 == 15);
-
- for ( ; file->id != 0; file++ ) {
- if (file->id == id) {
- int count;
- char* out = sim->out_buff;
- strcpy( out, "+CRSM: 144,0," );
- out += strlen(out);
- count = sim_file_to_hex( (SimFile) file, out );
- if (count < 0)
- return "ERROR: INTERNAL SIM ERROR";
- out[count] = 0;
- return sim->out_buff;
- }
- }
- break;
- }
-
- case A_SIM_CMD_READ_BINARY:
- {
- const SimFileEFDedicatedRec* file = _const_files_dedicated;
-
- assert(p1 == 0 && p2 == 0);
-
- for ( ; file->id != 0; file++ ) {
- if (file->id == id) {
- char* out = sim->out_buff;
-
- if (p3 > file->length)
- return "ERROR: BINARY LENGTH IS TOO LONG";
-
- strcpy( out, "+CRSM: 144,0," );
- out += strlen(out);
- gsm_hex_from_bytes( out, file->data, p3 );
- out[p3*2] = 0;
- return sim->out_buff;
- }
- }
- break;
- }
-
- case A_SIM_CMD_READ_RECORD:
- break;
-
- default:
- return "ERROR: UNSUPPORTED SIM COMMAND";
- }
- }
-#endif
-
- for (nn = 0; answers[nn].cmd != NULL; nn++) {
- if ( !strcmp( answers[nn].cmd, cmd ) ) {
- return answers[nn].answer;
- }
- }
- return "ERROR: BAD COMMAND";
-}
-
diff --git a/telephony/sim_card.h b/telephony/sim_card.h
deleted file mode 100644
index af78237..0000000
--- a/telephony/sim_card.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_sim_card_h
-#define _android_sim_card_h
-
-#include "gsm.h"
-
-typedef struct ASimCardRec_* ASimCard;
-
-extern ASimCard asimcard_create( void );
-extern void asimcard_destroy( ASimCard sim );
-
-typedef enum {
- A_SIM_STATUS_ABSENT = 0,
- A_SIM_STATUS_NOT_READY,
- A_SIM_STATUS_READY,
- A_SIM_STATUS_PIN,
- A_SIM_STATUS_PUK,
- A_SIM_STATUS_NETWORK_PERSONALIZATION
-} ASimStatus;
-
-extern ASimStatus asimcard_get_status( ASimCard sim );
-extern void asimcard_set_status( ASimCard sim, ASimStatus status );
-
-extern const char* asimcard_get_pin( ASimCard sim );
-extern const char* asimcard_get_puk( ASimCard sim );
-extern void asimcard_set_pin( ASimCard sim, const char* pin );
-extern void asimcard_set_puk( ASimCard sim, const char* puk );
-
-extern int asimcard_check_pin( ASimCard sim, const char* pin );
-extern int asimcard_check_puk( ASimCard sim, const char* puk, const char* pin );
-
-/* Restricted SIM Access command, as defined by 8.18 of 3GPP 27.007 */
-typedef enum {
- A_SIM_CMD_READ_BINARY = 176,
- A_SIM_CMD_READ_RECORD = 178,
- A_SIM_CMD_GET_RESPONSE = 192,
- A_SIM_CMD_UPDATE_BINARY = 214,
- A_SIM_CMD_UPDATE_RECORD = 220,
- A_SIM_CMD_STATUS = 242
-} ASimCommand;
-
-extern const char* asimcard_io( ASimCard sim, const char* cmd );
-
-#endif /* _android_sim_card_h */
diff --git a/telephony/simulator.c b/telephony/simulator.c
deleted file mode 100644
index 43f267a..0000000
--- a/telephony/simulator.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "android_modem.h"
-#include "sysdeps.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-
-#define DEFAULT_PORT 6703
-
-static AModem modem;
-
-typedef struct {
- SysChannel channel;
- char in_buff[ 128 ];
- int in_pos;
-
- char out_buff[ 128 ];
- int out_pos;
- int out_size;
-} ClientRec, *Client;
-
-static Client
-client_alloc( SysChannel channel )
-{
- Client client = calloc( sizeof(*client), 1 );
-
- client->channel = channel;
- return client;
-}
-
-static void
-client_free( Client client )
-{
- sys_channel_close( client->channel );
- client->channel = NULL;
- free( client );
-}
-
-static void
-client_append( Client client, const char* str, int len );
-
-static void
-dump_line( const char* line, const char* prefix )
-{
- if (prefix)
- printf( "%s", prefix );
-
- for ( ; *line; line++ ) {
- int c = line[0];
-
- if (c >= 32 && c < 127)
- printf( "%c", c );
- else if (c == '\r')
- printf( "<CR>" );
- else if (c == '\n')
- printf( "<LF>" );
- else
- printf( "\\x%02x", c );
- }
- printf( "\n" );
-}
-
-static void
-client_handle_line( Client client, const char* cmd )
-{
- const char* answer;
-
- dump_line( cmd, "<< " );
- answer = amodem_send( modem, cmd );
- if (answer == NULL) /* not an AT command, ignored */ {
- printf( "-- NO ANSWER\n" );
- return;
- }
-
- dump_line( answer, ">> " );
- client_append( client, answer, -1 );
- client_append( client, "\r", 1 );
-}
-
-static void
-client_handler( void* _client, int events )
-{
- Client client = _client;
-
- if (events & SYS_EVENT_READ) {
- int ret;
- /* read into buffer, one character at a time */
- ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- if (client->in_buff[client->in_pos] == '\r' ||
- client->in_buff[client->in_pos] == '\n' ) {
- const char* cmd = client->in_buff;
- client->in_buff[client->in_pos] = 0;
-
- if (client->in_pos > 0) {
- client_handle_line( client, cmd );
- client->in_pos = 0;
- }
- } else
- client->in_pos += 1;
- }
-
- if (events & SYS_EVENT_WRITE) {
- int ret;
- /* write from output buffer, one char at a time */
- ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- client->out_pos += 1;
- if (client->out_pos == client->out_size) {
- client->out_size = 0;
- client->out_pos = 0;
- /* we don't need to write */
- sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client );
- }
- }
- return;
-
-ExitClient:
- printf( "client %p exiting\n", client );
- client_free( client );
-}
-
-
-static void
-client_append( Client client, const char* str, int len )
-{
- int avail;
-
- if (len < 0)
- len = strlen(str);
-
- avail = sizeof(client->out_buff) - client->out_size;
- if (len > avail)
- len = avail;
-
- memcpy( client->out_buff + client->out_size, str, len );
- if (client->out_size == 0) {
- sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client );
- }
- client->out_size += len;
-}
-
-
-static void
-accept_func( void* _server, int events )
-{
- SysChannel server = _server;
- SysChannel handler;
- Client client;
-
- printf( "connection accepted for server channel, getting handler socket\n" );
- handler = sys_channel_create_tcp_handler( server );
- client = client_alloc( handler );
- printf( "got one. created client %p\n", client );
-
- events=events;
- sys_channel_on( handler, SYS_EVENT_READ, client_handler, client );
-}
-
-
-int main( void )
-{
- int port = DEFAULT_PORT;
- SysChannel server;
-
- sys_main_init();
- modem = amodem_create( NULL, NULL );
-
- server = sys_channel_create_tcp_server( port );
- printf( "GSM simulator listening on local port %d\n", port );
-
- sys_channel_on( server, SYS_EVENT_READ, accept_func, server );
- sys_main_loop();
- printf( "GSM simulator exiting\n" );
- return 0;
-}
diff --git a/telephony/sms.c b/telephony/sms.c
deleted file mode 100644
index 448eab4..0000000
--- a/telephony/sms.c
+++ /dev/null
@@ -1,1655 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sms.h"
-#include "gsm.h"
-#include <memory.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#define DEBUG 1
-
-#if 1
-# include "android/utils/debug.h"
-# define D_ACTIVE VERBOSE_CHECK(modem)
-#else
-# define D_ACTIVE DEBUG
-#endif
-
-#if DEBUG
-# define D(...) VERBOSE_PRINT(modem,__VA_ARGS__)
-#else
-# define D(...) ((void)0)
-#endif
-
-/* maximum number of data bytes in a SMS data message */
-#define MAX_USER_DATA_BYTES 140
-
-/* maximum number of 7-bit septets in a SMS text message */
-#define MAX_USER_DATA_SEPTETS 160
-
-/* size of the user data header in bytes */
-#define USER_DATA_HEADER_SIZE 6
-
-/** MESSAGE TEXT
- **/
-int
-sms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len )
-{
- cbytes_t p = (cbytes_t)str;
- cbytes_t end = p + strlen;
- int count = 0;
- int escaped = 0;
-
- while (p < end)
- {
- int c = p[0];
-
- /* read the value from the string */
- p += 1;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
- p++;
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- p++;
- }
- }
- if (escaped) {
- switch (c) {
- case '\\':
- break;
- case 'n': /* \n is line feed */
- c = 10;
- break;
-
- case 'x': /* \xNN, where NN is a 2-digit hexadecimal value */
- if (p+2 > end)
- return -1;
- c = gsm_hex2_to_byte( (const char*)p );
- if (c < 0)
- return -1;
- p += 2;
- break;
-
- case 'u': /* \uNNNN where NNNN is a 4-digiti hexadecimal value */
- if (p + 4 > end)
- return -1;
- c = gsm_hex4_to_short( (const char*)p );
- if (c < 0)
- return -1;
- p += 4;
- break;
-
- default: /* invalid escape, return -1 */
- return -1;
- }
- escaped = 0;
- }
- else if (c == '\\')
- {
- escaped = 1;
- continue;
- }
-
- /* now, try to write it to the destination */
- if (c < 128) {
- if (count < utf8len)
- utf8[count] = (byte_t) c;
- count += 1;
- }
- else if (c < 0x800) {
- if (count < utf8len)
- utf8[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f));
- if (count+1 < utf8len)
- utf8[count+1] = (byte_t)(0x80 | (c & 0x3f));
- count += 2;
- }
- else {
- if (count < utf8len)
- utf8[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf));
- if (count+1 < utf8len)
- utf8[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f));
- if (count+2 < utf8len)
- utf8[count+2] = (byte_t)(0x80 | (c & 0x3f));
- count += 3;
- }
- }
-
- if (escaped) /* bad final escape */
- return -1;
-
- return count;
-}
-
-/* to convert utf-8 to a message string, we only need to deal with control characters
- * and that's it */
-int sms_utf8_to_message_str( const unsigned char* utf8, int utf8len, char* str, int strlen )
-{
- cbytes_t p = utf8;
- cbytes_t end = p + utf8len;
- int count = 0;
-
- while (p < end)
- {
- int c = p[0];
- int escape = 0;
-
- /* read the value from the string */
- p += 1;
- if (c >= 128) {
- if ((c & 0xe0) == 0xc0)
- c &= 0x1f;
- else if ((c & 0xf0) == 0xe0)
- c &= 0x0f;
- else
- c &= 0x07;
- p++;
- while (p < end && (p[0] & 0xc0) == 0x80) {
- c = (c << 6) | (p[0] & 0x3f);
- p++;
- }
- }
-
- if (c < ' ') {
- escape = 1;
- if (c == '\n') {
- c = 'n';
- escape = 2;
- }
- }
- else if (c == '\\')
- escape = 2;
-
- switch (escape) {
- case 0:
- if (c < 128) {
- if (count < strlen)
- str[count] = (char) c;
- count += 1;
- }
- else if (c < 0x800) {
- if (count < strlen)
- str[count] = (byte_t)(0xc0 | ((c >> 6) & 0x1f));
- if (count+1 < strlen)
- str[count+1] = (byte_t)(0x80 | (c & 0x3f));
- count += 2;
- }
- else {
- if (count < strlen)
- str[count] = (byte_t)(0xc0 | ((c >> 12) & 0xf));
- if (count+1 < strlen)
- str[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f));
- if (count+2 < strlen)
- str[count+2] = (byte_t)(0x80 | (c & 0x3f));
- count += 3;
- }
- break;
-
- case 1:
- if (count+3 < strlen) {
- str[count+0] = '\\';
- str[count+1] = 'x';
- gsm_hex_from_byte(str + count + 2, c);
- }
- count += 4;
- break;
-
- default:
- if (count+2 < strlen) {
- str[count+0] = '\\';
- str[count+1] = (char) c;
- }
- count += 2;
- }
- }
- return count;
-}
-
-
-/** TIMESTAMPS
- **/
-void
-sms_timestamp_now( SmsTimeStamp stamp )
-{
- time_t now_time = time(NULL);
- struct tm gm = *(gmtime(&now_time));
- struct tm local = *(localtime(&now_time));
- int tzdiff = 0;
-
- stamp->data[0] = gsm_int_to_bcdi( local.tm_year % 100 );
- stamp->data[1] = gsm_int_to_bcdi( local.tm_mon+1 );
- stamp->data[2] = gsm_int_to_bcdi( local.tm_mday );
- stamp->data[3] = gsm_int_to_bcdi( local.tm_hour );
- stamp->data[4] = gsm_int_to_bcdi( local.tm_min );
- stamp->data[5] = gsm_int_to_bcdi( local.tm_sec );
-
- tzdiff = (local.tm_hour*4 + local.tm_min/15) - (gm.tm_hour*4 + gm.tm_min/15);
- if (local.tm_yday > gm.tm_yday)
- tzdiff += 24*4;
- else if (local.tm_yday < gm.tm_yday)
- tzdiff -= 24*4;
-
- stamp->data[6] = gsm_int_to_bcdi( tzdiff >= 0 ? tzdiff : -tzdiff );
- if (tzdiff < 0)
- stamp->data[6] |= 0x08;
-}
-
-int
-sms_timestamp_to_tm( SmsTimeStamp stamp, struct tm* tm )
-{
- int tzdiff;
-
- tm->tm_year = gsm_int_from_bcdi( stamp->data[0] );
- if (tm->tm_year < 50)
- tm->tm_year += 100;
- tm->tm_mon = gsm_int_from_bcdi( stamp->data[1] ) -1;
- tm->tm_mday = gsm_int_from_bcdi( stamp->data[2] );
- tm->tm_hour = gsm_int_from_bcdi( stamp->data[3] );
- tm->tm_min = gsm_int_from_bcdi( stamp->data[4] );
- tm->tm_sec = gsm_int_from_bcdi( stamp->data[5] );
-
- tm->tm_isdst = -1;
-
- tzdiff = gsm_int_from_bcdi( stamp->data[6] & 0xf7 );
- if (stamp->data[6] & 0x8)
- tzdiff = -tzdiff;
-
- return tzdiff;
-}
-
-static void
-gsm_rope_add_timestamp( GsmRope rope, const SmsTimeStampRec* ts )
-{
- gsm_rope_add( rope, ts->data, 7 );
-}
-
-
-/** SMS ADDRESSES
- **/
-
-int
-sms_address_from_str( SmsAddress address, const char* src, int srclen )
-{
- const char* end = src + srclen;
- int shift = 0, len = 0;
- bytes_t data = address->data;
-
- address->len = 0;
- address->toa = 0x81;
-
- if (src >= end)
- return -1;
-
- if ( src[0] == '+' ) {
- address->toa = 0x91;
- if (++src == end)
- goto Fail;
- }
-
- memset( address->data, 0, sizeof(address->data) );
-
- shift = 0;
-
- while (src < end) {
- int c = *src++ - '0';
-
- if ( (unsigned)c >= 10 ||
- data >= address->data + sizeof(address->data) )
- goto Fail;
-
- data[0] |= c << shift;
- len += 1;
- shift += 4;
- if (shift == 8) {
- shift = 0;
- data += 1;
- }
- }
- if (shift != 0)
- data[0] |= 0xf0;
-
- address->len = len;
- return 0;
-
-Fail:
- return -1;
-}
-
-int
-sms_address_to_str( SmsAddress address, char* str, int strlen )
-{
- static const char dialdigits[16] = "0123456789*#,N%";
- int n, count = 0;
-
- if (address->toa == 0x91) {
- if (count < strlen)
- str[count] = '+';
- count++;
- }
- for (n = 0; n < address->len; n += 2)
- {
- int c = address->data[n/2];
-
- if (count < strlen)
- str[count] = dialdigits[c & 0xf];
- count += 1;
-
- if (n+1 > address->len)
- break;
-
- if (count < strlen)
- str[count] = dialdigits[(c >> 4) & 0xf];
- count += 1;
- }
- return count;
-}
-
-int
-sms_address_from_bytes( SmsAddress address, const unsigned char* buf, int buflen )
-{
- int len = sizeof(address->data), num_digits;
-
- if (buflen < 2)
- return -1;
-
- address->len = num_digits = buf[0];
- address->toa = buf[1];
-
- len = (num_digits+1)/2;
- if ( len > sizeof(address->data) )
- return -1;
-
- memcpy( address->data, buf+2, len );
- return 0;
-}
-
-int
-sms_address_to_bytes( SmsAddress address, unsigned char* buf, int bufsize )
-{
- int len = (address->len + 1)/2 + 2;
-
- if (buf == NULL)
- bufsize = 0;
-
- if (bufsize < 1) goto Exit;
- buf[0] = address->len;
-
- if (bufsize < 2) goto Exit;
- buf[1] = address->toa;
-
- buf += 2;
- bufsize -= 2;
- if (bufsize > len-2)
- bufsize = len - 2;
-
- memcpy( buf, address->data, bufsize );
-Exit:
- return len;
-}
-
-int
-sms_address_from_hex ( SmsAddress address, const char* hex, int hexlen )
-{
- const char* hexend = hex + hexlen;
- int nn, len, num_digits;
-
- if (hexlen < 4)
- return -1;
-
- address->len = num_digits = gsm_hex2_to_byte( hex );
- address->toa = gsm_hex2_to_byte( hex+2 );
- hex += 4;
-
- len = (num_digits + 1)/2;
- if (hex + len*2 > hexend)
- return -1;
-
- for ( nn = 0; nn < len; nn++ )
- address->data[nn] = gsm_hex2_to_byte( hex + nn*2 );
-
- return 0;
-}
-
-int
-sms_address_to_hex ( SmsAddress address, char* hex, int hexlen )
-{
- int len = (address->len + 1)/2 + 2;
- int nn;
-
- if (hex == NULL)
- hexlen = 0;
-
- if (hexlen < 2) goto Exit;
- gsm_hex_from_byte( hex, address->len );
- if (hexlen < 4) goto Exit;
- gsm_hex_from_byte( hex+2, address->toa );
- hex += 4;
- hexlen -= 4;
- if ( hexlen > 2*(len - 2) )
- hexlen = (len - 2)/2;
-
- for ( nn = 0; nn < hexlen; nn += 2 )
- gsm_hex_from_byte( hex+nn, address->data[nn/2] );
-
-Exit:
- return len*2;
-}
-
-static void
-gsm_rope_add_address( GsmRope rope, const SmsAddressRec* addr )
-{
- gsm_rope_add_c( rope, addr->len );
- gsm_rope_add_c( rope, addr->toa );
- gsm_rope_add( rope, addr->data, (addr->len+1)/2 );
- if (addr->len & 1) {
- if (!rope->error && rope->data != NULL)
- rope->data[ rope->pos-1 ] |= 0xf0;
- }
-}
-
-static int
-sms_address_eq( const SmsAddressRec* addr1, const SmsAddressRec* addr2 )
-{
- if ( addr1->toa != addr2->toa ||
- addr1->len != addr2->len )
- return 0;
-
- return ( !memcmp( addr1->data, addr2->data, addr1->len ) );
-}
-
-/** SMS PARSER
- **/
-static int
-sms_get_byte( cbytes_t *pcur, cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int result = -1;
-
- if (cur < end) {
- result = cur[0];
- *pcur = cur + 1;
- }
- return result;
-}
-
-/* parse a service center address, returns -1 in case of error */
-static int
-sms_get_sc_address( cbytes_t *pcur,
- cbytes_t end,
- SmsAddress address )
-{
- cbytes_t cur = *pcur;
- int result = -1;
-
- if (cur < end) {
- int len = cur[0];
- int dlen, adjust = 0;
-
- cur += 1;
-
- if (len == 0) { /* empty address */
- address->len = 0;
- address->toa = 0x00;
- result = 0;
- goto Exit;
- }
-
- if (cur + len > end) {
- goto Exit;
- }
-
- address->toa = *cur++;
- len -= 1;
- result = 0;
-
- for (dlen = 0; dlen < len; dlen+=1)
- {
- int c = cur[dlen];
- int v;
-
- adjust = 0;
- if (dlen >= sizeof(address->data)) {
- result = -1;
- break;
- }
-
- v = (c & 0xf);
- if (v >= 0xe)
- break;
-
- adjust = 1;
- address->data[dlen] = (byte_t) c;
-
- v = (c >> 4) & 0xf;
- if (v >= 0xe) {
- break;
- }
- }
- address->len = 2*dlen + adjust;
- }
-Exit:
- if (!result)
- *pcur = cur;
-
- return result;
-}
-
-static int
-sms_skip_sc_address( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int len;
-
- if (cur >= end)
- goto Exit;
-
- len = cur[0];
- cur += 1 + len;
- if (cur > end)
- goto Exit;
-
- *pcur = cur;
- result = 0;
-Exit:
- return result;
-}
-
-/* parse a sender/receiver address, returns -1 in case of error */
-static int
-sms_get_address( cbytes_t *pcur,
- cbytes_t end,
- SmsAddress address )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int len, dlen;
-
- if (cur >= end)
- goto Exit;
-
- dlen = *cur++;
-
- if (dlen == 0) {
- address->len = 0;
- address->toa = 0;
- result = 0;
- goto Exit;
- }
-
- if (cur + 1 + (dlen+1)/2 > end)
- goto Exit;
-
- address->len = dlen;
- address->toa = *cur++;
-
- len = (dlen + 1)/2;
- if (len > sizeof(address->data))
- goto Exit;
-
- memcpy( address->data, cur, len );
- cur += len;
- result = 0;
-
-Exit:
- if (!result)
- *pcur = cur;
-
- return result;
-}
-
-static int
-sms_skip_address( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int dlen;
-
- if (cur + 2 > end)
- goto Exit;
-
- dlen = cur[0];
- cur += 2 + (dlen + 1)/2;
- if (cur > end)
- goto Exit;
-
- result = 0;
-Exit:
- return result;
-}
-
-/* parse a service center timestamp */
-static int
-sms_get_timestamp( cbytes_t *pcur,
- cbytes_t end,
- SmsTimeStamp ts )
-{
- cbytes_t cur = *pcur;
-
- if (cur + 7 > end)
- return -1;
-
- memcpy( ts->data, cur, 7 );
- *pcur = cur + 7;
- return 0;
-}
-
-static int
-sms_skip_timestamp( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
-
- if (cur + 7 > end)
- return -1;
-
- *pcur = cur + 7;
- return 0;
-}
-
-
-static int
-sms_skip_validity_period( cbytes_t *pcur,
- cbytes_t end,
- int mtiByte )
-{
- cbytes_t cur = *pcur;
-
- switch ((mtiByte >> 3) & 3) {
- case 1: /* relative format */
- cur += 1;
- break;
-
- case 2: /* enhanced format */
- case 3: /* absolute format */
- cur += 7;
- }
- if (cur > end)
- return -1;
-
- *pcur = cur;
- return 0;
-}
-
-/** SMS PDU
- **/
-
-typedef struct SmsPDURec {
- bytes_t base;
- bytes_t end;
- bytes_t tpdu;
-} SmsPDURec;
-
-void
-smspdu_free( SmsPDU pdu )
-{
- if (pdu) {
- free( pdu->base );
- pdu->base = NULL;
- pdu->end = NULL;
- pdu->tpdu = NULL;
- }
-}
-
-SmsPduType
-smspdu_get_type( SmsPDU pdu )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte(&data, end);
-
- switch (mtiByte & 3) {
- case 0: return SMS_PDU_DELIVER;
- case 1: return SMS_PDU_SUBMIT;
- case 2: return SMS_PDU_STATUS_REPORT;
- default: return SMS_PDU_INVALID;
- }
-}
-
-int
-smspdu_get_sender_address( SmsPDU pdu, SmsAddress address )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte(&data, end);
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER; */
- return sms_get_sc_address( &data, end, address );
-
- default: return -1;
- }
-}
-
-int
-smspdu_get_sc_timestamp( SmsPDU pdu, SmsTimeStamp ts )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER */
- {
- SmsAddressRec address;
-
- if ( sms_get_sc_address( &data, end, &address ) < 0 )
- return -1;
-
- data += 2; /* skip protocol identifer + coding scheme */
-
- return sms_get_timestamp( &data, end, ts );
- }
-
- default: return -1;
- }
-}
-
-int
-smspdu_get_receiver_address( SmsPDU pdu, SmsAddress address )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- switch (mtiByte & 3) {
- case 1: /* SMS_PDU_SUBMIT */
- {
- data += 1; /* skip message reference */
- return sms_get_address( &data, end, address );
- }
-
- default: return -1;
- }
-}
-
-typedef enum {
- SMS_CODING_SCHEME_UNKNOWN = 0,
- SMS_CODING_SCHEME_GSM7,
- SMS_CODING_SCHEME_UCS2
-
-} SmsCodingScheme;
-
-/* see TS 23.038 Section 5 for details */
-static SmsCodingScheme
-sms_get_coding_scheme( cbytes_t *pcur,
- cbytes_t end )
-{
- cbytes_t cur = *pcur;
- int dataCoding;
-
- if (cur >= end)
- return SMS_CODING_SCHEME_UNKNOWN;
-
- dataCoding = *cur++;
- *pcur = cur;
-
- switch (dataCoding >> 4) {
- case 0x00:
- case 0x02:
- case 0x03:
- return SMS_CODING_SCHEME_GSM7;
-
- case 0x01:
- if (dataCoding == 0x10) return SMS_CODING_SCHEME_GSM7;
- if (dataCoding == 0x11) return SMS_CODING_SCHEME_UCS2;
- break;
-
- case 0x04: case 0x05: case 0x06: case 0x07:
- if (dataCoding & 0x20) return SMS_CODING_SCHEME_UNKNOWN; /* compressed 7-bits */
- if (((dataCoding >> 2) & 3) == 0) return SMS_CODING_SCHEME_GSM7;
- if (((dataCoding >> 2) & 3) == 2) return SMS_CODING_SCHEME_UCS2;
- break;
-
- case 0xF:
- if (!(dataCoding & 4)) return SMS_CODING_SCHEME_GSM7;
- break;
- }
- return SMS_CODING_SCHEME_UNKNOWN;
-}
-
-
-/* see TS 23.040 section 9.2.3.24 for details */
-static int
-sms_get_text_utf8( cbytes_t *pcur,
- cbytes_t end,
- int hasUDH,
- SmsCodingScheme coding,
- GsmRope rope )
-{
- cbytes_t cur = *pcur;
- int result = -1;
- int len;
-
- if (cur >= end)
- goto Exit;
-
- len = *cur++;
-
- /* skip user data header if any */
- if ( hasUDH )
- {
- int hlen;
-
- if (cur >= end)
- goto Exit;
-
- hlen = *cur++;
- if (cur + hlen > end)
- goto Exit;
-
- cur += hlen;
-
- if (coding == SMS_CODING_SCHEME_GSM7)
- len -= 2*(hlen+1);
- else
- len -= hlen+1;
-
- if (len < 0)
- goto Exit;
- }
-
- /* switch the user data header if any */
- if (coding == SMS_CODING_SCHEME_GSM7)
- {
- int count = utf8_from_gsm7( cur, 0, len, NULL );
-
- if (rope != NULL)
- {
- bytes_t dst = gsm_rope_reserve( rope, count );
- if (dst != NULL)
- utf8_from_gsm7( cur, 0, len, dst );
- }
- cur += (len+1)/2;
- }
- else if (coding == SMS_CODING_SCHEME_UCS2)
- {
- int count = ucs2_to_utf8( cur, len/2, NULL );
-
- if (rope != NULL)
- {
- bytes_t dst = gsm_rope_reserve( rope, count );
- if (dst != NULL)
- ucs2_to_utf8( cur, len/2, dst );
- }
- cur += len;
- }
- result = 0;
-
-Exit:
- if (!result)
- *pcur = cur;
-
- return result;
-}
-
-/* get the message embedded in a SMS PDU as a utf8 byte array, returns the length of the message in bytes */
-/* or -1 in case of error */
-int
-smspdu_get_text_message( SmsPDU pdu, unsigned char* utf8, int utf8len )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER */
- {
- SmsAddressRec address;
- SmsTimeStampRec timestamp;
- SmsCodingScheme coding;
- GsmRopeRec rope[1];
- int result;
-
- if ( sms_get_sc_address( &data, end, &address ) < 0 )
- goto Fail;
-
- data += 1; /* skip protocol identifier */
- coding = sms_get_coding_scheme( &data, end );
- if (coding == SMS_CODING_SCHEME_UNKNOWN)
- goto Fail;
-
- if ( sms_get_timestamp( &data, end, &timestamp ) < 0 )
- goto Fail;
-
- if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 )
- goto Fail;
-
- result = rope->pos;
- if (utf8len > result)
- utf8len = result;
-
- if (utf8len > 0)
- memcpy( utf8, rope->data, utf8len );
-
- gsm_rope_done( rope );
- return result;
- }
-
- case 1: /* SMS_PDU_SUBMIT */
- {
- SmsAddressRec address;
- SmsCodingScheme coding;
- GsmRopeRec rope[1];
- int result;
-
- data += 1; /* message reference */
-
- if ( sms_get_address( &data, end, &address ) < 0 )
- goto Fail;
-
- data += 1; /* skip protocol identifier */
- coding = sms_get_coding_scheme( &data, end );
- if (coding == SMS_CODING_SCHEME_UNKNOWN)
- goto Fail;
-
- gsm_rope_init_alloc( rope, 0 );
- if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 ) {
- gsm_rope_done( rope );
- goto Fail;
- }
-
- result = rope->pos;
- if (utf8len > result)
- utf8len = result;
-
- if (utf8len > 0)
- memcpy( utf8, rope->data, utf8len );
-
- gsm_rope_done( rope );
- return result;
- }
- }
-Fail:
- return -1;
-}
-
-static cbytes_t
-smspdu_get_user_data_ref( SmsPDU pdu )
-{
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
- int len;
-
- /* if there is no user-data-header, there is no message reference here */
- if ((mtiByte & 0x40) == 0)
- goto Fail;
-
- switch (mtiByte & 3) {
- case 0: /* SMS_PDU_DELIVER */
- if ( sms_skip_address( &data, end ) < 0 )
- goto Fail;
-
- data += 2; /* skip protocol identifier + coding scheme */
-
- if ( sms_skip_timestamp( &data, end ) < 0 )
- goto Fail;
-
- break;
-
- case 1: /* SMS_PDU_SUBMIT */
- data += 1; /* skip message reference */
-
- if ( sms_skip_address( &data, end ) < 0 )
- goto Fail;
-
- data += 2; /* protocol identifier + oding schene */
- if ( sms_skip_validity_period( &data, end, mtiByte ) < 0 )
- goto Fail;
-
- break;
-
- default:
- goto Fail;
- }
-
- /* skip user-data length */
- if (data+1 >= end)
- goto Fail;
-
- len = data[1];
- data += 2;
-
- while (len >= 2 && data + 2 <= end) {
- int htype = data[0];
- int hlen = data[1];
-
- if (htype == 00 && hlen == 3 && data + 5 <= end) {
- return data + 2;
- }
-
- data += hlen;
- len -= hlen - 2;
- }
-Fail:
- return NULL;
-}
-
-int
-smspdu_get_ref( SmsPDU pdu )
-{
- cbytes_t user_ref = smspdu_get_user_data_ref( pdu );
-
- if (user_ref != NULL)
- {
- return user_ref[0];
- }
- else
- {
- cbytes_t data = pdu->tpdu;
- cbytes_t end = pdu->end;
- int mtiByte = sms_get_byte( &data, end );
-
- if ((mtiByte & 3) == 1) {
- /* try to extract directly the reference for a SMS-SUBMIT */
- if (data < end)
- return data[0];
- }
- }
- return -1;
-}
-
-int
-smspdu_get_max_index( SmsPDU pdu )
-{
- cbytes_t user_ref = smspdu_get_user_data_ref( pdu );
-
- if (user_ref != NULL) {
- return user_ref[1];
- } else {
- return 1;
- }
-}
-
-int
-smspdu_get_cur_index( SmsPDU pdu )
-{
- cbytes_t user_ref = smspdu_get_user_data_ref( pdu );
-
- if (user_ref != NULL) {
- return user_ref[2] - 1;
- } else {
- return 0;
- }
-}
-
-
-static void
-gsm_rope_add_sms_user_header( GsmRope rope,
- int ref_number,
- int pdu_count,
- int pdu_index )
-{
- gsm_rope_add_c( rope, 0x05 ); /* total header length == 5 bytes */
- gsm_rope_add_c( rope, 0x00 ); /* element id: concatenated message reference number */
- gsm_rope_add_c( rope, 0x03 ); /* element len: 3 bytes */
- gsm_rope_add_c( rope, (byte_t)ref_number ); /* reference number */
- gsm_rope_add_c( rope, (byte_t)pdu_count ); /* max pdu index */
- gsm_rope_add_c( rope, (byte_t)pdu_index+1 ); /* current pdu index */
-}
-
-/* write a SMS-DELIVER PDU into a rope */
-static void
-gsm_rope_add_sms_deliver_pdu( GsmRope rope,
- cbytes_t utf8,
- int utf8len,
- int use_gsm7,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp,
- int ref_num,
- int pdu_count,
- int pdu_index)
-{
- int coding;
- int mtiByte = 0x20; /* message type - SMS DELIVER */
-
- if (pdu_count > 1)
- mtiByte |= 0x40; /* user data header indicator */
-
- gsm_rope_add_c( rope, 0 ); /* no SC Address */
- gsm_rope_add_c( rope, mtiByte ); /* message type - SMS-DELIVER */
- gsm_rope_add_address( rope, sender_address );
- gsm_rope_add_c( rope, 0 ); /* protocol identifier */
-
- /* data coding scheme - GSM 7 bits / no class - or - 16-bit UCS2 / class 1 */
- coding = (use_gsm7 ? 0x00 : 0x09);
-
- gsm_rope_add_c( rope, coding ); /* data coding scheme */
- gsm_rope_add_timestamp( rope, timestamp ); /* service center timestamp */
-
- if (use_gsm7) {
- bytes_t dst;
- int count = utf8_to_gsm7( utf8, utf8len, NULL, 0 );
- int pad = 0;
-
- assert( count <= MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE );
-
- if (pdu_count > 1)
- {
- int headerBits = 6*8; /* 6 is size of header in bytes */
- int headerSeptets = headerBits / 7;
- if (headerBits % 7 > 0)
- headerSeptets += 1;
-
- pad = headerSeptets*7 - headerBits;
-
- gsm_rope_add_c( rope, count + headerSeptets );
- gsm_rope_add_sms_user_header(rope, ref_num, pdu_count, pdu_index);
- }
- else
- gsm_rope_add_c( rope, count );
-
- count = (count*7+pad+7)/8; /* convert to byte count */
-
- dst = gsm_rope_reserve( rope, count );
- if (dst != NULL) {
- utf8_to_gsm7( utf8, utf8len, dst, pad );
- }
- } else {
- bytes_t dst;
- int count = utf8_to_ucs2( utf8, utf8len, NULL );
-
- assert( count*2 <= MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE );
-
- if (pdu_count > 1)
- {
- gsm_rope_add_c( rope, count*2 + 6 );
- gsm_rope_add_sms_user_header( rope, ref_num, pdu_count, pdu_index );
- }
- else
- gsm_rope_add_c( rope, count*2 );
-
- gsm_rope_add_c( rope, count*2 );
- dst = gsm_rope_reserve( rope, count*2 );
- if (dst != NULL) {
- utf8_to_ucs2( utf8, utf8len, dst );
- }
- }
-}
-
-
-static SmsPDU
-smspdu_create_deliver( cbytes_t utf8,
- int utf8len,
- int use_gsm7,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp,
- int ref_num,
- int pdu_count,
- int pdu_index )
-{
- SmsPDU p;
- GsmRopeRec rope[1];
- int size;
-
- p = calloc( sizeof(*p), 1 );
- if (!p) goto Exit;
-
- gsm_rope_init( rope );
- gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7,
- sender_address, timestamp,
- ref_num, pdu_count, pdu_index);
- if (rope->error)
- goto Fail;
-
- gsm_rope_init_alloc( rope, rope->pos );
-
- gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7,
- sender_address, timestamp,
- ref_num, pdu_count, pdu_index );
-
- p->base = gsm_rope_done_acquire( rope, &size );
- if (p->base == NULL)
- goto Fail;
-
- p->end = p->base + size;
- p->tpdu = p->base + 1;
-Exit:
- return p;
-
-Fail:
- free(p);
- return NULL;
-}
-
-
-void
-smspdu_free_list( SmsPDU* pdus )
-{
- if (pdus) {
- int nn;
- for (nn = 0; pdus[nn] != NULL; nn++)
- smspdu_free( pdus[nn] );
-
- free( pdus );
- }
-}
-
-
-
-SmsPDU*
-smspdu_create_deliver_utf8( const unsigned char* utf8,
- int utf8len,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp )
-{
- SmsTimeStampRec ts0;
- int use_gsm7;
- int count, block;
- int num_pdus = 0;
- int leftover = 0;
- SmsPDU* list = NULL;
-
- static unsigned char ref_num = 0;
-
- if (timestamp == NULL) {
- sms_timestamp_now( &ts0 );
- timestamp = &ts0;
- }
-
- /* can we encode the message with the GSM 7-bit alphabet ? */
- use_gsm7 = utf8_check_gsm7( utf8, utf8len );
-
- /* count the number of SMS PDUs we'll need */
- block = MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE;
-
- if (use_gsm7) {
- count = utf8_to_gsm7( utf8, utf8len, NULL, 0 );
- } else {
- count = utf8_to_ucs2( utf8, utf8len, NULL );
- block = MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE;
- }
-
- num_pdus = count / block;
- leftover = count - num_pdus*block;
- if (leftover > 0)
- num_pdus += 1;
-
- list = calloc( sizeof(SmsPDU*), num_pdus + 1 );
- if (list == NULL)
- return NULL;
-
- /* now create each SMS PDU */
- {
- cbytes_t src = utf8;
- cbytes_t src_end = utf8 + utf8len;
- int nn;
-
- for (nn = 0; nn < num_pdus; nn++)
- {
- int skip = block;
- cbytes_t src_next;
-
- if (leftover > 0 && nn == num_pdus-1)
- skip = leftover;
-
- src_next = utf8_skip_gsm7( src, src_end, skip );
-
- list[nn] = smspdu_create_deliver( src, src_next - src, use_gsm7, sender_address, timestamp,
- ref_num, num_pdus, nn );
- if (list[nn] == NULL)
- goto Fail;
-
- src = src_next;
- }
- }
-
- ref_num++;
- return list;
-
-Fail:
- smspdu_free_list(list);
- return NULL;
-}
-
-
-SmsPDU
-smspdu_create_from_hex( const char* hex, int hexlen )
-{
- SmsPDU p;
- cbytes_t data;
-
- p = calloc( sizeof(*p), 1 );
- if (!p) goto Exit;
-
- p->base = malloc( (hexlen+1)/2 );
- if (p->base == NULL) {
- free(p);
- p = NULL;
- goto Exit;
- }
-
- if ( gsm_hex_to_bytes( (cbytes_t)hex, hexlen, p->base ) < 0 )
- goto Fail;
-
- p->end = p->base + (hexlen+1)/2;
-
- data = p->base;
- if ( sms_skip_sc_address( &data, p->end ) < 0 )
- goto Fail;
-
- p->tpdu = (bytes_t) data;
-
-Exit:
- return p;
-
-Fail:
- free(p->base);
- free(p);
- return NULL;
-}
-
-int
-smspdu_to_hex( SmsPDU pdu, char* hex, int hexlen )
-{
- int result = (pdu->end - pdu->base)*2;
- int nn;
-
- if (hexlen > result)
- hexlen = result;
-
- for (nn = 0; nn*2 < hexlen; nn++) {
- gsm_hex_from_byte( &hex[nn*2], pdu->base[nn] );
- }
- return result;
-}
-
-
-/** SMS SUBMIT RECEIVER
- ** collects one or more SMS-SUBMIT PDUs to generate a single message to deliver
- **/
-
-typedef struct SmsFragmentRec {
- struct SmsFragmentRec* next;
- SmsAddressRec from[1];
- byte_t ref;
- byte_t max;
- byte_t count;
- int index;
- SmsPDU* pdus;
-
-} SmsFragmentRec, *SmsFragment;
-
-
-typedef struct SmsReceiverRec {
- int last;
- SmsFragment fragments;
-
-} SmsReceiverRec;
-
-
-static void
-sms_fragment_free( SmsFragment frag )
-{
- int nn;
-
- for (nn = 0; nn < frag->max; nn++) {
- if (frag->pdus[nn] != NULL) {
- smspdu_free( frag->pdus[nn] );
- frag->pdus[nn] = NULL;
- }
- }
- frag->pdus = NULL;
- frag->count = 0;
- frag->max = 0;
- frag->index = 0;
- free( frag );
-}
-
-static SmsFragment
-sms_fragment_alloc( SmsReceiver rec, const SmsAddressRec* from, int ref, int max )
-{
- SmsFragment frag = calloc(sizeof(*frag) + max*sizeof(SmsPDU), 1 );
-
- if (frag != NULL) {
- frag->from[0] = from[0];
- frag->ref = ref;
- frag->max = max;
- frag->pdus = (SmsPDU*)(frag + 1);
- frag->index = ++rec->last;
- }
- return frag;
-}
-
-
-
-SmsReceiver sms_receiver_create( void )
-{
- SmsReceiver rec = calloc(sizeof(*rec),1);
- return rec;
-}
-
-void
-sms_receiver_destroy( SmsReceiver rec )
-{
- while (rec->fragments) {
- SmsFragment frag = rec->fragments;
- rec->fragments = frag->next;
- sms_fragment_free(frag);
- }
-}
-
-static SmsFragment*
-sms_receiver_find_p( SmsReceiver rec, const SmsAddressRec* from, int ref )
-{
- SmsFragment* pnode = &rec->fragments;
- SmsFragment node;
-
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
- if (node->ref == ref && sms_address_eq( node->from, from ))
- break;
- pnode = &node->next;
- }
- return pnode;
-}
-
-static SmsFragment*
-sms_receiver_find_index_p( SmsReceiver rec, int index )
-{
- SmsFragment* pnode = &rec->fragments;
- SmsFragment node;
-
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
- if (node->index == index)
- break;
- pnode = &node->next;
- }
- return pnode;
-}
-
-int
-sms_receiver_add_submit_pdu( SmsReceiver rec, SmsPDU submit_pdu )
-{
- SmsAddressRec from[1];
- int ref, max, cur;
- SmsFragment* pnode;
- SmsFragment frag;
-
- if ( smspdu_get_receiver_address( submit_pdu, from ) < 0 ) {
- D( "%s: could not extract receiver address\n", __FUNCTION__ );
- return -1;
- }
-
- ref = smspdu_get_ref( submit_pdu );
- if (ref < 0) {
- D( "%s: could not extract message reference from pdu\n", __FUNCTION__ );
- return -1;
- }
- max = smspdu_get_max_index( submit_pdu );
- if (max < 0) {
- D( "%s: invalid max fragment value: %d should be >= 1\n",
- __FUNCTION__, max );
- return -1;
- }
- pnode = sms_receiver_find_p( rec, from, ref );
- frag = *pnode;
- if (frag == NULL) {
- frag = sms_fragment_alloc( rec, from, ref, max );
- if (frag == NULL) {
- D("%s: not enough memory to allocate new fragment\n", __FUNCTION__ );
- return -1;
- }
- if (D_ACTIVE) {
- char tmp[32];
- int len;
-
- len = sms_address_to_str( from, tmp, sizeof(tmp) );
- if (len < 0) {
- strcpy( tmp, "<unknown>" );
- len = strlen(tmp);
- }
- D("%s: created SMS index %d, from %.*s, ref %d, max %d\n", __FUNCTION__,
- frag->index, len, tmp, frag->ref, frag->max);
- }
- *pnode = frag;
- }
-
- cur = smspdu_get_cur_index( submit_pdu );
- if (cur < 0) {
- D("%s: SMS fragment index is too small: %d should be >= 1\n", __FUNCTION__, cur+1 );
- return -1;
- }
- if (cur >= max) {
- D("%s: SMS fragment index is too large (%d >= %d)\n", __FUNCTION__, cur, max);
- return -1;
- }
- if ( frag->pdus[cur] != NULL ) {
- D("%s: receiving duplicate SMS fragment for %d/%d, ref=%d, discarding old one\n",
- __FUNCTION__, cur+1, max, ref);
- smspdu_free( frag->pdus[cur] );
- frag->count -= 1;
- }
- frag->pdus[cur] = submit_pdu;
- frag->count += 1;
-
- if (frag->count >= frag->max) {
- /* yes, we received all fragments for this SMS */
- D( "%s: SMS index %d, received all %d fragments\n", __FUNCTION__, frag->index, frag->count );
- return frag->index;
- }
- else {
- /* still waiting for more */
- D( "%s: SMS index %d, received %d/%d, waiting for %d more\n", __FUNCTION__,
- frag->index, cur+1, max, frag->max - frag->count );
- return 0;
- }
-}
-
-
-int
-sms_receiver_get_text_message( SmsReceiver rec, int index, bytes_t utf8, int utf8len )
-{
- SmsFragment* pnode = sms_receiver_find_index_p( rec, index );
- SmsFragment frag = *pnode;
- int nn, total;
-
- if (frag == NULL) {
- D( "%s: invalid SMS index %d\n", __FUNCTION__, index );
- return -1;
- }
- if (frag->count != frag->max) {
- D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__,
- frag->index, frag->max - frag->count );
- return -1;
- }
- /* get the size of all combined text */
- total = 0;
- for ( nn = 0; nn < frag->count; nn++ ) {
- int partial;
- if (utf8 && utf8len > 0) {
- partial = smspdu_get_text_message( frag->pdus[nn], utf8, utf8len );
- utf8 += partial;
- utf8len -= partial;
- } else {
- partial = smspdu_get_text_message( frag->pdus[nn], NULL, 0 );
- }
- total += partial;
- }
- return total;
-}
-
-
-static void
-sms_receiver_remove( SmsReceiver rec, int index )
-{
- SmsFragment* pnode = sms_receiver_find_index_p( rec, index );
- SmsFragment frag = *pnode;
- if (frag != NULL) {
- *pnode = frag->next;
- sms_fragment_free(frag);
- }
-}
-
-
-SmsPDU*
-sms_receiver_create_deliver( SmsReceiver rec, int index, const SmsAddressRec* from )
-{
- SmsPDU* result = NULL;
- SmsFragment* pnode = sms_receiver_find_index_p( rec, index );
- SmsFragment frag = *pnode;
- SmsTimeStampRec now[1];
- int nn, total;
- bytes_t utf8;
- int utf8len;
-
- if (frag == NULL) {
- D( "%s: invalid SMS index %d\n", __FUNCTION__, index );
- return NULL;
- }
- if (frag->count != frag->max) {
- D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__,
- frag->index, frag->max - frag->count );
- return NULL;
- }
-
- /* get the combined text message */
- utf8len = sms_receiver_get_text_message( rec, index, NULL, 0 );
- if (utf8len < 0)
- goto Exit;
-
- utf8 = malloc( utf8len + 1 );
- if (utf8 == NULL) {
- D( "%s: not enough memory to allocate %d bytes\n",
- __FUNCTION__, utf8len+1 );
- goto Exit;
- }
-
- total = 0;
- for ( nn = 0; nn < frag->count; nn++ ) {
- total += smspdu_get_text_message( frag->pdus[nn], utf8 + total, utf8len - total );
- }
-
- sms_timestamp_now( now );
-
- result = smspdu_create_deliver_utf8( utf8, utf8len, from, now );
-
- free(utf8);
-
-Exit:
- sms_receiver_remove( rec, index );
- return result;
-}
-
diff --git a/telephony/sms.h b/telephony/sms.h
deleted file mode 100644
index 7059ee3..0000000
--- a/telephony/sms.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef _android_sms_h
-#define _android_sms_h
-
-#include <time.h>
-
-/** MESSAGE TEXT
- **/
-/* convert a quoted message text into a utf8 string. Note: you can use 'str' as the destination buffer
- * with the current implementation. always return the number of utf8 bytes corresponding to the original
- * message string, even if utf8 is NULL and utf8len is 0
- */
-extern int sms_utf8_from_message_str( const char* str, int strlen, unsigned char* utf8, int utf8len );
-
-/* the equivalent in the opposite direction
- */
-extern int sms_utf8_to_message_str( const unsigned char* utf8, int utf8len, char* str, int strlen );
-
-/** TIMESTAMPS
- **/
-
-/* An SMS timestamp structure */
-typedef struct {
- unsigned char data[7];
-} SmsTimeStampRec, *SmsTimeStamp;
-
-extern void sms_timestamp_now( SmsTimeStamp stamp );
-extern int sms_timestamp_to_tm( SmsTimeStamp stamp, struct tm* tm );
-
-/** SMS ADDRESSES
- **/
-
-#define SMS_ADDRESS_MAX_SIZE 16
-
-typedef struct {
- unsigned char len;
- unsigned char toa;
- unsigned char data[ SMS_ADDRESS_MAX_SIZE ];
-} SmsAddressRec, *SmsAddress;
-
-extern int sms_address_from_str( SmsAddress address, const char* src, int srclen );
-extern int sms_address_to_str( SmsAddress address, char* src, int srclen );
-
-extern int sms_address_from_bytes( SmsAddress address, const unsigned char* buf, int buflen );
-extern int sms_address_to_bytes ( SmsAddress address, unsigned char* buf, int bufsize );
-extern int sms_address_from_hex ( SmsAddress address, const char* hex, int hexlen );
-extern int sms_address_to_hex ( SmsAddress address, char* hex, int hexsize );
-
-/** SMS PROTOCOL DATA UNITS
- **/
-
-typedef struct SmsPDURec* SmsPDU;
-
-extern SmsPDU* smspdu_create_deliver_utf8( const unsigned char* utf8,
- int utf8len,
- const SmsAddressRec* sender_address,
- const SmsTimeStampRec* timestamp );
-
-extern void smspdu_free_list( SmsPDU* pdus );
-
-extern SmsPDU smspdu_create_from_hex( const char* hex, int hexlen );
-
-extern int smspdu_to_hex( SmsPDU pdu, char* hex, int hexsize );
-
-/* free a given SMS PDU */
-extern void smspdu_free( SmsPDU pdu );
-
-typedef enum {
- SMS_PDU_INVALID = 0,
- SMS_PDU_DELIVER,
- SMS_PDU_SUBMIT,
- SMS_PDU_STATUS_REPORT
-} SmsPduType;
-
-extern SmsPduType smspdu_get_type( SmsPDU pdu );
-
-/* retrieve the sender address of a SMS-DELIVER pdu, returns -1 otherwise */
-extern int smspdu_get_sender_address( SmsPDU pdu, SmsAddress address );
-
-/* retrieve the service center timestamp of a SMS-DELIVER pdu, return -1 otherwise */
-extern int smspdu_get_sc_timestamp( SmsPDU pdu, SmsTimeStamp timestamp );
-
-/* retrieve the receiver address of a SMS-SUBMIT pdu, return -1 otherwise */
-extern int smspdu_get_receiver_address( SmsPDU pdu, SmsAddress address );
-
-extern int smspdu_get_ref ( SmsPDU pdu );
-extern int smspdu_get_max_index( SmsPDU pdu );
-extern int smspdu_get_cur_index( SmsPDU pdu );
-
-/* get the message embedded in a SMS PDU as a utf8 byte array, returns the length of the message in bytes */
-/* or -1 in case of error */
-extern int smspdu_get_text_message( SmsPDU pdu, unsigned char* utf8, int utf8len );
-
-/** SMS SUBMIT RECEIVER
- ** collects one or more SMS-SUBMIT PDUs to generate a single message to deliver
- **/
-
-typedef struct SmsReceiverRec *SmsReceiver;
-
-extern SmsReceiver sms_receiver_create( void );
-extern void sms_receiver_destroy( SmsReceiver rec );
-
-extern int sms_receiver_add_submit_pdu( SmsReceiver rec, SmsPDU submit_pdu );
-extern int sms_receiver_get_text_message( SmsReceiver rec, int index, unsigned char* utf8, int utf8len );
-extern SmsPDU* sms_receiver_create_deliver( SmsReceiver rec, int index, const SmsAddressRec* from );
-
-#endif /* _android_sms_h */
diff --git a/telephony/sysdeps.h b/telephony/sysdeps.h
deleted file mode 100644
index 19ca8d3..0000000
--- a/telephony/sysdeps.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#ifndef __sysdeps_h__
-#define __sysdeps_h__
-
-/* system-dependent platform abstraction used by the emulated GSM modem
- */
-
-/* to be called before anything else */
-
-extern void sys_main_init( void );
-
-/** callbacks
- **/
-typedef void (*SysCallback)( void* opaque );
-
-/** events
- **/
-enum {
- SYS_EVENT_READ = 0x01,
- SYS_EVENT_WRITE = 0x02,
- SYS_EVENT_ERROR = 0x04,
- SYS_EVENT_ALL = 0x07
-};
-
-/** channels
- **/
-typedef struct SysChannelRec_* SysChannel;
-
-typedef void (*SysChannelCallback)( void* opaque, int event_flags );
-
-/* XXX: TODO: channel creation functions */
-extern SysChannel sys_channel_create_tcp_server( int port );
-extern SysChannel sys_channel_create_tcp_handler( SysChannel server_channel );
-extern SysChannel sys_channel_create_tcp_client( const char* hostname, int port );
-extern int sys_channel_set_non_block( SysChannel channel );
-
-extern void sys_channel_on( SysChannel channel,
- int event_flags,
- SysChannelCallback event_callback,
- void* event_opaqe );
-
-extern int sys_channel_read( SysChannel channel, void* buffer, int size );
-
-extern int sys_channel_write( SysChannel channel, const void* buffer, int size );
-
-extern void sys_channel_close( SysChannel channel );
-
-
-/** time measurement
- **/
-typedef long long SysTime;
-
-extern SysTime sys_time_now( void );
-
-/** timers
- **/
-typedef struct SysTimerRec_* SysTimer;
-
-extern SysTimer sys_timer_create( void );
-extern void sys_timer_set( SysTimer timer, SysTime when, SysCallback callback, void* opaque );
-extern void sys_timer_unset( SysTimer timer );
-extern void sys_timer_destroy( SysTimer timer );
-
-extern long long sys_time_ms( void );
-
-/** main loop (may return immediately on some platform)
- **/
-extern int sys_main_loop( void );
-
-#endif /* __sysdeps_h__ */
diff --git a/telephony/sysdeps_posix.c b/telephony/sysdeps_posix.c
deleted file mode 100644
index 8c5eb12..0000000
--- a/telephony/sysdeps_posix.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sysdeps.h"
-#include <assert.h>
-#include <unistd.h>
-#include <sys/select.h>
-#include <errno.h>
-#include <memory.h>
-#include <stdio.h>
-#ifndef HAVE_WINSOCK
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif
-
-/** QUEUE
- **/
-#define SYS_MAX_QUEUE 16
-
-typedef struct {
- int start;
- int end;
- void* pending[ SYS_MAX_QUEUE ];
-}
-SysQueueRec, *SysQueue;
-
-static void
-sys_queue_reset( SysQueue queue )
-{
- queue->start = queue->end = 0;
-}
-
-static void
-sys_queue_add( SysQueue queue, void* item )
-{
- assert( queue->end - queue->start < SYS_MAX_QUEUE );
- assert( queue->start == 0 );
- assert( item != NULL );
- queue->pending[ queue->end++ ] = item;
-}
-
-#if 0
-static void
-sys_queue_remove( SysQueue queue, void* item )
-{
- int nn, count;
- assert( queue->end > queue->start );
- assert( item != NULL );
- count = queue->end - queue->start;
- for ( nn = queue->start; count > 0; ++nn, --count ) {
- if ( queue->pending[nn] == item ) {
- queue->pending[nn] = queue->pending[nn+count-1];
- queue->end -= 1;
- break;
- }
- }
- assert( 0 && "sys_queue_remove: item not found" );
-}
-#endif
-
-static void*
-sys_queue_get( SysQueue queue )
-{
- if (queue->end > queue->start) {
- return queue->pending[ queue->start++ ];
- }
- return NULL;
-}
-
-/** CHANNELS
- **/
-typedef struct SysChannelRec_ {
- SysChannel next;
- int fd;
- char active;
- char pending;
- char closed;
- int wanted;
- int ready;
- SysChannelCallback callback;
- void* opaque;
-} SysChannelRec;
-
-
-/*** channel allocation ***/
-#define SYS_EVENT_MAX 3
-#define SYS_MAX_CHANNELS 16
-
-static SysChannelRec _s_channels0[ SYS_MAX_CHANNELS ];
-static SysChannel _s_free_channels;
-
-static SysChannel
-sys_channel_alloc( void )
-{
- SysChannel channel = _s_free_channels;
- assert( channel != NULL && "out of free channels" );
- _s_free_channels = channel->next;
- channel->next = NULL;
- channel->active = 0;
- channel->closed = 0;
- channel->pending = 0;
- channel->wanted = 0;
- return channel;
-}
-
-static void
-sys_channel_free( SysChannel channel )
-{
- if (channel->fd >= 0) {
-#ifdef _WIN32
- shutdown( channel->fd, SD_BOTH );
-#else
- shutdown( channel->fd, SHUT_RDWR );
-#endif
- close(channel->fd);
- channel->fd = -1;
- }
- channel->wanted = 0;
- channel->ready = 0;
- channel->callback = NULL;
-
- channel->next = _s_free_channels;
- _s_free_channels = channel;
-}
-
-
-/* list of active channels */
-static SysChannel _s_channels;
-
-/* used by select to wait on channel events */
-static fd_set _s_fdsets[SYS_EVENT_MAX];
-static int _s_maxfd;
-
-static void
-sys_channel_deactivate( SysChannel channel )
-{
- assert( channel->active != 0 );
- SysChannel *pnode = &_s_channels;
- for (;;) {
- SysChannel node = *pnode;
- assert( node != NULL );
- if (node == channel)
- break;
- pnode = &node->next;
- }
- *pnode = channel->next;
- channel->next = NULL;
- channel->active = 0;
-}
-
-static void
-sys_channel_activate( SysChannel channel )
-{
- assert( channel->active == 0 );
- channel->next = _s_channels;
- _s_channels = channel;
- channel->active = 1;
- if (channel->fd > _s_maxfd)
- _s_maxfd = channel->fd;
-}
-
-
-/* queue of pending channels */
-static SysQueueRec _s_pending_channels[1];
-
-
-static void
-sys_init_channels( void )
-{
- int nn;
-
- for (nn = 0; nn < SYS_MAX_CHANNELS-1; nn++)
- _s_channels0[nn].next = &_s_channels0[nn+1];
- _s_free_channels = &_s_channels0[0];
-
- for (nn = 0; nn < SYS_EVENT_MAX; nn++)
- FD_ZERO( &_s_fdsets[nn] );
-
- _s_maxfd = -1;
-
- sys_queue_reset( _s_pending_channels );
-}
-
-
-void
-sys_channel_on( SysChannel channel,
- int events,
- SysChannelCallback callback,
- void* opaque )
-{
- int adds = events & ~channel->wanted;
- int removes = channel->wanted & ~events;
-
- channel->wanted = events;
- channel->callback = callback;
- channel->opaque = opaque;
-
- /* update global fdsets */
- if (adds) {
- int ee;
- for (ee = 0; ee < SYS_EVENT_MAX; ee++)
- if (adds & (1 << ee))
- FD_SET( channel->fd, &_s_fdsets[ee] );
- }
- if (removes) {
- int ee;
- for (ee = 0; ee < SYS_EVENT_MAX; ee++)
- if (removes & (1 << ee))
- FD_CLR( channel->fd, &_s_fdsets[ee] );
- }
- if (events && !channel->active) {
- sys_channel_activate( channel );
- }
- else if (!events && channel->active) {
- sys_channel_deactivate( channel );
- }
-}
-
-int
-sys_channel_read( SysChannel channel, void* buffer, int size )
-{
- char* buff = buffer;
- int count = 0;
-
- assert( !channel->closed );
-
- while (size > 0) {
- int len = read(channel->fd, buff, size);
- if (len < 0) {
- if (errno == EINTR)
- continue;
- if (count == 0)
- count = -1;
- break;
- }
- buff += len;
- size -= len;
- count += len;
- }
- return count;
-}
-
-
-int
-sys_channel_write( SysChannel channel, const void* buffer, int size )
-{
- const char* buff = buffer;
- int count = 0;
-
- assert( !channel->closed );
-
- while (size > 0) {
- int len = write(channel->fd, buff, size);
- if (len < 0) {
- if (errno == EINTR)
- continue;
- if (count == 0)
- count = -1;
- break;
- }
- buff += len;
- size -= len;
- count += len;
- }
- return count;
-}
-
-
-void
-sys_channel_close( SysChannel channel )
-{
- if (channel->active) {
- sys_channel_on( channel, 0, NULL, NULL );
- }
-
- if (channel->pending) {
- /* we can't free the channel right now because it */
- /* is in the pending list, set a flag */
- channel->closed = 1;
- return;
- }
-
- if (!channel->closed) {
- channel->closed = 1;
- }
-
- sys_channel_free( channel );
-}
-
-/** time measurement
- **/
-SysTime sys_time_ms( void )
-{
- struct timeval tv;
- gettimeofday( &tv, NULL );
- return (SysTime)(tv.tv_usec / 1000) + (SysTime)tv.tv_sec * 1000;
-}
-
-/** timers
- **/
-typedef struct SysTimerRec_
-{
- SysTimer next;
- SysTime when;
- SysCallback callback;
- void* opaque;
-} SysTimerRec;
-
-#define SYS_MAX_TIMERS 16
-
-static SysTimerRec _s_timers0[ SYS_MAX_TIMERS ];
-static SysTimer _s_free_timers;
-static SysTimer _s_timers;
-
-static SysQueueRec _s_pending_timers[1];
-
-
-static void
-sys_init_timers( void )
-{
- int nn;
- for (nn = 0; nn < SYS_MAX_TIMERS-1; nn++) {
- _s_timers0[nn].next = & _s_timers0[nn+1];
- }
- _s_free_timers = &_s_timers0[0];
-
- sys_queue_reset( _s_pending_timers );
-}
-
-
-SysTimer sys_timer_create( void )
-{
- SysTimer timer = _s_free_timers;
- assert( timer != NULL && "too many timers allocated" );
- _s_free_timers = timer->next;
- timer->next = NULL;
- return timer;
-}
-
-
-void sys_timer_unset( SysTimer timer )
-{
- if (timer->callback != NULL) {
- SysTimer *pnode, node;
- pnode = &_s_timers;
- for (;;) {
- node = *pnode;
- if (node == NULL)
- break;
- if (node == timer) {
- *pnode = node->next;
- break;
- }
- pnode = &node->next;
- }
- timer->next = NULL;
- timer->callback = NULL;
- timer->opaque = NULL;
- }
-}
-
-
-void sys_timer_set( SysTimer timer,
- SysTime when,
- SysCallback callback,
- void* opaque )
-{
- if (timer->callback != NULL)
- sys_timer_unset(timer);
-
- if (callback != NULL) {
- SysTime now = sys_time_ms();
-
- if (now >= when) {
- callback( opaque );
- } else {
- SysTimer *pnode, node;
- pnode = &_s_timers;
- for (;;) {
- node = *pnode;
- if (node == NULL || node->when >= when) {
- break;
- }
- pnode = &node->next;
- }
- timer->next = *pnode;
- *pnode = timer;
- timer->when = when;
- timer->callback = callback;
- timer->opaque = opaque;
- }
- }
-}
-
-
-void sys_timer_destroy( SysTimer timer )
-{
- assert( timer != NULL && "sys_timer_destroy: bad argument" );
- if (timer->callback != NULL)
- sys_timer_unset(timer);
-
- timer->next = _s_free_timers;
- _s_free_timers = timer;
-}
-
-
-static void
-sys_single_loop( void )
-{
- fd_set rfd, wfd, efd;
- struct timeval timeout_tv, *timeout = NULL;
- int n;
-
- memcpy(&rfd, &_s_fdsets[0], sizeof(fd_set));
- memcpy(&wfd, &_s_fdsets[1], sizeof(fd_set));
- memcpy(&efd, &_s_fdsets[2], sizeof(fd_set));
-
- if ( _s_timers != NULL ) {
- SysTime now = sys_time_ms();
- SysTimer first = _s_timers;
-
- timeout = &timeout_tv;
- if (first->when <= now) {
- timeout->tv_sec = 0;
- timeout->tv_usec = 0;
- } else {
- SysTime diff = first->when - now;
- timeout->tv_sec = diff / 1000;
- timeout->tv_usec = (diff - timeout->tv_sec*1000) * 1000;
- }
- }
-
- n = select( _s_maxfd+1, &rfd, &wfd, &efd, timeout);
- if(n < 0) {
- if(errno == EINTR) return;
- perror("select");
- return;
- }
-
- /* enqueue pending channels */
- {
- int i;
-
- sys_queue_reset( _s_pending_channels );
- for(i = 0; (i <= _s_maxfd) && (n > 0); i++)
- {
- int events = 0;
-
- if(FD_ISSET(i, &rfd)) events |= SYS_EVENT_READ;
- if(FD_ISSET(i, &wfd)) events |= SYS_EVENT_WRITE;
- if(FD_ISSET(i, &efd)) events |= SYS_EVENT_ERROR;
-
- if (events) {
- SysChannel channel;
-
- n--;
- for (channel = _s_channels; channel; channel = channel->next)
- {
- if (channel->fd != i)
- continue;
-
- channel->ready = events;
- channel->pending = 1;
- sys_queue_add( _s_pending_channels, channel );
- break;
- }
- }
- }
- }
-
- /* enqueue pending timers */
- {
- SysTimer timer = _s_timers;
- SysTime now = sys_time_ms();
-
- sys_queue_reset( _s_pending_timers );
- while (timer != NULL)
- {
- if (timer->when > now)
- break;
-
- sys_queue_add( _s_pending_timers, timer );
- _s_timers = timer = timer->next;
- }
- }
-}
-
-void sys_main_init( void )
-{
- sys_init_channels();
- sys_init_timers();
-}
-
-
-int sys_main_loop( void )
-{
- for (;;) {
- SysTimer timer;
- SysChannel channel;
-
- /* exit if we have nothing to do */
- if (_s_channels == NULL && _s_timers == NULL)
- break;
-
- sys_single_loop();
-
- while ((timer = sys_queue_get( _s_pending_timers )) != NULL) {
- timer->callback( timer->opaque );
- }
-
- while ((channel = sys_queue_get( _s_pending_channels )) != NULL) {
- int events;
-
- channel->pending = 0;
- if (channel->closed) {
- /* the channel was closed by a previous callback */
- sys_channel_close(channel);
- }
- events = channel->ready;
- channel->ready = 0;
- channel->callback( channel->opaque, events );
- }
- }
- return 0;
-}
-
-
-
-
-SysChannel
-sys_channel_create_tcp_server( int port )
-{
- SysChannel channel;
- int on = 1;
- const int BACKLOG = 4;
-
- channel = sys_channel_alloc();
- if (-1==(channel->fd=socket(AF_INET, SOCK_STREAM, 0))) {
- perror("socket");
- sys_channel_free( channel );
- return NULL;
- }
-
- /* Enable address re-use for server mode */
- if ( -1==setsockopt( channel->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) )) {
- perror("setsockopt(SO_REUSEADDR)");
- }
-
- {
- struct sockaddr_in servname;
- long in_addr = INADDR_ANY;
-
- servname.sin_family = AF_INET;
- servname.sin_port = htons(port);
-
- servname.sin_addr.s_addr=in_addr;
-
- if (-1==bind(channel->fd, (struct sockaddr*)&servname, sizeof(servname))) {
- perror("bind");
- sys_channel_close(channel);
- return NULL;
- }
-
- /* Listen but don't accept */
- if ( listen(channel->fd, BACKLOG) < 0 ) {
- perror("listen");
- sys_channel_close(channel);
- return NULL;
- }
- }
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_handler( SysChannel server_channel )
-{
- int on = 1;
- SysChannel channel = sys_channel_alloc();
-
- channel->fd = accept( server_channel->fd, NULL, 0 );
- if (channel->fd < 0) {
- perror( "accept" );
- sys_channel_free( channel );
- return NULL;
- }
-
- /* set to non-blocking and disable TCP Nagle algorithm */
- fcntl(channel->fd, F_SETFL, O_NONBLOCK);
- setsockopt(channel->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_client( const char* hostname, int port )
-{
- struct hostent* hp;
- struct sockaddr_in addr;
- SysChannel channel = sys_channel_alloc();
- int on = 1;
-
- hp = gethostbyname(hostname);
- if(hp == 0) {
- fprintf(stderr, "unknown host: %s\n", hostname);
- sys_channel_free(channel);
- return NULL;
- };
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = hp->h_addrtype;
- addr.sin_port = htons(port);
- memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
-
- channel->fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
- if(channel->fd < 0) {
- sys_channel_free(channel);
- return NULL;
- }
-
- if(connect( channel->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror( "connect" );
- sys_channel_free(channel);
- return NULL;
- }
-
- /* set to non-blocking and disable Nagle algorithm */
- fcntl(channel->fd, F_SETFL, O_NONBLOCK);
- setsockopt( channel->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on) );
- return channel;
-}
-
diff --git a/telephony/sysdeps_qemu.c b/telephony/sysdeps_qemu.c
deleted file mode 100644
index ec0b3f5..0000000
--- a/telephony/sysdeps_qemu.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sockets.h"
-#include "sysdeps.h"
-#include "qemu-timer.h"
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#endif
-
-#define DEBUG 1
-
-#define D_ACTIVE DEBUG
-
-#if DEBUG
-#define D(...) do { if (D_ACTIVE) fprintf(stderr, __VA_ARGS__); } while (0)
-#else
-#define D(...) ((void)0)
-#endif
-
-/** TIME
- **/
-
-SysTime
-sys_time_ms( void )
-{
- return qemu_get_clock( rt_clock );
-}
-
-/** TIMERS
- **/
-
-typedef struct SysTimerRec_ {
- QEMUTimer* timer;
- QEMUTimerCB* callback;
- void* opaque;
- SysTimer next;
-} SysTimerRec;
-
-#define MAX_TIMERS 32
-
-static SysTimerRec _s_timers0[ MAX_TIMERS ];
-static SysTimer _s_free_timers;
-
-static void
-sys_init_timers( void )
-{
- int nn;
- for (nn = 0; nn < MAX_TIMERS-1; nn++)
- _s_timers0[nn].next = _s_timers0 + (nn+1);
-
- _s_free_timers = _s_timers0;
-}
-
-static SysTimer
-sys_timer_alloc( void )
-{
- SysTimer timer = _s_free_timers;
-
- if (timer != NULL) {
- _s_free_timers = timer->next;
- timer->next = NULL;
- timer->timer = NULL;
- }
- return timer;
-}
-
-
-static void
-sys_timer_free( SysTimer timer )
-{
- if (timer->timer) {
- qemu_del_timer( timer->timer );
- qemu_free_timer( timer->timer );
- timer->timer = NULL;
- }
- timer->next = _s_free_timers;
- _s_free_timers = timer;
-}
-
-
-SysTimer sys_timer_create( void )
-{
- SysTimer timer = sys_timer_alloc();
- return timer;
-}
-
-void
-sys_timer_set( SysTimer timer, SysTime when, SysCallback _callback, void* opaque )
-{
- QEMUTimerCB* callback = (QEMUTimerCB*)_callback;
-
- if (callback == NULL) { /* unsetting the timer */
- if (timer->timer) {
- qemu_del_timer( timer->timer );
- qemu_free_timer( timer->timer );
- timer->timer = NULL;
- }
- timer->callback = callback;
- timer->opaque = NULL;
- return;
- }
-
- if ( timer->timer ) {
- if ( timer->callback == callback && timer->opaque == opaque )
- goto ReuseTimer;
-
- /* need to replace the timer */
- qemu_free_timer( timer->timer );
- }
-
- timer->timer = qemu_new_timer( rt_clock, callback, opaque );
- timer->callback = callback;
- timer->opaque = opaque;
-
-ReuseTimer:
- qemu_mod_timer( timer->timer, when );
-}
-
-void
-sys_timer_unset( SysTimer timer )
-{
- if (timer->timer) {
- qemu_del_timer( timer->timer );
- }
-}
-
-void
-sys_timer_destroy( SysTimer timer )
-{
- sys_timer_free( timer );
-}
-
-
-/** CHANNELS
- **/
-
-typedef struct SysChannelRec_ {
- int fd;
- SysChannelCallback callback;
- void* opaque;
- SysChannel next;
-} SysChannelRec;
-
-#define MAX_CHANNELS 16
-
-static SysChannelRec _s_channels0[ MAX_CHANNELS ];
-static SysChannel _s_free_channels;
-
-static void
-sys_init_channels( void )
-{
- int nn;
-
- for ( nn = 0; nn < MAX_CHANNELS-1; nn++ ) {
- _s_channels0[nn].next = _s_channels0 + (nn+1);
- }
- _s_free_channels = _s_channels0;
-}
-
-static SysChannel
-sys_channel_alloc( )
-{
- SysChannel channel = _s_free_channels;
- if (channel != NULL) {
- _s_free_channels = channel->next;
- channel->next = NULL;
- channel->fd = -1;
- channel->callback = NULL;
- channel->opaque = NULL;
- }
- return channel;
-}
-
-static void
-sys_channel_free( SysChannel channel )
-{
- if (channel->fd >= 0) {
- socket_close( channel->fd );
- channel->fd = -1;
- }
- channel->next = _s_free_channels;
- _s_free_channels = channel;
-}
-
-
-static void
-sys_channel_read_handler( void* _channel )
-{
- SysChannel channel = _channel;
- D( "%s: read event for channel %p:%d\n", __FUNCTION__,
- channel, channel->fd );
- channel->callback( channel->opaque, SYS_EVENT_READ );
-}
-
-static void
-sys_channel_write_handler( void* _channel )
-{
- SysChannel channel = _channel;
- D( "%s: write event for channel %p:%d\n", __FUNCTION__, channel, channel->fd );
- channel->callback( channel->opaque, SYS_EVENT_WRITE );
-}
-
-void
-sys_channel_on( SysChannel channel,
- int events,
- SysChannelCallback event_callback,
- void* event_opaque )
-{
- IOHandler* read_handler = NULL;
- IOHandler* write_handler = NULL;
-
- if (events & SYS_EVENT_READ) {
- read_handler = sys_channel_read_handler;
- }
- if (events & SYS_EVENT_WRITE) {
- write_handler = sys_channel_write_handler;
- }
- channel->callback = event_callback;
- channel->opaque = event_opaque;
- qemu_set_fd_handler( channel->fd, read_handler, write_handler, channel );
-}
-
-int
-sys_channel_read( SysChannel channel, void* buffer, int size )
-{
- int len = size;
- char* buf = (char*) buffer;
-
- while (len > 0) {
- int ret = socket_recv(channel->fd, buf, len);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK)
- break;
- D( "%s: after reading %d bytes, recv() returned error %d: %s\n",
- __FUNCTION__, size - len, errno, errno_str);
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return size - len;
-}
-
-
-int
-sys_channel_write( SysChannel channel, const void* buffer, int size )
-{
- int len = size;
- const char* buf = (const char*) buffer;
-
- while (len > 0) {
- int ret = socket_send(channel->fd, buf, len);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- if (errno == EWOULDBLOCK)
- break;
- D( "%s: send() returned error %d: %s\n",
- __FUNCTION__, errno, errno_str);
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return size - len;
-}
-
-void sys_channel_close( SysChannel channel )
-{
- qemu_set_fd_handler( channel->fd, NULL, NULL, NULL );
- sys_channel_free( channel );
-}
-
-void sys_main_init( void )
-{
- sys_init_channels();
- sys_init_timers();
-}
-
-
-int sys_main_loop( void )
-{
- /* no looping, qemu has its own event loop */
- return 0;
-}
-
-
-
-
-SysChannel
-sys_channel_create_tcp_server( int port )
-{
- SysChannel channel = sys_channel_alloc();
-
- channel->fd = socket_anyaddr_server( port, SOCKET_STREAM );
- if (channel->fd < 0) {
- D( "%s: failed to created network socket on TCP:%d\n",
- __FUNCTION__, port );
- sys_channel_free( channel );
- return NULL;
- }
-
- D( "%s: server channel %p:%d now listening on port %d\n",
- __FUNCTION__, channel, channel->fd, port );
-
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_handler( SysChannel server_channel )
-{
- SysChannel channel = sys_channel_alloc();
-
- D( "%s: creating handler from server channel %p:%d\n", __FUNCTION__,
- server_channel, server_channel->fd );
-
- channel->fd = socket_accept_any( server_channel->fd );
- if (channel->fd < 0) {
- perror( "accept" );
- sys_channel_free( channel );
- return NULL;
- }
-
- /* disable Nagle algorithm */
- socket_set_nodelay( channel->fd );
-
- D( "%s: handler %p:%d created from server %p:%d\n", __FUNCTION__,
- server_channel, server_channel->fd, channel, channel->fd );
-
- return channel;
-}
-
-
-SysChannel
-sys_channel_create_tcp_client( const char* hostname, int port )
-{
- SysChannel channel = sys_channel_alloc();
-
- channel->fd = socket_network_client( hostname, port, SOCKET_STREAM );
- if (channel->fd < 0) {
- sys_channel_free(channel);
- return NULL;
- };
-
- /* set to non-blocking and disable Nagle algorithm */
- socket_set_nonblock( channel->fd );
- socket_set_nodelay( channel->fd );
-
- return channel;
-}
-
diff --git a/telephony/test1.c b/telephony/test1.c
deleted file mode 100644
index 52701b9..0000000
--- a/telephony/test1.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sysdeps.h"
-#include <stdio.h>
-
-#define MAX_COUNTER 10
-
-static int counter = 0;
-
-static void
-timer_func( void* _timer )
-{
- SysTimer timer = _timer;
- SysTime now = sys_time_ms();
-
- ++counter;
- printf( "tick %d/%d a %.2fs\n", counter, MAX_COUNTER, now/1000. );
- if (counter < MAX_COUNTER)
- sys_timer_set( timer, now + 2000, timer_func, timer );
- else
- sys_timer_destroy( timer );
-}
-
-
-int main( void )
-{
- SysTimer timer;
-
- /* initialize event subsystem */
- sys_main_init();
-
- /* create timer and register it */
- timer = sys_timer_create();
- sys_timer_set( timer, sys_time_ms() + 1000, timer_func, timer );
-
- printf("entering event loop\n");
- sys_main_loop();
- printf("exiting event loop\n" );
- return 0;
-}
diff --git a/telephony/test2.c b/telephony/test2.c
deleted file mode 100644
index a0cd66f..0000000
--- a/telephony/test2.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include "sysdeps.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#define PORT 8000
-#define MAX_COUNTER 30
-#define INITIAL_DELAY 1000
-#define DELAY 5000
-
-static int counter = 0;
-
-static void
-timer_func( void* _timer )
-{
- SysTimer timer = _timer;
- SysTime now = sys_time_ms();
-
- ++counter;
- printf( "tick %d/%d a %.2fs\n", counter, MAX_COUNTER, now/1000. );
- if (counter < MAX_COUNTER)
- sys_timer_set( timer, now + DELAY, timer_func, timer );
- else
- sys_timer_destroy( timer );
-}
-
-typedef struct {
- SysChannel channel;
- char in_buff[ 128 ];
- int in_pos;
-
- char out_buff[ 128 ];
- int out_pos;
- int out_size;
-} ClientRec, *Client;
-
-static Client
-client_alloc( SysChannel channel )
-{
- Client client = calloc( sizeof(*client), 1 );
-
- client->channel = channel;
- return client;
-}
-
-static void
-client_free( Client client )
-{
- sys_channel_close( client->channel );
- client->channel = NULL;
- free( client );
-}
-
-static void
-client_append( Client client, const char* str, int len );
-
-static void
-client_handle_line( Client client, const char* cmd )
-{
- char temp[256];
- int nn, mm = 0;
-
- for (nn = 0; cmd[nn] != 0; nn++) {
- int c = cmd[nn];
- if (c >= 32 && c <= 127)
- temp[mm++] = c;
- else if (c == '\n') {
- strcat( temp+mm, "<LF>" );
- mm += 4;
- }
- else if (c == '\r') {
- strcat( temp+mm, "<CR>" );
- mm += 4;
- }
- else {
- sprintf( temp+mm, "\\x%02x", c );
- mm += strlen( temp+mm );
- }
- }
- temp[mm] = 0;
- printf( "%p: << %s\n", client, temp );
-
- if ( !strcmp( cmd, "quit" ) ) {
- printf( "client %p quitting\n", client );
- client_free( client );
- return;
- }
- client_append( client, "type 'quit' to quit\n", -1 );
-}
-
-static void
-client_handler( void* _client, int events )
-{
- Client client = _client;
-
- if (events & SYS_EVENT_READ) {
- int ret;
- /* read into buffer, one character at a time */
- ret = sys_channel_read( client->channel, client->in_buff + client->in_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not read byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- if (client->in_buff[client->in_pos] == '\r' ||
- client->in_buff[client->in_pos] == '\n' ) {
- const char* cmd = client->in_buff;
- client->in_buff[client->in_pos] = 0;
-
- /* eat leading cr and lf, maybe left-overs from previous line */
- while (*cmd == '\r' || *cmd =='\n')
- cmd++;
-
- client_handle_line( client, cmd );
- client->in_pos = 0;
- } else
- client->in_pos += 1;
- }
-
- if (events & SYS_EVENT_WRITE) {
- int ret;
- /* write from output buffer, one char at a time */
- ret = sys_channel_write( client->channel, client->out_buff + client->out_pos, 1 );
- if (ret != 1) {
- fprintf(stderr, "client %p could not write byte, result = %d, error: %s\n",
- client, ret, strerror(errno) );
- goto ExitClient;
- }
- client->out_pos += 1;
- if (client->out_pos == client->out_size) {
- client->out_size = 0;
- client->out_pos = 0;
- /* we don't need to write */
- sys_channel_on( client->channel, SYS_EVENT_READ, client_handler, client );
- }
- }
- return;
-
-ExitClient:
- printf( "client %p exiting\n", client );
- client_free( client );
-}
-
-static void
-client_append( Client client, const char* str, int len )
-{
- int avail;
-
- if (len < 0)
- len = strlen(str);
-
- avail = sizeof(client->out_buff) - client->out_size;
- if (len > avail)
- len = avail;
-
- memcpy( client->out_buff + client->out_size, str, len );
- if (client->out_size == 0) {
- sys_channel_on( client->channel, SYS_EVENT_READ | SYS_EVENT_WRITE, client_handler, client );
- }
- client->out_size += len;
-}
-
-
-static void
-accept_func( void* _server, int events )
-{
- SysChannel server = _server;
- SysChannel handler;
- Client client;
-
- printf( "connection accepted for server channel, getting handler socket\n" );
- handler = sys_channel_create_tcp_handler( server );
- printf( "got one. creating client\n" );
- client = client_alloc( handler );
-
- events=events;
- sys_channel_on( handler, SYS_EVENT_READ, client_handler, client );
- client_append( client, "Welcome !\n", -1 );
-}
-
-
-int main( void )
-{
- SysTimer timer;
- SysChannel server_channel;
-
- /* initialize event subsystem */
- sys_main_init();
-
- /* create timer and register it */
- timer = sys_timer_create();
- sys_timer_set( timer, sys_time_ms() + INITIAL_DELAY, timer_func, timer );
-
- server_channel = sys_channel_create_tcp_server( PORT );
- printf( "listening on port %d with %p\n", PORT, server_channel );
-
- sys_channel_on( server_channel, SYS_EVENT_READ, accept_func, server_channel );
-
- printf("entering event loop\n");
- sys_main_loop();
- printf("exiting event loop\n" );
- return 0;
-}
diff --git a/thunk.c b/thunk.c
deleted file mode 100644
index 7331aeb..0000000
--- a/thunk.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Generic thunking code to convert data between host and target CPU
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "qemu.h"
-#include "thunk.h"
-
-//#define DEBUG
-
-#define MAX_STRUCTS 128
-
-/* XXX: make it dynamic */
-StructEntry struct_entries[MAX_STRUCTS];
-
-static const argtype *thunk_type_next_ptr(const argtype *type_ptr);
-
-static inline const argtype *thunk_type_next(const argtype *type_ptr)
-{
- int type;
-
- type = *type_ptr++;
- switch(type) {
- case TYPE_CHAR:
- case TYPE_SHORT:
- case TYPE_INT:
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- return type_ptr;
- case TYPE_PTR:
- return thunk_type_next_ptr(type_ptr);
- case TYPE_ARRAY:
- return thunk_type_next_ptr(type_ptr + 1);
- case TYPE_STRUCT:
- return type_ptr + 1;
- default:
- return NULL;
- }
-}
-
-static const argtype *thunk_type_next_ptr(const argtype *type_ptr)
-{
- return thunk_type_next(type_ptr);
-}
-
-void thunk_register_struct(int id, const char *name, const argtype *types)
-{
- const argtype *type_ptr;
- StructEntry *se;
- int nb_fields, offset, max_align, align, size, i, j;
-
- se = struct_entries + id;
-
- /* first we count the number of fields */
- type_ptr = types;
- nb_fields = 0;
- while (*type_ptr != TYPE_NULL) {
- type_ptr = thunk_type_next(type_ptr);
- nb_fields++;
- }
- se->field_types = types;
- se->nb_fields = nb_fields;
- se->name = name;
-#ifdef DEBUG
- printf("struct %s: id=%d nb_fields=%d\n",
- se->name, id, se->nb_fields);
-#endif
- /* now we can alloc the data */
-
- for(i = 0;i < 2; i++) {
- offset = 0;
- max_align = 1;
- se->field_offsets[i] = malloc(nb_fields * sizeof(int));
- type_ptr = se->field_types;
- for(j = 0;j < nb_fields; j++) {
- size = thunk_type_size(type_ptr, i);
- align = thunk_type_align(type_ptr, i);
- offset = (offset + align - 1) & ~(align - 1);
- se->field_offsets[i][j] = offset;
- offset += size;
- if (align > max_align)
- max_align = align;
- type_ptr = thunk_type_next(type_ptr);
- }
- offset = (offset + max_align - 1) & ~(max_align - 1);
- se->size[i] = offset;
- se->align[i] = max_align;
-#ifdef DEBUG
- printf("%s: size=%d align=%d\n",
- i == THUNK_HOST ? "host" : "target", offset, max_align);
-#endif
- }
-}
-
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
-{
- StructEntry *se;
- se = struct_entries + id;
- *se = *se1;
- se->name = name;
-}
-
-
-/* now we can define the main conversion functions */
-const argtype *thunk_convert(void *dst, const void *src,
- const argtype *type_ptr, int to_host)
-{
- int type;
-
- type = *type_ptr++;
- switch(type) {
- case TYPE_CHAR:
- *(uint8_t *)dst = *(uint8_t *)src;
- break;
- case TYPE_SHORT:
- *(uint16_t *)dst = tswap16(*(uint16_t *)src);
- break;
- case TYPE_INT:
- *(uint32_t *)dst = tswap32(*(uint32_t *)src);
- break;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- *(uint64_t *)dst = tswap64(*(uint64_t *)src);
- break;
-#if HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 32
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- *(uint32_t *)dst = tswap32(*(uint32_t *)src);
- break;
-#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- if (to_host) {
- if (type == TYPE_LONG) {
- /* sign extension */
- *(uint64_t *)dst = (int32_t)tswap32(*(uint32_t *)src);
- } else {
- *(uint64_t *)dst = tswap32(*(uint32_t *)src);
- }
- } else {
- *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
- }
- break;
-#elif HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 64
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- *(uint64_t *)dst = tswap64(*(uint64_t *)src);
- break;
-#elif HOST_LONG_BITS == 32 && TARGET_ABI_BITS == 64
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- if (to_host) {
- *(uint32_t *)dst = tswap64(*(uint64_t *)src);
- } else {
- if (type == TYPE_LONG) {
- /* sign extension */
- *(uint64_t *)dst = tswap64(*(int32_t *)src);
- } else {
- *(uint64_t *)dst = tswap64(*(uint32_t *)src);
- }
- }
- break;
-#else
-#warning unsupported conversion
-#endif
- case TYPE_ARRAY:
- {
- int array_length, i, dst_size, src_size;
- const uint8_t *s;
- uint8_t *d;
-
- array_length = *type_ptr++;
- dst_size = thunk_type_size(type_ptr, to_host);
- src_size = thunk_type_size(type_ptr, 1 - to_host);
- d = dst;
- s = src;
- for(i = 0;i < array_length; i++) {
- thunk_convert(d, s, type_ptr, to_host);
- d += dst_size;
- s += src_size;
- }
- type_ptr = thunk_type_next(type_ptr);
- }
- break;
- case TYPE_STRUCT:
- {
- int i;
- const StructEntry *se;
- const uint8_t *s;
- uint8_t *d;
- const argtype *field_types;
- const int *dst_offsets, *src_offsets;
-
- se = struct_entries + *type_ptr++;
- if (se->convert[0] != NULL) {
- /* specific conversion is needed */
- (*se->convert[to_host])(dst, src);
- } else {
- /* standard struct conversion */
- field_types = se->field_types;
- dst_offsets = se->field_offsets[to_host];
- src_offsets = se->field_offsets[1 - to_host];
- d = dst;
- s = src;
- for(i = 0;i < se->nb_fields; i++) {
- field_types = thunk_convert(d + dst_offsets[i],
- s + src_offsets[i],
- field_types, to_host);
- }
- }
- }
- break;
- default:
- fprintf(stderr, "Invalid type 0x%x\n", type);
- break;
- }
- return type_ptr;
-}
-
-/* from em86 */
-
-/* Utility function: Table-driven functions to translate bitmasks
- * between X86 and Alpha formats...
- */
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
- bitmask_transtbl * trans_tbl)
-{
- bitmask_transtbl * btp;
- unsigned int alpha_mask = 0;
-
- for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
- if((x86_mask & btp->x86_mask) == btp->x86_bits) {
- alpha_mask |= btp->alpha_bits;
- }
- }
- return(alpha_mask);
-}
-
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
- bitmask_transtbl * trans_tbl)
-{
- bitmask_transtbl * btp;
- unsigned int x86_mask = 0;
-
- for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
- if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
- x86_mask |= btp->x86_bits;
- }
- }
- return(x86_mask);
-}
-
-#ifndef NO_THUNK_TYPE_SIZE
-int thunk_type_size_array(const argtype *type_ptr, int is_host)
-{
- return thunk_type_size(type_ptr, is_host);
-}
-
-int thunk_type_align_array(const argtype *type_ptr, int is_host)
-{
- return thunk_type_align(type_ptr, is_host);
-}
-#endif /* ndef NO_THUNK_TYPE_SIZE */
diff --git a/thunk.h b/thunk.h
deleted file mode 100644
index d650fa4..0000000
--- a/thunk.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Generic thunking code to convert data between host and target CPU
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef THUNK_H
-#define THUNK_H
-
-#include <inttypes.h>
-#include "cpu.h"
-
-/* types enums definitions */
-
-typedef enum argtype {
- TYPE_NULL,
- TYPE_CHAR,
- TYPE_SHORT,
- TYPE_INT,
- TYPE_LONG,
- TYPE_ULONG,
- TYPE_PTRVOID, /* pointer on unknown data */
- TYPE_LONGLONG,
- TYPE_ULONGLONG,
- TYPE_PTR,
- TYPE_ARRAY,
- TYPE_STRUCT,
-} argtype;
-
-#define MK_PTR(type) TYPE_PTR, type
-#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
-#define MK_STRUCT(id) TYPE_STRUCT, id
-
-#define THUNK_TARGET 0
-#define THUNK_HOST 1
-
-typedef struct {
- /* standard struct handling */
- const argtype *field_types;
- int nb_fields;
- int *field_offsets[2];
- /* special handling */
- void (*convert[2])(void *dst, const void *src);
- int size[2];
- int align[2];
- const char *name;
-} StructEntry;
-
-/* Translation table for bitmasks... */
-typedef struct bitmask_transtbl {
- unsigned int x86_mask;
- unsigned int x86_bits;
- unsigned int alpha_mask;
- unsigned int alpha_bits;
-} bitmask_transtbl;
-
-void thunk_register_struct(int id, const char *name, const argtype *types);
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
-const argtype *thunk_convert(void *dst, const void *src,
- const argtype *type_ptr, int to_host);
-#ifndef NO_THUNK_TYPE_SIZE
-
-extern StructEntry struct_entries[];
-
-int thunk_type_size_array(const argtype *type_ptr, int is_host);
-int thunk_type_align_array(const argtype *type_ptr, int is_host);
-
-static inline int thunk_type_size(const argtype *type_ptr, int is_host)
-{
- int type, size;
- const StructEntry *se;
-
- type = *type_ptr;
- switch(type) {
- case TYPE_CHAR:
- return 1;
- case TYPE_SHORT:
- return 2;
- case TYPE_INT:
- return 4;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- return 8;
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- case TYPE_PTR:
- if (is_host) {
- return HOST_LONG_SIZE;
- } else {
- return TARGET_ABI_BITS / 8;
- }
- break;
- case TYPE_ARRAY:
- size = type_ptr[1];
- return size * thunk_type_size_array(type_ptr + 2, is_host);
- case TYPE_STRUCT:
- se = struct_entries + type_ptr[1];
- return se->size[is_host];
- default:
- return -1;
- }
-}
-
-static inline int thunk_type_align(const argtype *type_ptr, int is_host)
-{
- int type;
- const StructEntry *se;
-
- type = *type_ptr;
- switch(type) {
- case TYPE_CHAR:
- return 1;
- case TYPE_SHORT:
- return 2;
- case TYPE_INT:
- return 4;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- return 8;
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- case TYPE_PTR:
- if (is_host) {
- return HOST_LONG_SIZE;
- } else {
- return TARGET_ABI_BITS / 8;
- }
- break;
- case TYPE_ARRAY:
- return thunk_type_align_array(type_ptr + 2, is_host);
- case TYPE_STRUCT:
- se = struct_entries + type_ptr[1];
- return se->align[is_host];
- default:
- return -1;
- }
-}
-
-#endif /* NO_THUNK_TYPE_SIZE */
-
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
- bitmask_transtbl * trans_tbl);
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
- bitmask_transtbl * trans_tbl);
-
-#endif
diff --git a/trace.c b/trace.c
deleted file mode 100644
index a96f87f..0000000
--- a/trace.c
+++ /dev/null
@@ -1,1879 +0,0 @@
-/* Copyright (C) 2006-2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-#include "cpu.h"
-#include "exec-all.h"
-#include "trace.h"
-#include "varint.h"
-
-TraceBB trace_bb;
-TraceInsn trace_insn;
-TraceStatic trace_static;
-TraceAddr trace_load;
-TraceAddr trace_store;
-TraceExc trace_exc;
-TracePid trace_pid;
-TraceMethod trace_method;
-static TraceHeader header;
-
-const char *trace_filename;
-int tracing;
-int trace_cache_miss;
-int trace_all_addr;
-
-// The simulation time in cpu clock cycles
-uint64_t sim_time = 1;
-
-// The current process id
-int current_pid;
-
-// The start and end (wall-clock) time in microseconds
-uint64_t start_time, end_time;
-uint64_t elapsed_usecs;
-
-// For debugging output
-FILE *ftrace_debug;
-
-// The maximum number of bytes consumed by an InsnRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxInsnCompressed 14
-
-// The maximum number of bytes consumed by an BBRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxBBCompressed 32
-
-// The maximum number of bytes consumed by an AddrRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxAddrCompressed 14
-
-// The maximum number of bytes consumed by a MethodRec after compression.
-// This is very conservative but needed to ensure no buffer overflows.
-#define kMaxMethodCompressed 18
-
-// The maximum number of bytes consumed by an exception record after
-// compression.
-#define kMaxExcCompressed 38
-
-// The maximum number of bytes consumed by a pid record for
-// kPidSwitch, or kPidExit after compression.
-#define kMaxPidCompressed 15
-
-// The maximum number of bytes consumed by a pid record for kPidFork,
-// or kPidClone after compression.
-#define kMaxPid2Compressed 20
-
-// The maximum number of bytes consumed by a pid record for kPidExecArgs
-// after compression, not counting the bytes for the args.
-#define kMaxExecArgsCompressed 15
-
-// The maximum number of bytes consumed by a pid record for kPidName
-// after compression, not counting the bytes for the name.
-#define kMaxNameCompressed 20
-
-// The maximum number of bytes consumed by a pid record for kPidMmap
-// after compression, not counting the bytes for the pathname.
-#define kMaxMmapCompressed 33
-
-// The maximum number of bytes consumed by a pid record for kPidMunmap,
-// after compression.
-#define kMaxMunmapCompressed 28
-
-// The maximum number of bytes consumed by a pid record for kPidSymbol
-// after compression, not counting the bytes for the symbol name.
-#define kMaxSymbolCompressed 24
-
-// The maximum number of bytes consumed by a pid record for kPidKthreadName
-// after compression, not counting the bytes for the name.
-#define kMaxKthreadNameCompressed 25
-
-void trace_cleanup();
-
-// Return current time in microseconds as a 64-bit integer.
-uint64 Now() {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- uint64 val = tv.tv_sec;
- val = val * 1000000ull + tv.tv_usec;
- return val;
-}
-
-static void create_trace_dir(const char *dirname)
-{
- int err;
-
- err = path_mkdir(dirname, 0755);
- if (err != 0 && errno != EEXIST) {
- printf("err: %d\n", err);
- perror(dirname);
- exit(1);
- }
-}
-
-static char *create_trace_path(const char *filename, const char *ext)
-{
- char *fname;
- const char *base_start, *base_end;
- int ii, len, base_len, dir_len, path_len, qtrace_len;
-
- // Handle error cases
- if (filename == NULL || *filename == 0 || strcmp(filename, "/") == 0)
- return NULL;
-
- // Ignore a trailing slash, if any
- len = strlen(filename);
- if (filename[len - 1] == '/')
- len -= 1;
-
- // Find the basename. We don't use basename(3) because there are
- // different behaviors for GNU and Posix in the case where the
- // last character is a slash.
- base_start = base_end = &filename[len];
- for (ii = 0; ii < len; ++ii) {
- base_start -= 1;
- if (*base_start == '/') {
- base_start += 1;
- break;
- }
- }
- base_len = base_end - base_start;
- dir_len = len - base_len;
- qtrace_len = strlen("/qtrace");
-
- // Create space for the pathname: "/dir/basename/qtrace.ext"
- // The "ext" string already contains the dot, so just add a byte
- // for the terminating zero.
- path_len = dir_len + base_len + qtrace_len + strlen(ext) + 1;
- fname = malloc(path_len);
- if (dir_len > 0)
- strncpy(fname, filename, dir_len);
- fname[dir_len] = 0;
- strncat(fname, base_start, base_len);
- strcat(fname, "/qtrace");
- strcat(fname, ext);
- return fname;
-}
-
-void convert_secs_to_date_time(time_t secs, uint32_t *pdate, uint32_t *ptime)
-{
- struct tm *tm = localtime(&secs);
- uint32_t year = tm->tm_year + 1900;
- uint32_t thousands = year / 1000;
- year -= thousands * 1000;
- uint32_t hundreds = year / 100;
- year -= hundreds * 100;
- uint32_t tens = year / 10;
- year -= tens * 10;
- uint32_t ones = year;
- year = (thousands << 12) | (hundreds << 8) | (tens << 4) | ones;
-
- uint32_t mon = tm->tm_mon + 1;
- tens = mon / 10;
- ones = (mon - tens * 10);
- mon = (tens << 4) | ones;
-
- uint32_t day = tm->tm_mday;
- tens = day / 10;
- ones = (day - tens * 10);
- day = (tens << 4) | ones;
-
- *pdate = (year << 16) | (mon << 8) | day;
-
- uint32_t hour = tm->tm_hour;
- tens = hour / 10;
- ones = (hour - tens * 10);
- hour = (tens << 4) | ones;
-
- uint32_t min = tm->tm_min;
- tens = min / 10;
- ones = (min - tens * 10);
- min = (tens << 4) | ones;
-
- uint32_t sec = tm->tm_sec;
- tens = sec / 10;
- ones = (sec - tens * 10);
- sec = (tens << 4) | ones;
-
- *ptime = (hour << 16) | (min << 8) | sec;
-}
-
-void write_trace_header(TraceHeader *header)
-{
- TraceHeader swappedHeader;
-
- memcpy(&swappedHeader, header, sizeof(TraceHeader));
-
- convert32(swappedHeader.version);
- convert32(swappedHeader.start_sec);
- convert32(swappedHeader.start_usec);
- convert32(swappedHeader.pdate);
- convert32(swappedHeader.ptime);
- convert32(swappedHeader.num_used_pids);
- convert32(swappedHeader.first_unused_pid);
- convert64(swappedHeader.num_static_bb);
- convert64(swappedHeader.num_static_insn);
- convert64(swappedHeader.num_dynamic_bb);
- convert64(swappedHeader.num_dynamic_insn);
- convert64(swappedHeader.elapsed_usecs);
-
- fwrite(&swappedHeader, sizeof(TraceHeader), 1, trace_static.fstream);
-}
-
-void create_trace_bb(const char *filename)
-{
- char *fname = create_trace_path(filename, ".bb");
- trace_bb.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_bb.fstream = fstream;
- trace_bb.next = &trace_bb.buffer[0];
- trace_bb.flush_time = 0;
- trace_bb.compressed_ptr = trace_bb.compressed;
- trace_bb.high_water_ptr = &trace_bb.compressed[kCompressedSize] - kMaxBBCompressed;
- trace_bb.prev_bb_num = 0;
- trace_bb.prev_bb_time = 0;
- trace_bb.num_insns = 0;
- trace_bb.recnum = 0;
-}
-
-void create_trace_insn(const char *filename)
-{
- // Create the instruction time trace file
- char *fname = create_trace_path(filename, ".insn");
- trace_insn.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_insn.fstream = fstream;
- trace_insn.current = &trace_insn.dummy;
- trace_insn.dummy.time_diff = 0;
- trace_insn.dummy.repeat = 0;
- trace_insn.prev_time = 0;
- trace_insn.compressed_ptr = trace_insn.compressed;
- trace_insn.high_water_ptr = &trace_insn.compressed[kCompressedSize] - kMaxInsnCompressed;
-}
-
-void create_trace_static(const char *filename)
-{
- // Create the static basic block trace file
- char *fname = create_trace_path(filename, ".static");
- trace_static.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_static.fstream = fstream;
- trace_static.next_insn = 0;
- trace_static.bb_num = 1;
- trace_static.bb_addr = 0;
-
- // Write an empty header to reserve space for it in the file.
- // The header will be filled in later when post-processing the
- // trace file.
- memset(&header, 0, sizeof(TraceHeader));
-
- // Write out the version number so that tools can detect if the trace
- // file format is the same as what they expect.
- header.version = TRACE_VERSION;
-
- // Record the start time in the header now.
- struct timeval tv;
- struct timezone tz;
- gettimeofday(&tv, &tz);
- header.start_sec = tv.tv_sec;
- header.start_usec = tv.tv_usec;
- convert_secs_to_date_time(header.start_sec, &header.pdate, &header.ptime);
- write_trace_header(&header);
-
- // Write out the record for the unused basic block number 0.
- uint64_t zero = 0;
- fwrite(&zero, sizeof(uint64_t), 1, trace_static.fstream); // bb_num
- fwrite(&zero, sizeof(uint32_t), 1, trace_static.fstream); // bb_addr
- fwrite(&zero, sizeof(uint32_t), 1, trace_static.fstream); // num_insns
-}
-
-void create_trace_addr(const char *filename)
-{
- // The "qtrace.load" and "qtrace.store" files are optional
- trace_load.fstream = NULL;
- trace_store.fstream = NULL;
- if (trace_all_addr || trace_cache_miss) {
- // Create the "qtrace.load" file
- char *fname = create_trace_path(filename, ".load");
- trace_load.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_load.fstream = fstream;
- trace_load.next = &trace_load.buffer[0];
- trace_load.compressed_ptr = trace_load.compressed;
- trace_load.high_water_ptr = &trace_load.compressed[kCompressedSize] - kMaxAddrCompressed;
- trace_load.prev_addr = 0;
- trace_load.prev_time = 0;
-
- // Create the "qtrace.store" file
- fname = create_trace_path(filename, ".store");
- trace_store.filename = fname;
-
- fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_store.fstream = fstream;
- trace_store.next = &trace_store.buffer[0];
- trace_store.compressed_ptr = trace_store.compressed;
- trace_store.high_water_ptr = &trace_store.compressed[kCompressedSize] - kMaxAddrCompressed;
- trace_store.prev_addr = 0;
- trace_store.prev_time = 0;
- }
-}
-
-void create_trace_exc(const char *filename)
-{
- // Create the exception trace file
- char *fname = create_trace_path(filename, ".exc");
- trace_exc.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_exc.fstream = fstream;
- trace_exc.compressed_ptr = trace_exc.compressed;
- trace_exc.high_water_ptr = &trace_exc.compressed[kCompressedSize] - kMaxExcCompressed;
- trace_exc.prev_time = 0;
- trace_exc.prev_bb_recnum = 0;
-}
-
-void create_trace_pid(const char *filename)
-{
- // Create the pid trace file
- char *fname = create_trace_path(filename, ".pid");
- trace_pid.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_pid.fstream = fstream;
- trace_pid.compressed_ptr = trace_pid.compressed;
- trace_pid.prev_time = 0;
-}
-
-void create_trace_method(const char *filename)
-{
- // Create the method trace file
- char *fname = create_trace_path(filename, ".method");
- trace_method.filename = fname;
-
- FILE *fstream = fopen(fname, "wb");
- if (fstream == NULL) {
- perror(fname);
- exit(1);
- }
- trace_method.fstream = fstream;
- trace_method.compressed_ptr = trace_method.compressed;
- trace_method.prev_time = 0;
- trace_method.prev_addr = 0;
- trace_method.prev_pid = 0;
-}
-
-void trace_init(const char *filename)
-{
- // Create the trace files
- create_trace_dir(filename);
- create_trace_bb(filename);
- create_trace_insn(filename);
- create_trace_static(filename);
- create_trace_addr(filename);
- create_trace_exc(filename);
- create_trace_pid(filename);
- create_trace_method(filename);
-
-#if 0
- char *fname = create_trace_path(filename, ".debug");
- ftrace_debug = fopen(fname, "wb");
- if (ftrace_debug == NULL) {
- perror(fname);
- exit(1);
- }
-#else
- ftrace_debug = NULL;
-#endif
- atexit(trace_cleanup);
-
- // If tracing is on, then start timing the simulator
- if (tracing)
- start_time = Now();
-}
-
-/* the following array is used to deal with def-use register interlocks, which we
- * can compute statically (ignoring conditions), very fortunately.
- *
- * the idea is that interlock_base contains the number of cycles "executed" from
- * the start of a basic block. It is set to 0 in trace_bb_start, and incremented
- * in each call to get_insn_ticks_arm.
- *
- * interlocks[N] correspond to the value of interlock_base after which a register N
- * can be used by another operation, it is set each time an instruction writes to
- * the register in get_insn_ticks()
- */
-
-static int interlocks[16];
-static int interlock_base;
-
-static void
-_interlock_def(int reg, int delay)
-{
- if (reg >= 0)
- interlocks[reg] = interlock_base + delay;
-}
-
-static int
-_interlock_use(int reg)
-{
- int delay = 0;
-
- if (reg >= 0)
- {
- delay = interlocks[reg] - interlock_base;
- if (delay < 0)
- delay = 0;
- }
- return delay;
-}
-
-void trace_bb_start(uint32_t bb_addr)
-{
- int nn;
-
- trace_static.bb_addr = bb_addr;
- trace_static.is_thumb = 0;
-
- interlock_base = 0;
- for (nn = 0; nn < 16; nn++)
- interlocks[nn] = 0;
-}
-
-void trace_add_insn(uint32_t insn, int is_thumb)
-{
- trace_static.insns[trace_static.next_insn++] = insn;
- // This relies on the fact that a basic block does not contain a mix
- // of ARM and Thumb instructions. If that is not true, then many
- // software tools that read the trace will have to change.
- trace_static.is_thumb = is_thumb;
-}
-
-void trace_bb_end()
-{
- int ii, num_insns;
- uint32_t insn;
-
- uint64_t bb_num = hostToLE64(trace_static.bb_num);
- // If these are Thumb instructions, then encode that fact by setting
- // the low bit of the basic-block address to 1.
- uint32_t bb_addr = trace_static.bb_addr | trace_static.is_thumb;
- bb_addr = hostToLE32(bb_addr);
- num_insns = hostToLE32(trace_static.next_insn);
- fwrite(&bb_num, sizeof(bb_num), 1, trace_static.fstream);
- fwrite(&bb_addr, sizeof(bb_addr), 1, trace_static.fstream);
- fwrite(&num_insns, sizeof(num_insns), 1, trace_static.fstream);
- for (ii = 0; ii < trace_static.next_insn; ++ii) {
- insn = hostToLE32(trace_static.insns[ii]);
- fwrite(&insn, sizeof(insn), 1, trace_static.fstream);
- }
-
- trace_static.bb_num += 1;
- trace_static.next_insn = 0;
-}
-
-void trace_cleanup()
-{
- if (tracing) {
- end_time = Now();
- elapsed_usecs += end_time - start_time;
- }
- header.elapsed_usecs = elapsed_usecs;
- double elapsed_secs = elapsed_usecs / 1000000.0;
- double cycles_per_sec = 0;
- if (elapsed_secs != 0)
- cycles_per_sec = sim_time / elapsed_secs;
- char *suffix = "";
- if (cycles_per_sec >= 1000000) {
- cycles_per_sec /= 1000000.0;
- suffix = "M";
- } else if (cycles_per_sec > 1000) {
- cycles_per_sec /= 1000.0;
- suffix = "K";
- }
- printf("Elapsed seconds: %.2f, simulated cycles/sec: %.1f%s\n",
- elapsed_secs, cycles_per_sec, suffix);
- if (trace_bb.fstream) {
- BBRec *ptr;
- BBRec *next = trace_bb.next;
- char *comp_ptr = trace_bb.compressed_ptr;
- int64_t prev_bb_num = trace_bb.prev_bb_num;
- uint64_t prev_bb_time = trace_bb.prev_bb_time;
- for (ptr = trace_bb.buffer; ptr != next; ++ptr) {
- if (comp_ptr >= trace_bb.high_water_ptr) {
- uint32_t size = comp_ptr - trace_bb.compressed;
- fwrite(trace_bb.compressed, sizeof(char), size,
- trace_bb.fstream);
- comp_ptr = trace_bb.compressed;
- }
- int64_t bb_diff = ptr->bb_num - prev_bb_num;
- prev_bb_num = ptr->bb_num;
- uint64_t time_diff = ptr->start_time - prev_bb_time;
- prev_bb_time = ptr->start_time;
- comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode(ptr->repeat, comp_ptr);
- if (ptr->repeat)
- comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
- }
-
- // Add an extra record at the end containing the ending simulation
- // time and a basic block number of 0.
- uint64_t time_diff = sim_time - prev_bb_time;
- if (time_diff > 0) {
- int64_t bb_diff = -prev_bb_num;
- comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode(0, comp_ptr);
- }
-
- uint32_t size = comp_ptr - trace_bb.compressed;
- if (size)
- fwrite(trace_bb.compressed, sizeof(char), size, trace_bb.fstream);
-
- // Terminate the file with three zeros so that we can detect
- // the end of file quickly.
- uint32_t zeros = 0;
- fwrite(&zeros, 3, 1, trace_bb.fstream);
- fclose(trace_bb.fstream);
- }
-
- if (trace_insn.fstream) {
- InsnRec *ptr;
- InsnRec *current = trace_insn.current + 1;
- char *comp_ptr = trace_insn.compressed_ptr;
- for (ptr = trace_insn.buffer; ptr != current; ++ptr) {
- if (comp_ptr >= trace_insn.high_water_ptr) {
- uint32_t size = comp_ptr - trace_insn.compressed;
- uint32_t rval = fwrite(trace_insn.compressed, sizeof(char),
- size, trace_insn.fstream);
- if (rval != size) {
- fprintf(stderr, "fwrite() failed\n");
- perror(trace_insn.filename);
- exit(1);
- }
- comp_ptr = trace_insn.compressed;
- }
- comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
- comp_ptr = varint_encode(ptr->repeat, comp_ptr);
- }
-
- uint32_t size = comp_ptr - trace_insn.compressed;
- if (size) {
- uint32_t rval = fwrite(trace_insn.compressed, sizeof(char), size,
- trace_insn.fstream);
- if (rval != size) {
- fprintf(stderr, "fwrite() failed\n");
- perror(trace_insn.filename);
- exit(1);
- }
- }
- fclose(trace_insn.fstream);
- }
-
- if (trace_static.fstream) {
- fseek(trace_static.fstream, 0, SEEK_SET);
- write_trace_header(&header);
- fclose(trace_static.fstream);
- }
-
- if (trace_load.fstream) {
- AddrRec *ptr;
- char *comp_ptr = trace_load.compressed_ptr;
- AddrRec *next = trace_load.next;
- uint32_t prev_addr = trace_load.prev_addr;
- uint64_t prev_time = trace_load.prev_time;
- for (ptr = trace_load.buffer; ptr != next; ++ptr) {
- if (comp_ptr >= trace_load.high_water_ptr) {
- uint32_t size = comp_ptr - trace_load.compressed;
- fwrite(trace_load.compressed, sizeof(char), size,
- trace_load.fstream);
- comp_ptr = trace_load.compressed;
- }
-
- int addr_diff = ptr->addr - prev_addr;
- uint64_t time_diff = ptr->time - prev_time;
- prev_addr = ptr->addr;
- prev_time = ptr->time;
-
- comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
- comp_ptr = varint_encode(time_diff, comp_ptr);
- }
-
- uint32_t size = comp_ptr - trace_load.compressed;
- if (size) {
- fwrite(trace_load.compressed, sizeof(char), size,
- trace_load.fstream);
- }
-
- // Terminate the file with two zeros so that we can detect
- // the end of file quickly.
- uint32_t zeros = 0;
- fwrite(&zeros, 2, 1, trace_load.fstream);
- fclose(trace_load.fstream);
- }
-
- if (trace_store.fstream) {
- AddrRec *ptr;
- char *comp_ptr = trace_store.compressed_ptr;
- AddrRec *next = trace_store.next;
- uint32_t prev_addr = trace_store.prev_addr;
- uint64_t prev_time = trace_store.prev_time;
- for (ptr = trace_store.buffer; ptr != next; ++ptr) {
- if (comp_ptr >= trace_store.high_water_ptr) {
- uint32_t size = comp_ptr - trace_store.compressed;
- fwrite(trace_store.compressed, sizeof(char), size,
- trace_store.fstream);
- comp_ptr = trace_store.compressed;
- }
-
- int addr_diff = ptr->addr - prev_addr;
- uint64_t time_diff = ptr->time - prev_time;
- prev_addr = ptr->addr;
- prev_time = ptr->time;
-
- comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
- comp_ptr = varint_encode(time_diff, comp_ptr);
- }
-
- uint32_t size = comp_ptr - trace_store.compressed;
- if (size) {
- fwrite(trace_store.compressed, sizeof(char), size,
- trace_store.fstream);
- }
-
- // Terminate the file with two zeros so that we can detect
- // the end of file quickly.
- uint32_t zeros = 0;
- fwrite(&zeros, 2, 1, trace_store.fstream);
- fclose(trace_store.fstream);
- }
-
- if (trace_exc.fstream) {
- uint32_t size = trace_exc.compressed_ptr - trace_exc.compressed;
- if (size) {
- fwrite(trace_exc.compressed, sizeof(char), size,
- trace_exc.fstream);
- }
-
- // Terminate the file with 7 zeros so that we can detect
- // the end of file quickly.
- uint64_t zeros = 0;
- fwrite(&zeros, 7, 1, trace_exc.fstream);
- fclose(trace_exc.fstream);
- }
- if (trace_pid.fstream) {
- uint32_t size = trace_pid.compressed_ptr - trace_pid.compressed;
- if (size) {
- fwrite(trace_pid.compressed, sizeof(char), size,
- trace_pid.fstream);
- }
-
- // Terminate the file with 2 zeros so that we can detect
- // the end of file quickly.
- uint64_t zeros = 0;
- fwrite(&zeros, 2, 1, trace_pid.fstream);
- fclose(trace_pid.fstream);
- }
- if (trace_method.fstream) {
- uint32_t size = trace_method.compressed_ptr - trace_method.compressed;
- if (size) {
- fwrite(trace_method.compressed, sizeof(char), size,
- trace_method.fstream);
- }
-
- // Terminate the file with 2 zeros so that we can detect
- // the end of file quickly.
- uint64_t zeros = 0;
- fwrite(&zeros, 2, 1, trace_method.fstream);
- fclose(trace_method.fstream);
- }
- if (ftrace_debug)
- fclose(ftrace_debug);
-}
-
-// Define the number of clock ticks for some instructions. Add one to these
-// (in some cases) if there is an interlock. We currently do not check for
-// interlocks.
-#define TICKS_OTHER 1
-#define TICKS_SMULxy 1
-#define TICKS_SMLAWy 1
-#define TICKS_SMLALxy 2
-#define TICKS_MUL 2
-#define TICKS_MLA 2
-#define TICKS_MULS 4 // no interlock penalty
-#define TICKS_MLAS 4 // no interlock penalty
-#define TICKS_UMULL 3
-#define TICKS_UMLAL 3
-#define TICKS_SMULL 3
-#define TICKS_SMLAL 3
-#define TICKS_UMULLS 5 // no interlock penalty
-#define TICKS_UMLALS 5 // no interlock penalty
-#define TICKS_SMULLS 5 // no interlock penalty
-#define TICKS_SMLALS 5 // no interlock penalty
-
-// Compute the number of cycles that this instruction will take,
-// not including any I-cache or D-cache misses. This function
-// is called for each instruction in a basic block when that
-// block is being translated.
-int get_insn_ticks_arm(uint32_t insn)
-{
-#if 1
- int result = 1; /* by default, use 1 cycle */
-
- /* See Chapter 12 of the ARM920T Reference Manual for details about clock cycles */
-
- /* first check for invalid condition codes */
- if ((insn >> 28) == 0xf)
- {
- if ((insn >> 25) == 0x7d) { /* BLX */
- result = 3;
- goto Exit;
- }
- /* XXX: if we get there, we're either in an UNDEFINED instruction */
- /* or in co-processor related ones. For now, only return 1 cycle */
- goto Exit;
- }
-
- /* other cases */
- switch ((insn >> 25) & 7)
- {
- case 0:
- if ((insn & 0x00000090) == 0x00000090) /* Multiplies, extra load/store, Table 3-2 */
- {
- /* XXX: TODO: Add support for multiplier operand content penalties in the translator */
-
- if ((insn & 0x0fc000f0) == 0x00000090) /* 3-2: Multiply (accumulate) */
- {
- int Rm = (insn & 15);
- int Rs = (insn >> 8) & 15;
- int Rn = (insn >> 12) & 15;
-
- if ((insn & 0x00200000) != 0) { /* MLA */
- result += _interlock_use(Rn);
- } else { /* MLU */
- if (Rn != 0) /* UNDEFINED */
- goto Exit;
- }
- /* cycles=2+m, assume m=1, this should be adjusted at interpretation time */
- result += 2 + _interlock_use(Rm) + _interlock_use(Rs);
- }
- else if ((insn & 0x0f8000f0) == 0x00800090) /* 3-2: Multiply (accumulate) long */
- {
- int Rm = (insn & 15);
- int Rs = (insn >> 8) & 15;
- int RdLo = (insn >> 12) & 15;
- int RdHi = (insn >> 16) & 15;
-
- if ((insn & 0x00200000) != 0) { /* SMLAL & UMLAL */
- result += _interlock_use(RdLo) + _interlock_use(RdHi);
- }
- /* else SMLL and UMLL */
-
- /* cucles=3+m, assume m=1, this should be adjusted at interpretation time */
- result += 3 + _interlock_use(Rm) + _interlock_use(Rs);
- }
- else if ((insn & 0x0fd00ff0) == 0x01000090) /* 3-2: Swap/swap byte */
- {
- int Rm = (insn & 15);
- int Rd = (insn >> 8) & 15;
-
- result = 2 + _interlock_use(Rm);
- _interlock_def(Rd, result+1);
- }
- else if ((insn & 0x0e400ff0) == 0x00000090) /* 3-2: load/store halfword, reg offset */
- {
- int Rm = (insn & 15);
- int Rd = (insn >> 12) & 15;
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rn) + _interlock_use(Rm);
- if ((insn & 0x00100000) != 0) /* it's a load, there's a 2-cycle interlock */
- _interlock_def(Rd, result+2);
- }
- else if ((insn & 0x0e400ff0) == 0x00400090) /* 3-2: load/store halfword, imm offset */
- {
- int Rd = (insn >> 12) & 15;
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rn);
- if ((insn & 0x00100000) != 0) /* it's a load, there's a 2-cycle interlock */
- _interlock_def(Rd, result+2);
- }
- else if ((insn & 0x0e500fd0) == 0x000000d0) /* 3-2: load/store two words, reg offset */
- {
- /* XXX: TODO: Enhanced DSP instructions */
- }
- else if ((insn & 0x0e500fd0) == 0x001000d0) /* 3-2: load/store half/byte, reg offset */
- {
- int Rm = (insn & 15);
- int Rd = (insn >> 12) & 15;
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rn) + _interlock_use(Rm);
- if ((insn & 0x00100000) != 0) /* load, 2-cycle interlock */
- _interlock_def(Rd, result+2);
- }
- else if ((insn & 0x0e5000d0) == 0x004000d0) /* 3-2: load/store two words, imm offset */
- {
- /* XXX: TODO: Enhanced DSP instructions */
- }
- else if ((insn & 0x0e5000d0) == 0x005000d0) /* 3-2: load/store half/byte, imm offset */
- {
- int Rd = (insn >> 12) & 15;
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rn);
- if ((insn & 0x00100000) != 0) /* load, 2-cycle interlock */
- _interlock_def(Rd, result+2);
- }
- else
- {
- /* UNDEFINED */
- }
- }
- else if ((insn & 0x0f900000) == 0x01000000) /* Misc. instructions, table 3-3 */
- {
- switch ((insn >> 4) & 15)
- {
- case 0:
- if ((insn & 0x0fb0fff0) == 0x0120f000) /* move register to status register */
- {
- int Rm = (insn & 15);
- result += _interlock_use(Rm);
- }
- break;
-
- case 1:
- if ( ((insn & 0x0ffffff0) == 0x01200010) || /* branch/exchange */
- ((insn & 0x0fff0ff0) == 0x01600010) ) /* count leading zeroes */
- {
- int Rm = (insn & 15);
- result += _interlock_use(Rm);
- }
- break;
-
- case 3:
- if ((insn & 0x0ffffff0) == 0x01200030) /* link/exchange */
- {
- int Rm = (insn & 15);
- result += _interlock_use(Rm);
- }
- break;
-
- default:
- /* TODO: Enhanced DSP instructions */
- ;
- }
- }
- else /* Data processing */
- {
- int Rm = (insn & 15);
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rn) + _interlock_use(Rm);
- if ((insn & 0x10)) { /* register-controlled shift => 1 cycle penalty */
- int Rs = (insn >> 8) & 15;
- result += 1 + _interlock_use(Rs);
- }
- }
- break;
-
- case 1:
- if ((insn & 0x01900000) == 0x01900000)
- {
- /* either UNDEFINED or move immediate to CPSR */
- }
- else /* Data processing immediate */
- {
- int Rn = (insn >> 12) & 15;
- result += _interlock_use(Rn);
- }
- break;
-
- case 2: /* load/store immediate */
- {
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rn);
- if (insn & 0x00100000) { /* LDR */
- int Rd = (insn >> 12) & 15;
-
- if (Rd == 15) /* loading PC */
- result = 5;
- else
- _interlock_def(Rd,result+1);
- }
- }
- break;
-
- case 3:
- if ((insn & 0x10) == 0) /* load/store register offset */
- {
- int Rm = (insn & 15);
- int Rn = (insn >> 16) & 15;
-
- result += _interlock_use(Rm) + _interlock_use(Rn);
-
- if (insn & 0x00100000) { /* LDR */
- int Rd = (insn >> 12) & 15;
- if (Rd == 15)
- result = 5;
- else
- _interlock_def(Rd,result+1);
- }
- }
- /* else UNDEFINED */
- break;
-
- case 4: /* load/store multiple */
- {
- int Rn = (insn >> 16) & 15;
- uint32_t mask = (insn & 0xffff);
- int count;
-
- for (count = 0; mask; count++)
- mask &= (mask-1);
-
- result += _interlock_use(Rn);
-
- if (insn & 0x00100000) /* LDM */
- {
- int nn;
-
- if (insn & 0x8000) { /* loading PC */
- result = count+4;
- } else { /* not loading PC */
- result = (count < 2) ? 2 : count;
- }
- /* create defs, all registers locked until the end of the load */
- for (nn = 0; nn < 15; nn++)
- if ((insn & (1U << nn)) != 0)
- _interlock_def(nn,result);
- }
- else /* STM */
- result = (count < 2) ? 2 : count;
- }
- break;
-
- case 5: /* branch and branch+link */
- break;
-
- case 6: /* coprocessor load/store */
- {
- int Rn = (insn >> 16) & 15;
-
- if (insn & 0x00100000)
- result += _interlock_use(Rn);
-
- /* XXX: other things to do ? */
- }
- break;
-
- default: /* i.e. 7 */
- /* XXX: TODO: co-processor related things */
- ;
- }
-Exit:
- interlock_base += result;
- return result;
-#else /* old code - this seems to be completely buggy ?? */
- if ((insn & 0x0ff0f090) == 0x01600080) {
- return TICKS_SMULxy;
- } else if ((insn & 0x0ff00090) == 0x01200080) {
- return TICKS_SMLAWy;
- } else if ((insn & 0x0ff00090) == 0x01400080) {
- return TICKS_SMLALxy;
- } else if ((insn & 0x0f0000f0) == 0x00000090) {
- // multiply
- uint8_t bit23 = (insn >> 23) & 0x1;
- uint8_t bit22_U = (insn >> 22) & 0x1;
- uint8_t bit21_A = (insn >> 21) & 0x1;
- uint8_t bit20_S = (insn >> 20) & 0x1;
-
- if (bit23 == 0) {
- // 32-bit multiply
- if (bit22_U != 0) {
- // This is an unexpected bit pattern.
- return TICKS_OTHER;
- }
- if (bit21_A == 0) {
- if (bit20_S)
- return TICKS_MULS;
- return TICKS_MUL;
- }
- if (bit20_S)
- return TICKS_MLAS;
- return TICKS_MLA;
- }
- // 64-bit multiply
- if (bit22_U == 0) {
- // Unsigned multiply long
- if (bit21_A == 0) {
- if (bit20_S)
- return TICKS_UMULLS;
- return TICKS_UMULL;
- }
- if (bit20_S)
- return TICKS_UMLALS;
- return TICKS_UMLAL;
- }
- // Signed multiply long
- if (bit21_A == 0) {
- if (bit20_S)
- return TICKS_SMULLS;
- return TICKS_SMULL;
- }
- if (bit20_S)
- return TICKS_SMLALS;
- return TICKS_SMLAL;
- }
- return TICKS_OTHER;
-#endif
-}
-
-int get_insn_ticks_thumb(uint32_t insn)
-{
-#if 1
- int result = 1;
-
- switch ((insn >> 11) & 31)
- {
- case 0:
- case 1:
- case 2: /* Shift by immediate */
- {
- int Rm = (insn >> 3) & 7;
- result += _interlock_use(Rm);
- }
- break;
-
- case 3: /* Add/Substract */
- {
- int Rn = (insn >> 3) & 7;
- result += _interlock_use(Rn);
-
- if ((insn & 0x0400) == 0) { /* register value */
- int Rm = (insn >> 6) & 7;
- result += _interlock_use(Rm);
- }
- }
- break;
-
- case 4: /* move immediate */
- break;
-
- case 5:
- case 6:
- case 7: /* add/substract/compare immediate */
- {
- int Rd = (insn >> 8) & 7;
- result += _interlock_use(Rd);
- }
- break;
-
- case 8:
- {
- if ((insn & 0x0400) == 0) /* data processing register */
- {
- /* the registers can also be Rs and Rn in some cases */
- /* but they're always read anyway and located at the */
- /* same place, so we don't check the opcode */
- int Rm = (insn >> 3) & 7;
- int Rd = (insn >> 3) & 7;
-
- result += _interlock_use(Rm) + _interlock_use(Rd);
- }
- else switch ((insn >> 8) & 3)
- {
- case 0:
- case 1:
- case 2: /* special data processing */
- {
- int Rn = (insn & 7) | ((insn >> 4) & 0x8);
- int Rm = ((insn >> 3) & 15);
-
- result += _interlock_use(Rn) + _interlock_use(Rm);
- }
- break;
-
- case 3:
- if ((insn & 0xff07) == 0x4700) /* branch/exchange */
- {
- int Rm = (insn >> 3) & 15;
-
- result = 3 + _interlock_use(Rm);
- }
- /* else UNDEFINED */
- break;
- }
- }
- break;
-
- case 9: /* load from literal pool */
- {
- int Rd = (insn >> 8) & 7;
- _interlock_def(Rd,result+1);
- }
- break;
-
- case 10:
- case 11: /* load/store register offset */
- {
- int Rd = (insn & 7);
- int Rn = (insn >> 3) & 7;
- int Rm = (insn >> 6) & 7;
-
- result += _interlock_use(Rn) + _interlock_use(Rm);
-
- switch ((insn >> 9) & 7)
- {
- case 0: /* STR */
- case 1: /* STRH */
- case 2: /* STRB */
- result += _interlock_use(Rd);
- break;
-
- case 3: /* LDRSB */
- case 5: /* LDRH */
- case 6: /* LDRB */
- case 7: /* LDRSH */
- _interlock_def(Rd,result+2);
- break;
-
- case 4: /* LDR */
- _interlock_def(Rd,result+1);
- }
- }
- break;
-
- case 12: /* store word immediate offset */
- case 14: /* store byte immediate offset */
- {
- int Rd = (insn & 7);
- int Rn = (insn >> 3) & 7;
-
- result += _interlock_use(Rd) + _interlock_use(Rn);
- }
- break;
-
- case 13: /* load word immediate offset */
- {
- int Rd = (insn & 7);
- int Rn = (insn >> 3) & 7;
-
- result += _interlock_use(Rn);
- _interlock_def(Rd,result+1);
- }
- break;
-
- case 15: /* load byte immediate offset */
- {
- int Rd = (insn & 7);
- int Rn = (insn >> 3) & 7;
-
- result += _interlock_use(Rn);
- _interlock_def(Rd,result+2);
- }
- break;
-
- case 16: /* store halfword immediate offset */
- {
- int Rd = (insn & 7);
- int Rn = (insn >> 3) & 7;
-
- result += _interlock_use(Rn) + _interlock_use(Rd);
- }
- break;
-
- case 17: /* load halfword immediate offset */
- {
- int Rd = (insn & 7);
- int Rn = (insn >> 3) & 7;
-
- result += _interlock_use(Rn);
- _interlock_def(Rd,result+2);
- }
- break;
-
- case 18: /* store to stack */
- {
- int Rd = (insn >> 8) & 3;
- result += _interlock_use(Rd);
- }
- break;
-
- case 19: /* load from stack */
- {
- int Rd = (insn >> 8) & 3;
- _interlock_def(Rd,result+1);
- }
- break;
-
- case 20: /* add to PC */
- case 21: /* add to SP */
- {
- int Rd = (insn >> 8) & 3;
- result += _interlock_use(Rd);
- }
- break;
-
- case 22:
- case 23: /* misc. instructions, table 6-2 */
- {
- if ((insn & 0xff00) == 0xb000) /* adjust stack pointer */
- {
- result += _interlock_use(14);
- }
- else if ((insn & 0x0600) == 0x0400) /* push pop register list */
- {
- uint32_t mask = insn & 0x01ff;
- int count, nn;
-
- for (count = 0; mask; count++)
- mask &= (mask-1);
-
- result = (count < 2) ? 2 : count;
-
- if (insn & 0x0800) /* pop register list */
- {
- for (nn = 0; nn < 9; nn++)
- if (insn & (1 << nn))
- _interlock_def(nn, result);
- }
- else /* push register list */
- {
- for (nn = 0; nn < 9; nn++)
- if (insn & (1 << nn))
- result += _interlock_use(nn);
- }
- }
- /* else software breakpoint */
- }
- break;
-
- case 24: /* store multiple */
- {
- int Rd = (insn >> 8) & 7;
- uint32_t mask = insn & 255;
- int count, nn;
-
- for (count = 0; mask; count++)
- mask &= (mask-1);
-
- result = (count < 2) ? 2 : count;
- result += _interlock_use(Rd);
-
- for (nn = 0; nn < 8; nn++)
- if (insn & (1 << nn))
- result += _interlock_use(nn);
- }
- break;
-
- case 25: /* load multiple */
- {
- int Rd = (insn >> 8) & 7;
- uint32_t mask = insn & 255;
- int count, nn;
-
- for (count = 0; mask; count++)
- mask &= (mask-1);
-
- result = (count < 2) ? 2 : count;
- result += _interlock_use(Rd);
-
- for (nn = 0; nn < 8; nn++)
- if (insn & (1 << nn))
- _interlock_def(nn, result);
- }
- break;
-
- case 26:
- case 27: /* conditional branch / undefined / software interrupt */
- switch ((insn >> 8) & 15)
- {
- case 14: /* UNDEFINED */
- case 15: /* SWI */
- break;
-
- default: /* conditional branch */
- result = 3;
- }
- break;
-
- case 28: /* unconditional branch */
- result = 3;
- break;
-
- case 29: /* BLX suffix or undefined */
- if ((insn & 1) == 0)
- result = 3;
- break;
-
- case 30: /* BLX/BLX prefix */
- break;
-
- case 31: /* BL suffix */
- result = 3;
- break;
- }
- interlock_base += result;
- return result;
-#else /* old code */
- if ((insn & 0xfc00) == 0x4340) /* MUL */
- return TICKS_SMULxy;
-
- return TICKS_OTHER;
-#endif
-}
-
-// Adds an exception trace record.
-void trace_exception(uint32 target_pc)
-{
- if (trace_exc.fstream == NULL)
- return;
-
- // Sometimes we get an unexpected exception as the first record. If the
- // basic block number is zero, then we know it is bogus.
- if (trace_bb.current_bb_num == 0)
- return;
-
- uint32_t current_pc = trace_bb.current_bb_addr + 4 * (trace_bb.num_insns - 1);
-#if 0
- if (ftrace_debug) {
- fprintf(ftrace_debug, "t%llu exc pc: 0x%x bb_addr: 0x%x num_insns: %d current_pc: 0x%x bb_num %llu bb_start_time %llu\n",
- sim_time, target_pc, trace_bb.current_bb_addr,
- trace_bb.num_insns, current_pc, trace_bb.current_bb_num,
- trace_bb.current_bb_start_time);
- }
-#endif
- char *comp_ptr = trace_exc.compressed_ptr;
- if (comp_ptr >= trace_exc.high_water_ptr) {
- uint32_t size = comp_ptr - trace_exc.compressed;
- fwrite(trace_exc.compressed, sizeof(char), size, trace_exc.fstream);
- comp_ptr = trace_exc.compressed;
- }
- uint64_t time_diff = sim_time - trace_exc.prev_time;
- trace_exc.prev_time = sim_time;
- uint64_t bb_recnum_diff = trace_bb.recnum - trace_exc.prev_bb_recnum;
- trace_exc.prev_bb_recnum = trace_bb.recnum;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode(current_pc, comp_ptr);
- comp_ptr = varint_encode(bb_recnum_diff, comp_ptr);
- comp_ptr = varint_encode(target_pc, comp_ptr);
- comp_ptr = varint_encode(trace_bb.current_bb_num, comp_ptr);
- comp_ptr = varint_encode(trace_bb.current_bb_start_time, comp_ptr);
- comp_ptr = varint_encode(trace_bb.num_insns, comp_ptr);
- trace_exc.compressed_ptr = comp_ptr;
-}
-
-void trace_pid_1arg(int pid, int rec_type)
-{
- if (trace_pid.fstream == NULL)
- return;
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + kMaxPidCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(pid, comp_ptr);
- trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_pid_2arg(int tgid, int pid, int rec_type)
-{
- if (trace_pid.fstream == NULL)
- return;
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + kMaxPid2Compressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(tgid, comp_ptr);
- comp_ptr = varint_encode(pid, comp_ptr);
- trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_switch(int pid)
-{
-#if 0
- if (ftrace_debug && trace_pid.fstream)
- fprintf(ftrace_debug, "t%lld switch %d\n", sim_time, pid);
-#endif
- trace_pid_1arg(pid, kPidSwitch);
- current_pid = pid;
-}
-
-void trace_fork(int tgid, int pid)
-{
-#if 0
- if (ftrace_debug && trace_pid.fstream)
- fprintf(ftrace_debug, "t%lld fork %d\n", sim_time, pid);
-#endif
- trace_pid_2arg(tgid, pid, kPidFork);
-}
-
-void trace_clone(int tgid, int pid)
-{
-#if 0
- if (ftrace_debug && trace_pid.fstream)
- fprintf(ftrace_debug, "t%lld clone %d\n", sim_time, pid);
-#endif
- trace_pid_2arg(tgid, pid, kPidClone);
-}
-
-void trace_exit(int exitcode)
-{
-#if 0
- if (ftrace_debug && trace_pid.fstream)
- fprintf(ftrace_debug, "t%lld exit %d\n", sim_time, exitcode);
-#endif
- trace_pid_1arg(exitcode, kPidExit);
-}
-
-void trace_name(char *name)
-{
-#if 0
- if (ftrace_debug && trace_pid.fstream) {
- fprintf(ftrace_debug, "t%lld pid %d name %s\n",
- sim_time, current_pid, name);
- }
-#endif
- if (trace_pid.fstream == NULL)
- return;
- int len = strlen(name);
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + len + kMaxNameCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidName;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(current_pid, comp_ptr);
- comp_ptr = varint_encode(len, comp_ptr);
- strncpy(comp_ptr, name, len);
- comp_ptr += len;
- trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_execve(const char *argv, int len)
-{
- int ii;
-
- if (trace_pid.fstream == NULL)
- return;
- // Count the number of args
- int alen = 0;
- int sum_len = 0;
- int argc = 0;
- const char *ptr = argv;
- while (sum_len < len) {
- argc += 1;
- alen = strlen(ptr);
- ptr += alen + 1;
- sum_len += alen + 1;
- }
-
-#if 0
- if (ftrace_debug) {
- fprintf(ftrace_debug, "t%lld argc: %d\n", sim_time, argc);
- alen = 0;
- ptr = argv;
- for (ii = 0; ii < argc; ++ii) {
- fprintf(ftrace_debug, " argv[%d]: %s\n", ii, ptr);
- alen = strlen(ptr);
- ptr += alen + 1;
- }
- }
-#endif
-
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + len + 5 * argc + kMaxExecArgsCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidExec;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(argc, comp_ptr);
-
- ptr = argv;
- for (ii = 0; ii < argc; ++ii) {
- alen = strlen(ptr);
- comp_ptr = varint_encode(alen, comp_ptr);
- strncpy(comp_ptr, ptr, alen);
- comp_ptr += alen;
- ptr += alen + 1;
- }
- trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_mmap(unsigned long vstart, unsigned long vend,
- unsigned long offset, const char *path)
-{
- if (trace_pid.fstream == NULL)
- return;
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld mmap %08lx - %08lx, offset %08lx '%s'\n",
- sim_time, vstart, vend, offset, path);
-#endif
- int len = strlen(path);
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + len + kMaxMmapCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidMmap;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(vstart, comp_ptr);
- comp_ptr = varint_encode(vend, comp_ptr);
- comp_ptr = varint_encode(offset, comp_ptr);
- comp_ptr = varint_encode(len, comp_ptr);
- strncpy(comp_ptr, path, len);
- trace_pid.compressed_ptr = comp_ptr + len;
-}
-
-void trace_munmap(unsigned long vstart, unsigned long vend)
-{
- if (trace_pid.fstream == NULL)
- return;
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld munmap %08lx - %08lx\n",
- sim_time, vstart, vend);
-#endif
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + kMaxMunmapCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidMunmap;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(vstart, comp_ptr);
- comp_ptr = varint_encode(vend, comp_ptr);
- trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_dynamic_symbol_add(unsigned long vaddr, const char *name)
-{
- if (trace_pid.fstream == NULL)
- return;
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld sym %08lx '%s'\n", sim_time, vaddr, name);
-#endif
- int len = strlen(name);
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + len + kMaxSymbolCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidSymbolAdd;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(vaddr, comp_ptr);
- comp_ptr = varint_encode(len, comp_ptr);
- strncpy(comp_ptr, name, len);
- trace_pid.compressed_ptr = comp_ptr + len;
-}
-
-void trace_dynamic_symbol_remove(unsigned long vaddr)
-{
- if (trace_pid.fstream == NULL)
- return;
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld remove %08lx\n", sim_time, vaddr);
-#endif
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + kMaxSymbolCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidSymbolRemove;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(vaddr, comp_ptr);
- trace_pid.compressed_ptr = comp_ptr;
-}
-
-void trace_init_name(int tgid, int pid, const char *name)
-{
- if (trace_pid.fstream == NULL)
- return;
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld kthread %d %s\n", sim_time, pid, name);
-#endif
- int len = strlen(name);
- char *comp_ptr = trace_pid.compressed_ptr;
- char *max_end_ptr = comp_ptr + len + kMaxKthreadNameCompressed;
- if (max_end_ptr >= &trace_pid.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_pid.compressed;
- fwrite(trace_pid.compressed, sizeof(char), size, trace_pid.fstream);
- comp_ptr = trace_pid.compressed;
- }
- uint64_t time_diff = sim_time - trace_pid.prev_time;
- trace_pid.prev_time = sim_time;
- comp_ptr = varint_encode(time_diff, comp_ptr);
- int rec_type = kPidKthreadName;
- comp_ptr = varint_encode(rec_type, comp_ptr);
- comp_ptr = varint_encode(tgid, comp_ptr);
- comp_ptr = varint_encode(pid, comp_ptr);
- comp_ptr = varint_encode(len, comp_ptr);
- strncpy(comp_ptr, name, len);
- trace_pid.compressed_ptr = comp_ptr + len;
-}
-
-void trace_init_exec(unsigned long start, unsigned long end,
- unsigned long offset, const char *exe)
-{
-}
-
-// This function is called by the generated code to record the basic
-// block number.
-void trace_bb_helper(uint64_t bb_num, TranslationBlock *tb)
-{
- BBRec *bb_rec = tb->bb_rec;
- uint64_t prev_time = tb->prev_time;
- trace_bb.current_bb_addr = tb->pc;
- trace_bb.current_bb_num = bb_num;
- trace_bb.current_bb_start_time = sim_time;
- trace_bb.num_insns = 0;
- trace_bb.recnum += 1;
-
-#if 0
- if (ftrace_debug)
- fprintf(ftrace_debug, "t%lld %lld\n", sim_time, bb_num);
-#endif
- if (bb_rec && bb_rec->bb_num == bb_num && prev_time > trace_bb.flush_time) {
- uint64_t time_diff = sim_time - prev_time;
- if (bb_rec->repeat == 0) {
- bb_rec->repeat = 1;
- bb_rec->time_diff = time_diff;
- tb->prev_time = sim_time;
- return;
- } else if (time_diff == bb_rec->time_diff) {
- bb_rec->repeat += 1;
- tb->prev_time = sim_time;
- return;
- }
- }
-
- BBRec *next = trace_bb.next;
- if (next == &trace_bb.buffer[kMaxNumBasicBlocks]) {
- BBRec *ptr;
- char *comp_ptr = trace_bb.compressed_ptr;
- int64_t prev_bb_num = trace_bb.prev_bb_num;
- uint64_t prev_bb_time = trace_bb.prev_bb_time;
- for (ptr = trace_bb.buffer; ptr != next; ++ptr) {
- if (comp_ptr >= trace_bb.high_water_ptr) {
- uint32_t size = comp_ptr - trace_bb.compressed;
- fwrite(trace_bb.compressed, sizeof(char), size, trace_bb.fstream);
- comp_ptr = trace_bb.compressed;
- }
- int64_t bb_diff = ptr->bb_num - prev_bb_num;
- prev_bb_num = ptr->bb_num;
- uint64_t time_diff = ptr->start_time - prev_bb_time;
- prev_bb_time = ptr->start_time;
- comp_ptr = varint_encode_signed(bb_diff, comp_ptr);
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode(ptr->repeat, comp_ptr);
- if (ptr->repeat)
- comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
- }
- trace_bb.compressed_ptr = comp_ptr;
- trace_bb.prev_bb_num = prev_bb_num;
- trace_bb.prev_bb_time = prev_bb_time;
-
- next = trace_bb.buffer;
- trace_bb.flush_time = sim_time;
- }
- tb->bb_rec = next;
- next->bb_num = bb_num;
- next->start_time = sim_time;
- next->time_diff = 0;
- next->repeat = 0;
- tb->prev_time = sim_time;
- next += 1;
- trace_bb.next = next;
-}
-
-// This function is called by the generated code to record the simulation
-// time at the start of each instruction.
-void trace_insn_helper()
-{
- InsnRec *current = trace_insn.current;
- uint64_t time_diff = sim_time - trace_insn.prev_time;
- trace_insn.prev_time = sim_time;
-
- // Keep track of the number of traced instructions so far in this
- // basic block in case we get an exception in the middle of the bb.
- trace_bb.num_insns += 1;
-
-#if 0
- if (ftrace_debug) {
- uint32_t current_pc = trace_bb.current_bb_addr + 4 * (trace_bb.num_insns - 1);
- fprintf(ftrace_debug, "%llu %x\n", sim_time, current_pc);
- }
-#endif
- if (time_diff == current->time_diff) {
- current->repeat += 1;
- if (current->repeat != 0)
- return;
-
- // The repeat count wrapped around, so back up one and create
- // a new record.
- current->repeat -= 1;
- }
- current += 1;
-
- if (current == &trace_insn.buffer[kInsnBufferSize]) {
- InsnRec *ptr;
- char *comp_ptr = trace_insn.compressed_ptr;
- for (ptr = trace_insn.buffer; ptr != current; ++ptr) {
- if (comp_ptr >= trace_insn.high_water_ptr) {
- uint32_t size = comp_ptr - trace_insn.compressed;
- uint32_t rval = fwrite(trace_insn.compressed, sizeof(char),
- size, trace_insn.fstream);
- if (rval != size) {
- fprintf(stderr, "fwrite() failed\n");
- perror(trace_insn.filename);
- exit(1);
- }
- comp_ptr = trace_insn.compressed;
- }
- comp_ptr = varint_encode(ptr->time_diff, comp_ptr);
- comp_ptr = varint_encode(ptr->repeat, comp_ptr);
- }
- trace_insn.compressed_ptr = comp_ptr;
- current = trace_insn.buffer;
- }
- current->time_diff = time_diff;
- current->repeat = 0;
- trace_insn.current = current;
-}
-
-// Adds an interpreted method trace record. Each trace record is a time
-// stamped entry or exit to a method in a language executed by a "virtual
-// machine". This allows profiling tools to show the method names instead
-// of the core virtual machine interpreter.
-void trace_interpreted_method(uint32_t addr, int call_type)
-{
- if (trace_method.fstream == NULL)
- return;
-#if 0
- fprintf(stderr, "trace_method time: %llu p%d 0x%x %d\n",
- sim_time, current_pid, addr, call_type);
-#endif
- char *comp_ptr = trace_method.compressed_ptr;
- char *max_end_ptr = comp_ptr + kMaxMethodCompressed;
- if (max_end_ptr >= &trace_method.compressed[kCompressedSize]) {
- uint32_t size = comp_ptr - trace_method.compressed;
- fwrite(trace_method.compressed, sizeof(char), size, trace_method.fstream);
- comp_ptr = trace_method.compressed;
- }
- uint64_t time_diff = sim_time - trace_method.prev_time;
- trace_method.prev_time = sim_time;
-
- int32_t addr_diff = addr - trace_method.prev_addr;
- trace_method.prev_addr = addr;
-
- int32_t pid_diff = current_pid - trace_method.prev_pid;
- trace_method.prev_pid = current_pid;
-
- comp_ptr = varint_encode(time_diff, comp_ptr);
- comp_ptr = varint_encode_signed(addr_diff, comp_ptr);
- comp_ptr = varint_encode_signed(pid_diff, comp_ptr);
- comp_ptr = varint_encode(call_type, comp_ptr);
- trace_method.compressed_ptr = comp_ptr;
-}
diff --git a/trace.h b/trace.h
deleted file mode 100644
index ebb0e8c..0000000
--- a/trace.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (C) 2006-2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef TRACE_H
-#define TRACE_H
-
-#include <inttypes.h>
-#include "trace_common.h"
-
-extern uint64_t start_time, end_time;
-extern uint64_t elapsed_usecs;
-extern uint64 Now();
-
-// Define magic addresses so that the simulated program can interact with the
-// simulator.
-#define kMagicBaseAddr 0x08000000
-#define kMagicBaseMask 0xfffff000
-#define kMagicOffsetMask 0x00000fff
-
-#define kMethodTraceEnterOffset 0x0004
-#define kMethodTraceExitOffset 0x0008
-#define kMethodTraceExceptionOffset 0x000c
-
-struct TranslationBlock;
-
-// For tracing dynamic execution of basic blocks
-typedef struct TraceBB {
- char *filename;
- FILE *fstream;
- BBRec buffer[kMaxNumBasicBlocks];
- BBRec *next; // points to next record in buffer
- uint64_t flush_time; // time of last buffer flush
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
- int64_t prev_bb_num;
- uint64_t prev_bb_time;
- uint64_t current_bb_num;
- uint64_t current_bb_start_time;
- uint64_t recnum; // counts number of trace records
- uint32_t current_bb_addr;
- int num_insns;
-} TraceBB;
-
-// For tracing simuation start times of instructions
-typedef struct TraceInsn {
- char *filename;
- FILE *fstream;
- InsnRec dummy; // this is here so we can use buffer[-1]
- InsnRec buffer[kInsnBufferSize];
- InsnRec *current;
- uint64_t prev_time; // time of last instruction start
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
-} TraceInsn;
-
-// For tracing the static information about a basic block
-typedef struct TraceStatic {
- char *filename;
- FILE *fstream;
- uint32_t insns[kMaxInsnPerBB];
- int next_insn;
- uint64_t bb_num;
- uint32_t bb_addr;
- int is_thumb;
-} TraceStatic;
-
-// For tracing load and store addresses
-typedef struct TraceAddr {
- char *filename;
- FILE *fstream;
- AddrRec buffer[kMaxNumAddrs];
- AddrRec *next;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
- uint32_t prev_addr;
- uint64_t prev_time;
-} TraceAddr;
-
-// For tracing exceptions
-typedef struct TraceExc {
- char *filename;
- FILE *fstream;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- char *high_water_ptr;
- uint64_t prev_time;
- uint64_t prev_bb_recnum;
-} TraceExc;
-
-// For tracing process id changes
-typedef struct TracePid {
- char *filename;
- FILE *fstream;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- uint64_t prev_time;
-} TracePid;
-
-// For tracing Dalvik VM method enter and exit
-typedef struct TraceMethod {
- char *filename;
- FILE *fstream;
- char compressed[kCompressedSize];
- char *compressed_ptr;
- uint64_t prev_time;
- uint32_t prev_addr;
- int32_t prev_pid;
-} TraceMethod;
-
-extern TraceBB trace_bb;
-extern TraceInsn trace_insn;
-extern TraceStatic trace_static;
-extern TraceAddr trace_load;
-extern TraceAddr trace_store;
-extern TraceExc trace_exc;
-extern TracePid trace_pid;
-extern TraceMethod trace_method;
-
-// The simulated time, in clock ticks, starting with one.
-extern uint64_t sim_time;
-
-// This variable == 1 if we are currently tracing, otherwise == 0.
-extern int tracing;
-extern int trace_all_addr;
-extern int trace_cache_miss;
-
-extern void start_tracing();
-extern void stop_tracing();
-extern void trace_init(const char *filename);
-extern void trace_bb_start(uint32_t bb_addr);
-extern void trace_add_insn_arm(uint32_t insn, int is_thumb);
-extern void trace_bb_end();
-
-extern int get_insn_ticks_arm(uint32_t insn);
-extern int get_insn_ticks_thumb(uint32_t insn);
-
-extern void trace_exception(uint32 pc);
-extern void trace_bb_helper(uint64_t bb_num, TranslationBlock *tb);
-extern void trace_insn_helper();
-extern void sim_dcache_load(uint32_t addr);
-extern void sim_dcache_store(uint32_t addr, uint32_t val);
-extern void sim_dcache_swp(uint32_t addr);
-extern void trace_interpreted_method(uint32_t addr, int call_type);
-
-extern const char *trace_filename;
-extern int tracing;
-extern int trace_cache_miss;
-extern int trace_all_addr;
-
-#endif /* TRACE_H */
diff --git a/trace_common.h b/trace_common.h
deleted file mode 100644
index 3c4440d..0000000
--- a/trace_common.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Copyright (C) 2006-2007 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-
-#ifndef TRACE_COMMON_H
-#define TRACE_COMMON_H
-
-#include <inttypes.h>
-
-// This should be the same as OPC_BUF_SIZE
-#define kMaxInsnPerBB 512
-
-#define kMaxNumBasicBlocks 1024
-
-#define kMaxNumAddrs 1024
-
-#define kInsnBufferSize 1024
-
-#define kCompressedSize 8192
-
-#define kMethodEnter 0
-#define kMethodExit 1
-#define kMethodException 2
-
-// The trace identifier string must be less than 16 characters.
-#define TRACE_IDENT "qemu_trace_file"
-#define TRACE_VERSION 1
-
-typedef struct TraceHeader {
- char ident[16];
- int version;
- uint32_t start_sec;
- uint32_t start_usec;
- uint32_t pdate;
- uint32_t ptime;
- uint32_t num_used_pids; // number of distinct process ids used
- int first_unused_pid; // -1 if all 32,768 pids are used (unlikely)
- uint8_t padding[4]; // next field is 8-byte aligned
- uint64_t num_static_bb;
- uint64_t num_static_insn;
- uint64_t num_dynamic_bb;
- uint64_t num_dynamic_insn;
- uint64_t elapsed_usecs;
-} TraceHeader;
-
-typedef struct BBRec {
- uint64_t start_time; // time of first occurrence
- uint64_t bb_num; // basic block number
- uint32_t repeat; // repeat count (= 0 if just one occurrence)
- uint64_t time_diff; // diff from previous time (if repeat > 0)
-} BBRec;
-
-// Define a trace record for addresses that miss in the cache
-typedef struct AddrRec {
- uint64_t time;
- uint32_t addr;
-} AddrRec;
-
-// Define a trace record for the start time of each instruction
-typedef struct InsnRec {
- uint64_t time_diff; // time difference from last instruction
- uint32_t repeat; // repeat count
-} InsnRec;
-
-// Define record types for process id changes.
-#define kPidEndOfFile 0
-#define kPidFork 1
-#define kPidClone 2
-#define kPidSwitch 3
-#define kPidExec 4
-#define kPidMmap 5
-#define kPidExit 6
-#define kPidKthreadName 7
-#define kPidSymbolAdd 8
-#define kPidSymbolRemove 9
-#define kPidMunmap 10
-#define kPidNoAction 11
-#define kPidName 12
-
-#define bswap16(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
-
-#define bswap32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
- | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff))
-
-#define bswap64(x) (((x) << 56) | (((x) & 0xff00) << 40) \
- | (((x) & 0xff0000) << 24) | (((x) & 0xff000000ull) << 8) \
- | (((x) >> 8) & 0xff000000ull) | (((x) >> 24) & 0xff0000) \
- | (((x) >> 40) & 0xff00) | ((x) >> 56))
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define hostToLE16(x) (x)
-#define hostToLE32(x) (x)
-#define hostToLE64(x) (x)
-#define LE16ToHost(x) (x)
-#define LE32ToHost(x) (x)
-#define LE64ToHost(x) (x)
-#define convert16(x)
-#define convert32(x)
-#define convert64(x)
-#else
-#define hostToLE16(x) bswap16(x)
-#define hostToLE32(x) bswap32(x)
-#define hostToLE64(x) bswap64(x)
-#define LE16ToHost(x) bswap16(x)
-#define LE32ToHost(x) bswap32(x)
-#define LE64ToHost(x) bswap64(x)
-#define convert16(x) (x = bswap16(x))
-#define convert32(x) (x = bswap32(x))
-#define convert64(x) (x = bswap64(x))
-#endif
-
-/* XXX: we wrap 16-bit thumb instructions into 32-bit undefined ARM instructions
- * for simplicity reasons. See section 3.13.1 section of the ARM ARM for details
- * on the undefined instruction space we're using
- */
-static __inline__ int insn_is_thumb(uint32_t insn)
-{
- return ((insn & 0xfff000f0) == 0xf7f000f0);
-}
-
-static __inline__ uint32_t insn_wrap_thumb(uint32_t insn)
-{
- return 0xf7f000f0 | ((insn & 0xfff0) << 4) | (insn & 0x000f);
-}
-
-static __inline__ uint32_t insn_unwrap_thumb(uint32_t insn)
-{
- return ((insn >> 4) & 0xfff0) | (insn & 0x000f);
-}
-
-#endif /* TRACE_COMMON_H */
diff --git a/translate-all.c b/translate-all.c
deleted file mode 100644
index 1c27fd3..0000000
--- a/translate-all.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Host code generation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-
-#define NO_CPU_IO_DEFS
-#include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
-#include "tcg.h"
-
-/* code generation context */
-TCGContext tcg_ctx;
-
-uint16_t gen_opc_buf[OPC_BUF_SIZE];
-TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
-
-target_ulong gen_opc_pc[OPC_BUF_SIZE];
-uint16_t gen_opc_icount[OPC_BUF_SIZE];
-uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-#if defined(TARGET_I386)
-uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-#elif defined(TARGET_SPARC)
-target_ulong gen_opc_npc[OPC_BUF_SIZE];
-target_ulong gen_opc_jump_pc[2];
-#elif defined(TARGET_MIPS) || defined(TARGET_SH4)
-uint32_t gen_opc_hflags[OPC_BUF_SIZE];
-#endif
-
-/* XXX: suppress that */
-unsigned long code_gen_max_block_size(void)
-{
- static unsigned long max;
-
- if (max == 0) {
- max = TCG_MAX_OP_SIZE;
-#define DEF(s, n, copy_size) max = copy_size > max? copy_size : max;
-#include "tcg-opc.h"
-#undef DEF
- max *= OPC_MAX_SIZE;
- }
-
- return max;
-}
-
-void cpu_gen_init(void)
-{
- tcg_context_init(&tcg_ctx);
- tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
- CPU_TEMP_BUF_NLONGS * sizeof(long));
-}
-
-/* return non zero if the very first instruction is invalid so that
- the virtual CPU can trigger an exception.
-
- '*gen_code_size_ptr' contains the size of the generated code (host
- code).
-*/
-int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
-{
- TCGContext *s = &tcg_ctx;
- uint8_t *gen_code_buf;
- int gen_code_size;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
-
-#ifdef CONFIG_PROFILER
- s->tb_count1++; /* includes aborted translations because of
- exceptions */
- ti = profile_getclock();
-#endif
- tcg_func_start(s);
-
- gen_intermediate_code(env, tb);
-
- /* generate machine code */
- gen_code_buf = tb->tc_ptr;
- tb->tb_next_offset[0] = 0xffff;
- tb->tb_next_offset[1] = 0xffff;
- s->tb_next_offset = tb->tb_next_offset;
-#ifdef USE_DIRECT_JUMP
- s->tb_jmp_offset = tb->tb_jmp_offset;
- s->tb_next = NULL;
- /* the following two entries are optional (only used for string ops) */
- /* XXX: not used ? */
- tb->tb_jmp_offset[2] = 0xffff;
- tb->tb_jmp_offset[3] = 0xffff;
-#else
- s->tb_jmp_offset = NULL;
- s->tb_next = tb->tb_next;
-#endif
-
-#ifdef CONFIG_PROFILER
- s->tb_count++;
- s->interm_time += profile_getclock() - ti;
- s->code_time -= profile_getclock();
-#endif
- gen_code_size = dyngen_code(s, gen_code_buf);
- *gen_code_size_ptr = gen_code_size;
-#ifdef CONFIG_PROFILER
- s->code_time += profile_getclock();
- s->code_in_len += tb->size;
- s->code_out_len += gen_code_size;
-#endif
-
-#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_OUT_ASM) {
- fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
- disas(logfile, tb->tc_ptr, *gen_code_size_ptr);
- fprintf(logfile, "\n");
- fflush(logfile);
- }
-#endif
- return 0;
-}
-
-/* The cpu state corresponding to 'searched_pc' is restored.
- */
-int cpu_restore_state(TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc)
-{
- TCGContext *s = &tcg_ctx;
- int j;
- unsigned long tc_ptr;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
-
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
- tcg_func_start(s);
-
- gen_intermediate_code_pc(env, tb);
-
- if (use_icount) {
- /* Reset the cycle counter to the start of the block. */
- env->icount_decr.u16.low += tb->icount;
- /* Clear the IO flag. */
- env->can_do_io = 0;
- }
-
- /* find opc index corresponding to search_pc */
- tc_ptr = (unsigned long)tb->tc_ptr;
- if (searched_pc < tc_ptr)
- return -1;
-
- s->tb_next_offset = tb->tb_next_offset;
-#ifdef USE_DIRECT_JUMP
- s->tb_jmp_offset = tb->tb_jmp_offset;
- s->tb_next = NULL;
-#else
- s->tb_jmp_offset = NULL;
- s->tb_next = tb->tb_next;
-#endif
- j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr);
- if (j < 0)
- return -1;
- /* now find start of instruction before */
- while (gen_opc_instr_start[j] == 0)
- j--;
- env->icount_decr.u16.low -= gen_opc_icount[j];
-
- gen_pc_load(env, tb, searched_pc, j, puc);
-
-#ifdef CONFIG_PROFILER
- s->restore_time += profile_getclock() - ti;
- s->restore_count++;
-#endif
- return 0;
-}
diff --git a/translate-op.c b/translate-op.c
deleted file mode 100644
index c25a161..0000000
--- a/translate-op.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Host code generation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#ifdef GEN_TRACE
-#include "opc-trace.h"
-#else
-#include "opc.h"
-#endif
-#undef DEF
- NB_OPS,
-};
-
-#include "dyngen.h"
-#ifdef GEN_TRACE
-#define dyngen_code _trace_dyngen_code
-#include "op-trace.h"
-#else
-#define dyngen_code _default_dyngen_code
-#include "op.h"
-#endif
-
-typedef int (*dyngen_code_func)(uint8_t *gen_code_buf,
- uint16_t *label_offsets, uint16_t *jmp_offsets,
- const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels);
-
-extern dyngen_code_func _dyngen_code;
-
-#ifdef GEN_TRACE
-
-void qemu_trace_enable_dyngen( void )
-{
- _dyngen_code = dyngen_code;
-}
-
-#else
-
-void qemu_trace_disable_dyngen( void )
-{
- _dyngen_code = dyngen_code;
-}
-
-dyngen_code_func _dyngen_code = _default_dyngen_code;
-
-#undef dyngen_code
-
-int dyngen_code(uint8_t *gen_code_buf,
- uint16_t *label_offsets, uint16_t *jmp_offsets,
- const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels)
-{
- return (*_dyngen_code)(gen_code_buf, label_offsets, jmp_offsets, opc_buf, opparam_buf, gen_labels);
-}
-
-#endif
-
-
diff --git a/translate.make b/translate.make
deleted file mode 100644
index cba105f..0000000
--- a/translate.make
+++ /dev/null
@@ -1,37 +0,0 @@
-# this sub-Makefile is included to define a dynamic translating library
-#
-EMULATOR_OP_LIBRARIES := $(EMULATOR_OP_LIBRARIES) $(LOCAL_MODULE)
-
-# we need to compile this with GCC-3.3 preferabbly
-#
-LOCAL_NO_DEFAULT_COMPILER_FLAGS := true
-LOCAL_CC := $(MY_CC)
-
-LOCAL_LDFLAGS += $(my_32bit_ldflags)
-LOCAL_CFLAGS += $(my_32bit_cflags) $(OP_CFLAGS)
-
-INTERMEDIATE := $(call intermediates-dir-for,STATIC_LIBRARIES,$(LOCAL_MODULE),true)
-OP_OBJ := $(INTERMEDIATE)/target-arm/op.o
-
-LOCAL_CFLAGS += -I$(INTERMEDIATE)
-
-OP_H := $(INTERMEDIATE)/op$(OP_SUFFIX).h
-OPC_H := $(INTERMEDIATE)/opc$(OP_SUFFIX).h
-GEN_OP_H := $(INTERMEDIATE)/gen-op$(OP_SUFFIX).h
-
-$(OP_H): $(OP_OBJ) $(DYNGEN)
- $(DYNGEN) -o $@ $<
-
-$(OPC_H): $(OP_OBJ) $(DYNGEN)
- $(DYNGEN) -c -o $@ $<
-
-$(GEN_OP_H): $(OP_OBJ) $(DYNGEN)
- $(DYNGEN) -g -o $@ $<
-
-TRANSLATE_SOURCES := target-arm/translate.c \
- translate-all.c \
- translate-op.c
-
-LOCAL_SRC_FILES += target-arm/op.c $(TRANSLATE_SOURCES)
-
-$(TRANSLATE_SOURCES:%.c=$(INTERMEDIATE)/%.o): $(OP_H) $(OPC_H) $(GEN_OP_H)
diff --git a/uboot_image.h b/uboot_image.h
deleted file mode 100644
index d5a5b30..0000000
--- a/uboot_image.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * (C) Copyright 2000-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- ********************************************************************
- * NOTE: This header file defines an interface to U-Boot. Including
- * this (unmodified) header file in another file is considered normal
- * use of U-Boot, and does *not* fall under the heading of "derived
- * work".
- ********************************************************************
- */
-
-#ifndef __UBOOT_IMAGE_H__
-#define __UBOOT_IMAGE_H__
-
-/*
- * Operating System Codes
- */
-#define IH_OS_INVALID 0 /* Invalid OS */
-#define IH_OS_OPENBSD 1 /* OpenBSD */
-#define IH_OS_NETBSD 2 /* NetBSD */
-#define IH_OS_FREEBSD 3 /* FreeBSD */
-#define IH_OS_4_4BSD 4 /* 4.4BSD */
-#define IH_OS_LINUX 5 /* Linux */
-#define IH_OS_SVR4 6 /* SVR4 */
-#define IH_OS_ESIX 7 /* Esix */
-#define IH_OS_SOLARIS 8 /* Solaris */
-#define IH_OS_IRIX 9 /* Irix */
-#define IH_OS_SCO 10 /* SCO */
-#define IH_OS_DELL 11 /* Dell */
-#define IH_OS_NCR 12 /* NCR */
-#define IH_OS_LYNXOS 13 /* LynxOS */
-#define IH_OS_VXWORKS 14 /* VxWorks */
-#define IH_OS_PSOS 15 /* pSOS */
-#define IH_OS_QNX 16 /* QNX */
-#define IH_OS_U_BOOT 17 /* Firmware */
-#define IH_OS_RTEMS 18 /* RTEMS */
-#define IH_OS_ARTOS 19 /* ARTOS */
-#define IH_OS_UNITY 20 /* Unity OS */
-
-/*
- * CPU Architecture Codes (supported by Linux)
- */
-#define IH_CPU_INVALID 0 /* Invalid CPU */
-#define IH_CPU_ALPHA 1 /* Alpha */
-#define IH_CPU_ARM 2 /* ARM */
-#define IH_CPU_I386 3 /* Intel x86 */
-#define IH_CPU_IA64 4 /* IA64 */
-#define IH_CPU_MIPS 5 /* MIPS */
-#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */
-#define IH_CPU_PPC 7 /* PowerPC */
-#define IH_CPU_S390 8 /* IBM S390 */
-#define IH_CPU_SH 9 /* SuperH */
-#define IH_CPU_SPARC 10 /* Sparc */
-#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */
-#define IH_CPU_M68K 12 /* M68K */
-#define IH_CPU_NIOS 13 /* Nios-32 */
-#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */
-#define IH_CPU_NIOS2 15 /* Nios-II */
-#define IH_CPU_BLACKFIN 16 /* Blackfin */
-#define IH_CPU_AVR32 17 /* AVR32 */
-
-/*
- * Image Types
- *
- * "Standalone Programs" are directly runnable in the environment
- * provided by U-Boot; it is expected that (if they behave
- * well) you can continue to work in U-Boot after return from
- * the Standalone Program.
- * "OS Kernel Images" are usually images of some Embedded OS which
- * will take over control completely. Usually these programs
- * will install their own set of exception handlers, device
- * drivers, set up the MMU, etc. - this means, that you cannot
- * expect to re-enter U-Boot except by resetting the CPU.
- * "RAMDisk Images" are more or less just data blocks, and their
- * parameters (address, size) are passed to an OS kernel that is
- * being started.
- * "Multi-File Images" contain several images, typically an OS
- * (Linux) kernel image and one or more data images like
- * RAMDisks. This construct is useful for instance when you want
- * to boot over the network using BOOTP etc., where the boot
- * server provides just a single image file, but you want to get
- * for instance an OS kernel and a RAMDisk image.
- *
- * "Multi-File Images" start with a list of image sizes, each
- * image size (in bytes) specified by an "uint32_t" in network
- * byte order. This list is terminated by an "(uint32_t)0".
- * Immediately after the terminating 0 follow the images, one by
- * one, all aligned on "uint32_t" boundaries (size rounded up to
- * a multiple of 4 bytes - except for the last file).
- *
- * "Firmware Images" are binary images containing firmware (like
- * U-Boot or FPGA images) which usually will be programmed to
- * flash memory.
- *
- * "Script files" are command sequences that will be executed by
- * U-Boot's command interpreter; this feature is especially
- * useful when you configure U-Boot to use a real shell (hush)
- * as command interpreter (=> Shell Scripts).
- */
-
-#define IH_TYPE_INVALID 0 /* Invalid Image */
-#define IH_TYPE_STANDALONE 1 /* Standalone Program */
-#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
-#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */
-#define IH_TYPE_MULTI 4 /* Multi-File Image */
-#define IH_TYPE_FIRMWARE 5 /* Firmware Image */
-#define IH_TYPE_SCRIPT 6 /* Script file */
-#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
-#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
-
-/*
- * Compression Types
- */
-#define IH_COMP_NONE 0 /* No Compression Used */
-#define IH_COMP_GZIP 1 /* gzip Compression Used */
-#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
-
-#define IH_MAGIC 0x27051956 /* Image Magic Number */
-#define IH_NMLEN 32 /* Image Name Length */
-
-/*
- * all data in network byte order (aka natural aka bigendian)
- */
-
-typedef struct uboot_image_header {
- uint32_t ih_magic; /* Image Header Magic Number */
- uint32_t ih_hcrc; /* Image Header CRC Checksum */
- uint32_t ih_time; /* Image Creation Timestamp */
- uint32_t ih_size; /* Image Data Size */
- uint32_t ih_load; /* Data Load Address */
- uint32_t ih_ep; /* Entry Point Address */
- uint32_t ih_dcrc; /* Image Data CRC Checksum */
- uint8_t ih_os; /* Operating System */
- uint8_t ih_arch; /* CPU architecture */
- uint8_t ih_type; /* Image Type */
- uint8_t ih_comp; /* Compression Type */
- uint8_t ih_name[IH_NMLEN]; /* Image Name */
-} uboot_image_header_t;
-
-
-#endif /* __IMAGE_H__ */
diff --git a/usb-linux.c b/usb-linux.c
deleted file mode 100644
index 91acccd..0000000
--- a/usb-linux.c
+++ /dev/null
@@ -1,1506 +0,0 @@
-/*
- * Linux host USB redirector
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Copyright (c) 2008 Max Krasnyansky
- * Support for host device auto connect & disconnect
- * Major rewrite to support fully async operation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "qemu-timer.h"
-#include "console.h"
-
-#if defined(__linux__)
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <signal.h>
-
-#include <linux/usbdevice_fs.h>
-#include <linux/version.h>
-#include "hw/usb.h"
-
-/* We redefine it to avoid version problems */
-struct usb_ctrltransfer {
- uint8_t bRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
- uint32_t timeout;
- void *data;
-};
-
-struct usb_ctrlrequest {
- uint8_t bRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
-};
-
-typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed);
-static int usb_host_find_device(int *pbus_num, int *paddr,
- char *product_name, int product_name_size,
- const char *devname);
-//#define DEBUG
-
-#ifdef DEBUG
-#define dprintf printf
-#else
-#define dprintf(...)
-#endif
-
-#define USBDEVFS_PATH "/proc/bus/usb"
-#define PRODUCT_NAME_SZ 32
-#define MAX_ENDPOINTS 16
-
-/* endpoint association data */
-struct endp_data {
- uint8_t type;
- uint8_t halted;
-};
-
-enum {
- CTRL_STATE_IDLE = 0,
- CTRL_STATE_SETUP,
- CTRL_STATE_DATA,
- CTRL_STATE_ACK
-};
-
-/*
- * Control transfer state.
- * Note that 'buffer' _must_ follow 'req' field because
- * we need contigious buffer when we submit control URB.
- */
-struct ctrl_struct {
- uint16_t len;
- uint16_t offset;
- uint8_t state;
- struct usb_ctrlrequest req;
- uint8_t buffer[1024];
-};
-
-typedef struct USBHostDevice {
- USBDevice dev;
- int fd;
-
- uint8_t descr[1024];
- int descr_len;
- int configuration;
- int ninterfaces;
- int closing;
-
- struct ctrl_struct ctrl;
- struct endp_data endp_table[MAX_ENDPOINTS];
-
- /* Host side address */
- int bus_num;
- int addr;
-
- struct USBHostDevice *next;
-} USBHostDevice;
-
-static int is_isoc(USBHostDevice *s, int ep)
-{
- return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
-}
-
-static int is_halted(USBHostDevice *s, int ep)
-{
- return s->endp_table[ep - 1].halted;
-}
-
-static void clear_halt(USBHostDevice *s, int ep)
-{
- s->endp_table[ep - 1].halted = 0;
-}
-
-static void set_halt(USBHostDevice *s, int ep)
-{
- s->endp_table[ep - 1].halted = 1;
-}
-
-static USBHostDevice *hostdev_list;
-
-static void hostdev_link(USBHostDevice *dev)
-{
- dev->next = hostdev_list;
- hostdev_list = dev;
-}
-
-static void hostdev_unlink(USBHostDevice *dev)
-{
- USBHostDevice *pdev = hostdev_list;
- USBHostDevice **prev = &hostdev_list;
-
- while (pdev) {
- if (pdev == dev) {
- *prev = dev->next;
- return;
- }
-
- prev = &pdev->next;
- pdev = pdev->next;
- }
-}
-
-static USBHostDevice *hostdev_find(int bus_num, int addr)
-{
- USBHostDevice *s = hostdev_list;
- while (s) {
- if (s->bus_num == bus_num && s->addr == addr)
- return s;
- s = s->next;
- }
- return NULL;
-}
-
-/*
- * Async URB state.
- * We always allocate one isoc descriptor even for bulk transfers
- * to simplify allocation and casts.
- */
-typedef struct AsyncURB
-{
- struct usbdevfs_urb urb;
- struct usbdevfs_iso_packet_desc isocpd;
-
- USBPacket *packet;
- USBHostDevice *hdev;
-} AsyncURB;
-
-static AsyncURB *async_alloc(void)
-{
- return (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
-}
-
-static void async_free(AsyncURB *aurb)
-{
- qemu_free(aurb);
-}
-
-static void async_complete_ctrl(USBHostDevice *s, USBPacket *p)
-{
- switch(s->ctrl.state) {
- case CTRL_STATE_SETUP:
- if (p->len < s->ctrl.len)
- s->ctrl.len = p->len;
- s->ctrl.state = CTRL_STATE_DATA;
- p->len = 8;
- break;
-
- case CTRL_STATE_ACK:
- s->ctrl.state = CTRL_STATE_IDLE;
- p->len = 0;
- break;
-
- default:
- break;
- }
-}
-
-static void async_complete(void *opaque)
-{
- USBHostDevice *s = opaque;
- AsyncURB *aurb;
-
- while (1) {
- USBPacket *p;
-
- int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
- if (r < 0) {
- if (errno == EAGAIN)
- return;
-
- if (errno == ENODEV && !s->closing) {
- printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
- usb_device_del_addr(0, s->dev.addr);
- return;
- }
-
- dprintf("husb: async. reap urb failed errno %d\n", errno);
- return;
- }
-
- p = aurb->packet;
-
- dprintf("husb: async completed. aurb %p status %d alen %d\n",
- aurb, aurb->urb.status, aurb->urb.actual_length);
-
- if (p) {
- switch (aurb->urb.status) {
- case 0:
- p->len = aurb->urb.actual_length;
- if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL)
- async_complete_ctrl(s, p);
- break;
-
- case -EPIPE:
- set_halt(s, p->devep);
- /* fall through */
- default:
- p->len = USB_RET_NAK;
- break;
- }
-
- usb_packet_complete(p);
- }
-
- async_free(aurb);
- }
-}
-
-static void async_cancel(USBPacket *unused, void *opaque)
-{
- AsyncURB *aurb = opaque;
- USBHostDevice *s = aurb->hdev;
-
- dprintf("husb: async cancel. aurb %p\n", aurb);
-
- /* Mark it as dead (see async_complete above) */
- aurb->packet = NULL;
-
- int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
- if (r < 0) {
- dprintf("husb: async. discard urb failed errno %d\n", errno);
- }
-}
-
-static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
-{
- int dev_descr_len, config_descr_len;
- int interface, nb_interfaces, nb_configurations;
- int ret, i;
-
- if (configuration == 0) /* address state - ignore */
- return 1;
-
- dprintf("husb: claiming interfaces. config %d\n", configuration);
-
- i = 0;
- dev_descr_len = dev->descr[0];
- if (dev_descr_len > dev->descr_len)
- goto fail;
- nb_configurations = dev->descr[17];
-
- i += dev_descr_len;
- while (i < dev->descr_len) {
- dprintf("husb: i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
- dev->descr[i], dev->descr[i+1]);
-
- if (dev->descr[i+1] != USB_DT_CONFIG) {
- i += dev->descr[i];
- continue;
- }
- config_descr_len = dev->descr[i];
-
- printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
-
- if (configuration < 0 || configuration == dev->descr[i + 5]) {
- configuration = dev->descr[i + 5];
- break;
- }
-
- i += config_descr_len;
- }
-
- if (i >= dev->descr_len) {
- fprintf(stderr, "husb: update iface failed. no matching configuration\n");
- goto fail;
- }
- nb_interfaces = dev->descr[i + 4];
-
-#ifdef USBDEVFS_DISCONNECT
- /* earlier Linux 2.4 do not support that */
- {
- struct usbdevfs_ioctl ctrl;
- for (interface = 0; interface < nb_interfaces; interface++) {
- ctrl.ioctl_code = USBDEVFS_DISCONNECT;
- ctrl.ifno = interface;
- ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
- if (ret < 0 && errno != ENODATA) {
- perror("USBDEVFS_DISCONNECT");
- goto fail;
- }
- }
- }
-#endif
-
- /* XXX: only grab if all interfaces are free */
- for (interface = 0; interface < nb_interfaces; interface++) {
- ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
- if (ret < 0) {
- if (errno == EBUSY) {
- printf("husb: update iface. device already grabbed\n");
- } else {
- perror("husb: failed to claim interface");
- }
- fail:
- return 0;
- }
- }
-
- printf("husb: %d interfaces claimed for configuration %d\n",
- nb_interfaces, configuration);
-
- dev->ninterfaces = nb_interfaces;
- dev->configuration = configuration;
- return 1;
-}
-
-static int usb_host_release_interfaces(USBHostDevice *s)
-{
- int ret, i;
-
- dprintf("husb: releasing interfaces\n");
-
- for (i = 0; i < s->ninterfaces; i++) {
- ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
- if (ret < 0) {
- perror("husb: failed to release interface");
- return 0;
- }
- }
-
- return 1;
-}
-
-static void usb_host_handle_reset(USBDevice *dev)
-{
- USBHostDevice *s = (USBHostDevice *) dev;
-
- dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);
-
- ioctl(s->fd, USBDEVFS_RESET);
-
- usb_host_claim_interfaces(s, s->configuration);
-}
-
-static void usb_host_handle_destroy(USBDevice *dev)
-{
- USBHostDevice *s = (USBHostDevice *)dev;
-
- s->closing = 1;
-
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-
- hostdev_unlink(s);
-
- async_complete(s);
-
- if (s->fd >= 0)
- close(s->fd);
-
- qemu_free(s);
-}
-
-static int usb_linux_update_endp_table(USBHostDevice *s);
-
-static int usb_host_handle_data(USBHostDevice *s, USBPacket *p)
-{
- struct usbdevfs_urb *urb;
- AsyncURB *aurb;
- int ret;
-
- aurb = async_alloc();
- if (!aurb) {
- dprintf("husb: async malloc failed\n");
- return USB_RET_NAK;
- }
- aurb->hdev = s;
- aurb->packet = p;
-
- urb = &aurb->urb;
-
- if (p->pid == USB_TOKEN_IN)
- urb->endpoint = p->devep | 0x80;
- else
- urb->endpoint = p->devep;
-
- if (is_halted(s, p->devep)) {
- ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
- if (ret < 0) {
- dprintf("husb: failed to clear halt. ep 0x%x errno %d\n",
- urb->endpoint, errno);
- return USB_RET_NAK;
- }
- clear_halt(s, p->devep);
- }
-
- urb->buffer = p->data;
- urb->buffer_length = p->len;
-
- if (is_isoc(s, p->devep)) {
- /* Setup ISOC transfer */
- urb->type = USBDEVFS_URB_TYPE_ISO;
- urb->flags = USBDEVFS_URB_ISO_ASAP;
- urb->number_of_packets = 1;
- urb->iso_frame_desc[0].length = p->len;
- } else {
- /* Setup bulk transfer */
- urb->type = USBDEVFS_URB_TYPE_BULK;
- }
-
- urb->usercontext = s;
-
- ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
-
- dprintf("husb: data submit. ep 0x%x len %u aurb %p\n", urb->endpoint, p->len, aurb);
-
- if (ret < 0) {
- dprintf("husb: submit failed. errno %d\n", errno);
- async_free(aurb);
-
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- case EPIPE:
- default:
- return USB_RET_STALL;
- }
- }
-
- usb_defer_packet(p, async_cancel, aurb);
- return USB_RET_ASYNC;
-}
-
-static int ctrl_error(void)
-{
- if (errno == ETIMEDOUT)
- return USB_RET_NAK;
- else
- return USB_RET_STALL;
-}
-
-static int usb_host_set_address(USBHostDevice *s, int addr)
-{
- dprintf("husb: ctrl set addr %u\n", addr);
- s->dev.addr = addr;
- return 0;
-}
-
-static int usb_host_set_config(USBHostDevice *s, int config)
-{
- usb_host_release_interfaces(s);
-
- int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
-
- dprintf("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
-
- if (ret < 0)
- return ctrl_error();
-
- usb_host_claim_interfaces(s, config);
- return 0;
-}
-
-static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
-{
- struct usbdevfs_setinterface si;
- int ret;
-
- si.interface = iface;
- si.altsetting = alt;
- ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
-
- dprintf("husb: ctrl set iface %d altset %d ret %d errno %d\n",
- iface, alt, ret, errno);
-
- if (ret < 0)
- return ctrl_error();
-
- usb_linux_update_endp_table(s);
- return 0;
-}
-
-static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
-{
- struct usbdevfs_urb *urb;
- AsyncURB *aurb;
- int ret, value, index;
-
- /*
- * Process certain standard device requests.
- * These are infrequent and are processed synchronously.
- */
- value = le16_to_cpu(s->ctrl.req.wValue);
- index = le16_to_cpu(s->ctrl.req.wIndex);
-
- dprintf("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
- s->ctrl.req.bRequestType, s->ctrl.req.bRequest, value, index,
- s->ctrl.len);
-
- if (s->ctrl.req.bRequestType == 0) {
- switch (s->ctrl.req.bRequest) {
- case USB_REQ_SET_ADDRESS:
- return usb_host_set_address(s, value);
-
- case USB_REQ_SET_CONFIGURATION:
- return usb_host_set_config(s, value & 0xff);
- }
- }
-
- if (s->ctrl.req.bRequestType == 1 &&
- s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE)
- return usb_host_set_interface(s, index, value);
-
- /* The rest are asynchronous */
-
- aurb = async_alloc();
- if (!aurb) {
- dprintf("husb: async malloc failed\n");
- return USB_RET_NAK;
- }
- aurb->hdev = s;
- aurb->packet = p;
-
- /*
- * Setup ctrl transfer.
- *
- * s->ctrl is layed out such that data buffer immediately follows
- * 'req' struct which is exactly what usbdevfs expects.
- */
- urb = &aurb->urb;
-
- urb->type = USBDEVFS_URB_TYPE_CONTROL;
- urb->endpoint = p->devep;
-
- urb->buffer = &s->ctrl.req;
- urb->buffer_length = 8 + s->ctrl.len;
-
- urb->usercontext = s;
-
- ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
-
- dprintf("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
-
- if (ret < 0) {
- dprintf("husb: submit failed. errno %d\n", errno);
- async_free(aurb);
-
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- case EPIPE:
- default:
- return USB_RET_STALL;
- }
- }
-
- usb_defer_packet(p, async_cancel, aurb);
- return USB_RET_ASYNC;
-}
-
-static int do_token_setup(USBDevice *dev, USBPacket *p)
-{
- USBHostDevice *s = (USBHostDevice *) dev;
- int ret = 0;
-
- if (p->len != 8)
- return USB_RET_STALL;
-
- memcpy(&s->ctrl.req, p->data, 8);
- s->ctrl.len = le16_to_cpu(s->ctrl.req.wLength);
- s->ctrl.offset = 0;
- s->ctrl.state = CTRL_STATE_SETUP;
-
- if (s->ctrl.req.bRequestType & USB_DIR_IN) {
- ret = usb_host_handle_control(s, p);
- if (ret < 0)
- return ret;
-
- if (ret < s->ctrl.len)
- s->ctrl.len = ret;
- s->ctrl.state = CTRL_STATE_DATA;
- } else {
- if (s->ctrl.len == 0)
- s->ctrl.state = CTRL_STATE_ACK;
- else
- s->ctrl.state = CTRL_STATE_DATA;
- }
-
- return ret;
-}
-
-static int do_token_in(USBDevice *dev, USBPacket *p)
-{
- USBHostDevice *s = (USBHostDevice *) dev;
- int ret = 0;
-
- if (p->devep != 0)
- return usb_host_handle_data(s, p);
-
- switch(s->ctrl.state) {
- case CTRL_STATE_ACK:
- if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
- ret = usb_host_handle_control(s, p);
- if (ret == USB_RET_ASYNC)
- return USB_RET_ASYNC;
-
- s->ctrl.state = CTRL_STATE_IDLE;
- return ret > 0 ? 0 : ret;
- }
-
- return 0;
-
- case CTRL_STATE_DATA:
- if (s->ctrl.req.bRequestType & USB_DIR_IN) {
- int len = s->ctrl.len - s->ctrl.offset;
- if (len > p->len)
- len = p->len;
- memcpy(p->data, s->ctrl.buffer + s->ctrl.offset, len);
- s->ctrl.offset += len;
- if (s->ctrl.offset >= s->ctrl.len)
- s->ctrl.state = CTRL_STATE_ACK;
- return len;
- }
-
- s->ctrl.state = CTRL_STATE_IDLE;
- return USB_RET_STALL;
-
- default:
- return USB_RET_STALL;
- }
-}
-
-static int do_token_out(USBDevice *dev, USBPacket *p)
-{
- USBHostDevice *s = (USBHostDevice *) dev;
-
- if (p->devep != 0)
- return usb_host_handle_data(s, p);
-
- switch(s->ctrl.state) {
- case CTRL_STATE_ACK:
- if (s->ctrl.req.bRequestType & USB_DIR_IN) {
- s->ctrl.state = CTRL_STATE_IDLE;
- /* transfer OK */
- } else {
- /* ignore additional output */
- }
- return 0;
-
- case CTRL_STATE_DATA:
- if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
- int len = s->ctrl.len - s->ctrl.offset;
- if (len > p->len)
- len = p->len;
- memcpy(s->ctrl.buffer + s->ctrl.offset, p->data, len);
- s->ctrl.offset += len;
- if (s->ctrl.offset >= s->ctrl.len)
- s->ctrl.state = CTRL_STATE_ACK;
- return len;
- }
-
- s->ctrl.state = CTRL_STATE_IDLE;
- return USB_RET_STALL;
-
- default:
- return USB_RET_STALL;
- }
-}
-
-/*
- * Packet handler.
- * Called by the HC (host controller).
- *
- * Returns length of the transaction or one of the USB_RET_XXX codes.
- */
-static int usb_host_handle_packet(USBDevice *s, USBPacket *p)
-{
- switch(p->pid) {
- case USB_MSG_ATTACH:
- s->state = USB_STATE_ATTACHED;
- return 0;
-
- case USB_MSG_DETACH:
- s->state = USB_STATE_NOTATTACHED;
- return 0;
-
- case USB_MSG_RESET:
- s->remote_wakeup = 0;
- s->addr = 0;
- s->state = USB_STATE_DEFAULT;
- s->handle_reset(s);
- return 0;
- }
-
- /* Rest of the PIDs must match our address */
- if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
- return USB_RET_NODEV;
-
- switch (p->pid) {
- case USB_TOKEN_SETUP:
- return do_token_setup(s, p);
-
- case USB_TOKEN_IN:
- return do_token_in(s, p);
-
- case USB_TOKEN_OUT:
- return do_token_out(s, p);
-
- default:
- return USB_RET_STALL;
- }
-}
-
-/* returns 1 on problem encountered or 0 for success */
-static int usb_linux_update_endp_table(USBHostDevice *s)
-{
- uint8_t *descriptors;
- uint8_t devep, type, configuration, alt_interface;
- struct usbdevfs_ctrltransfer ct;
- int interface, ret, length, i;
-
- ct.bRequestType = USB_DIR_IN;
- ct.bRequest = USB_REQ_GET_CONFIGURATION;
- ct.wValue = 0;
- ct.wIndex = 0;
- ct.wLength = 1;
- ct.data = &configuration;
- ct.timeout = 50;
-
- ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
- if (ret < 0) {
- perror("usb_linux_update_endp_table");
- return 1;
- }
-
- /* in address state */
- if (configuration == 0)
- return 1;
-
- /* get the desired configuration, interface, and endpoint descriptors
- * from device description */
- descriptors = &s->descr[18];
- length = s->descr_len - 18;
- i = 0;
-
- if (descriptors[i + 1] != USB_DT_CONFIG ||
- descriptors[i + 5] != configuration) {
- dprintf("invalid descriptor data - configuration\n");
- return 1;
- }
- i += descriptors[i];
-
- while (i < length) {
- if (descriptors[i + 1] != USB_DT_INTERFACE ||
- (descriptors[i + 1] == USB_DT_INTERFACE &&
- descriptors[i + 4] == 0)) {
- i += descriptors[i];
- continue;
- }
-
- interface = descriptors[i + 2];
-
- ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
- ct.bRequest = USB_REQ_GET_INTERFACE;
- ct.wValue = 0;
- ct.wIndex = interface;
- ct.wLength = 1;
- ct.data = &alt_interface;
- ct.timeout = 50;
-
- ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
- if (ret < 0) {
- perror("usb_linux_update_endp_table");
- return 1;
- }
-
- /* the current interface descriptor is the active interface
- * and has endpoints */
- if (descriptors[i + 3] != alt_interface) {
- i += descriptors[i];
- continue;
- }
-
- /* advance to the endpoints */
- while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
- i += descriptors[i];
-
- if (i >= length)
- break;
-
- while (i < length) {
- if (descriptors[i + 1] != USB_DT_ENDPOINT)
- break;
-
- devep = descriptors[i + 2];
- switch (descriptors[i + 3] & 0x3) {
- case 0x00:
- type = USBDEVFS_URB_TYPE_CONTROL;
- break;
- case 0x01:
- type = USBDEVFS_URB_TYPE_ISO;
- break;
- case 0x02:
- type = USBDEVFS_URB_TYPE_BULK;
- break;
- case 0x03:
- type = USBDEVFS_URB_TYPE_INTERRUPT;
- break;
- default:
- dprintf("usb_host: malformed endpoint type\n");
- type = USBDEVFS_URB_TYPE_BULK;
- }
- s->endp_table[(devep & 0xf) - 1].type = type;
- s->endp_table[(devep & 0xf) - 1].halted = 0;
-
- i += descriptors[i];
- }
- }
- return 0;
-}
-
-static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
-{
- int fd = -1, ret;
- USBHostDevice *dev = NULL;
- struct usbdevfs_connectinfo ci;
- char buf[1024];
-
- dev = qemu_mallocz(sizeof(USBHostDevice));
- if (!dev)
- goto fail;
-
- dev->bus_num = bus_num;
- dev->addr = addr;
-
- printf("husb: open device %d.%d\n", bus_num, addr);
-
- snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
- bus_num, addr);
- fd = open(buf, O_RDWR | O_NONBLOCK);
- if (fd < 0) {
- perror(buf);
- goto fail;
- }
-
- /* read the device description */
- dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
- if (dev->descr_len <= 0) {
- perror("husb: reading device data failed");
- goto fail;
- }
-
-#ifdef DEBUG
- {
- int x;
- printf("=== begin dumping device descriptor data ===\n");
- for (x = 0; x < dev->descr_len; x++)
- printf("%02x ", dev->descr[x]);
- printf("\n=== end dumping device descriptor data ===\n");
- }
-#endif
-
- dev->fd = fd;
-
- /*
- * Initial configuration is -1 which makes us claim first
- * available config. We used to start with 1, which does not
- * always work. I've seen devices where first config starts
- * with 2.
- */
- if (!usb_host_claim_interfaces(dev, -1))
- goto fail;
-
- ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
- if (ret < 0) {
- perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
- goto fail;
- }
-
- printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
-
- ret = usb_linux_update_endp_table(dev);
- if (ret)
- goto fail;
-
- if (ci.slow)
- dev->dev.speed = USB_SPEED_LOW;
- else
- dev->dev.speed = USB_SPEED_HIGH;
-
- dev->dev.handle_packet = usb_host_handle_packet;
- dev->dev.handle_reset = usb_host_handle_reset;
- dev->dev.handle_destroy = usb_host_handle_destroy;
-
- if (!prod_name || prod_name[0] == '\0')
- snprintf(dev->dev.devname, sizeof(dev->dev.devname),
- "host:%d.%d", bus_num, addr);
- else
- pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
- prod_name);
-
- /* USB devio uses 'write' flag to check for async completions */
- qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
-
- hostdev_link(dev);
-
- return (USBDevice *) dev;
-
-fail:
- if (dev)
- qemu_free(dev);
-
- close(fd);
- return NULL;
-}
-
-static int usb_host_auto_add(const char *spec);
-static int usb_host_auto_del(const char *spec);
-
-USBDevice *usb_host_device_open(const char *devname)
-{
- int bus_num, addr;
- char product_name[PRODUCT_NAME_SZ];
-
- if (strstr(devname, "auto:")) {
- usb_host_auto_add(devname);
- return NULL;
- }
-
- if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
- devname) < 0)
- return NULL;
-
- if (hostdev_find(bus_num, addr)) {
- term_printf("husb: host usb device %d.%d is already open\n", bus_num, addr);
- return NULL;
- }
-
- return usb_host_device_open_addr(bus_num, addr, product_name);
-}
-
-int usb_host_device_close(const char *devname)
-{
- char product_name[PRODUCT_NAME_SZ];
- int bus_num, addr;
- USBHostDevice *s;
-
- if (strstr(devname, "auto:"))
- return usb_host_auto_del(devname);
-
- if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
- devname) < 0)
- return -1;
-
- s = hostdev_find(bus_num, addr);
- if (s) {
- usb_device_del_addr(0, s->dev.addr);
- return 0;
- }
-
- return -1;
-}
-
-static int get_tag_value(char *buf, int buf_size,
- const char *str, const char *tag,
- const char *stopchars)
-{
- const char *p;
- char *q;
- p = strstr(str, tag);
- if (!p)
- return -1;
- p += strlen(tag);
- while (isspace(*p))
- p++;
- q = buf;
- while (*p != '\0' && !strchr(stopchars, *p)) {
- if ((q - buf) < (buf_size - 1))
- *q++ = *p;
- p++;
- }
- *q = '\0';
- return q - buf;
-}
-
-static int usb_host_scan(void *opaque, USBScanFunc *func)
-{
- FILE *f;
- char line[1024];
- char buf[1024];
- int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
- int ret;
- char product_name[512];
-
- f = fopen(USBDEVFS_PATH "/devices", "r");
- if (!f) {
- term_printf("husb: could not open %s\n", USBDEVFS_PATH "/devices");
- return 0;
- }
- device_count = 0;
- bus_num = addr = speed = class_id = product_id = vendor_id = 0;
- ret = 0;
- for(;;) {
- if (fgets(line, sizeof(line), f) == NULL)
- break;
- if (strlen(line) > 0)
- line[strlen(line) - 1] = '\0';
- if (line[0] == 'T' && line[1] == ':') {
- if (device_count && (vendor_id || product_id)) {
- /* New device. Add the previously discovered device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
- if (ret)
- goto the_end;
- }
- if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
- goto fail;
- bus_num = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
- goto fail;
- addr = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
- goto fail;
- if (!strcmp(buf, "480"))
- speed = USB_SPEED_HIGH;
- else if (!strcmp(buf, "1.5"))
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- product_name[0] = '\0';
- class_id = 0xff;
- device_count++;
- product_id = 0;
- vendor_id = 0;
- } else if (line[0] == 'P' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
- goto fail;
- vendor_id = strtoul(buf, NULL, 16);
- if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
- goto fail;
- product_id = strtoul(buf, NULL, 16);
- } else if (line[0] == 'S' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
- goto fail;
- pstrcpy(product_name, sizeof(product_name), buf);
- } else if (line[0] == 'D' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
- goto fail;
- class_id = strtoul(buf, NULL, 16);
- }
- fail: ;
- }
- if (device_count && (vendor_id || product_id)) {
- /* Add the last device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
- }
- the_end:
- fclose(f);
- return ret;
-}
-
-struct USBAutoFilter {
- struct USBAutoFilter *next;
- int bus_num;
- int addr;
- int vendor_id;
- int product_id;
-};
-
-static QEMUTimer *usb_auto_timer;
-static struct USBAutoFilter *usb_auto_filter;
-
-static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
- int class_id, int vendor_id, int product_id,
- const char *product_name, int speed)
-{
- struct USBAutoFilter *f;
- struct USBDevice *dev;
-
- /* Ignore hubs */
- if (class_id == 9)
- return 0;
-
- for (f = usb_auto_filter; f; f = f->next) {
- if (f->bus_num >= 0 && f->bus_num != bus_num)
- continue;
-
- if (f->addr >= 0 && f->addr != addr)
- continue;
-
- if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
- continue;
-
- if (f->product_id >= 0 && f->product_id != product_id)
- continue;
-
- /* We got a match */
-
- /* Allredy attached ? */
- if (hostdev_find(bus_num, addr))
- return 0;
-
- dprintf("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
-
- dev = usb_host_device_open_addr(bus_num, addr, product_name);
- if (dev)
- usb_device_add_dev(dev);
- }
-
- return 0;
-}
-
-static void usb_host_auto_timer(void *unused)
-{
- usb_host_scan(NULL, usb_host_auto_scan);
- qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
-}
-
-/*
- * Autoconnect filter
- * Format:
- * auto:bus:dev[:vid:pid]
- * auto:bus.dev[:vid:pid]
- *
- * bus - bus number (dec, * means any)
- * dev - device number (dec, * means any)
- * vid - vendor id (hex, * means any)
- * pid - product id (hex, * means any)
- *
- * See 'lsusb' output.
- */
-static int parse_filter(const char *spec, struct USBAutoFilter *f)
-{
- enum { BUS, DEV, VID, PID, DONE };
- const char *p = spec;
- int i;
-
- f->bus_num = -1;
- f->addr = -1;
- f->vendor_id = -1;
- f->product_id = -1;
-
- for (i = BUS; i < DONE; i++) {
- p = strpbrk(p, ":.");
- if (!p) break;
- p++;
-
- if (*p == '*')
- continue;
-
- switch(i) {
- case BUS: f->bus_num = strtol(p, NULL, 10); break;
- case DEV: f->addr = strtol(p, NULL, 10); break;
- case VID: f->vendor_id = strtol(p, NULL, 16); break;
- case PID: f->product_id = strtol(p, NULL, 16); break;
- }
- }
-
- if (i < DEV) {
- fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
- return -1;
- }
-
- return 0;
-}
-
-static int match_filter(const struct USBAutoFilter *f1,
- const struct USBAutoFilter *f2)
-{
- return f1->bus_num == f2->bus_num &&
- f1->addr == f2->addr &&
- f1->vendor_id == f2->vendor_id &&
- f1->product_id == f2->product_id;
-}
-
-static int usb_host_auto_add(const char *spec)
-{
- struct USBAutoFilter filter, *f;
-
- if (parse_filter(spec, &filter) < 0)
- return -1;
-
- f = qemu_mallocz(sizeof(*f));
- if (!f) {
- fprintf(stderr, "husb: failed to allocate auto filter\n");
- return -1;
- }
-
- *f = filter;
-
- if (!usb_auto_filter) {
- /*
- * First entry. Init and start the monitor.
- * Right now we're using timer to check for new devices.
- * If this turns out to be too expensive we can move that into a
- * separate thread.
- */
- usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
- if (!usb_auto_timer) {
- fprintf(stderr, "husb: failed to allocate auto scan timer\n");
- qemu_free(f);
- return -1;
- }
-
- /* Check for new devices every two seconds */
- qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
- }
-
- dprintf("husb: added auto filter: bus_num %d addr %d vid %d pid %d\n",
- f->bus_num, f->addr, f->vendor_id, f->product_id);
-
- f->next = usb_auto_filter;
- usb_auto_filter = f;
-
- return 0;
-}
-
-static int usb_host_auto_del(const char *spec)
-{
- struct USBAutoFilter *pf = usb_auto_filter;
- struct USBAutoFilter **prev = &usb_auto_filter;
- struct USBAutoFilter filter;
-
- if (parse_filter(spec, &filter) < 0)
- return -1;
-
- while (pf) {
- if (match_filter(pf, &filter)) {
- dprintf("husb: removed auto filter: bus_num %d addr %d vid %d pid %d\n",
- pf->bus_num, pf->addr, pf->vendor_id, pf->product_id);
-
- *prev = pf->next;
-
- if (!usb_auto_filter) {
- /* No more filters. Stop scanning. */
- qemu_del_timer(usb_auto_timer);
- qemu_free_timer(usb_auto_timer);
- }
-
- return 0;
- }
-
- prev = &pf->next;
- pf = pf->next;
- }
-
- return -1;
-}
-
-typedef struct FindDeviceState {
- int vendor_id;
- int product_id;
- int bus_num;
- int addr;
- char product_name[PRODUCT_NAME_SZ];
-} FindDeviceState;
-
-static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed)
-{
- FindDeviceState *s = opaque;
- if ((vendor_id == s->vendor_id &&
- product_id == s->product_id) ||
- (bus_num == s->bus_num &&
- addr == s->addr)) {
- pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
- s->bus_num = bus_num;
- s->addr = addr;
- return 1;
- } else {
- return 0;
- }
-}
-
-/* the syntax is :
- 'bus.addr' (decimal numbers) or
- 'vendor_id:product_id' (hexa numbers) */
-static int usb_host_find_device(int *pbus_num, int *paddr,
- char *product_name, int product_name_size,
- const char *devname)
-{
- const char *p;
- int ret;
- FindDeviceState fs;
-
- p = strchr(devname, '.');
- if (p) {
- *pbus_num = strtoul(devname, NULL, 0);
- *paddr = strtoul(p + 1, NULL, 0);
- fs.bus_num = *pbus_num;
- fs.addr = *paddr;
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret)
- pstrcpy(product_name, product_name_size, fs.product_name);
- return 0;
- }
-
- p = strchr(devname, ':');
- if (p) {
- fs.vendor_id = strtoul(devname, NULL, 16);
- fs.product_id = strtoul(p + 1, NULL, 16);
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret) {
- *pbus_num = fs.bus_num;
- *paddr = fs.addr;
- pstrcpy(product_name, product_name_size, fs.product_name);
- return 0;
- }
- }
- return -1;
-}
-
-/**********************/
-/* USB host device info */
-
-struct usb_class_info {
- int class;
- const char *class_name;
-};
-
-static const struct usb_class_info usb_class_info[] = {
- { USB_CLASS_AUDIO, "Audio"},
- { USB_CLASS_COMM, "Communication"},
- { USB_CLASS_HID, "HID"},
- { USB_CLASS_HUB, "Hub" },
- { USB_CLASS_PHYSICAL, "Physical" },
- { USB_CLASS_PRINTER, "Printer" },
- { USB_CLASS_MASS_STORAGE, "Storage" },
- { USB_CLASS_CDC_DATA, "Data" },
- { USB_CLASS_APP_SPEC, "Application Specific" },
- { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
- { USB_CLASS_STILL_IMAGE, "Still Image" },
- { USB_CLASS_CSCID, "Smart Card" },
- { USB_CLASS_CONTENT_SEC, "Content Security" },
- { -1, NULL }
-};
-
-static const char *usb_class_str(uint8_t class)
-{
- const struct usb_class_info *p;
- for(p = usb_class_info; p->class != -1; p++) {
- if (p->class == class)
- break;
- }
- return p->class_name;
-}
-
-static void usb_info_device(int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- const char *class_str, *speed_str;
-
- switch(speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
-
- term_printf(" Device %d.%d, speed %s Mb/s\n",
- bus_num, addr, speed_str);
- class_str = usb_class_str(class_id);
- if (class_str)
- term_printf(" %s:", class_str);
- else
- term_printf(" Class %02x:", class_id);
- term_printf(" USB device %04x:%04x", vendor_id, product_id);
- if (product_name[0] != '\0')
- term_printf(", %s", product_name);
- term_printf("\n");
-}
-
-static int usb_host_info_device(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
- product_name, speed);
- return 0;
-}
-
-static void dec2str(int val, char *str)
-{
- if (val == -1)
- strcpy(str, "*");
- else
- sprintf(str, "%d", val);
-}
-
-static void hex2str(int val, char *str)
-{
- if (val == -1)
- strcpy(str, "*");
- else
- sprintf(str, "%x", val);
-}
-
-void usb_host_info(void)
-{
- struct USBAutoFilter *f;
-
- usb_host_scan(NULL, usb_host_info_device);
-
- if (usb_auto_filter)
- term_printf(" Auto filters:\n");
- for (f = usb_auto_filter; f; f = f->next) {
- char bus[10], addr[10], vid[10], pid[10];
- dec2str(f->bus_num, bus);
- dec2str(f->addr, addr);
- hex2str(f->vendor_id, vid);
- hex2str(f->product_id, pid);
- term_printf(" Device %s.%s ID %s:%s\n", bus, addr, vid, pid);
- }
-}
-
-#else
-
-#include "hw/usb.h"
-
-void usb_host_info(void)
-{
- term_printf("USB host devices not supported\n");
-}
-
-/* XXX: modify configure to compile the right host driver */
-USBDevice *usb_host_device_open(const char *devname)
-{
- return NULL;
-}
-
-int usb_host_device_close(const char *devname)
-{
- return 0;
-}
-
-#endif
diff --git a/varint.c b/varint.c
deleted file mode 100644
index 41f6c67..0000000
--- a/varint.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include <inttypes.h>
-#include "varint.h"
-
-// Define some constants for powers of two.
-static const int k2Exp6 = 64;
-static const uint32_t k2Exp7 = 128;
-static const int k2Exp13 = 8192;
-static const uint32_t k2Exp14 = 16384;
-static const int k2Exp20 = (1 * 1024 * 1024);
-static const uint32_t k2Exp21 = (2 * 1024 * 1024);
-static const int k2Exp27 = (128 * 1024 * 1024);
-static const uint32_t k2Exp28 = (256 * 1024 * 1024);
-static const uint64_t k2Exp35 = (32LL * 1024LL * 1024LL * 1024LL);
-static const uint64_t k2Exp42 = (4LL * 1024LL * 1024LL * 1024LL * 1024LL);
-
-// Encodes the 64-bit value "value" using the varint encoding. The varint
-// encoding uses a prefix followed by some data bits. The valid prefixes
-// and the number of data bits are given in the table below.
-//
-// Prefix Bytes Data bits
-// 0 1 7
-// 10 2 14
-// 110 3 21
-// 1110 4 28
-// 11110 5 35
-// 111110 6 42
-// 11111100 9 64
-// 11111101 reserved
-// 11111110 reserved
-// 11111111 reserved
-char *varint_encode(uint64_t value, char *buf) {
- if (value < k2Exp7) {
- *buf++ = value;
- } else if (value < k2Exp14) {
- *buf++ = (2 << 6) | (value >> 8);
- *buf++ = value & 0xff;
- } else if (value < k2Exp21) {
- *buf++ = (6 << 5) | (value >> 16);
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- } else if (value < k2Exp28) {
- *buf++ = (0xe << 4) | (value >> 24);
- *buf++ = (value >> 16) & 0xff;
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- } else if (value < k2Exp35) {
- *buf++ = (0x1e << 3) | (value >> 32);
- *buf++ = (value >> 24) & 0xff;
- *buf++ = (value >> 16) & 0xff;
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- } else if (value < k2Exp42) {
- *buf++ = (0x3e << 2) | (value >> 40);
- *buf++ = (value >> 32) & 0xff;
- *buf++ = (value >> 24) & 0xff;
- *buf++ = (value >> 16) & 0xff;
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- } else {
- *buf++ = (0x7e << 1);
- *buf++ = (value >> 56) & 0xff;
- *buf++ = (value >> 48) & 0xff;
- *buf++ = (value >> 40) & 0xff;
- *buf++ = (value >> 32) & 0xff;
- *buf++ = (value >> 24) & 0xff;
- *buf++ = (value >> 16) & 0xff;
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- }
- return buf;
-}
-
-// Encodes the 35-bit signed value "value" using the varint encoding.
-// The varint encoding uses a prefix followed by some data bits. The
-// valid prefixes and the number of data bits is given in the table
-// below.
-//
-// Prefix Bytes Data bits
-// 0 1 7
-// 10 2 14
-// 110 3 21
-// 1110 4 28
-// 11110 5 35
-char *varint_encode_signed(int64_t value, char *buf) {
- if (value < k2Exp6 && value >= -k2Exp6) {
- *buf++ = value & 0x7f;
- } else if (value < k2Exp13 && value >= -k2Exp13) {
- *buf++ = (2 << 6) | ((value >> 8) & 0x3f);
- *buf++ = value & 0xff;
- } else if (value < k2Exp20 && value >= -k2Exp20) {
- *buf++ = (6 << 5) | ((value >> 16) & 0x1f);
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- } else if (value < k2Exp27 && value >= -k2Exp27) {
- *buf++ = (0xe << 4) | ((value >> 24) & 0xf);
- *buf++ = (value >> 16) & 0xff;
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- } else {
- *buf++ = (0x1e << 3);
- *buf++ = (value >> 24) & 0xff;
- *buf++ = (value >> 16) & 0xff;
- *buf++ = (value >> 8) & 0xff;
- *buf++ = value & 0xff;
- }
- return buf;
-}
diff --git a/varint.h b/varint.h
deleted file mode 100644
index 7822756..0000000
--- a/varint.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Copyright (C) 2007-2008 The Android Open Source Project
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-*/
-#include <inttypes.h>
-
-extern char *varint_encode(uint64_t value, char *buf);
-extern char *varint_encode_signed(int64_t value, char *buf);
diff --git a/vgafont.h b/vgafont.h
deleted file mode 100644
index 3606dd7..0000000
--- a/vgafont.h
+++ /dev/null
@@ -1,4611 +0,0 @@
-static const uint8_t vgafont16[256 * 16] = {
-
- /* 0 0x00 '^@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 1 0x01 '^A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x81, /* 10000001 */
- 0xa5, /* 10100101 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 2 0x02 '^B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xdb, /* 11011011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 3 0x03 '^C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 4 0x04 '^D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 5 0x05 '^E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 6 0x06 '^F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 7 0x07 '^G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 8 0x08 '^H' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xe7, /* 11100111 */
- 0xc3, /* 11000011 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 9 0x09 '^I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x42, /* 01000010 */
- 0x42, /* 01000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 10 0x0a '^J' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0x99, /* 10011001 */
- 0xbd, /* 10111101 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0xc3, /* 11000011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 11 0x0b '^K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x1a, /* 00011010 */
- 0x32, /* 00110010 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 12 0x0c '^L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 13 0x0d '^M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x33, /* 00110011 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x70, /* 01110000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 14 0x0e '^N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x67, /* 01100111 */
- 0xe7, /* 11100111 */
- 0xe6, /* 11100110 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 15 0x0f '^O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xdb, /* 11011011 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0x3c, /* 00111100 */
- 0xdb, /* 11011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 16 0x10 '^P' */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0xf0, /* 11110000 */
- 0xf8, /* 11111000 */
- 0xfe, /* 11111110 */
- 0xf8, /* 11111000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 17 0x11 '^Q' */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0e, /* 00001110 */
- 0x1e, /* 00011110 */
- 0x3e, /* 00111110 */
- 0xfe, /* 11111110 */
- 0x3e, /* 00111110 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 18 0x12 '^R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 19 0x13 '^S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 20 0x14 '^T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7b, /* 01111011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 21 0x15 '^U' */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 22 0x16 '^V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 23 0x17 '^W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 24 0x18 '^X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 25 0x19 '^Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 26 0x1a '^Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 27 0x1b '^[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xfe, /* 11111110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 28 0x1c '^\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 29 0x1d '^]' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x28, /* 00101000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x28, /* 00101000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 30 0x1e '^^' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 31 0x1f '^_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 32 0x20 ' ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 33 0x21 '!' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 34 0x22 '"' */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x24, /* 00100100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 35 0x23 '#' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 36 0x24 '$' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x86, /* 10000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 37 0x25 '%' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 38 0x26 '&' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 39 0x27 ''' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 40 0x28 '(' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 41 0x29 ')' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 42 0x2a '*' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0xff, /* 11111111 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 43 0x2b '+' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 44 0x2c ',' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 45 0x2d '-' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 46 0x2e '.' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 47 0x2f '/' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 48 0x30 '0' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 49 0x31 '1' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x38, /* 00111000 */
- 0x78, /* 01111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 50 0x32 '2' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 51 0x33 '3' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x3c, /* 00111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 52 0x34 '4' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x1c, /* 00011100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 53 0x35 '5' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 54 0x36 '6' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 55 0x37 '7' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 56 0x38 '8' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 57 0x39 '9' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 58 0x3a ':' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 59 0x3b ';' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 60 0x3c '<' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 61 0x3d '=' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 62 0x3e '>' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 63 0x3f '?' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 64 0x40 '@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xdc, /* 11011100 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 65 0x41 'A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 66 0x42 'B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 67 0x43 'C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 68 0x44 'D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 69 0x45 'E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 70 0x46 'F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 71 0x47 'G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xde, /* 11011110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x66, /* 01100110 */
- 0x3a, /* 00111010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 72 0x48 'H' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 73 0x49 'I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 74 0x4a 'J' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 75 0x4b 'K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe6, /* 11100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 76 0x4c 'L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 77 0x4d 'M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xee, /* 11101110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 78 0x4e 'N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 79 0x4f 'O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 80 0x50 'P' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 81 0x51 'Q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xde, /* 11011110 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 82 0x52 'R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 83 0x53 'S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 84 0x54 'T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x5a, /* 01011010 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 85 0x55 'U' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 86 0x56 'V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 87 0x57 'W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0xee, /* 11101110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 88 0x58 'X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 89 0x59 'Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 90 0x5a 'Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 91 0x5b '[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 92 0x5c '\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0x70, /* 01110000 */
- 0x38, /* 00111000 */
- 0x1c, /* 00011100 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 93 0x5d ']' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 94 0x5e '^' */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 95 0x5f '_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 96 0x60 '`' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 97 0x61 'a' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 98 0x62 'b' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 99 0x63 'c' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 100 0x64 'd' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 101 0x65 'e' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 102 0x66 'f' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x36, /* 00110110 */
- 0x32, /* 00110010 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 103 0x67 'g' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 104 0x68 'h' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x6c, /* 01101100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 105 0x69 'i' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 106 0x6a 'j' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
-
- /* 107 0x6b 'k' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 108 0x6c 'l' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 109 0x6d 'm' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 110 0x6e 'n' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 111 0x6f 'o' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 112 0x70 'p' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
-
- /* 113 0x71 'q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
-
- /* 114 0x72 'r' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 115 0x73 's' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 116 0x74 't' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0xfc, /* 11111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x36, /* 00110110 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 117 0x75 'u' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 118 0x76 'v' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 119 0x77 'w' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 120 0x78 'x' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 121 0x79 'y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
-
- /* 122 0x7a 'z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 123 0x7b '{' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 124 0x7c '|' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 125 0x7d '}' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 126 0x7e '~' */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 127 0x7f '' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 128 0x80 '€' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 129 0x81 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 130 0x82 '‚' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 131 0x83 'ƒ' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 132 0x84 '„' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 133 0x85 'Â…' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 134 0x86 '†' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 135 0x87 '‡' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 136 0x88 'ˆ' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 137 0x89 '‰' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 138 0x8a 'Š' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 139 0x8b '‹' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 140 0x8c 'Œ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 141 0x8d 'Â' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 142 0x8e 'ÂŽ' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 143 0x8f 'Â' */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 144 0x90 'Â' */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 145 0x91 '‘' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x6e, /* 01101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 146 0x92 'Â’' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3e, /* 00111110 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xce, /* 11001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 147 0x93 '“' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 148 0x94 '”' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 149 0x95 '•' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 150 0x96 '–' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 151 0x97 '—' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 152 0x98 '˜' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 153 0x99 '™' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 154 0x9a 'š' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 155 0x9b '›' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 156 0x9c 'œ' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x64, /* 01100100 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xe6, /* 11100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 157 0x9d 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 158 0x9e 'ž' */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xf8, /* 11111000 */
- 0xc4, /* 11000100 */
- 0xcc, /* 11001100 */
- 0xde, /* 11011110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 159 0x9f 'Ÿ' */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 160 0xa0 ' ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 161 0xa1 '¡' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 162 0xa2 '¢' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 163 0xa3 '£' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 164 0xa4 '¤' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 165 0xa5 'Â¥' */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 166 0xa6 '¦' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 167 0xa7 '§' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 168 0xa8 '¨' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 169 0xa9 '©' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 170 0xaa 'ª' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 171 0xab '«' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xdc, /* 11011100 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 172 0xac '¬' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x66, /* 01100110 */
- 0xce, /* 11001110 */
- 0x9a, /* 10011010 */
- 0x3f, /* 00111111 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 173 0xad '­' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 174 0xae '®' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 175 0xaf '¯' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 176 0xb0 '°' */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
-
- /* 177 0xb1 '±' */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
-
- /* 178 0xb2 '²' */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
-
- /* 179 0xb3 '³' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 180 0xb4 '´' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 181 0xb5 'µ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 182 0xb6 '¶' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 183 0xb7 '·' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 184 0xb8 '¸' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 185 0xb9 '¹' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 186 0xba 'º' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 187 0xbb '»' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 188 0xbc '¼' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 189 0xbd '½' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 190 0xbe '¾' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 191 0xbf '¿' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 192 0xc0 'À' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 193 0xc1 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 194 0xc2 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 195 0xc3 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 196 0xc4 'Ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 197 0xc5 'Ã…' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 198 0xc6 'Æ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 199 0xc7 'Ç' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 200 0xc8 'È' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 201 0xc9 'É' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 202 0xca 'Ê' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 203 0xcb 'Ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 204 0xcc 'Ì' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 205 0xcd 'Ã' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 206 0xce 'ÃŽ' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 207 0xcf 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 208 0xd0 'Ã' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 209 0xd1 'Ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 210 0xd2 'Ã’' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 211 0xd3 'Ó' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 212 0xd4 'Ô' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 213 0xd5 'Õ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 214 0xd6 'Ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 215 0xd7 '×' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 216 0xd8 'Ø' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 217 0xd9 'Ù' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 218 0xda 'Ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 219 0xdb 'Û' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 220 0xdc 'Ü' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 221 0xdd 'Ã' */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
-
- /* 222 0xde 'Þ' */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
-
- /* 223 0xdf 'ß' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 224 0xe0 'à' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 225 0xe1 'á' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xd8, /* 11011000 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 226 0xe2 'â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 227 0xe3 'ã' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 228 0xe4 'ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 229 0xe5 'Ã¥' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 230 0xe6 'æ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
-
- /* 231 0xe7 'ç' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 232 0xe8 'è' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 233 0xe9 'é' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 234 0xea 'ê' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xee, /* 11101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 235 0xeb 'ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x3e, /* 00111110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 236 0xec 'ì' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 237 0xed 'í' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x03, /* 00000011 */
- 0x06, /* 00000110 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xf3, /* 11110011 */
- 0x7e, /* 01111110 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 238 0xee 'î' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 239 0xef 'ï' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 240 0xf0 'ð' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 241 0xf1 'ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 242 0xf2 'ò' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 243 0xf3 'ó' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 244 0xf4 'ô' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 245 0xf5 'õ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 246 0xf6 'ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 247 0xf7 '÷' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 248 0xf8 'ø' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 249 0xf9 'ù' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 250 0xfa 'ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 251 0xfb 'û' */
- 0x00, /* 00000000 */
- 0x0f, /* 00001111 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xec, /* 11101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3c, /* 00111100 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 252 0xfc 'ü' */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 253 0xfd 'ý' */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x32, /* 00110010 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 254 0xfe 'þ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 255 0xff 'ÿ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
-};
diff --git a/vl.c b/vl.c
deleted file mode 100644
index 99c49bf..0000000
--- a/vl.c
+++ /dev/null
@@ -1,9803 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* the following is needed on Linux to define ptsname() in stdlib.h */
-#if defined(__linux__)
-#define _GNU_SOURCE 1
-#endif
-
-#include "qemu-common.h"
-#include "hw/hw.h"
-#include "hw/boards.h"
-#include "hw/usb.h"
-#include "hw/pcmcia.h"
-#include "hw/pc.h"
-#include "hw/audiodev.h"
-#include "hw/isa.h"
-#include "hw/baum.h"
-#include "net.h"
-#include "console.h"
-#include "sysemu.h"
-#include "gdbstub.h"
-#include "qemu-timer.h"
-#include "qemu-char.h"
-#include "block.h"
-#include "audio/audio.h"
-
-#include "qemu_file.h"
-#include "android/android.h"
-#include "charpipe.h"
-#include "shaper.h"
-#include "modem_driver.h"
-#include "android/gps.h"
-#include "android/qemud.h"
-#include "android/hw-kmsg.h"
-#include "tcpdump.h"
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <zlib.h>
-
-#ifndef _WIN32
-#include <sys/times.h>
-#include <sys/wait.h>
-#include <termios.h>
-#include <sys/poll.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <dirent.h>
-#include <netdb.h>
-#include <sys/select.h>
-#include <arpa/inet.h>
-#ifdef _BSD
-#include <sys/stat.h>
-#if !defined(__APPLE__) && !defined(__OpenBSD__)
-#include <libutil.h>
-#endif
-#ifdef __OpenBSD__
-#include <net/if.h>
-#endif
-#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
-#include <freebsd/stdlib.h>
-#else
-#ifndef __sun__
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <pty.h>
-#include <malloc.h>
-#include <linux/rtc.h>
-
-/* For the benefit of older linux systems which don't supply it,
- we use a local copy of hpet.h. */
-/* #include <linux/hpet.h> */
-#include "hpet.h"
-
-#include <linux/ppdev.h>
-#include <linux/parport.h>
-#else
-#include <sys/stat.h>
-#include <sys/ethernet.h>
-#include <sys/sockio.h>
-#include <netinet/arp.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h> // must come after ip.h
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-#include <net/if.h>
-#include <syslog.h>
-#include <stropts.h>
-#endif
-#endif
-#endif
-
-#include "qemu_socket.h"
-
-#if defined(CONFIG_SLIRP)
-#include "libslirp.h"
-#endif
-
-#if defined(__OpenBSD__)
-#include <util.h>
-#endif
-
-#if defined(CONFIG_VDE)
-#include <libvdeplug.h>
-#endif
-
-#ifdef _WIN32
-#include <malloc.h>
-#include <sys/timeb.h>
-#include <mmsystem.h>
-#define getopt_long_only getopt_long
-#define memalign(align, size) malloc(size)
-#endif
-
-
-#ifdef CONFIG_COCOA
-#undef main
-#define main qemu_main
-#endif /* CONFIG_COCOA */
-
-#ifdef CONFIG_SKINS
-#undef main
-#define main qemu_main
-#endif
-
-#include "disas.h"
-
-#include "exec-all.h"
-
-#ifdef CONFIG_TRACE
-#include "trace.h"
-#include "dcache.h"
-#endif
-
-#ifdef CONFIG_NAND
-#include "hw/goldfish_nand.h"
-#endif
-
-#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
-#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
-#ifdef __sun__
-#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
-#else
-#define SMBD_COMMAND "/usr/sbin/smbd"
-#endif
-
-//#define DEBUG_UNUSED_IOPORT
-//#define DEBUG_IOPORT
-
-#ifdef TARGET_PPC
-#define DEFAULT_RAM_SIZE 144
-#else
-#define DEFAULT_RAM_SIZE 128
-#endif
-
-/* Max number of USB devices that can be specified on the commandline. */
-#define MAX_USB_CMDLINE 8
-
-/* XXX: use a two level table to limit memory usage */
-#define MAX_IOPORTS 65536
-
-const char *bios_dir = CONFIG_QEMU_SHAREDIR;
-const char *bios_name = NULL;
-void *ioport_opaque[MAX_IOPORTS];
-IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
-IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
-/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
- to store the VM snapshots */
-DriveInfo drives_table[MAX_DRIVES+1];
-int nb_drives;
-/* point to the block driver where the snapshots are managed */
-BlockDriverState *bs_snapshots;
-int vga_ram_size;
-static DisplayState display_state;
-int nographic;
-int curses;
-const char* keyboard_layout = NULL;
-int64_t ticks_per_sec;
-ram_addr_t ram_size;
-int pit_min_timer_count = 0;
-int nb_nics;
-NICInfo nd_table[MAX_NICS];
-int vm_running;
-static int rtc_utc = 1;
-static int rtc_date_offset = -1; /* -1 means no change */
-int cirrus_vga_enabled = 1;
-int vmsvga_enabled = 0;
-#ifdef TARGET_SPARC
-int graphic_width = 1024;
-int graphic_height = 768;
-int graphic_depth = 8;
-#else
-int graphic_width = 800;
-int graphic_height = 600;
-int graphic_depth = 15;
-#endif
-int full_screen = 0;
-int no_frame = 0;
-int no_quit = 0;
-CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-#ifdef TARGET_I386
-int win2k_install_hack = 0;
-#endif
-int usb_enabled = 0;
-static VLANState *first_vlan;
-int smp_cpus = 1;
-const char *vnc_display;
-#if defined(TARGET_SPARC)
-#define MAX_CPUS 16
-#elif defined(TARGET_I386)
-#define MAX_CPUS 255
-#else
-#define MAX_CPUS 1
-#endif
-int acpi_enabled = 1;
-int fd_bootchk = 1;
-int no_reboot = 0;
-int no_shutdown = 0;
-int cursor_hide = 1;
-int graphic_rotate = 0;
-int daemonize = 0;
-const char *option_rom[MAX_OPTION_ROMS];
-int nb_option_roms;
-int semihosting_enabled = 0;
-int autostart = 1;
-#ifdef TARGET_ARM
-int old_param = 0;
-#endif
-const char *qemu_name;
-int alt_grab = 0;
-#ifdef TARGET_SPARC
-unsigned int nb_prom_envs = 0;
-const char *prom_envs[MAX_PROM_ENVS];
-#endif
-int nb_drives_opt;
-struct drive_opt {
- const char *file;
- char opt[1024];
-} drives_opt[MAX_DRIVES];
-
-static CPUState *cur_cpu;
-static CPUState *next_cpu;
-static int event_pending = 1;
-/* Conversion factor from emulated instructions to virtual clock ticks. */
-static int icount_time_shift;
-/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
-#define MAX_ICOUNT_SHIFT 10
-/* Compensate for varying guest execution speed. */
-static int64_t qemu_icount_bias;
-QEMUTimer *icount_rt_timer;
-QEMUTimer *icount_vm_timer;
-
-
-extern int qemu_cpu_delay;
-extern int android_audio_enabled;
-extern char* audio_input_source;
-
-extern void dprint( const char* format, ... );
-
-#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
-
-/***********************************************************/
-/* x86 ISA bus support */
-
-target_phys_addr_t isa_mem_base = 0;
-PicState2 *isa_pic;
-
-static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
-static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
-
-static uint32_t ioport_read(int index, uint32_t address)
-{
- static IOPortReadFunc *default_func[3] = {
- default_ioport_readb,
- default_ioport_readw,
- default_ioport_readl
- };
- IOPortReadFunc *func = ioport_read_table[index][address];
- if (!func)
- func = default_func[index];
- return func(ioport_opaque[address], address);
-}
-
-static void ioport_write(int index, uint32_t address, uint32_t data)
-{
- static IOPortWriteFunc *default_func[3] = {
- default_ioport_writeb,
- default_ioport_writew,
- default_ioport_writel
- };
- IOPortWriteFunc *func = ioport_write_table[index][address];
- if (!func)
- func = default_func[index];
- func(ioport_opaque[address], address, data);
-}
-
-static uint32_t default_ioport_readb(void *opaque, uint32_t address)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused inb: port=0x%04x\n", address);
-#endif
- return 0xff;
-}
-
-static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
-#endif
-}
-
-/* default is to make two byte accesses */
-static uint32_t default_ioport_readw(void *opaque, uint32_t address)
-{
- uint32_t data;
- data = ioport_read(0, address);
- address = (address + 1) & (MAX_IOPORTS - 1);
- data |= ioport_read(0, address) << 8;
- return data;
-}
-
-static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
-{
- ioport_write(0, address, data & 0xff);
- address = (address + 1) & (MAX_IOPORTS - 1);
- ioport_write(0, address, (data >> 8) & 0xff);
-}
-
-static uint32_t default_ioport_readl(void *opaque, uint32_t address)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused inl: port=0x%04x\n", address);
-#endif
- return 0xffffffff;
-}
-
-static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
-#endif
-}
-
-/* size is the word size in byte */
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque)
-{
- int i, bsize;
-
- if (size == 1) {
- bsize = 0;
- } else if (size == 2) {
- bsize = 1;
- } else if (size == 4) {
- bsize = 2;
- } else {
- hw_error("register_ioport_read: invalid size");
- return -1;
- }
- for(i = start; i < start + length; i += size) {
- ioport_read_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_read: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-}
-
-/* size is the word size in byte */
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque)
-{
- int i, bsize;
-
- if (size == 1) {
- bsize = 0;
- } else if (size == 2) {
- bsize = 1;
- } else if (size == 4) {
- bsize = 2;
- } else {
- hw_error("register_ioport_write: invalid size");
- return -1;
- }
- for(i = start; i < start + length; i += size) {
- ioport_write_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_write: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-}
-
-void isa_unassign_ioport(int start, int length)
-{
- int i;
-
- for(i = start; i < start + length; i++) {
- ioport_read_table[0][i] = default_ioport_readb;
- ioport_read_table[1][i] = default_ioport_readw;
- ioport_read_table[2][i] = default_ioport_readl;
-
- ioport_write_table[0][i] = default_ioport_writeb;
- ioport_write_table[1][i] = default_ioport_writew;
- ioport_write_table[2][i] = default_ioport_writel;
- }
-}
-
-/***********************************************************/
-
-void cpu_outb(CPUState *env, int addr, int val)
-{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outb: %04x %02x\n", addr, val);
-#endif
- ioport_write(0, addr, val);
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-void cpu_outw(CPUState *env, int addr, int val)
-{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outw: %04x %04x\n", addr, val);
-#endif
- ioport_write(1, addr, val);
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-void cpu_outl(CPUState *env, int addr, int val)
-{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outl: %04x %08x\n", addr, val);
-#endif
- ioport_write(2, addr, val);
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
-}
-
-int cpu_inb(CPUState *env, int addr)
-{
- int val;
- val = ioport_read(0, addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inb : %04x %02x\n", addr, val);
-#endif
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
- return val;
-}
-
-int cpu_inw(CPUState *env, int addr)
-{
- int val;
- val = ioport_read(1, addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inw : %04x %04x\n", addr, val);
-#endif
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
- return val;
-}
-
-int cpu_inl(CPUState *env, int addr)
-{
- int val;
- val = ioport_read(2, addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inl : %04x %08x\n", addr, val);
-#endif
-#ifdef USE_KQEMU
- if (env)
- env->last_io_time = cpu_get_time_fast();
-#endif
- return val;
-}
-
-/***********************************************************/
-void hw_error(const char *fmt, ...)
-{
- va_list ap;
- CPUState *env;
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: hardware error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- for(env = first_cpu; env != NULL; env = env->next_cpu) {
- fprintf(stderr, "CPU #%d:\n", env->cpu_index);
-#ifdef TARGET_I386
- cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
-#else
- cpu_dump_state(env, stderr, fprintf, 0);
-#endif
- }
- va_end(ap);
- abort();
-}
-
-/***********************************************************/
-/* keyboard/mouse */
-
-static QEMUPutKBDEvent* qemu_put_kbd_event;
-static void* qemu_put_kbd_event_opaque;
-
-static QEMUPutKBDEventN* qemu_put_kbd_event_n;
-static void* qemu_put_kbd_event_n_opaque;
-
-
-static QEMUPutGenericEvent* qemu_put_generic_event;
-static void* qemu_put_generic_event_opaque;
-
-static QEMUPutMouseEntry *qemu_put_mouse_event_head;
-static QEMUPutMouseEntry *qemu_put_mouse_event_current;
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
-}
-
-void qemu_add_kbd_event_n_handler(QEMUPutKBDEventN *func, void *opaque)
-{
- qemu_put_kbd_event_n_opaque = opaque;
- qemu_put_kbd_event_n = func;
-}
-
-#if 0
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
-{
- qemu_put_mouse_event_opaque = opaque;
- qemu_put_mouse_event = func;
- qemu_put_mouse_event_absolute = absolute;
-}
-#else
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name)
-{
- QEMUPutMouseEntry *s, *cursor;
-
- s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
- if (!s)
- return NULL;
-
- s->qemu_put_mouse_event = func;
- s->qemu_put_mouse_event_opaque = opaque;
- s->qemu_put_mouse_event_absolute = absolute;
- s->qemu_put_mouse_event_name = qemu_strdup(name);
- s->next = NULL;
-
- if (!qemu_put_mouse_event_head) {
- qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
- return s;
- }
-
- cursor = qemu_put_mouse_event_head;
- while (cursor->next != NULL)
- cursor = cursor->next;
-
- cursor->next = s;
- qemu_put_mouse_event_current = s;
-
- return s;
-}
-
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
-{
- QEMUPutMouseEntry *prev = NULL, *cursor;
-
- if (!qemu_put_mouse_event_head || entry == NULL)
- return;
-
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL && cursor != entry) {
- prev = cursor;
- cursor = cursor->next;
- }
-
- if (cursor == NULL) // does not exist or list empty
- return;
- else if (prev == NULL) { // entry is head
- qemu_put_mouse_event_head = cursor->next;
- if (qemu_put_mouse_event_current == entry)
- qemu_put_mouse_event_current = cursor->next;
- qemu_free(entry->qemu_put_mouse_event_name);
- qemu_free(entry);
- return;
- }
-
- prev->next = entry->next;
-
- if (qemu_put_mouse_event_current == entry)
- qemu_put_mouse_event_current = prev;
-
- qemu_free(entry->qemu_put_mouse_event_name);
- qemu_free(entry);
-}
-#endif
-
-void qemu_add_generic_event_handler(QEMUPutGenericEvent *func, void* opaque)
-{
- qemu_put_generic_event = func;
- qemu_put_generic_event_opaque = opaque;
-}
-
-void kbd_put_keycode(int keycode)
-{
- if (qemu_put_kbd_event) {
- qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
- }
-}
-
-void kbd_put_keycodes(int* keycodes, int count)
-{
- if (qemu_put_kbd_event_n)
- {
- qemu_put_kbd_event_n(qemu_put_kbd_event_n_opaque, keycodes, count);
- }
- else if (qemu_put_kbd_event)
- {
- int nn;
-
- for (nn = 0; nn < count; nn++)
- qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycodes[nn]);
- }
-}
-
-
-void kbd_generic_event(int type, int code, int value)
-{
- if (qemu_put_generic_event)
- qemu_put_generic_event(qemu_put_generic_event_opaque, type, code, value);
-}
-
-
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
-{
- QEMUPutMouseEvent *mouse_event;
- void *mouse_event_opaque;
- int width;
-
- if (!qemu_put_mouse_event_current) {
- return;
- }
-
- mouse_event =
- qemu_put_mouse_event_current->qemu_put_mouse_event;
- mouse_event_opaque =
- qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
-
- if (mouse_event) {
- if (graphic_rotate) {
- if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
- width = 0x7fff;
- else
- width = graphic_width - 1;
- mouse_event(mouse_event_opaque,
- width - dy, dx, dz, buttons_state);
- } else
- mouse_event(mouse_event_opaque,
- dx, dy, dz, buttons_state);
- }
-}
-
-int kbd_mouse_is_absolute(void)
-{
- if (!qemu_put_mouse_event_current)
- return 0;
-
- return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
-}
-
-void do_info_mice(void)
-{
- QEMUPutMouseEntry *cursor;
- int index = 0;
-
- if (!qemu_put_mouse_event_head) {
- term_printf("No mouse devices connected\n");
- return;
- }
-
- term_printf("Mouse devices available:\n");
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL) {
- term_printf("%c Mouse #%d: %s\n",
- (cursor == qemu_put_mouse_event_current ? '*' : ' '),
- index, cursor->qemu_put_mouse_event_name);
- index++;
- cursor = cursor->next;
- }
-}
-
-void do_mouse_set(int index)
-{
- QEMUPutMouseEntry *cursor;
- int i = 0;
-
- if (!qemu_put_mouse_event_head) {
- term_printf("No mouse devices connected\n");
- return;
- }
-
- cursor = qemu_put_mouse_event_head;
- while (cursor != NULL && index != i) {
- i++;
- cursor = cursor->next;
- }
-
- if (cursor != NULL)
- qemu_put_mouse_event_current = cursor;
- else
- term_printf("Mouse at given index not found\n");
-}
-
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
-#ifdef WORDS_BIGENDIAN
- uint32_t high, low;
-#else
- uint32_t low, high;
-#endif
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
-
-/***********************************************************/
-/* real time host monotonic timer */
-
-#define QEMU_TIMER_BASE 1000000000LL
-
-#ifdef WIN32
-
-static int64_t clock_freq;
-
-static void init_get_clock(void)
-{
- LARGE_INTEGER freq;
- int ret;
- ret = QueryPerformanceFrequency(&freq);
- if (ret == 0) {
- fprintf(stderr, "Could not calibrate ticks\n");
- exit(1);
- }
- clock_freq = freq.QuadPart;
-}
-
-static int64_t get_clock(void)
-{
- LARGE_INTEGER ti;
- QueryPerformanceCounter(&ti);
- return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
-}
-
-#else
-
-static int use_rt_clock;
-
-static void init_get_clock(void)
-{
- use_rt_clock = 0;
-#if defined(__linux__)
- {
- struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
- use_rt_clock = 1;
- }
- }
-#endif
-}
-
-static int64_t get_clock(void)
-{
-#if defined(__linux__)
- if (use_rt_clock) {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- } else
-#endif
- {
- /* XXX: using gettimeofday leads to problems if the date
- changes, so it should be avoided. */
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
- }
-}
-#endif
-
-/* Return the virtual CPU time, based on the instruction counter. */
-static int64_t cpu_get_icount(void)
-{
- int64_t icount;
- CPUState *env = cpu_single_env;;
- icount = qemu_icount;
- if (env) {
- if (!can_do_io(env))
- fprintf(stderr, "Bad clock read\n");
- icount -= (env->icount_decr.u16.low + env->icount_extra);
- }
- return qemu_icount_bias + (icount << icount_time_shift);
-}
-
-/***********************************************************/
-/* guest cycle counter */
-
-static int64_t cpu_ticks_prev;
-static int64_t cpu_ticks_offset;
-static int64_t cpu_clock_offset;
-static int cpu_ticks_enabled;
-
-/* return the host CPU cycle counter and handle stop/restart */
-int64_t cpu_get_ticks(void)
-{
- if (use_icount) {
- return cpu_get_icount();
- }
- if (!cpu_ticks_enabled) {
- return cpu_ticks_offset;
- } else {
- int64_t ticks;
- ticks = cpu_get_real_ticks();
- if (cpu_ticks_prev > ticks) {
- /* Note: non increasing ticks may happen if the host uses
- software suspend */
- cpu_ticks_offset += cpu_ticks_prev - ticks;
- }
- cpu_ticks_prev = ticks;
- return ticks + cpu_ticks_offset;
- }
-}
-
-/* return the host CPU monotonic timer and handle stop/restart */
-static int64_t cpu_get_clock(void)
-{
- int64_t ti;
- if (!cpu_ticks_enabled) {
- return cpu_clock_offset;
- } else {
- ti = get_clock();
- return ti + cpu_clock_offset;
- }
-}
-
-/* enable cpu_get_ticks() */
-void cpu_enable_ticks(void)
-{
- if (!cpu_ticks_enabled) {
- cpu_ticks_offset -= cpu_get_real_ticks();
- cpu_clock_offset -= get_clock();
- cpu_ticks_enabled = 1;
- }
-}
-
-/* disable cpu_get_ticks() : the clock is stopped. You must not call
- cpu_get_ticks() after that. */
-void cpu_disable_ticks(void)
-{
- if (cpu_ticks_enabled) {
- cpu_ticks_offset = cpu_get_ticks();
- cpu_clock_offset = cpu_get_clock();
- cpu_ticks_enabled = 0;
- }
-}
-
-/***********************************************************/
-/* timers */
-
-#define QEMU_TIMER_REALTIME 0
-#define QEMU_TIMER_VIRTUAL 1
-
-struct QEMUClock {
- int type;
- /* XXX: add frequency */
-};
-
-struct QEMUTimer {
- QEMUClock *clock;
- int64_t expire_time;
- QEMUTimerCB *cb;
- void *opaque;
- struct QEMUTimer *next;
-};
-
-struct qemu_alarm_timer {
- char const *name;
- unsigned int flags;
-
- int (*start)(struct qemu_alarm_timer *t);
- void (*stop)(struct qemu_alarm_timer *t);
- void (*rearm)(struct qemu_alarm_timer *t);
- void *priv;
-};
-
-#define ALARM_FLAG_DYNTICKS 0x1
-#define ALARM_FLAG_EXPIRED 0x2
-
-static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
-{
- return t->flags & ALARM_FLAG_DYNTICKS;
-}
-
-static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
-{
- if (!alarm_has_dynticks(t))
- return;
-
- t->rearm(t);
-}
-
-/* TODO: MIN_TIMER_REARM_US should be optimized */
-#define MIN_TIMER_REARM_US 250
-
-static struct qemu_alarm_timer *alarm_timer;
-
-#ifdef _WIN32
-
-struct qemu_alarm_win32 {
- MMRESULT timerId;
- HANDLE host_alarm;
- unsigned int period;
-} alarm_win32_data = {0, NULL, -1};
-
-static int win32_start_timer(struct qemu_alarm_timer *t);
-static void win32_stop_timer(struct qemu_alarm_timer *t);
-static void win32_rearm_timer(struct qemu_alarm_timer *t);
-
-#else
-
-static int unix_start_timer(struct qemu_alarm_timer *t);
-static void unix_stop_timer(struct qemu_alarm_timer *t);
-
-#ifdef __linux__
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t);
-static void dynticks_stop_timer(struct qemu_alarm_timer *t);
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
-
-static int hpet_start_timer(struct qemu_alarm_timer *t);
-static void hpet_stop_timer(struct qemu_alarm_timer *t);
-
-static int rtc_start_timer(struct qemu_alarm_timer *t);
-static void rtc_stop_timer(struct qemu_alarm_timer *t);
-
-#endif /* __linux__ */
-
-#endif /* _WIN32 */
-
-/* Correlation between real and virtual time is always going to be
- fairly approximate, so ignore small variation.
- When the guest is idle real and virtual time will be aligned in
- the IO wait loop. */
-#define ICOUNT_WOBBLE (QEMU_TIMER_BASE / 10)
-
-static void icount_adjust(void)
-{
- int64_t cur_time;
- int64_t cur_icount;
- int64_t delta;
- static int64_t last_delta;
- /* If the VM is not running, then do nothing. */
- if (!vm_running)
- return;
-
- cur_time = cpu_get_clock();
- cur_icount = qemu_get_clock(vm_clock);
- delta = cur_icount - cur_time;
- /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
- if (delta > 0
- && last_delta + ICOUNT_WOBBLE < delta * 2
- && icount_time_shift > 0) {
- /* The guest is getting too far ahead. Slow time down. */
- icount_time_shift--;
- }
- if (delta < 0
- && last_delta - ICOUNT_WOBBLE > delta * 2
- && icount_time_shift < MAX_ICOUNT_SHIFT) {
- /* The guest is getting too far behind. Speed time up. */
- icount_time_shift++;
- }
- last_delta = delta;
- qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
-}
-
-static void icount_adjust_rt(void * opaque)
-{
- qemu_mod_timer(icount_rt_timer,
- qemu_get_clock(rt_clock) + 1000);
- icount_adjust();
-}
-
-static void icount_adjust_vm(void * opaque)
-{
- qemu_mod_timer(icount_vm_timer,
- qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
- icount_adjust();
-}
-
-static void init_icount_adjust(void)
-{
- /* Have both realtime and virtual time triggers for speed adjustment.
- The realtime trigger catches emulated time passing too slowly,
- the virtual time trigger catches emulated time passing too fast.
- Realtime triggers occur even when idle, so use them less frequently
- than VM triggers. */
- icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
- qemu_mod_timer(icount_rt_timer,
- qemu_get_clock(rt_clock) + 1000);
- icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
- qemu_mod_timer(icount_vm_timer,
- qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
-}
-
-static struct qemu_alarm_timer alarm_timers[] = {
-#ifndef _WIN32
-#ifdef __linux__
- {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
- dynticks_stop_timer, dynticks_rearm_timer, NULL},
- /* HPET - if available - is preferred */
- {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
- /* ...otherwise try RTC */
- {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
-#endif
- {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
-#else
- {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
- win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
- {"win32", 0, win32_start_timer,
- win32_stop_timer, NULL, &alarm_win32_data},
-#endif
- {NULL, 0, NULL, NULL, NULL, NULL}
-};
-
-static void show_available_alarms(void)
-{
- int i;
-
- printf("Available alarm timers, in order of precedence:\n");
- for (i = 0; alarm_timers[i].name; i++)
- printf("%s\n", alarm_timers[i].name);
-}
-
-static void configure_alarms(char const *opt)
-{
- int i;
- int cur = 0;
- int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
- char *arg;
- char *name;
- struct qemu_alarm_timer tmp;
-
- if (!strcmp(opt, "?")) {
- show_available_alarms();
- exit(0);
- }
-
- arg = strdup(opt);
-
- /* Reorder the array */
- name = strtok(arg, ",");
- while (name) {
- for (i = 0; i < count && alarm_timers[i].name; i++) {
- if (!strcmp(alarm_timers[i].name, name))
- break;
- }
-
- if (i == count) {
- fprintf(stderr, "Unknown clock %s\n", name);
- goto next;
- }
-
- if (i < cur)
- /* Ignore */
- goto next;
-
- /* Swap */
- tmp = alarm_timers[i];
- alarm_timers[i] = alarm_timers[cur];
- alarm_timers[cur] = tmp;
-
- cur++;
-next:
- name = strtok(NULL, ",");
- }
-
- free(arg);
-
- if (cur) {
- /* Disable remaining timers */
- for (i = cur; i < count; i++)
- alarm_timers[i].name = NULL;
- } else {
- show_available_alarms();
- exit(1);
- }
-}
-
-QEMUClock *rt_clock;
-QEMUClock *vm_clock;
-
-static QEMUTimer *active_timers[2];
-
-static QEMUClock *qemu_new_clock(int type)
-{
- QEMUClock *clock;
- clock = qemu_mallocz(sizeof(QEMUClock));
- if (!clock)
- return NULL;
- clock->type = type;
- return clock;
-}
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
-{
- QEMUTimer *ts;
-
- ts = qemu_mallocz(sizeof(QEMUTimer));
- ts->clock = clock;
- ts->cb = cb;
- ts->opaque = opaque;
- return ts;
-}
-
-void qemu_free_timer(QEMUTimer *ts)
-{
- qemu_free(ts);
-}
-
-/* stop a timer, but do not dealloc it */
-void qemu_del_timer(QEMUTimer *ts)
-{
- QEMUTimer **pt, *t;
-
- /* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &active_timers[ts->clock->type];
- for(;;) {
- t = *pt;
- if (!t)
- break;
- if (t == ts) {
- *pt = t->next;
- break;
- }
- pt = &t->next;
- }
-}
-
-/* modify the current timer so that it will be fired when current_time
- >= expire_time. The corresponding callback will be called. */
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
-{
- QEMUTimer **pt, *t;
-
- qemu_del_timer(ts);
-
- /* add the timer in the sorted list */
- /* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &active_timers[ts->clock->type];
- for(;;) {
- t = *pt;
- if (!t)
- break;
- if (t->expire_time > expire_time)
- break;
- pt = &t->next;
- }
- ts->expire_time = expire_time;
- ts->next = *pt;
- *pt = ts;
-
- /* Rearm if necessary */
- if (pt == &active_timers[ts->clock->type]) {
- if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
- qemu_rearm_alarm_timer(alarm_timer);
- }
- /* Interrupt execution to force deadline recalculation. */
- if (use_icount && cpu_single_env) {
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
- }
- }
-}
-
-int qemu_timer_pending(QEMUTimer *ts)
-{
- QEMUTimer *t;
- for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
- if (t == ts)
- return 1;
- }
- return 0;
-}
-
-static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
-{
- if (!timer_head)
- return 0;
- return (timer_head->expire_time <= current_time);
-}
-
-static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
-{
- QEMUTimer *ts;
-
- for(;;) {
- ts = *ptimer_head;
- if (!ts || ts->expire_time > current_time)
- break;
- /* remove timer from the list before calling the callback */
- *ptimer_head = ts->next;
- ts->next = NULL;
-
- /* run the callback (the timer list can be modified) */
- ts->cb(ts->opaque);
- }
-}
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
- switch(clock->type) {
- case QEMU_TIMER_REALTIME:
- return get_clock() / 1000000;
- default:
- case QEMU_TIMER_VIRTUAL:
- if (use_icount) {
- return cpu_get_icount();
- } else {
- return cpu_get_clock();
- }
- }
-}
-
-static void init_timers(void)
-{
- init_get_clock();
- ticks_per_sec = QEMU_TIMER_BASE;
- rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
- vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
-}
-
-/* save a timer */
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- if (qemu_timer_pending(ts)) {
- expire_time = ts->expire_time;
- } else {
- expire_time = -1;
- }
- qemu_put_be64(f, expire_time);
-}
-
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- expire_time = qemu_get_be64(f);
- if (expire_time != -1) {
- qemu_mod_timer(ts, expire_time);
- } else {
- qemu_del_timer(ts);
- }
-}
-
-static void timer_save(QEMUFile *f, void *opaque)
-{
- if (cpu_ticks_enabled) {
- hw_error("cannot save state if virtual timers are running");
- }
- qemu_put_be64(f, cpu_ticks_offset);
- qemu_put_be64(f, ticks_per_sec);
- qemu_put_be64(f, cpu_clock_offset);
-}
-
-static int timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- if (version_id != 1 && version_id != 2)
- return -EINVAL;
- if (cpu_ticks_enabled) {
- return -EINVAL;
- }
- cpu_ticks_offset=qemu_get_be64(f);
- ticks_per_sec=qemu_get_be64(f);
- if (version_id == 2) {
- cpu_clock_offset=qemu_get_be64(f);
- }
- return 0;
-}
-
-#ifdef _WIN32
-void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
- DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
-#else
-static void host_alarm_handler(int host_signum)
-#endif
-{
-#if 0
-#define DISP_FREQ 1000
- {
- static int64_t delta_min = INT64_MAX;
- static int64_t delta_max, delta_cum, last_clock, delta, ti;
- static int count;
- ti = qemu_get_clock(vm_clock);
- if (last_clock != 0) {
- delta = ti - last_clock;
- if (delta < delta_min)
- delta_min = delta;
- if (delta > delta_max)
- delta_max = delta;
- delta_cum += delta;
- if (++count == DISP_FREQ) {
- printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
- muldiv64(delta_min, 1000000, ticks_per_sec),
- muldiv64(delta_max, 1000000, ticks_per_sec),
- muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
- (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
- count = 0;
- delta_min = INT64_MAX;
- delta_max = 0;
- delta_cum = 0;
- }
- }
- last_clock = ti;
- }
-#endif
- if (alarm_has_dynticks(alarm_timer) ||
- (!use_icount &&
- qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock))) ||
- qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock))) {
-#ifdef _WIN32
- struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
- SetEvent(data->host_alarm);
-#endif
- CPUState *env = next_cpu;
-
- alarm_timer->flags |= ALARM_FLAG_EXPIRED;
-
- if (env) {
- /* stop the currently executing cpu because a timer occured */
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
- if (env->kqemu_enabled) {
- kqemu_cpu_interrupt(env);
- }
-#endif
- }
- event_pending = 1;
- }
-}
-
-static int64_t qemu_next_deadline(void)
-{
- int64_t delta;
-
- if (active_timers[QEMU_TIMER_VIRTUAL]) {
- delta = active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
- qemu_get_clock(vm_clock);
- } else {
- /* To avoid problems with overflow limit this to 2^32. */
- delta = INT32_MAX;
- }
-
- if (delta < 0)
- delta = 0;
-
- return delta;
-}
-
-#if defined(__linux__) || defined(_WIN32)
-static uint64_t qemu_next_deadline_dyntick(void)
-{
- int64_t delta;
- int64_t rtdelta;
-
- if (use_icount)
- delta = INT32_MAX;
- else
- delta = (qemu_next_deadline() + 999) / 1000;
-
- if (active_timers[QEMU_TIMER_REALTIME]) {
- rtdelta = (active_timers[QEMU_TIMER_REALTIME]->expire_time -
- qemu_get_clock(rt_clock))*1000;
- if (rtdelta < delta)
- delta = rtdelta;
- }
-
- if (delta < MIN_TIMER_REARM_US)
- delta = MIN_TIMER_REARM_US;
-
- return delta;
-}
-#endif
-
-#ifndef _WIN32
-
-#if defined(__linux__)
-
-#define RTC_FREQ 1024
-
-static void enable_sigio_timer(int fd)
-{
- struct sigaction act;
-
- /* timer signal */
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = host_alarm_handler;
-
- sigaction(SIGIO, &act, NULL);
- fcntl(fd, F_SETFL, O_ASYNC);
- fcntl(fd, F_SETOWN, getpid());
-}
-
-static int hpet_start_timer(struct qemu_alarm_timer *t)
-{
- struct hpet_info info;
- int r, fd;
-
- fd = open("/dev/hpet", O_RDONLY);
- if (fd < 0)
- return -1;
-
- /* Set frequency */
- r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
- if (r < 0) {
- fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
- "error, but for better emulation accuracy type:\n"
- "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
- goto fail;
- }
-
- /* Check capabilities */
- r = ioctl(fd, HPET_INFO, &info);
- if (r < 0)
- goto fail;
-
- /* Enable periodic mode */
- r = ioctl(fd, HPET_EPI, 0);
- if (info.hi_flags && (r < 0))
- goto fail;
-
- /* Enable interrupt */
- r = ioctl(fd, HPET_IE_ON, 0);
- if (r < 0)
- goto fail;
-
- enable_sigio_timer(fd);
- t->priv = (void *)(long)fd;
-
- return 0;
-fail:
- close(fd);
- return -1;
-}
-
-static void hpet_stop_timer(struct qemu_alarm_timer *t)
-{
- int fd = (long)t->priv;
-
- close(fd);
-}
-
-static int rtc_start_timer(struct qemu_alarm_timer *t)
-{
- int rtc_fd;
- unsigned long current_rtc_freq = 0;
-
- TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
- if (rtc_fd < 0)
- return -1;
- ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
- if (current_rtc_freq != RTC_FREQ &&
- ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
- fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
- "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
- "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
- goto fail;
- }
- if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
- fail:
- close(rtc_fd);
- return -1;
- }
-
- enable_sigio_timer(rtc_fd);
-
- t->priv = (void *)(long)rtc_fd;
-
- return 0;
-}
-
-static void rtc_stop_timer(struct qemu_alarm_timer *t)
-{
- int rtc_fd = (long)t->priv;
-
- close(rtc_fd);
-}
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t)
-{
- struct sigevent ev;
- timer_t host_timer;
- struct sigaction act;
-
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = host_alarm_handler;
-
- sigaction(SIGALRM, &act, NULL);
-
- ev.sigev_value.sival_int = 0;
- ev.sigev_notify = SIGEV_SIGNAL;
- ev.sigev_signo = SIGALRM;
-
- if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
- perror("timer_create");
-
- /* disable dynticks */
- fprintf(stderr, "Dynamic Ticks disabled\n");
-
- return -1;
- }
-
- t->priv = (void *)host_timer;
-
- return 0;
-}
-
-static void dynticks_stop_timer(struct qemu_alarm_timer *t)
-{
- timer_t host_timer = (timer_t)t->priv;
-
- timer_delete(host_timer);
-}
-
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
-{
- timer_t host_timer = (timer_t)t->priv;
- struct itimerspec timeout;
- int64_t nearest_delta_us = INT64_MAX;
- int64_t current_us;
-
- if (!active_timers[QEMU_TIMER_REALTIME] &&
- !active_timers[QEMU_TIMER_VIRTUAL])
- return;
-
- nearest_delta_us = qemu_next_deadline_dyntick();
-
- /* check whether a timer is already running */
- if (timer_gettime(host_timer, &timeout)) {
- perror("gettime");
- fprintf(stderr, "Internal timer error: aborting\n");
- exit(1);
- }
- current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
- if (current_us && current_us <= nearest_delta_us)
- return;
-
- timeout.it_interval.tv_sec = 0;
- timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
- timeout.it_value.tv_sec = nearest_delta_us / 1000000;
- timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
- if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
- perror("settime");
- fprintf(stderr, "Internal timer error: aborting\n");
- exit(1);
- }
-}
-
-#endif /* defined(__linux__) */
-
-static int unix_start_timer(struct qemu_alarm_timer *t)
-{
- struct sigaction act;
- struct itimerval itv;
- int err;
-
- /* timer signal */
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = host_alarm_handler;
-
- sigaction(SIGALRM, &act, NULL);
-
- itv.it_interval.tv_sec = 0;
- /* for i386 kernel 2.6 to get 1 ms */
- itv.it_interval.tv_usec = 999;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 10 * 1000;
-
- err = setitimer(ITIMER_REAL, &itv, NULL);
- if (err)
- return -1;
-
- return 0;
-}
-
-static void unix_stop_timer(struct qemu_alarm_timer *t)
-{
- struct itimerval itv;
-
- memset(&itv, 0, sizeof(itv));
- setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-#endif /* !defined(_WIN32) */
-
-#ifdef _WIN32
-
-static int win32_start_timer(struct qemu_alarm_timer *t)
-{
- TIMECAPS tc;
- struct qemu_alarm_win32 *data = t->priv;
- UINT flags;
-
- data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!data->host_alarm) {
- perror("Failed CreateEvent");
- return -1;
- }
-
- memset(&tc, 0, sizeof(tc));
- timeGetDevCaps(&tc, sizeof(tc));
-
- if (data->period < tc.wPeriodMin)
- data->period = tc.wPeriodMin;
-
- timeBeginPeriod(data->period);
-
- flags = TIME_CALLBACK_FUNCTION;
- if (alarm_has_dynticks(t))
- flags |= TIME_ONESHOT;
- else
- flags |= TIME_PERIODIC;
-
- data->timerId = timeSetEvent(1, // interval (ms)
- data->period, // resolution
- host_alarm_handler, // function
- (DWORD)t, // parameter
- flags);
-
- if (!data->timerId) {
- perror("Failed to initialize win32 alarm timer");
-
- timeEndPeriod(data->period);
- CloseHandle(data->host_alarm);
- return -1;
- }
-
- qemu_add_wait_object(data->host_alarm, NULL, NULL);
-
- return 0;
-}
-
-static void win32_stop_timer(struct qemu_alarm_timer *t)
-{
- struct qemu_alarm_win32 *data = t->priv;
-
- timeKillEvent(data->timerId);
- timeEndPeriod(data->period);
-
- CloseHandle(data->host_alarm);
-}
-
-static void win32_rearm_timer(struct qemu_alarm_timer *t)
-{
- struct qemu_alarm_win32 *data = t->priv;
- uint64_t nearest_delta_us;
-
- if (!active_timers[QEMU_TIMER_REALTIME] &&
- !active_timers[QEMU_TIMER_VIRTUAL])
- return;
-
- nearest_delta_us = qemu_next_deadline_dyntick();
- nearest_delta_us /= 1000;
-
- timeKillEvent(data->timerId);
-
- data->timerId = timeSetEvent(1,
- data->period,
- host_alarm_handler,
- (DWORD)t,
- TIME_ONESHOT | TIME_PERIODIC);
-
- if (!data->timerId) {
- perror("Failed to re-arm win32 alarm timer");
-
- timeEndPeriod(data->period);
- CloseHandle(data->host_alarm);
- exit(1);
- }
-}
-
-#endif /* _WIN32 */
-
-static void init_timer_alarm(void)
-{
- struct qemu_alarm_timer *t;
- int i, err = -1;
-
- for (i = 0; alarm_timers[i].name; i++) {
- t = &alarm_timers[i];
-
- err = t->start(t);
- if (!err)
- break;
- }
-
- if (err) {
- fprintf(stderr, "Unable to find any suitable alarm timer.\n");
- fprintf(stderr, "Terminating\n");
- exit(1);
- }
-
- alarm_timer = t;
-}
-
-static void quit_timers(void)
-{
- alarm_timer->stop(alarm_timer);
- alarm_timer = NULL;
-}
-
-/***********************************************************/
-/* host time/date access */
-void qemu_get_timedate(struct tm *tm, int offset)
-{
- time_t ti;
- struct tm *ret;
-
- time(&ti);
- ti += offset;
- if (rtc_date_offset == -1) {
- if (rtc_utc)
- ret = gmtime(&ti);
- else
- ret = localtime(&ti);
- } else {
- ti -= rtc_date_offset;
- ret = gmtime(&ti);
- }
-
- memcpy(tm, ret, sizeof(struct tm));
-}
-
-int qemu_timedate_diff(struct tm *tm)
-{
- time_t seconds;
-
- if (rtc_date_offset == -1)
- if (rtc_utc)
- seconds = mktimegm(tm);
- else
- seconds = mktime(tm);
- else
- seconds = mktimegm(tm) + rtc_date_offset;
-
- return seconds - time(NULL);
-}
-
-
-#ifdef CONFIG_TRACE
-static int tbflush_requested;
-static int exit_requested;
-
-void start_tracing()
-{
- if (trace_filename == NULL)
- return;
- if (!tracing) {
- fprintf(stderr,"-- start tracing --\n");
- start_time = Now();
- }
- tracing = 1;
- tbflush_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void stop_tracing()
-{
- if (trace_filename == NULL)
- return;
- if (tracing) {
- end_time = Now();
- elapsed_usecs += end_time - start_time;
- fprintf(stderr,"-- stop tracing --\n");
- }
- tracing = 0;
- tbflush_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-#ifndef _WIN32
-/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
- * SIGUSR1 turns tracing on. SIGUSR2 turns tracing off.
- */
-void sigusr_handler(int sig)
-{
- if (sig == SIGUSR1)
- start_tracing();
- else
- stop_tracing();
-}
-#endif
-
-/* This is the handler to catch control-C so that we can exit cleanly.
- * This is needed when tracing to flush the buffers to disk.
- */
-void sigint_handler(int sig)
-{
- exit_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-#endif /* CONFIG_TRACE */
-
-
-/***********************************************************/
-/* character device */
-
-static void qemu_chr_event(CharDriverState *s, int event)
-{
- if (!s->chr_event)
- return;
- s->chr_event(s->handler_opaque, event);
-}
-
-static void qemu_chr_reset_bh(void *opaque)
-{
- CharDriverState *s = opaque;
- qemu_chr_event(s, CHR_EVENT_RESET);
- qemu_bh_delete(s->bh);
- s->bh = NULL;
-}
-
-void qemu_chr_reset(CharDriverState *s)
-{
- if (s->bh == NULL) {
- s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
- qemu_bh_schedule(s->bh);
- }
-}
-
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
-{
- return s->chr_write(s, buf, len);
-}
-
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
-{
- if (!s->chr_ioctl)
- return -ENOTSUP;
- return s->chr_ioctl(s, cmd, arg);
-}
-
-int qemu_chr_can_read(CharDriverState *s)
-{
- if (!s->chr_can_read)
- return 0;
- return s->chr_can_read(s->handler_opaque);
-}
-
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
-{
- s->chr_read(s->handler_opaque, buf, len);
-}
-
-void qemu_chr_accept_input(CharDriverState *s)
-{
- if (s->chr_accept_input)
- s->chr_accept_input(s);
-}
-
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
-{
- char buf[4096];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
- va_end(ap);
-}
-
-void qemu_chr_send_event(CharDriverState *s, int event)
-{
- if (s->chr_send_event)
- s->chr_send_event(s, event);
-}
-
-void qemu_chr_add_handlers(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read,
- IOEventHandler *fd_event,
- void *opaque)
-{
- s->chr_can_read = fd_can_read;
- s->chr_read = fd_read;
- s->chr_event = fd_event;
- s->handler_opaque = opaque;
- if (s->chr_update_read_handler)
- s->chr_update_read_handler(s);
-}
-
-static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- return len;
-}
-
-static CharDriverState *qemu_chr_open_null(void)
-{
- CharDriverState *chr;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- chr->chr_write = null_chr_write;
- return chr;
-}
-
-/* MUX driver for serial I/O splitting */
-static int term_timestamps;
-static int64_t term_timestamps_start;
-#define MAX_MUX 4
-#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
-#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
-typedef struct {
- IOCanRWHandler *chr_can_read[MAX_MUX];
- IOReadHandler *chr_read[MAX_MUX];
- IOEventHandler *chr_event[MAX_MUX];
- void *ext_opaque[MAX_MUX];
- CharDriverState *drv;
- unsigned char buffer[MUX_BUFFER_SIZE];
- int prod;
- int cons;
- int mux_cnt;
- int term_got_escape;
- int max_size;
-} MuxDriver;
-
-
-static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- MuxDriver *d = chr->opaque;
- int ret;
- if (!term_timestamps) {
- ret = d->drv->chr_write(d->drv, buf, len);
- } else {
- int i;
-
- ret = 0;
- for(i = 0; i < len; i++) {
- ret += d->drv->chr_write(d->drv, buf+i, 1);
- if (buf[i] == '\n') {
- char buf1[64];
- int64_t ti;
- int secs;
-
- ti = get_clock();
- if (term_timestamps_start == -1)
- term_timestamps_start = ti;
- ti -= term_timestamps_start;
- secs = ti / 1000000000;
- snprintf(buf1, sizeof(buf1),
- "[%02d:%02d:%02d.%03d] ",
- secs / 3600,
- (secs / 60) % 60,
- secs % 60,
- (int)((ti / 1000000) % 1000));
- d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
- }
- }
- }
- return ret;
-}
-
-static const char * const mux_help[] = {
- "% h print this help\n\r",
- "% x exit emulator\n\r",
- "% s save disk data back to file (if -snapshot)\n\r",
- "% t toggle console timestamps\n\r"
- "% b send break (magic sysrq)\n\r",
- "% c switch between console and monitor\n\r",
- "% % sends %\n\r",
- NULL
-};
-
-static int term_escape_char = 0x01; /* ctrl-a is used for escape */
-static void mux_print_help(CharDriverState *chr)
-{
- int i, j;
- char ebuf[15] = "Escape-Char";
- char cbuf[50] = "\n\r";
-
- if (term_escape_char > 0 && term_escape_char < 26) {
- snprintf(cbuf, sizeof(cbuf), "\n\r");
- snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
- } else {
- snprintf(cbuf, sizeof(cbuf),
- "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
- term_escape_char);
- }
- chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
- for (i = 0; mux_help[i] != NULL; i++) {
- for (j=0; mux_help[i][j] != '\0'; j++) {
- if (mux_help[i][j] == '%')
- chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
- else
- chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
- }
- }
-}
-
-static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
-{
- if (d->term_got_escape) {
- d->term_got_escape = 0;
- if (ch == term_escape_char)
- goto send_char;
- switch(ch) {
- case '?':
- case 'h':
- mux_print_help(chr);
- break;
- case 'x':
- {
- const char *term = "QEMU: Terminated\n\r";
- chr->chr_write(chr,(uint8_t *)term,strlen(term));
- exit(0);
- break;
- }
- case 's':
- {
- int i;
- for (i = 0; i < nb_drives; i++) {
- bdrv_commit(drives_table[i].bdrv);
- }
- }
- break;
- case 'b':
- qemu_chr_event(chr, CHR_EVENT_BREAK);
- break;
- case 'c':
- /* Switch to the next registered device */
- chr->focus++;
- if (chr->focus >= d->mux_cnt)
- chr->focus = 0;
- break;
- case 't':
- term_timestamps = !term_timestamps;
- term_timestamps_start = -1;
- break;
- }
- } else if (ch == term_escape_char) {
- d->term_got_escape = 1;
- } else {
- send_char:
- return 1;
- }
- return 0;
-}
-
-static void mux_chr_accept_input(CharDriverState *chr)
-{
- int m = chr->focus;
- MuxDriver *d = chr->opaque;
-
- while (d->prod != d->cons &&
- d->chr_can_read[m] &&
- d->chr_can_read[m](d->ext_opaque[m])) {
- d->chr_read[m](d->ext_opaque[m],
- &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
- }
-}
-
-static int mux_chr_can_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- MuxDriver *d = chr->opaque;
-
- if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
- return 1;
- if (d->chr_can_read[chr->focus])
- return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
- return 0;
-}
-
-static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
-{
- CharDriverState *chr = opaque;
- MuxDriver *d = chr->opaque;
- int m = chr->focus;
- int i;
-
- mux_chr_accept_input (opaque);
-
- for(i = 0; i < size; i++)
- if (mux_proc_byte(chr, d, buf[i])) {
- if (d->prod == d->cons &&
- d->chr_can_read[m] &&
- d->chr_can_read[m](d->ext_opaque[m]))
- d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
- else
- d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
- }
-}
-
-static void mux_chr_event(void *opaque, int event)
-{
- CharDriverState *chr = opaque;
- MuxDriver *d = chr->opaque;
- int i;
-
- /* Send the event to all registered listeners */
- for (i = 0; i < d->mux_cnt; i++)
- if (d->chr_event[i])
- d->chr_event[i](d->ext_opaque[i], event);
-}
-
-static void mux_chr_update_read_handler(CharDriverState *chr)
-{
- MuxDriver *d = chr->opaque;
-
- if (d->mux_cnt >= MAX_MUX) {
- fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
- return;
- }
- d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
- d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
- d->chr_read[d->mux_cnt] = chr->chr_read;
- d->chr_event[d->mux_cnt] = chr->chr_event;
- /* Fix up the real driver with mux routines */
- if (d->mux_cnt == 0) {
- qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
- mux_chr_event, chr);
- }
- chr->focus = d->mux_cnt;
- d->mux_cnt++;
-}
-
-static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
-{
- CharDriverState *chr;
- MuxDriver *d;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- d = qemu_mallocz(sizeof(MuxDriver));
- if (!d) {
- free(chr);
- return NULL;
- }
-
- chr->opaque = d;
- d->drv = drv;
- chr->focus = -1;
- chr->chr_write = mux_chr_write;
- chr->chr_update_read_handler = mux_chr_update_read_handler;
- chr->chr_accept_input = mux_chr_accept_input;
- return chr;
-}
-
-
-#ifdef _WIN32
-
-static int send_all(int fd, const uint8_t *buf, int len1)
-{
- int ret, len;
-
- len = len1;
- while (len > 0) {
- ret = socket_send(fd, buf, len);
- if (ret < 0) {
- if (errno != EWOULDBLOCK) {
- return -1;
- }
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return len1 - len;
-}
-
-#else
-
-static int unix_write(int fd, const uint8_t *buf, int len1)
-{
- int ret, len;
-
- len = len1;
- while (len > 0) {
- ret = write(fd, buf, len);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- return len1 - len;
-}
-
-static inline int send_all(int fd, const uint8_t *buf, int len1)
-{
- return unix_write(fd, buf, len1);
-}
-#endif /* !_WIN32 */
-
-#ifndef _WIN32
-
-typedef struct {
- int fd_in, fd_out;
- int max_size;
-} FDCharDriver;
-
-#define STDIO_MAX_CLIENTS 1
-static int stdio_nb_clients = 0;
-
-static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- FDCharDriver *s = chr->opaque;
- return unix_write(s->fd_out, buf, len);
-}
-
-static int fd_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- FDCharDriver *s = chr->opaque;
-
- s->max_size = qemu_chr_can_read(chr);
- return s->max_size;
-}
-
-static void fd_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- FDCharDriver *s = chr->opaque;
- int size, len;
- uint8_t buf[1024];
-
- len = sizeof(buf);
- if (len > s->max_size)
- len = s->max_size;
- if (len == 0)
- return;
- size = read(s->fd_in, buf, len);
- if (size == 0) {
- /* FD has been closed. Remove it from the active list. */
- qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
- return;
- }
- if (size > 0) {
- qemu_chr_read(chr, buf, size);
- }
-}
-
-static void fd_chr_update_read_handler(CharDriverState *chr)
-{
- FDCharDriver *s = chr->opaque;
-
- if (s->fd_in >= 0) {
- if (nographic && s->fd_in == 0) {
- } else {
- qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
- fd_chr_read, NULL, chr);
- }
- }
-}
-
-static void fd_chr_close(struct CharDriverState *chr)
-{
- FDCharDriver *s = chr->opaque;
-
- if (s->fd_in >= 0) {
- if (nographic && s->fd_in == 0) {
- } else {
- qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
- }
- }
-
- qemu_free(s);
-}
-
-/* open a character device to a unix fd */
-static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
-{
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(FDCharDriver));
- if (!s) {
- free(chr);
- return NULL;
- }
- s->fd_in = fd_in;
- s->fd_out = fd_out;
- chr->opaque = s;
- chr->chr_write = fd_chr_write;
- chr->chr_update_read_handler = fd_chr_update_read_handler;
- chr->chr_close = fd_chr_close;
-
- qemu_chr_reset(chr);
-
- return chr;
-}
-
-static CharDriverState *qemu_chr_open_file_out(const char *file_out)
-{
- int fd_out;
-
- TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
- if (fd_out < 0)
- return NULL;
- return qemu_chr_open_fd(-1, fd_out);
-}
-
-static CharDriverState *qemu_chr_open_pipe(const char *filename)
-{
- int fd_in, fd_out;
- char filename_in[256], filename_out[256];
-
- snprintf(filename_in, 256, "%s.in", filename);
- snprintf(filename_out, 256, "%s.out", filename);
- TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
- TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
- if (fd_in < 0 || fd_out < 0) {
- if (fd_in >= 0)
- close(fd_in);
- if (fd_out >= 0)
- close(fd_out);
- TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
- if (fd_in < 0)
- return NULL;
- }
- return qemu_chr_open_fd(fd_in, fd_out);
-}
-
-CharDriverState *qemu_chr_open_fdpair(const char *fd_pair)
-{
- int fd_in, fd_out;
- char *endptr;
-
- /* fd_pair should contain two decimal fd values, separated by
- * a colon. */
- endptr = NULL;
- fd_in = strtol(fd_pair, &endptr, 10);
- if (endptr == NULL || endptr == fd_pair || *endptr != ':')
- return NULL;
- endptr++; // skip colon
- fd_pair = endptr;
- endptr = NULL;
- fd_out = strtol(fd_pair, &endptr, 10);
- if (endptr == NULL || endptr == fd_pair || *endptr != '\0')
- return NULL;
-
- return qemu_chr_open_fd(fd_in, fd_out);
-}
-
-
-/* for STDIO, we handle the case where several clients use it
- (nographic mode) */
-
-#define TERM_FIFO_MAX_SIZE 1
-
-static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
-static int term_fifo_size;
-
-static int stdio_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
-
- /* try to flush the queue if needed */
- if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
- qemu_chr_read(chr, term_fifo, 1);
- term_fifo_size = 0;
- }
- /* see if we can absorb more chars */
- if (term_fifo_size == 0)
- return 1;
- else
- return 0;
-}
-
-static void stdio_read(void *opaque)
-{
- int size;
- uint8_t buf[1];
- CharDriverState *chr = opaque;
-
- size = read(0, buf, 1);
- if (size == 0) {
- /* stdin has been closed. Remove it from the active list. */
- qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
- return;
- }
- if (size > 0) {
- if (qemu_chr_can_read(chr) > 0) {
- qemu_chr_read(chr, buf, 1);
- } else if (term_fifo_size == 0) {
- term_fifo[term_fifo_size++] = buf[0];
- }
- }
-}
-
-/* init terminal so that we can grab keys */
-static struct termios oldtty;
-static int old_fd0_flags;
-static int term_atexit_done;
-
-static void term_exit(void)
-{
- tcsetattr (0, TCSANOW, &oldtty);
- fcntl(0, F_SETFL, old_fd0_flags);
-}
-
-static void term_init(void)
-{
- struct termios tty;
-
- tcgetattr (0, &tty);
- oldtty = tty;
- old_fd0_flags = fcntl(0, F_GETFL);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
- /* if graphical mode, we allow Ctrl-C handling */
- if (nographic)
- tty.c_lflag &= ~ISIG;
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
-
- tcsetattr (0, TCSANOW, &tty);
-
- if (!term_atexit_done++)
- atexit(term_exit);
-
- fcntl(0, F_SETFL, O_NONBLOCK);
-}
-
-static void qemu_chr_close_stdio(struct CharDriverState *chr)
-{
- term_exit();
- stdio_nb_clients--;
- qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
- fd_chr_close(chr);
-}
-
-static CharDriverState *qemu_chr_open_stdio(void)
-{
- CharDriverState *chr;
-
- if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- chr->chr_close = qemu_chr_close_stdio;
- qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
- stdio_nb_clients++;
- term_init();
-
- return chr;
-}
-
-#ifdef __sun__
-/* Once Solaris has openpty(), this is going to be removed. */
-int openpty(int *amaster, int *aslave, char *name,
- struct termios *termp, struct winsize *winp)
-{
- const char *slave;
- int mfd = -1, sfd = -1;
-
- *amaster = *aslave = -1;
-
- mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
- if (mfd < 0)
- goto err;
-
- if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
- goto err;
-
- if ((slave = ptsname(mfd)) == NULL)
- goto err;
-
- if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
- goto err;
-
- if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
- (termp != NULL && tcgetattr(sfd, termp) < 0))
- goto err;
-
- if (amaster)
- *amaster = mfd;
- if (aslave)
- *aslave = sfd;
- if (winp)
- ioctl(sfd, TIOCSWINSZ, winp);
-
- return 0;
-
-err:
- if (sfd != -1)
- close(sfd);
- close(mfd);
- return -1;
-}
-
-void cfmakeraw (struct termios *termios_p)
-{
- termios_p->c_iflag &=
- ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
- termios_p->c_oflag &= ~OPOST;
- termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- termios_p->c_cflag &= ~(CSIZE|PARENB);
- termios_p->c_cflag |= CS8;
-
- termios_p->c_cc[VMIN] = 0;
- termios_p->c_cc[VTIME] = 0;
-}
-#endif /* __sun__ */
-
-#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
- || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
-
-typedef struct {
- int fd;
- int connected;
- int polling;
- int read_bytes;
- QEMUTimer *timer;
-} PtyCharDriver;
-
-static void pty_chr_update_read_handler(CharDriverState *chr);
-static void pty_chr_state(CharDriverState *chr, int connected);
-
-static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- PtyCharDriver *s = chr->opaque;
-
- if (!s->connected) {
- /* guest sends data, check for (re-)connect */
- pty_chr_update_read_handler(chr);
- return 0;
- }
- return unix_write(s->fd, buf, len);
-}
-
-static int pty_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- PtyCharDriver *s = chr->opaque;
-
- s->read_bytes = qemu_chr_can_read(chr);
- return s->read_bytes;
-}
-
-static void pty_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- PtyCharDriver *s = chr->opaque;
- int size, len;
- uint8_t buf[1024];
-
- len = sizeof(buf);
- if (len > s->read_bytes)
- len = s->read_bytes;
- if (len == 0)
- return;
- size = read(s->fd, buf, len);
- if ((size == -1 && errno == EIO) ||
- (size == 0)) {
- pty_chr_state(chr, 0);
- return;
- }
- if (size > 0) {
- pty_chr_state(chr, 1);
- qemu_chr_read(chr, buf, size);
- }
-}
-
-static void pty_chr_update_read_handler(CharDriverState *chr)
-{
- PtyCharDriver *s = chr->opaque;
-
- qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
- pty_chr_read, NULL, chr);
- s->polling = 1;
- /*
- * Short timeout here: just need wait long enougth that qemu makes
- * it through the poll loop once. When reconnected we want a
- * short timeout so we notice it almost instantly. Otherwise
- * read() gives us -EIO instantly, making pty_chr_state() reset the
- * timeout to the normal (much longer) poll interval before the
- * timer triggers.
- */
- qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
-}
-
-static void pty_chr_state(CharDriverState *chr, int connected)
-{
- PtyCharDriver *s = chr->opaque;
-
- if (!connected) {
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
- s->connected = 0;
- s->polling = 0;
- /* (re-)connect poll interval for idle guests: once per second.
- * We check more frequently in case the guests sends data to
- * the virtual device linked to our pty. */
- qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
- } else {
- if (!s->connected)
- qemu_chr_reset(chr);
- s->connected = 1;
- }
-}
-
-static void pty_chr_timer(void *opaque)
-{
- struct CharDriverState *chr = opaque;
- PtyCharDriver *s = chr->opaque;
-
- if (s->connected)
- return;
- if (s->polling) {
- /* If we arrive here without polling being cleared due
- * read returning -EIO, then we are (re-)connected */
- pty_chr_state(chr, 1);
- return;
- }
-
- /* Next poll ... */
- pty_chr_update_read_handler(chr);
-}
-
-static void pty_chr_close(struct CharDriverState *chr)
-{
- PtyCharDriver *s = chr->opaque;
-
- qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
- close(s->fd);
- qemu_free(s);
-}
-
-static CharDriverState *qemu_chr_open_pty(void)
-{
- CharDriverState *chr;
- PtyCharDriver *s;
- struct termios tty;
- int slave_fd;
-#if defined(__OpenBSD__)
- char pty_name[PATH_MAX];
-#define q_ptsname(x) pty_name
-#else
- char *pty_name = NULL;
-#define q_ptsname(x) ptsname(x)
-#endif
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(PtyCharDriver));
- if (!s) {
- qemu_free(chr);
- return NULL;
- }
-
- if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
- return NULL;
- }
-
- /* Set raw attributes on the pty. */
- cfmakeraw(&tty);
- tcsetattr(slave_fd, TCSAFLUSH, &tty);
- close(slave_fd);
-
- fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
-
- chr->opaque = s;
- chr->chr_write = pty_chr_write;
- chr->chr_update_read_handler = pty_chr_update_read_handler;
- chr->chr_close = pty_chr_close;
-
- s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
-
- return chr;
-}
-#endif /* __linux__ || __sun__ || __xxxBSD__ */
-
-static void tty_serial_init(int fd, int speed,
- int parity, int data_bits, int stop_bits)
-{
- struct termios tty;
- speed_t spd;
-
-#if 0
- printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
- speed, parity, data_bits, stop_bits);
-#endif
- tcgetattr (fd, &tty);
-
-#define MARGIN 1.1
- if (speed <= 50 * MARGIN)
- spd = B50;
- else if (speed <= 75 * MARGIN)
- spd = B75;
- else if (speed <= 300 * MARGIN)
- spd = B300;
- else if (speed <= 600 * MARGIN)
- spd = B600;
- else if (speed <= 1200 * MARGIN)
- spd = B1200;
- else if (speed <= 2400 * MARGIN)
- spd = B2400;
- else if (speed <= 4800 * MARGIN)
- spd = B4800;
- else if (speed <= 9600 * MARGIN)
- spd = B9600;
- else if (speed <= 19200 * MARGIN)
- spd = B19200;
- else if (speed <= 38400 * MARGIN)
- spd = B38400;
- else if (speed <= 57600 * MARGIN)
- spd = B57600;
- else if (speed <= 115200 * MARGIN)
- spd = B115200;
- else
- spd = B115200;
-
- cfsetispeed(&tty, spd);
- cfsetospeed(&tty, spd);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
- tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
- switch(data_bits) {
- default:
- case 8:
- tty.c_cflag |= CS8;
- break;
- case 7:
- tty.c_cflag |= CS7;
- break;
- case 6:
- tty.c_cflag |= CS6;
- break;
- case 5:
- tty.c_cflag |= CS5;
- break;
- }
- switch(parity) {
- default:
- case 'N':
- break;
- case 'E':
- tty.c_cflag |= PARENB;
- break;
- case 'O':
- tty.c_cflag |= PARENB | PARODD;
- break;
- }
- if (stop_bits == 2)
- tty.c_cflag |= CSTOPB;
-
- tcsetattr (fd, TCSANOW, &tty);
-}
-
-static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
-{
- FDCharDriver *s = chr->opaque;
-
- switch(cmd) {
- case CHR_IOCTL_SERIAL_SET_PARAMS:
- {
- QEMUSerialSetParams *ssp = arg;
- tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
- ssp->data_bits, ssp->stop_bits);
- }
- break;
- case CHR_IOCTL_SERIAL_SET_BREAK:
- {
- int enable = *(int *)arg;
- if (enable)
- tcsendbreak(s->fd_in, 1);
- }
- break;
- case CHR_IOCTL_SERIAL_GET_TIOCM:
- {
- int sarg = 0;
- int *targ = (int *)arg;
- ioctl(s->fd_in, TIOCMGET, &sarg);
- *targ = 0;
- if (sarg | TIOCM_CTS)
- *targ |= CHR_TIOCM_CTS;
- if (sarg | TIOCM_CAR)
- *targ |= CHR_TIOCM_CAR;
- if (sarg | TIOCM_DSR)
- *targ |= CHR_TIOCM_DSR;
- if (sarg | TIOCM_RI)
- *targ |= CHR_TIOCM_RI;
- if (sarg | TIOCM_DTR)
- *targ |= CHR_TIOCM_DTR;
- if (sarg | TIOCM_RTS)
- *targ |= CHR_TIOCM_RTS;
- }
- break;
- case CHR_IOCTL_SERIAL_SET_TIOCM:
- {
- int sarg = *(int *)arg;
- int targ = 0;
- if (sarg | CHR_TIOCM_DTR)
- targ |= TIOCM_DTR;
- if (sarg | CHR_TIOCM_RTS)
- targ |= TIOCM_RTS;
- ioctl(s->fd_in, TIOCMSET, &targ);
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static CharDriverState *qemu_chr_open_tty(const char *filename)
-{
- CharDriverState *chr;
- int fd;
-
- TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
- tty_serial_init(fd, 115200, 'N', 8, 1);
- chr = qemu_chr_open_fd(fd, fd);
- if (!chr) {
- close(fd);
- return NULL;
- }
- chr->chr_ioctl = tty_serial_ioctl;
- qemu_chr_reset(chr);
- return chr;
-}
-
-#if defined(__linux__)
-typedef struct {
- int fd;
- int mode;
-} ParallelCharDriver;
-
-static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
-{
- if (s->mode != mode) {
- int m = mode;
- if (ioctl(s->fd, PPSETMODE, &m) < 0)
- return 0;
- s->mode = mode;
- }
- return 1;
-}
-
-static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
-{
- ParallelCharDriver *drv = chr->opaque;
- int fd = drv->fd;
- uint8_t b;
-
- switch(cmd) {
- case CHR_IOCTL_PP_READ_DATA:
- if (ioctl(fd, PPRDATA, &b) < 0)
- return -ENOTSUP;
- *(uint8_t *)arg = b;
- break;
- case CHR_IOCTL_PP_WRITE_DATA:
- b = *(uint8_t *)arg;
- if (ioctl(fd, PPWDATA, &b) < 0)
- return -ENOTSUP;
- break;
- case CHR_IOCTL_PP_READ_CONTROL:
- if (ioctl(fd, PPRCONTROL, &b) < 0)
- return -ENOTSUP;
- /* Linux gives only the lowest bits, and no way to know data
- direction! For better compatibility set the fixed upper
- bits. */
- *(uint8_t *)arg = b | 0xc0;
- break;
- case CHR_IOCTL_PP_WRITE_CONTROL:
- b = *(uint8_t *)arg;
- if (ioctl(fd, PPWCONTROL, &b) < 0)
- return -ENOTSUP;
- break;
- case CHR_IOCTL_PP_READ_STATUS:
- if (ioctl(fd, PPRSTATUS, &b) < 0)
- return -ENOTSUP;
- *(uint8_t *)arg = b;
- break;
- case CHR_IOCTL_PP_DATA_DIR:
- if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
- return -ENOTSUP;
- break;
- case CHR_IOCTL_PP_EPP_READ_ADDR:
- if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
- struct ParallelIOArg *parg = arg;
- int n = read(fd, parg->buffer, parg->count);
- if (n != parg->count) {
- return -EIO;
- }
- }
- break;
- case CHR_IOCTL_PP_EPP_READ:
- if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
- struct ParallelIOArg *parg = arg;
- int n = read(fd, parg->buffer, parg->count);
- if (n != parg->count) {
- return -EIO;
- }
- }
- break;
- case CHR_IOCTL_PP_EPP_WRITE_ADDR:
- if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
- struct ParallelIOArg *parg = arg;
- int n = write(fd, parg->buffer, parg->count);
- if (n != parg->count) {
- return -EIO;
- }
- }
- break;
- case CHR_IOCTL_PP_EPP_WRITE:
- if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
- struct ParallelIOArg *parg = arg;
- int n = write(fd, parg->buffer, parg->count);
- if (n != parg->count) {
- return -EIO;
- }
- }
- break;
- default:
- return -ENOTSUP;
- }
- return 0;
-}
-
-static void pp_close(CharDriverState *chr)
-{
- ParallelCharDriver *drv = chr->opaque;
- int fd = drv->fd;
-
- pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
- ioctl(fd, PPRELEASE);
- close(fd);
- qemu_free(drv);
-}
-
-static CharDriverState *qemu_chr_open_pp(const char *filename)
-{
- CharDriverState *chr;
- ParallelCharDriver *drv;
- int fd;
-
- TFR(fd = open(filename, O_RDWR));
- if (fd < 0)
- return NULL;
-
- if (ioctl(fd, PPCLAIM) < 0) {
- close(fd);
- return NULL;
- }
-
- drv = qemu_mallocz(sizeof(ParallelCharDriver));
- if (!drv) {
- close(fd);
- return NULL;
- }
- drv->fd = fd;
- drv->mode = IEEE1284_MODE_COMPAT;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr) {
- qemu_free(drv);
- close(fd);
- return NULL;
- }
- chr->chr_write = null_chr_write;
- chr->chr_ioctl = pp_ioctl;
- chr->chr_close = pp_close;
- chr->opaque = drv;
-
- qemu_chr_reset(chr);
-
- return chr;
-}
-#endif /* __linux__ */
-
-#else /* _WIN32 */
-
-typedef struct {
- int max_size;
- HANDLE hcom, hrecv, hsend;
- OVERLAPPED orecv, osend;
- BOOL fpipe;
- DWORD len;
-} WinCharState;
-
-#define NSENDBUF 2048
-#define NRECVBUF 2048
-#define MAXCONNECT 1
-#define NTIMEOUT 5000
-
-static int win_chr_poll(void *opaque);
-static int win_chr_pipe_poll(void *opaque);
-
-static void win_chr_close(CharDriverState *chr)
-{
- WinCharState *s = chr->opaque;
-
- if (s->hsend) {
- CloseHandle(s->hsend);
- s->hsend = NULL;
- }
- if (s->hrecv) {
- CloseHandle(s->hrecv);
- s->hrecv = NULL;
- }
- if (s->hcom) {
- CloseHandle(s->hcom);
- s->hcom = NULL;
- }
- if (s->fpipe)
- qemu_del_polling_cb(win_chr_pipe_poll, chr);
- else
- qemu_del_polling_cb(win_chr_poll, chr);
-}
-
-static int win_chr_init(CharDriverState *chr, const char *filename)
-{
- WinCharState *s = chr->opaque;
- COMMCONFIG comcfg;
- COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
- COMSTAT comstat;
- DWORD size;
- DWORD err;
-
- s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hsend) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
- s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hrecv) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
-
- s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
- if (s->hcom == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
- s->hcom = NULL;
- goto fail;
- }
-
- if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
- fprintf(stderr, "Failed SetupComm\n");
- goto fail;
- }
-
- ZeroMemory(&comcfg, sizeof(COMMCONFIG));
- size = sizeof(COMMCONFIG);
- GetDefaultCommConfig(filename, &comcfg, &size);
- comcfg.dcb.DCBlength = sizeof(DCB);
- CommConfigDialog(filename, NULL, &comcfg);
-
- if (!SetCommState(s->hcom, &comcfg.dcb)) {
- fprintf(stderr, "Failed SetCommState\n");
- goto fail;
- }
-
- if (!SetCommMask(s->hcom, EV_ERR)) {
- fprintf(stderr, "Failed SetCommMask\n");
- goto fail;
- }
-
- cto.ReadIntervalTimeout = MAXDWORD;
- if (!SetCommTimeouts(s->hcom, &cto)) {
- fprintf(stderr, "Failed SetCommTimeouts\n");
- goto fail;
- }
-
- if (!ClearCommError(s->hcom, &err, &comstat)) {
- fprintf(stderr, "Failed ClearCommError\n");
- goto fail;
- }
- qemu_add_polling_cb(win_chr_poll, chr);
- return 0;
-
- fail:
- win_chr_close(chr);
- return -1;
-}
-
-static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
-{
- WinCharState *s = chr->opaque;
- DWORD len, ret, size, err;
-
- len = len1;
- ZeroMemory(&s->osend, sizeof(s->osend));
- s->osend.hEvent = s->hsend;
- while (len > 0) {
- if (s->hsend)
- ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
- else
- ret = WriteFile(s->hcom, buf, len, &size, NULL);
- if (!ret) {
- err = GetLastError();
- if (err == ERROR_IO_PENDING) {
- ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
- if (ret) {
- buf += size;
- len -= size;
- } else {
- break;
- }
- } else {
- break;
- }
- } else {
- buf += size;
- len -= size;
- }
- }
- return len1 - len;
-}
-
-static int win_chr_read_poll(CharDriverState *chr)
-{
- WinCharState *s = chr->opaque;
-
- s->max_size = qemu_chr_can_read(chr);
- return s->max_size;
-}
-
-static void win_chr_readfile(CharDriverState *chr)
-{
- WinCharState *s = chr->opaque;
- int ret, err;
- uint8_t buf[1024];
- DWORD size;
-
- ZeroMemory(&s->orecv, sizeof(s->orecv));
- s->orecv.hEvent = s->hrecv;
- ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
- if (!ret) {
- err = GetLastError();
- if (err == ERROR_IO_PENDING) {
- ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
- }
- }
-
- if (size > 0) {
- qemu_chr_read(chr, buf, size);
- }
-}
-
-static void win_chr_read(CharDriverState *chr)
-{
- WinCharState *s = chr->opaque;
-
- if (s->len > s->max_size)
- s->len = s->max_size;
- if (s->len == 0)
- return;
-
- win_chr_readfile(chr);
-}
-
-static int win_chr_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- WinCharState *s = chr->opaque;
- COMSTAT status;
- DWORD comerr;
-
- ClearCommError(s->hcom, &comerr, &status);
- if (status.cbInQue > 0) {
- s->len = status.cbInQue;
- win_chr_read_poll(chr);
- win_chr_read(chr);
- return 1;
- }
- return 0;
-}
-
-static CharDriverState *qemu_chr_open_win(const char *filename)
-{
- CharDriverState *chr;
- WinCharState *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(WinCharState));
- if (!s) {
- free(chr);
- return NULL;
- }
- chr->opaque = s;
- chr->chr_write = win_chr_write;
- chr->chr_close = win_chr_close;
-
- if (win_chr_init(chr, filename) < 0) {
- free(s);
- free(chr);
- return NULL;
- }
- qemu_chr_reset(chr);
- return chr;
-}
-
-static int win_chr_pipe_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- WinCharState *s = chr->opaque;
- DWORD size;
-
- PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
- if (size > 0) {
- s->len = size;
- win_chr_read_poll(chr);
- win_chr_read(chr);
- return 1;
- }
- return 0;
-}
-
-static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
-{
- WinCharState *s = chr->opaque;
- OVERLAPPED ov;
- int ret;
- DWORD size;
- char openname[256];
-
- s->fpipe = TRUE;
-
- s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hsend) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
- s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (!s->hrecv) {
- fprintf(stderr, "Failed CreateEvent\n");
- goto fail;
- }
-
- snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
- s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
- PIPE_WAIT,
- MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
- if (s->hcom == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
- s->hcom = NULL;
- goto fail;
- }
-
- ZeroMemory(&ov, sizeof(ov));
- ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- ret = ConnectNamedPipe(s->hcom, &ov);
- if (ret) {
- fprintf(stderr, "Failed ConnectNamedPipe\n");
- goto fail;
- }
-
- ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
- if (!ret) {
- fprintf(stderr, "Failed GetOverlappedResult\n");
- if (ov.hEvent) {
- CloseHandle(ov.hEvent);
- ov.hEvent = NULL;
- }
- goto fail;
- }
-
- if (ov.hEvent) {
- CloseHandle(ov.hEvent);
- ov.hEvent = NULL;
- }
- qemu_add_polling_cb(win_chr_pipe_poll, chr);
- return 0;
-
- fail:
- win_chr_close(chr);
- return -1;
-}
-
-
-static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
-{
- CharDriverState *chr;
- WinCharState *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(WinCharState));
- if (!s) {
- free(chr);
- return NULL;
- }
- chr->opaque = s;
- chr->chr_write = win_chr_write;
- chr->chr_close = win_chr_close;
-
- if (win_chr_pipe_init(chr, filename) < 0) {
- free(s);
- free(chr);
- return NULL;
- }
- qemu_chr_reset(chr);
- return chr;
-}
-
-static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
-{
- CharDriverState *chr;
- WinCharState *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(WinCharState));
- if (!s) {
- free(chr);
- return NULL;
- }
- s->hcom = fd_out;
- chr->opaque = s;
- chr->chr_write = win_chr_write;
- qemu_chr_reset(chr);
- return chr;
-}
-
-static CharDriverState *qemu_chr_open_win_con(const char *filename)
-{
- return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
-}
-
-static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
-{
- HANDLE fd_out;
-
- fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (fd_out == INVALID_HANDLE_VALUE)
- return NULL;
-
- return qemu_chr_open_win_file(fd_out);
-}
-#endif /* !_WIN32 */
-
-/***********************************************************/
-/* UDP Net console */
-
-typedef struct {
- int fd;
- SockAddress daddr;
- uint8_t buf[1024];
- int bufcnt;
- int bufptr;
- int max_size;
-} NetCharDriver;
-
-static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- NetCharDriver *s = chr->opaque;
-
- return socket_sendto(s->fd, buf, len, &s->daddr);
-}
-
-static int udp_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- NetCharDriver *s = chr->opaque;
-
- s->max_size = qemu_chr_can_read(chr);
-
- /* If there were any stray characters in the queue process them
- * first
- */
- while (s->max_size > 0 && s->bufptr < s->bufcnt) {
- qemu_chr_read(chr, &s->buf[s->bufptr], 1);
- s->bufptr++;
- s->max_size = qemu_chr_can_read(chr);
- }
- return s->max_size;
-}
-
-static void udp_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- NetCharDriver *s = chr->opaque;
-
- if (s->max_size == 0)
- return;
- s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
- s->bufptr = s->bufcnt;
- if (s->bufcnt <= 0)
- return;
-
- s->bufptr = 0;
- while (s->max_size > 0 && s->bufptr < s->bufcnt) {
- qemu_chr_read(chr, &s->buf[s->bufptr], 1);
- s->bufptr++;
- s->max_size = qemu_chr_can_read(chr);
- }
-}
-
-static void udp_chr_update_read_handler(CharDriverState *chr)
-{
- NetCharDriver *s = chr->opaque;
-
- if (s->fd >= 0) {
- qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
- udp_chr_read, NULL, chr);
- }
-}
-
-int parse_host_port(SockAddress *saddr, const char *str);
-int parse_host_src_port(SockAddress *haddr,
- SockAddress *saddr,
- const char *str);
-#ifndef _WIN32
-static int parse_unix_path(SockAddress *uaddr, const char* str);
-#endif
-
-static CharDriverState *qemu_chr_open_udp(const char *def)
-{
- CharDriverState *chr = NULL;
- NetCharDriver *s = NULL;
- int fd = -1;
- SockAddress saddr;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- goto return_err;
- s = qemu_mallocz(sizeof(NetCharDriver));
- if (!s)
- goto return_err;
-
- fd = socket(PF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- perror("socket(PF_INET, SOCK_DGRAM)");
- goto return_err;
- }
-
- if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
- printf("Could not parse: %s\n", def);
- goto return_err;
- }
-
- if (socket_bind(fd, &saddr) < 0)
- {
- perror("bind");
- goto return_err;
- }
-
- s->fd = fd;
- s->bufcnt = 0;
- s->bufptr = 0;
- chr->opaque = s;
- chr->chr_write = udp_chr_write;
- chr->chr_update_read_handler = udp_chr_update_read_handler;
- return chr;
-
-return_err:
- if (chr)
- free(chr);
- if (s)
- free(s);
- if (fd >= 0)
- closesocket(fd);
- return NULL;
-}
-
-/***********************************************************/
-/* TCP Net console */
-
-typedef struct {
- int fd, listen_fd;
- int connected;
- int max_size;
- int do_telnetopt;
- int do_nodelay;
- int is_unix;
-} TCPCharDriver;
-
-static void tcp_chr_accept(void *opaque);
-
-static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- TCPCharDriver *s = chr->opaque;
- if (s->connected) {
- return send_all(s->fd, buf, len);
- } else {
- /* XXX: indicate an error ? */
- return len;
- }
-}
-
-static int tcp_chr_read_poll(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
- if (!s->connected)
- return 0;
- s->max_size = qemu_chr_can_read(chr);
- return s->max_size;
-}
-
-#define IAC 255
-#define IAC_BREAK 243
-static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
- TCPCharDriver *s,
- uint8_t *buf, int *size)
-{
- /* Handle any telnet client's basic IAC options to satisfy char by
- * char mode with no echo. All IAC options will be removed from
- * the buf and the do_telnetopt variable will be used to track the
- * state of the width of the IAC information.
- *
- * IAC commands come in sets of 3 bytes with the exception of the
- * "IAC BREAK" command and the double IAC.
- */
-
- int i;
- int j = 0;
-
- for (i = 0; i < *size; i++) {
- if (s->do_telnetopt > 1) {
- if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
- /* Double IAC means send an IAC */
- if (j != i)
- buf[j] = buf[i];
- j++;
- s->do_telnetopt = 1;
- } else {
- if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
- /* Handle IAC break commands by sending a serial break */
- qemu_chr_event(chr, CHR_EVENT_BREAK);
- s->do_telnetopt++;
- }
- s->do_telnetopt++;
- }
- if (s->do_telnetopt >= 4) {
- s->do_telnetopt = 1;
- }
- } else {
- if ((unsigned char)buf[i] == IAC) {
- s->do_telnetopt = 2;
- } else {
- if (j != i)
- buf[j] = buf[i];
- j++;
- }
- }
- }
- *size = j;
-}
-
-static void tcp_chr_read(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
- uint8_t buf[1024];
- int len, size;
-
- if (!s->connected || s->max_size <= 0)
- return;
- len = sizeof(buf);
- if (len > s->max_size)
- len = s->max_size;
- size = socket_recv(s->fd, buf, len);
- if (size == 0) {
- /* connection closed */
- s->connected = 0;
- if (s->listen_fd >= 0) {
- qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
- }
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- socket_close(s->fd);
- s->fd = -1;
- } else if (size > 0) {
- if (s->do_telnetopt)
- tcp_chr_process_IAC_bytes(chr, s, buf, &size);
- if (size > 0)
- qemu_chr_read(chr, buf, size);
- }
-}
-
-static void tcp_chr_connect(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
-
- s->connected = 1;
- qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
- tcp_chr_read, NULL, chr);
- qemu_chr_reset(chr);
-}
-
-#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
-static void tcp_chr_telnet_init(int fd)
-{
- char buf[3];
- /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
- IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
- socket_send(fd, (char *)buf, 3);
- IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
- socket_send(fd, (char *)buf, 3);
- IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
- socket_send(fd, (char *)buf, 3);
- IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
- socket_send(fd, (char *)buf, 3);
-}
-
-static void tcp_chr_accept(void *opaque)
-{
- CharDriverState *chr = opaque;
- TCPCharDriver *s = chr->opaque;
- int fd;
-
- for(;;) {
- fd = socket_accept(s->listen_fd, NULL);
- if (fd < 0) {
- return;
- } else if (fd >= 0) {
- if (s->do_telnetopt)
- tcp_chr_telnet_init(fd);
- break;
- }
- }
- socket_set_nonblock(fd);
- if (s->do_nodelay)
- socket_set_nodelay(fd);
- s->fd = fd;
- qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
- tcp_chr_connect(chr);
-}
-
-static void tcp_chr_close(CharDriverState *chr)
-{
- TCPCharDriver *s = chr->opaque;
- if (s->fd >= 0)
- closesocket(s->fd);
- if (s->listen_fd >= 0)
- closesocket(s->listen_fd);
- qemu_free(s);
-}
-
-static CharDriverState *qemu_chr_open_tcp(const char *host_str,
- int is_telnet,
- int is_unix)
-{
- CharDriverState *chr = NULL;
- TCPCharDriver *s = NULL;
- int fd = -1, ret, err;
- int is_listen = 0;
- int is_waitconnect = 1;
- int do_nodelay = 0;
- const char *ptr;
- SockAddress saddr;
-
-#ifndef _WIN32
- if (is_unix) {
- if (parse_unix_path(&saddr, host_str) < 0)
- goto fail;
- } else
-#endif
- {
- if (parse_host_port(&saddr, host_str) < 0)
- goto fail;
- }
-
- ptr = host_str;
- while((ptr = strchr(ptr,','))) {
- ptr++;
- if (!strncmp(ptr,"server",6)) {
- is_listen = 1;
- } else if (!strncmp(ptr,"nowait",6)) {
- is_waitconnect = 0;
- } else if (!strncmp(ptr,"nodelay",6)) {
- do_nodelay = 1;
- } else {
- printf("Unknown option: %s\n", ptr);
- goto fail;
- }
- }
- if (!is_listen)
- is_waitconnect = 0;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- goto fail;
- s = qemu_mallocz(sizeof(TCPCharDriver));
- if (!s)
- goto fail;
-
-#ifndef _WIN32
- if (is_unix)
- fd = socket_create( SOCKET_UNIX, SOCKET_STREAM );
- else
-#endif
- fd = socket_create_inet( SOCKET_STREAM );
-
- if (fd < 0)
- goto fail;
-
- if (!is_waitconnect)
- socket_set_nonblock(fd);
-
- s->connected = 0;
- s->fd = -1;
- s->listen_fd = -1;
- s->is_unix = is_unix;
- s->do_nodelay = do_nodelay && !is_unix;
-
- chr->opaque = s;
- chr->chr_write = tcp_chr_write;
- chr->chr_close = tcp_chr_close;
-
- if (is_listen) {
- /* allow fast reuse */
-#ifndef _WIN32
- if (is_unix) {
- unlink( sock_address_get_path(&saddr) );
- } else
-#endif
- socket_set_xreuseaddr(fd);
-
- if (socket_bind(fd, &saddr) < 0 ||
- socket_listen(fd, 0) < 0)
- goto fail;
-
- s->listen_fd = fd;
- qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
- if (is_telnet)
- s->do_telnetopt = 1;
- } else {
- for(;;) {
- ret = socket_connect(fd, &saddr);
- if (ret < 0) {
- err = errno;
- if (err == EINTR || err == EWOULDBLOCK) {
- } else if (err == EINPROGRESS) {
- break;
-#ifdef _WIN32
- } else if (err == EALREADY) {
- break;
-#endif
- } else {
- goto fail;
- }
- } else {
- s->connected = 1;
- break;
- }
- }
- s->fd = fd;
- socket_set_nodelay(fd);
- if (s->connected)
- tcp_chr_connect(chr);
- else
- qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
- }
-
- if (is_listen && is_waitconnect) {
- printf("QEMU waiting for connection on: %s\n", host_str);
- tcp_chr_accept(chr);
- socket_set_nonblock(s->listen_fd);
- }
-
- return chr;
- fail:
- if (fd >= 0)
- socket_close(fd);
- qemu_free(s);
- qemu_free(chr);
- return NULL;
-}
-
-CharDriverState *qemu_chr_open(const char *filename)
-{
- const char *p;
-
- if (!strcmp(filename, "vc")) {
- return text_console_init(&display_state, 0);
- } else if (strstart(filename, "vc:", &p)) {
- return text_console_init(&display_state, p);
- } else if (!strcmp(filename, "null")) {
- return qemu_chr_open_null();
- } else
- if (strstart(filename, "tcp:", &p)) {
- return qemu_chr_open_tcp(p, 0, 0);
- } else
- if (strstart(filename, "telnet:", &p)) {
- return qemu_chr_open_tcp(p, 1, 0);
- } else
- if (strstart(filename, "udp:", &p)) {
- return qemu_chr_open_udp(p);
- } else
- if (strstart(filename, "mon:", &p)) {
- CharDriverState *drv = qemu_chr_open(p);
- if (drv) {
- drv = qemu_chr_open_mux(drv);
- monitor_init(drv, !nographic);
- return drv;
- }
- printf("Unable to open driver: %s\n", p);
- return 0;
- } else
-#ifndef _WIN32
- if (strstart(filename, "unix:", &p)) {
- return qemu_chr_open_tcp(p, 0, 1);
- } else if (strstart(filename, "file:", &p)) {
- return qemu_chr_open_file_out(p);
- } else if (strstart(filename, "pipe:", &p)) {
- return qemu_chr_open_pipe(p);
- } else if (!strcmp(filename, "pty")) {
- return qemu_chr_open_pty();
- } else if (!strcmp(filename, "stdio")) {
- return qemu_chr_open_stdio();
- } else if (strstart(filename, "fdpair:", &p)) {
- return qemu_chr_open_fdpair(p);
- } else
-#endif
-#if defined(__linux__)
- if (strstart(filename, "/dev/parport", NULL)) {
- return qemu_chr_open_pp(filename);
- } else
-#endif
-#ifndef _WIN32
- if (strstart(filename, "/dev/", NULL)) {
- return qemu_chr_open_tty(filename);
- } else
-#endif
- if (!strcmp(filename, "android-modem")) {
- CharDriverState* cs;
- qemu_chr_open_charpipe( &cs, &android_modem_cs );
- return cs;
- } else if (!strcmp(filename, "android-gps")) {
- CharDriverState* cs;
- qemu_chr_open_charpipe( &cs, &android_gps_cs );
- return cs;
- } else if (!strcmp(filename, "android-kmsg")) {
- return android_kmsg_get_cs();
- } else if (!strcmp(filename, "android-qemud")) {
- return android_qemud_get_cs();
- } else
-#if defined(__linux__)
- if (strstart(filename, "/dev/parport", NULL)) {
- return qemu_chr_open_pp(filename);
- } else
-#endif
-#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
- || defined(__NetBSD__) || defined(__OpenBSD__)
- if (strstart(filename, "/dev/", NULL)) {
- return qemu_chr_open_tty(filename);
- } else
-#endif
-#ifdef _WIN32
- if (strstart(filename, "COM", NULL)) {
- return qemu_chr_open_win(filename);
- } else
- if (strstart(filename, "pipe:", &p)) {
- return qemu_chr_open_win_pipe(p);
- } else
- if (strstart(filename, "con:", NULL)) {
- return qemu_chr_open_win_con(filename);
- } else
- if (strstart(filename, "file:", &p)) {
- return qemu_chr_open_win_file_out(p);
- } else
-#endif
-#ifdef CONFIG_BRLAPI
- if (!strcmp(filename, "braille")) {
- return chr_baum_init();
- } else
-#endif
- {
- return NULL;
- }
-}
-
-void qemu_chr_close(CharDriverState *chr)
-{
- if (chr->chr_close)
- chr->chr_close(chr);
- qemu_free(chr);
-}
-
-/***********************************************************/
-/* network device redirectors */
-
-__attribute__ (( unused ))
-static void hex_dump(FILE *f, const uint8_t *buf, int size)
-{
- int len, i, j, c;
-
- for(i=0;i<size;i+=16) {
- len = size - i;
- if (len > 16)
- len = 16;
- fprintf(f, "%08x ", i);
- for(j=0;j<16;j++) {
- if (j < len)
- fprintf(f, " %02x", buf[i+j]);
- else
- fprintf(f, " ");
- }
- fprintf(f, " ");
- for(j=0;j<len;j++) {
- c = buf[i+j];
- if (c < ' ' || c > '~')
- c = '.';
- fprintf(f, "%c", c);
- }
- fprintf(f, "\n");
- }
-}
-
-static int parse_macaddr(uint8_t *macaddr, const char *p)
-{
- int i;
- char *last_char;
- long int offset;
-
- errno = 0;
- offset = strtol(p, &last_char, 0);
- if (0 == errno && '\0' == *last_char &&
- offset >= 0 && offset <= 0xFFFFFF) {
- macaddr[3] = (offset & 0xFF0000) >> 16;
- macaddr[4] = (offset & 0xFF00) >> 8;
- macaddr[5] = offset & 0xFF;
- return 0;
- } else {
- for(i = 0; i < 6; i++) {
- macaddr[i] = strtol(p, (char **)&p, 16);
- if (i == 5) {
- if (*p != '\0')
- return -1;
- } else {
- if (*p != ':' && *p != '-')
- return -1;
- p++;
- }
- }
- return 0;
- }
-
- return -1;
-}
-
-static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
-{
- const char *p, *p1;
- int len;
- p = *pp;
- p1 = strchr(p, sep);
- if (!p1)
- return -1;
- len = p1 - p;
- p1++;
- if (buf_size > 0) {
- if (len > buf_size - 1)
- len = buf_size - 1;
- memcpy(buf, p, len);
- buf[len] = '\0';
- }
- *pp = p1;
- return 0;
-}
-
-int parse_host_src_port(SockAddress *haddr,
- SockAddress *saddr,
- const char *input_str)
-{
- char *str = strdup(input_str);
- char *host_str = str;
- char *src_str;
- const char *src_str2;
- char *ptr;
-
- /*
- * Chop off any extra arguments at the end of the string which
- * would start with a comma, then fill in the src port information
- * if it was provided else use the "any address" and "any port".
- */
- if ((ptr = strchr(str,',')))
- *ptr = '\0';
-
- if ((src_str = strchr(input_str,'@'))) {
- *src_str = '\0';
- src_str++;
- }
-
- if (parse_host_port(haddr, host_str) < 0)
- goto fail;
-
- src_str2 = src_str;
- if (!src_str || *src_str == '\0')
- src_str2 = ":0";
-
- if (parse_host_port(saddr, src_str2) < 0)
- goto fail;
-
- free(str);
- return(0);
-
-fail:
- free(str);
- return -1;
-}
-
-int parse_host_port(SockAddress *saddr, const char *str)
-{
- char buf[512];
- const char *p, *r;
- uint16_t port;
-
- p = str;
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- return -1;
-
- port = strtol(p, (char **)&r, 0);
- if (r == p)
- return -1;
-
- if (buf[0] == '\0') {
- sock_address_init_inet( saddr, SOCK_ADDRESS_INET_ANY, port );
- } else {
- if (sock_address_init_resolve( saddr, buf, port, 0 ) < 0)
- return -1;
- }
- return 0;
-}
-
-#ifndef _WIN32
-static int
-parse_unix_path(SockAddress* uaddr, const char *str)
-{
- char temp[109];
- const char *p;
- int len;
-
- len = MIN(108, strlen(str));
- p = strchr(str, ',');
- if (p)
- len = MIN(len, p - str);
-
- memcpy(temp, str, len);
- temp[len] = 0;
-
- sock_address_init_unix( uaddr, temp );
- return 0;
-}
-#endif
-
-/* find or alloc a new VLAN */
-VLANState *qemu_find_vlan(int id)
-{
- VLANState **pvlan, *vlan;
- for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
- if (vlan->id == id)
- return vlan;
- }
- vlan = qemu_mallocz(sizeof(VLANState));
- if (!vlan)
- return NULL;
- vlan->id = id;
- vlan->next = NULL;
- pvlan = &first_vlan;
- while (*pvlan != NULL)
- pvlan = &(*pvlan)->next;
- *pvlan = vlan;
- return vlan;
-}
-
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque)
-{
- VLANClientState *vc, **pvc;
- vc = qemu_mallocz(sizeof(VLANClientState));
- if (!vc)
- return NULL;
- vc->fd_read = fd_read;
- vc->fd_can_read = fd_can_read;
- vc->opaque = opaque;
- vc->vlan = vlan;
-
- vc->next = NULL;
- pvc = &vlan->first_client;
- while (*pvc != NULL)
- pvc = &(*pvc)->next;
- *pvc = vc;
- return vc;
-}
-
-void qemu_del_vlan_client(VLANClientState *vc)
-{
- VLANClientState **pvc = &vc->vlan->first_client;
-
- while (*pvc != NULL)
- if (*pvc == vc) {
- *pvc = vc->next;
- free(vc);
- break;
- } else
- pvc = &(*pvc)->next;
-}
-
-int qemu_can_send_packet(VLANClientState *vc1)
-{
- VLANState *vlan = vc1->vlan;
- VLANClientState *vc;
-
- for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
- if (vc != vc1) {
- if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
- return 1;
- }
- }
- return 0;
-}
-
-void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
-{
- VLANState *vlan = vc1->vlan;
- VLANClientState *vc;
-
-#if 0
- printf("vlan %d send:\n", vlan->id);
- hex_dump(stdout, buf, size);
-#endif
- for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
- if (vc != vc1) {
- vc->fd_read(vc->opaque, buf, size);
- }
- }
-}
-
-#if defined(CONFIG_SLIRP)
-
-/* slirp network adapter */
-
-int slirp_inited;
-static VLANClientState *slirp_vc;
-
-double qemu_net_upload_speed = 0.;
-double qemu_net_download_speed = 0.;
-int qemu_net_min_latency = 0;
-int qemu_net_max_latency = 0;
-int qemu_net_disable = 0;
-
-int
-ip_packet_is_internal( const uint8_t* data, size_t size )
-{
- const uint8_t* end = data + size;
-
- /* must have room for Mac + IP header */
- if (data + 40 > end)
- return 0;
-
- if (data[12] != 0x08 || data[13] != 0x00 )
- return 0;
-
- /* must have valid IP header */
- data += 14;
- if ((data[0] >> 4) != 4 || (data[0] & 15) < 5)
- return 0;
-
- /* internal if both source and dest addresses are in 10.x.x.x */
- return ( data[12] == 10 && data[16] == 10);
-}
-
-#ifdef CONFIG_SHAPER
-
-/* see http://en.wikipedia.org/wiki/List_of_device_bandwidths or a complete list */
-const NetworkSpeed android_netspeeds[] = {
- { "gsm", "GSM/CSD", 14400, 14400 },
- { "hscsd", "HSCSD", 14400, 43200 },
- { "gprs", "GPRS", 40000, 80000 },
- { "edge", "EDGE/EGPRS", 118400, 236800 },
- { "umts", "UMTS/3G", 128000, 1920000 },
- { "hsdpa", "HSDPA", 348000, 14400000 },
- { "full", "no limit", 0, 0 },
- { NULL, NULL, 0, 0 }
-};
-
-const NetworkLatency android_netdelays[] = {
- /* FIXME: these numbers are totally imaginary */
- { "gprs", "GPRS", 150, 550 },
- { "edge", "EDGE/EGPRS", 80, 400 },
- { "umts", "UMTS/3G", 35, 200 },
- { "none", "no latency", 0, 0 },
- { NULL, NULL, 0, 0 }
-};
-
-
-NetShaper slirp_shaper_in;
-NetShaper slirp_shaper_out;
-NetDelay slirp_delay_in;
-
-static void
-slirp_delay_in_cb( void* data,
- size_t size,
- void* opaque )
-{
- slirp_input( (const uint8_t*)data, (int)size );
- opaque = opaque;
-}
-
-static void
-slirp_shaper_in_cb( void* data,
- size_t size,
- void* opaque )
-{
- netdelay_send_aux( slirp_delay_in, data, size, opaque );
-}
-
-static void
-slirp_shaper_out_cb( void* data,
- size_t size,
- void* opaque )
-{
- qemu_send_packet( slirp_vc, (const uint8_t*)data, (int)size );
-}
-
-void
-slirp_init_shapers( void )
-{
- slirp_delay_in = netdelay_create( slirp_delay_in_cb );
- slirp_shaper_in = netshaper_create( 1, slirp_shaper_in_cb );
- slirp_shaper_out = netshaper_create( 1, slirp_shaper_out_cb );
-
- netdelay_set_latency( slirp_delay_in, qemu_net_min_latency, qemu_net_max_latency );
- netshaper_set_rate( slirp_shaper_out, qemu_net_download_speed );
- netshaper_set_rate( slirp_shaper_in, qemu_net_upload_speed );
-}
-
-#endif /* CONFIG_SHAPER */
-
-int slirp_can_output(void)
-{
-#ifdef CONFIG_SHAPER
- return !slirp_vc ||
- ( netshaper_can_send( slirp_shaper_out ) &&
- qemu_can_send_packet(slirp_vc) );
-#else
- return !slirp_vc || qemu_can_send_packet(slirp_vc);
-#endif
-}
-
-
-
-void slirp_output(const uint8_t *pkt, int pkt_len)
-{
-#if 0
- printf("slirp output:\n");
- hex_dump(stdout, pkt, pkt_len);
-#endif
- if (!slirp_vc)
- return;
-
- if (qemu_tcpdump_active)
- qemu_tcpdump_packet(pkt, pkt_len);
-
- /* always send internal packets */
- if ( ip_packet_is_internal( pkt, pkt_len ) ) {
- qemu_send_packet( slirp_vc, pkt, pkt_len );
- return;
- }
-
- if ( qemu_net_disable )
- return;
-
-#ifdef CONFIG_SHAPER
- netshaper_send( slirp_shaper_out, (void*)pkt, pkt_len );
-#else
- qemu_send_packet(slirp_vc, pkt, pkt_len);
-#endif
-}
-
-static void slirp_receive(void *opaque, const uint8_t *buf, int size)
-{
-#if 0
- printf("slirp input:\n");
- hex_dump(stdout, buf, size);
-#endif
- if (qemu_tcpdump_active)
- qemu_tcpdump_packet(buf, size);
-
- if ( ip_packet_is_internal( buf, size ) ) {
- slirp_input(buf, size);
- return;
- }
-
- if (qemu_net_disable)
- return;
-
-#ifdef CONFIG_SHAPER
- netshaper_send( slirp_shaper_in, (char*)buf, size );
-#else
- slirp_input(buf, size);
-#endif
-}
-
-static int net_slirp_init(VLANState *vlan)
-{
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
- slirp_vc = qemu_new_vlan_client(vlan,
- slirp_receive, NULL, NULL);
- snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
- return 0;
-}
-
-static void net_slirp_redir(const char *redir_str)
-{
- int is_udp;
- char buf[256], *r;
- const char *p;
- uint32_t guest_ip;
- int host_port, guest_port;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- p = redir_str;
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- if (!strcmp(buf, "tcp")) {
- is_udp = 0;
- } else if (!strcmp(buf, "udp")) {
- is_udp = 1;
- } else {
- goto fail;
- }
-
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- host_port = strtol(buf, &r, 0);
- if (r == buf)
- goto fail;
-
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- if (buf[0] == '\0') {
- pstrcpy(buf, sizeof(buf), "10.0.2.15");
- }
- if (inet_strtoip(buf, &guest_ip) < 0)
- goto fail;
-
- guest_port = strtol(p, &r, 0);
- if (r == p)
- goto fail;
-
- if (slirp_redir(is_udp, host_port, guest_ip, guest_port) < 0) {
- fprintf(stderr, "qemu: could not set up redirection\n");
- exit(1);
- }
- return;
- fail:
- fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
- exit(1);
-}
-
-#if 0 /* ANDROID disabled */
-
-char smb_dir[1024];
-
-static void erase_dir(char *dir_name)
-{
- DIR *d;
- struct dirent *de;
- char filename[1024];
-
- /* erase all the files in the directory */
- if ((d = opendir(dir_name)) != 0) {
- for(;;) {
- de = readdir(d);
- if (!de)
- break;
- if (strcmp(de->d_name, ".") != 0 &&
- strcmp(de->d_name, "..") != 0) {
- snprintf(filename, sizeof(filename), "%s/%s",
- smb_dir, de->d_name);
- if (unlink(filename) != 0) /* is it a directory? */
- erase_dir(filename);
- }
- }
- closedir(d);
- rmdir(dir_name);
- }
-}
-
-/* automatic user mode samba server configuration */
-static void smb_exit(void)
-{
- erase_dir(smb_dir);
-}
-
-/* automatic user mode samba server configuration */
-static void net_slirp_smb(const char *exported_dir)
-{
- char smb_conf[1024];
- char smb_cmdline[1024];
- FILE *f;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- /* XXX: better tmp dir construction */
- snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
- if (mkdir(smb_dir, 0700) < 0) {
- fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
- exit(1);
- }
- snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
-
- f = fopen(smb_conf, "w");
- if (!f) {
- fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
- exit(1);
- }
- fprintf(f,
- "[global]\n"
- "private dir=%s\n"
- "smb ports=0\n"
- "socket address=127.0.0.1\n"
- "pid directory=%s\n"
- "lock directory=%s\n"
- "log file=%s/log.smbd\n"
- "smb passwd file=%s/smbpasswd\n"
- "security = share\n"
- "[qemu]\n"
- "path=%s\n"
- "read only=no\n"
- "guest ok=yes\n",
- smb_dir,
- smb_dir,
- smb_dir,
- smb_dir,
- smb_dir,
- exported_dir
- );
- fclose(f);
- atexit(smb_exit);
-
- snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
- SMBD_COMMAND, smb_conf);
-
- slirp_add_exec(0, smb_cmdline, 4, 139);
-}
-
-#endif /* !defined(_WIN32) */
-
-#endif /* CONFIG_SLIRP */
-
-#if !defined(_WIN32)
-
-typedef struct TAPState {
- VLANClientState *vc;
- int fd;
- char down_script[1024];
-} TAPState;
-
-static void tap_receive(void *opaque, const uint8_t *buf, int size)
-{
- TAPState *s = opaque;
- int ret;
- for(;;) {
- ret = write(s->fd, buf, size);
- if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
- } else {
- break;
- }
- }
-}
-
-static void tap_send(void *opaque)
-{
- TAPState *s = opaque;
- uint8_t buf[4096];
- int size;
-
-#ifdef __sun__
- struct strbuf sbuf;
- int f = 0;
- sbuf.maxlen = sizeof(buf);
- sbuf.buf = buf;
- size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
-#else
- size = read(s->fd, buf, sizeof(buf));
-#endif
- if (size > 0) {
- qemu_send_packet(s->vc, buf, size);
- }
-}
-
-/* fd support */
-
-static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
-{
- TAPState *s;
-
- s = qemu_mallocz(sizeof(TAPState));
- if (!s)
- return NULL;
- s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
- qemu_set_fd_handler(s->fd, tap_send, NULL, s);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
- return s;
-}
-
-#if defined (_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size)
-{
- int fd;
- char *dev;
- struct stat s;
-
- TFR(fd = open("/dev/tap", O_RDWR));
- if (fd < 0) {
- fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
- return -1;
- }
-
- fstat(fd, &s);
- dev = devname(s.st_rdev, S_IFCHR);
- pstrcpy(ifname, ifname_size, dev);
-
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#elif defined(__sun__)
-#define TUNNEWPPA (('T'<<16) | 0x0001)
-/*
- * Allocate TAP device, returns opened fd.
- * Stores dev name in the first arg(must be large enough).
- */
-int tap_alloc(char *dev, size_t dev_size)
-{
- int tap_fd, if_fd, ppa = -1;
- static int ip_fd = 0;
- char *ptr;
-
- static int arp_fd = 0;
- int ip_muxid, arp_muxid;
- struct strioctl strioc_if, strioc_ppa;
- int link_type = I_PLINK;;
- struct lifreq ifr;
- char actual_name[32] = "";
-
- memset(&ifr, 0x0, sizeof(ifr));
-
- if( *dev ){
- ptr = dev;
- while( *ptr && !isdigit((int)*ptr) ) ptr++;
- ppa = atoi(ptr);
- }
-
- /* Check if IP device was opened */
- if( ip_fd )
- close(ip_fd);
-
- TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
- if (ip_fd < 0) {
- syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
- return -1;
- }
-
- TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
- if (tap_fd < 0) {
- syslog(LOG_ERR, "Can't open /dev/tap");
- return -1;
- }
-
- /* Assign a new PPA and get its unit number. */
- strioc_ppa.ic_cmd = TUNNEWPPA;
- strioc_ppa.ic_timout = 0;
- strioc_ppa.ic_len = sizeof(ppa);
- strioc_ppa.ic_dp = (char *)&ppa;
- if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
- syslog (LOG_ERR, "Can't assign new interface");
-
- TFR(if_fd = open("/dev/tap", O_RDWR, 0));
- if (if_fd < 0) {
- syslog(LOG_ERR, "Can't open /dev/tap (2)");
- return -1;
- }
- if(ioctl(if_fd, I_PUSH, "ip") < 0){
- syslog(LOG_ERR, "Can't push IP module");
- return -1;
- }
-
- if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
- syslog(LOG_ERR, "Can't get flags\n");
-
- snprintf (actual_name, 32, "tap%d", ppa);
- strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
-
- ifr.lifr_ppa = ppa;
- /* Assign ppa according to the unit number returned by tun device */
-
- if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
- syslog (LOG_ERR, "Can't set PPA %d", ppa);
- if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
- syslog (LOG_ERR, "Can't get flags\n");
- /* Push arp module to if_fd */
- if (ioctl (if_fd, I_PUSH, "arp") < 0)
- syslog (LOG_ERR, "Can't push ARP module (2)");
-
- /* Push arp module to ip_fd */
- if (ioctl (ip_fd, I_POP, NULL) < 0)
- syslog (LOG_ERR, "I_POP failed\n");
- if (ioctl (ip_fd, I_PUSH, "arp") < 0)
- syslog (LOG_ERR, "Can't push ARP module (3)\n");
- /* Open arp_fd */
- TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
- if (arp_fd < 0)
- syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
-
- /* Set ifname to arp */
- strioc_if.ic_cmd = SIOCSLIFNAME;
- strioc_if.ic_timout = 0;
- strioc_if.ic_len = sizeof(ifr);
- strioc_if.ic_dp = (char *)&ifr;
- if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
- syslog (LOG_ERR, "Can't set ifname to arp\n");
- }
-
- if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
- syslog(LOG_ERR, "Can't link TAP device to IP");
- return -1;
- }
-
- if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
- syslog (LOG_ERR, "Can't link TAP device to ARP");
-
- close (if_fd);
-
- memset(&ifr, 0x0, sizeof(ifr));
- strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
- ifr.lifr_ip_muxid = ip_muxid;
- ifr.lifr_arp_muxid = arp_muxid;
-
- if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
- {
- ioctl (ip_fd, I_PUNLINK , arp_muxid);
- ioctl (ip_fd, I_PUNLINK, ip_muxid);
- syslog (LOG_ERR, "Can't set multiplexor id");
- }
-
- snprintf(dev, dev_size, "tap%d", ppa);
- return tap_fd;
-}
-
-static int tap_open(char *ifname, int ifname_size)
-{
- char dev[10]="";
- int fd;
- if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
- fprintf(stderr, "Cannot allocate TAP device\n");
- return -1;
- }
- pstrcpy(ifname, ifname_size, dev);
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#else
-static int tap_open(char *ifname, int ifname_size)
-{
- struct ifreq ifr;
- int fd, ret;
-
- TFR(fd = open("/dev/net/tun", O_RDWR));
- if (fd < 0) {
- fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
- return -1;
- }
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- if (ifname[0] != '\0')
- pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
- else
- pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
- ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (ret != 0) {
- fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
- close(fd);
- return -1;
- }
- pstrcpy(ifname, ifname_size, ifr.ifr_name);
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#endif
-
-static int launch_script(const char *setup_script, const char *ifname, int fd)
-{
- int pid, status;
- char *args[3];
- char **parg;
-
- /* try to launch network script */
- pid = fork();
- if (pid >= 0) {
- if (pid == 0) {
- int open_max = sysconf (_SC_OPEN_MAX), i;
- for (i = 0; i < open_max; i++)
- if (i != STDIN_FILENO &&
- i != STDOUT_FILENO &&
- i != STDERR_FILENO &&
- i != fd)
- close(i);
-
- parg = args;
- *parg++ = (char *)setup_script;
- *parg++ = (char *)ifname;
- *parg++ = NULL;
- execv(setup_script, args);
- _exit(1);
- }
- while (waitpid(pid, &status, 0) != pid);
- if (!WIFEXITED(status) ||
- WEXITSTATUS(status) != 0) {
- fprintf(stderr, "%s: could not launch network script\n",
- setup_script);
- return -1;
- }
- }
- return 0;
-}
-
-static int net_tap_init(VLANState *vlan, const char *ifname1,
- const char *setup_script, const char *down_script)
-{
- TAPState *s;
- int fd;
- char ifname[128];
-
- if (ifname1 != NULL)
- pstrcpy(ifname, sizeof(ifname), ifname1);
- else
- ifname[0] = '\0';
- TFR(fd = tap_open(ifname, sizeof(ifname)));
- if (fd < 0)
- return -1;
-
- if (!setup_script || !strcmp(setup_script, "no"))
- setup_script = "";
- if (setup_script[0] != '\0') {
- if (launch_script(setup_script, ifname, fd))
- return -1;
- }
- s = net_tap_fd_init(vlan, fd);
- if (!s)
- return -1;
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "tap: ifname=%s setup_script=%s", ifname, setup_script);
- if (down_script && strcmp(down_script, "no"))
- snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
- return 0;
-}
-
-#endif /* !_WIN32 */
-
-#if defined(CONFIG_VDE)
-typedef struct VDEState {
- VLANClientState *vc;
- VDECONN *vde;
-} VDEState;
-
-static void vde_to_qemu(void *opaque)
-{
- VDEState *s = opaque;
- uint8_t buf[4096];
- int size;
-
- size = vde_recv(s->vde, buf, sizeof(buf), 0);
- if (size > 0) {
- qemu_send_packet(s->vc, buf, size);
- }
-}
-
-static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
-{
- VDEState *s = opaque;
- int ret;
- for(;;) {
- ret = vde_send(s->vde, buf, size, 0);
- if (ret < 0 && errno == EINTR) {
- } else {
- break;
- }
- }
-}
-
-static int net_vde_init(VLANState *vlan, const char *sock, int port,
- const char *group, int mode)
-{
- VDEState *s;
- char *init_group = strlen(group) ? (char *)group : NULL;
- char *init_sock = strlen(sock) ? (char *)sock : NULL;
-
- struct vde_open_args args = {
- .port = port,
- .group = init_group,
- .mode = mode,
- };
-
- s = qemu_mallocz(sizeof(VDEState));
- if (!s)
- return -1;
- s->vde = vde_open(init_sock, "QEMU", &args);
- if (!s->vde){
- free(s);
- return -1;
- }
- s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
- qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
- sock, vde_datafd(s->vde));
- return 0;
-}
-#endif
-
-/* network connection */
-typedef struct NetSocketState {
- VLANClientState *vc;
- int fd;
- int state; /* 0 = getting length, 1 = getting data */
- int index;
- int packet_len;
- uint8_t buf[4096];
- SockAddress dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
-} NetSocketState;
-
-typedef struct NetSocketListenState {
- VLANState *vlan;
- int fd;
-} NetSocketListenState;
-
-/* XXX: we consider we can send the whole packet without blocking */
-static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
-{
- NetSocketState *s = opaque;
- uint32_t len;
- len = htonl(size);
-
- send_all(s->fd, (const uint8_t *)&len, sizeof(len));
- send_all(s->fd, buf, size);
-}
-
-static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
-{
- NetSocketState *s = opaque;
- socket_sendto(s->fd, buf, size, &s->dgram_dst);
-}
-
-static void net_socket_send(void *opaque)
-{
- NetSocketState *s = opaque;
- int l, size, err;
- uint8_t buf1[4096];
- const uint8_t *buf;
-
- size = socket_recv(s->fd, buf1, sizeof(buf1));
- if (size < 0) {
- err = errno;
- if (err != EWOULDBLOCK)
- goto eoc;
- } else if (size == 0) {
- /* end of connection */
- eoc:
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- socket_close(s->fd);
- return;
- }
- buf = buf1;
- while (size > 0) {
- /* reassemble a packet from the network */
- switch(s->state) {
- case 0:
- l = 4 - s->index;
- if (l > size)
- l = size;
- memcpy(s->buf + s->index, buf, l);
- buf += l;
- size -= l;
- s->index += l;
- if (s->index == 4) {
- /* got length */
- s->packet_len = ntohl(*(uint32_t *)s->buf);
- s->index = 0;
- s->state = 1;
- }
- break;
- case 1:
- l = s->packet_len - s->index;
- if (l > size)
- l = size;
- memcpy(s->buf + s->index, buf, l);
- s->index += l;
- buf += l;
- size -= l;
- if (s->index >= s->packet_len) {
- qemu_send_packet(s->vc, s->buf, s->packet_len);
- s->index = 0;
- s->state = 0;
- }
- break;
- }
- }
-}
-
-static void net_socket_send_dgram(void *opaque)
-{
- NetSocketState *s = opaque;
- int size;
-
- size = socket_recv(s->fd, s->buf, sizeof(s->buf));
- if (size < 0)
- return;
- if (size == 0) {
- /* end of connection */
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
- return;
- }
- qemu_send_packet(s->vc, s->buf, size);
-}
-
-static int net_socket_mcast_create(SockAddress* mcastaddr)
-{
- uint32_t mcast_ip = (uint32_t) sock_address_get_ip(mcastaddr);
-
- int fd, ret;
-
- if (!IN_MULTICAST(mcast_ip)) {
- fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" does not contain a multicast address\n",
- sock_address_to_string(mcastaddr));
- return -1;
-
- }
- fd = socket_create_inet( SOCKET_DGRAM );
- if (fd < 0) {
- perror("socket(PF_INET, SOCK_DGRAM)");
- return -1;
- }
-
-#if 0
- val = 1;
- ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (const char *)&val, sizeof(val));
-#else
- ret=socket_set_xreuseaddr(fd);
-#endif
- if (ret < 0) {
- perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
- goto fail;
- }
-
- if (socket_bind(fd, mcastaddr) < 0) {
- perror("bind");
- goto fail;
- }
-
- /* Add host to multicast group */
- if (socket_mcast_inet_add_membership(fd, mcast_ip) < 0) {
- perror("setsockopt(IP_ADD_MEMBERSHIP)");
- goto fail;
- }
-
- /* Force mcast msgs to loopback (eg. several QEMUs in same host */
- if (socket_mcast_inet_set_loop(fd, 1) < 0) {
- perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
- goto fail;
- }
-
- socket_set_nonblock(fd);
- return fd;
-fail:
- if (fd >= 0)
- closesocket(fd);
- return -1;
-}
-
-static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
- int is_connected)
-{
- SockAddress saddr;
- int newfd;
- NetSocketState *s;
-
- /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
- * Because this may be "shared" socket from a "master" process, datagrams would be recv()
- * by ONLY ONE process: we must "clone" this dgram socket --jjo
- */
-
- if (is_connected) {
- if (socket_get_address(fd, &saddr) == 0) {
- /* must be bound */
- if (sock_address_get_ip(&saddr) == 0) {
- fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
- fd);
- return NULL;
- }
- /* clone dgram socket */
- newfd = net_socket_mcast_create(&saddr);
- if (newfd < 0) {
- /* error already reported by net_socket_mcast_create() */
- close(fd);
- return NULL;
- }
- /* clone newfd to fd, close newfd */
- dup2(newfd, fd);
- close(newfd);
-
- } else {
- fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
- fd, errno_str);
- return NULL;
- }
- }
-
- s = qemu_mallocz(sizeof(NetSocketState));
- if (!s)
- return NULL;
- s->fd = fd;
-
- s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
- qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
-
- /* mcast: save bound address as dst */
- if (is_connected) s->dgram_dst=saddr;
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: fd=%d (%s mcast=%s)",
- fd, is_connected? "cloned" : "",
- sock_address_to_string(&saddr));
- return s;
-}
-
-static void net_socket_connect(void *opaque)
-{
- NetSocketState *s = opaque;
- qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
-}
-
-static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
- int is_connected)
-{
- NetSocketState *s;
- s = qemu_mallocz(sizeof(NetSocketState));
- if (!s)
- return NULL;
- s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan,
- net_socket_receive, NULL, s);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: fd=%d", fd);
- if (is_connected) {
- net_socket_connect(s);
- } else {
- qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
- }
- return s;
-}
-
-static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
- int is_connected)
-{
- SocketType so_type;
-
- so_type = socket_get_type(fd);
- switch(so_type) {
- case SOCKET_DGRAM:
- return net_socket_fd_init_dgram(vlan, fd, is_connected);
- case SOCKET_STREAM:
- return net_socket_fd_init_stream(vlan, fd, is_connected);
- default:
- /* who knows ... this could be a eg. a pty, do warn and continue as stream */
- fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
- return net_socket_fd_init_stream(vlan, fd, is_connected);
- }
- return NULL;
-}
-
-static void net_socket_accept(void *opaque)
-{
- NetSocketListenState *s = opaque;
- NetSocketState *s1;
- SockAddress saddr;
- int fd;
-
- fd = socket_accept(s->fd, &saddr);
- if (fd < 0)
- return;
-
- s1 = net_socket_fd_init(s->vlan, fd, 1);
- if (!s1) {
- closesocket(fd);
- } else {
- snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
- "socket: connection from %s",
- sock_address_to_string(&saddr));
- }
- sock_address_done(&saddr);
-}
-
-static int net_socket_listen_init(VLANState *vlan, const char *host_str)
-{
- NetSocketListenState *s;
- int fd, ret;
- SockAddress saddr;
-
- if (parse_host_port(&saddr, host_str) < 0)
- return -1;
-
- s = qemu_mallocz(sizeof(NetSocketListenState));
- if (!s)
- return -1;
-
- fd = socket_create_inet( SOCKET_STREAM );
- if (fd < 0) {
- perror("socket");
- return -1;
- }
- socket_set_nonblock(fd);
-#if 0
- /* allow fast reuse */
- val = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
-#else
- socket_set_xreuseaddr(fd);
-#endif
-
- ret = socket_bind(fd, &saddr);
- if (ret < 0) {
- perror("bind");
- socket_close(fd);
- return -1;
- }
- ret = socket_listen(fd, 0);
- if (ret < 0) {
- perror("listen");
- socket_close(fd);
- return -1;
- }
- s->vlan = vlan;
- s->fd = fd;
- qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
- return 0;
-}
-
-static int net_socket_connect_init(VLANState *vlan, const char *host_str)
-{
- NetSocketState *s;
- int fd, connected, ret, err;
- SockAddress saddr;
-
- if (parse_host_port(&saddr, host_str) < 0)
- return -1;
-
- fd = socket_create_inet( SOCKET_STREAM );
- if (fd < 0) {
- perror("socket");
- return -1;
- }
- socket_set_nonblock(fd);
-
- connected = 0;
- for(;;) {
- ret = socket_connect(fd, &saddr);
- if (ret < 0) {
- err = errno;
- if (err == EINTR || err == EWOULDBLOCK) {
- } else if (err == EINPROGRESS) {
- break;
-#ifdef _WIN32
- } else if (err == EALREADY) {
- break;
-#endif
- } else {
- perror("connect");
- socket_close(fd);
- return -1;
- }
- } else {
- connected = 1;
- break;
- }
- }
- s = net_socket_fd_init(vlan, fd, connected);
- if (!s)
- return -1;
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: connect to %s", sock_address_to_string(&saddr));
- return 0;
-}
-
-static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
-{
- NetSocketState *s;
- int fd;
- SockAddress saddr;
-
- if (parse_host_port(&saddr, host_str) < 0)
- return -1;
-
-
- fd = net_socket_mcast_create(&saddr);
- if (fd < 0)
- return -1;
-
- s = net_socket_fd_init(vlan, fd, 0);
- if (!s)
- return -1;
-
- s->dgram_dst = saddr;
-
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "socket: mcast=%s", sock_address_to_string(&saddr));
- return 0;
-
-}
-
-static const char *get_opt_name(char *buf, int buf_size, const char *p)
-{
- char *q;
-
- q = buf;
- while (*p != '\0' && *p != '=') {
- if (q && (q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- if (q)
- *q = '\0';
-
- return p;
-}
-
-static const char *get_opt_value(char *buf, int buf_size, const char *p)
-{
- char *q;
-
- q = buf;
- while (*p != '\0') {
- if (*p == ',') {
- if (*(p + 1) != ',')
- break;
- p++;
- }
- if (q && (q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- if (q)
- *q = '\0';
-
- return p;
-}
-
-static int get_param_value(char *buf, int buf_size,
- const char *tag, const char *str)
-{
- const char *p;
- char option[128];
-
- p = str;
- for(;;) {
- p = get_opt_name(option, sizeof(option), p);
- if (*p != '=')
- break;
- p++;
- if (!strcmp(tag, option)) {
- (void)get_opt_value(buf, buf_size, p);
- return strlen(buf);
- } else {
- p = get_opt_value(NULL, 0, p);
- }
- if (*p != ',')
- break;
- p++;
- }
- return 0;
-}
-
-static int check_params(char *buf, int buf_size,
- const char * const *params, const char *str)
-{
- const char *p;
- int i;
-
- p = str;
- for(;;) {
- p = get_opt_name(buf, buf_size, p);
- if (*p != '=')
- return -1;
- p++;
- for(i = 0; params[i] != NULL; i++)
- if (!strcmp(params[i], buf))
- break;
- if (params[i] == NULL)
- return -1;
- p = get_opt_value(NULL, 0, p);
- if (*p != ',')
- break;
- p++;
- }
- return 0;
-}
-
-static int net_client_init(const char *device, const char *p)
-{
- char buf[1024];
- int vlan_id, ret;
- VLANState *vlan;
-
- vlan_id = 0;
- if (get_param_value(buf, sizeof(buf), "vlan", p)) {
- vlan_id = strtol(buf, NULL, 0);
- }
- vlan = qemu_find_vlan(vlan_id);
- if (!vlan) {
- fprintf(stderr, "Could not create vlan %d\n", vlan_id);
- return -1;
- }
- if (!strcmp(device, "nic")) {
- NICInfo *nd;
- uint8_t *macaddr;
-
- if (nb_nics >= MAX_NICS) {
- fprintf(stderr, "Too Many NICs\n");
- return -1;
- }
- nd = &nd_table[nb_nics];
- macaddr = nd->macaddr;
- macaddr[0] = 0x52;
- macaddr[1] = 0x54;
- macaddr[2] = 0x00;
- macaddr[3] = 0x12;
- macaddr[4] = 0x34;
- macaddr[5] = 0x56 + nb_nics;
-
- if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
- if (parse_macaddr(macaddr, buf) < 0) {
- fprintf(stderr, "invalid syntax for ethernet address\n");
- return -1;
- }
- }
- if (get_param_value(buf, sizeof(buf), "model", p)) {
- nd->model = strdup(buf);
- }
- nd->vlan = vlan;
- nb_nics++;
- vlan->nb_guest_devs++;
- ret = 0;
- } else
- if (!strcmp(device, "none")) {
- /* does nothing. It is needed to signal that no network cards
- are wanted */
-#if 1 /* ANDROID */
- fprintf(stderr, "sorry, you need to enable the network to use the Android emulator\n");
- return -1;
-#else
- ret = 0;
-#endif
- } else
-#ifdef CONFIG_SLIRP
- if (!strcmp(device, "user")) {
- if (get_param_value(buf, sizeof(buf), "hostname", p)) {
- pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
- }
- vlan->nb_host_devs++;
- ret = net_slirp_init(vlan);
- } else
-#endif
-#ifdef _WIN32
-#if 0
- if (!strcmp(device, "tap")) {
- char ifname[64];
- if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
- fprintf(stderr, "tap: no interface name\n");
- return -1;
- }
- vlan->nb_host_devs++;
- ret = tap_win32_init(vlan, ifname);
- } else
-#endif
-#else
- if (!strcmp(device, "tap")) {
- char ifname[64];
- char setup_script[1024], down_script[1024];
- int fd;
- vlan->nb_host_devs++;
- if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
- fd = strtol(buf, NULL, 0);
- socket_set_nonblock(fd);
- ret = -1;
- if (net_tap_fd_init(vlan, fd))
- ret = 0;
- } else {
- if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
- ifname[0] = '\0';
- }
- if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
- pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
- }
- if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
- pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
- }
- ret = net_tap_init(vlan, ifname, setup_script, down_script);
- }
- } else
-#endif
- if (!strcmp(device, "socket")) {
- if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
- int fd;
- fd = strtol(buf, NULL, 0);
- ret = -1;
- if (net_socket_fd_init(vlan, fd, 1))
- ret = 0;
- } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
- ret = net_socket_listen_init(vlan, buf);
- } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
- ret = net_socket_connect_init(vlan, buf);
- } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
- ret = net_socket_mcast_init(vlan, buf);
- } else {
- fprintf(stderr, "Unknown socket options: %s\n", p);
- return -1;
- }
- vlan->nb_host_devs++;
- } else
-#ifdef CONFIG_VDE
- if (!strcmp(device, "vde")) {
- char vde_sock[1024], vde_group[512];
- int vde_port, vde_mode;
- vlan->nb_host_devs++;
- if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
- vde_sock[0] = '\0';
- }
- if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
- vde_port = strtol(buf, NULL, 10);
- } else {
- vde_port = 0;
- }
- if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
- vde_group[0] = '\0';
- }
- if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
- vde_mode = strtol(buf, NULL, 8);
- } else {
- vde_mode = 0700;
- }
- ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
- } else
-#endif
- {
- fprintf(stderr, "Unknown network device: %s\n", device);
- return -1;
- }
- if (ret < 0) {
- fprintf(stderr, "Could not initialize device '%s'\n", device);
- }
-
- return ret;
-}
-
-static int net_client_parse(const char *str)
-{
- const char *p;
- char *q;
- char device[64];
-
- p = str;
- q = device;
- while (*p != '\0' && *p != ',') {
- if ((q - device) < sizeof(device) - 1)
- *q++ = *p;
- p++;
- }
- *q = '\0';
- if (*p == ',')
- p++;
-
- return net_client_init(device, p);
-}
-
-void do_info_network(void)
-{
- VLANState *vlan;
- VLANClientState *vc;
-
- for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
- term_printf("VLAN %d devices:\n", vlan->id);
- for(vc = vlan->first_client; vc != NULL; vc = vc->next)
- term_printf(" %s\n", vc->info_str);
- }
-}
-
-#define HD_ALIAS "index=%d,media=disk"
-#ifdef TARGET_PPC
-#define CDROM_ALIAS "index=1,media=cdrom"
-#else
-#define CDROM_ALIAS "index=2,media=cdrom"
-#endif
-#define FD_ALIAS "index=%d,if=floppy"
-#define PFLASH_ALIAS "if=pflash"
-#define MTD_ALIAS "if=mtd"
-#define SD_ALIAS "index=0,if=sd"
-
-static int drive_add(const char *file, const char *fmt, ...)
-{
- va_list ap;
-
- if (nb_drives_opt >= MAX_DRIVES) {
- fprintf(stderr, "qemu: too many drives\n");
- exit(1);
- }
-
- drives_opt[nb_drives_opt].file = file;
- va_start(ap, fmt);
- vsnprintf(drives_opt[nb_drives_opt].opt,
- sizeof(drives_opt[0].opt), fmt, ap);
- va_end(ap);
-
- return nb_drives_opt++;
-}
-
-int drive_get_index(BlockInterfaceType type, int bus, int unit)
-{
- int index;
-
- /* seek interface, bus and unit */
-
- for (index = 0; index < nb_drives; index++)
- if (drives_table[index].type == type &&
- drives_table[index].bus == bus &&
- drives_table[index].unit == unit)
- return index;
-
- return -1;
-}
-
-int drive_get_max_bus(BlockInterfaceType type)
-{
- int max_bus;
- int index;
-
- max_bus = -1;
- for (index = 0; index < nb_drives; index++) {
- if(drives_table[index].type == type &&
- drives_table[index].bus > max_bus)
- max_bus = drives_table[index].bus;
- }
- return max_bus;
-}
-
-static void bdrv_format_print(void *opaque, const char *name)
-{
- fprintf(stderr, " %s", name);
-}
-
-static int drive_init(struct drive_opt *arg, int snapshot,
- QEMUMachine *machine)
-{
- char buf[128];
- char file[1024];
- char devname[128];
- const char *mediastr = "";
- BlockInterfaceType type;
- enum { MEDIA_DISK, MEDIA_CDROM } media;
- int bus_id, unit_id;
- int cyls, heads, secs, translation;
- BlockDriverState *bdrv;
- BlockDriver *drv = NULL;
- int max_devs;
- int index;
- int cache;
- int bdrv_flags;
- char *str = arg->opt;
- static const char * const params[] = { "bus", "unit", "if", "index",
- "cyls", "heads", "secs", "trans",
- "media", "snapshot", "file",
- "cache", "format", NULL };
-
- if (check_params(buf, sizeof(buf), params, str) < 0) {
- fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
- buf, str);
- return -1;
- }
-
- file[0] = 0;
- cyls = heads = secs = 0;
- bus_id = 0;
- unit_id = -1;
- translation = BIOS_ATA_TRANSLATION_AUTO;
- index = -1;
- cache = 1;
-
- if (!strcmp(machine->name, "realview") ||
- !strcmp(machine->name, "SS-5") ||
- !strcmp(machine->name, "SS-10") ||
- !strcmp(machine->name, "SS-600MP") ||
- !strcmp(machine->name, "versatilepb") ||
- !strcmp(machine->name, "versatileab")) {
- type = IF_SCSI;
- max_devs = MAX_SCSI_DEVS;
- pstrcpy(devname, sizeof(devname), "scsi");
- } else {
- type = IF_IDE;
- max_devs = MAX_IDE_DEVS;
- pstrcpy(devname, sizeof(devname), "ide");
- }
- media = MEDIA_DISK;
-
- /* extract parameters */
-
- if (get_param_value(buf, sizeof(buf), "bus", str)) {
- bus_id = strtol(buf, NULL, 0);
- if (bus_id < 0) {
- fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "unit", str)) {
- unit_id = strtol(buf, NULL, 0);
- if (unit_id < 0) {
- fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "if", str)) {
- pstrcpy(devname, sizeof(devname), buf);
- if (!strcmp(buf, "ide")) {
- type = IF_IDE;
- max_devs = MAX_IDE_DEVS;
- } else if (!strcmp(buf, "scsi")) {
- type = IF_SCSI;
- max_devs = MAX_SCSI_DEVS;
- } else if (!strcmp(buf, "floppy")) {
- type = IF_FLOPPY;
- max_devs = 0;
- } else if (!strcmp(buf, "pflash")) {
- type = IF_PFLASH;
- max_devs = 0;
- } else if (!strcmp(buf, "mtd")) {
- type = IF_MTD;
- max_devs = 0;
- } else if (!strcmp(buf, "sd")) {
- type = IF_SD;
- max_devs = 0;
- } else {
- fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "index", str)) {
- index = strtol(buf, NULL, 0);
- if (index < 0) {
- fprintf(stderr, "qemu: '%s' invalid index\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "cyls", str)) {
- cyls = strtol(buf, NULL, 0);
- }
-
- if (get_param_value(buf, sizeof(buf), "heads", str)) {
- heads = strtol(buf, NULL, 0);
- }
-
- if (get_param_value(buf, sizeof(buf), "secs", str)) {
- secs = strtol(buf, NULL, 0);
- }
-
- if (cyls || heads || secs) {
- if (cyls < 1 || cyls > 16383) {
- fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
- return -1;
- }
- if (heads < 1 || heads > 16) {
- fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
- return -1;
- }
- if (secs < 1 || secs > 63) {
- fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "trans", str)) {
- if (!cyls) {
- fprintf(stderr,
- "qemu: '%s' trans must be used with cyls,heads and secs\n",
- str);
- return -1;
- }
- if (!strcmp(buf, "none"))
- translation = BIOS_ATA_TRANSLATION_NONE;
- else if (!strcmp(buf, "lba"))
- translation = BIOS_ATA_TRANSLATION_LBA;
- else if (!strcmp(buf, "auto"))
- translation = BIOS_ATA_TRANSLATION_AUTO;
- else {
- fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "media", str)) {
- if (!strcmp(buf, "disk")) {
- media = MEDIA_DISK;
- } else if (!strcmp(buf, "cdrom")) {
- if (cyls || secs || heads) {
- fprintf(stderr,
- "qemu: '%s' invalid physical CHS format\n", str);
- return -1;
- }
- media = MEDIA_CDROM;
- } else {
- fprintf(stderr, "qemu: '%s' invalid media\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
- if (!strcmp(buf, "on"))
- snapshot = 1;
- else if (!strcmp(buf, "off"))
- snapshot = 0;
- else {
- fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "cache", str)) {
- if (!strcmp(buf, "off"))
- cache = 0;
- else if (!strcmp(buf, "on"))
- cache = 1;
- else {
- fprintf(stderr, "qemu: invalid cache option\n");
- return -1;
- }
- }
-
- if (get_param_value(buf, sizeof(buf), "format", str)) {
- if (strcmp(buf, "?") == 0) {
- fprintf(stderr, "qemu: Supported formats:");
- bdrv_iterate_format(bdrv_format_print, NULL);
- fprintf(stderr, "\n");
- return -1;
- }
- drv = bdrv_find_format(buf);
- if (!drv) {
- fprintf(stderr, "qemu: '%s' invalid format\n", buf);
- return -1;
- }
- }
-
- if (arg->file == NULL)
- get_param_value(file, sizeof(file), "file", str);
- else
- pstrcpy(file, sizeof(file), arg->file);
-
- /* compute bus and unit according index */
-
- if (index != -1) {
- if (bus_id != 0 || unit_id != -1) {
- fprintf(stderr,
- "qemu: '%s' index cannot be used with bus and unit\n", str);
- return -1;
- }
- if (max_devs == 0)
- {
- unit_id = index;
- bus_id = 0;
- } else {
- unit_id = index % max_devs;
- bus_id = index / max_devs;
- }
- }
-
- /* if user doesn't specify a unit_id,
- * try to find the first free
- */
-
- if (unit_id == -1) {
- unit_id = 0;
- while (drive_get_index(type, bus_id, unit_id) != -1) {
- unit_id++;
- if (max_devs && unit_id >= max_devs) {
- unit_id -= max_devs;
- bus_id++;
- }
- }
- }
-
- /* check unit id */
-
- if (max_devs && unit_id >= max_devs) {
- fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
- str, unit_id, max_devs - 1);
- return -1;
- }
-
- /*
- * ignore multiple definitions
- */
-
- if (drive_get_index(type, bus_id, unit_id) != -1)
- return 0;
-
- /* init */
-
- if (type == IF_IDE || type == IF_SCSI)
- mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
- if (max_devs)
- snprintf(buf, sizeof(buf), "%s%i%s%i",
- devname, bus_id, mediastr, unit_id);
- else
- snprintf(buf, sizeof(buf), "%s%s%i",
- devname, mediastr, unit_id);
- bdrv = bdrv_new(buf);
- drives_table[nb_drives].bdrv = bdrv;
- drives_table[nb_drives].type = type;
- drives_table[nb_drives].bus = bus_id;
- drives_table[nb_drives].unit = unit_id;
- nb_drives++;
-
- switch(type) {
- case IF_IDE:
- case IF_SCSI:
- switch(media) {
- case MEDIA_DISK:
- if (cyls != 0) {
- bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
- bdrv_set_translation_hint(bdrv, translation);
- }
- break;
- case MEDIA_CDROM:
- bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
- break;
- }
- break;
- case IF_SD:
- /* FIXME: This isn't really a floppy, but it's a reasonable
- approximation. */
- case IF_FLOPPY:
- bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
- break;
- case IF_PFLASH:
- case IF_MTD:
- break;
- }
- if (!file[0])
- return 0;
- bdrv_flags = 0;
- if (snapshot)
- bdrv_flags |= BDRV_O_SNAPSHOT;
- if (!cache)
- bdrv_flags |= BDRV_O_DIRECT;
- if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
- fprintf(stderr, "qemu: could not open disk image %s\n",
- file);
- return -1;
- }
- return 0;
-}
-
-/***********************************************************/
-/* USB devices */
-
-static USBPort *used_usb_ports;
-static USBPort *free_usb_ports;
-
-/* ??? Maybe change this to register a hub to keep track of the topology. */
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach)
-{
- port->opaque = opaque;
- port->index = index;
- port->attach = attach;
- port->next = free_usb_ports;
- free_usb_ports = port;
-}
-
-int usb_device_add_dev(USBDevice *dev)
-{
- USBPort *port;
-
- /* Find a USB port to add the device to. */
- port = free_usb_ports;
- if (!port->next) {
- USBDevice *hub;
-
- /* Create a new hub and chain it on. */
- free_usb_ports = NULL;
- port->next = used_usb_ports;
- used_usb_ports = port;
-
- hub = usb_hub_init(VM_USB_HUB_SIZE);
- usb_attach(port, hub);
- port = free_usb_ports;
- }
-
- free_usb_ports = port->next;
- port->next = used_usb_ports;
- used_usb_ports = port;
- usb_attach(port, dev);
- return 0;
-}
-
-static int usb_device_add(const char *devname)
-{
- const char *p;
- USBDevice *dev;
-
- if (!free_usb_ports)
- return -1;
-
- if (strstart(devname, "host:", &p)) {
- dev = usb_host_device_open(p);
- } else if (!strcmp(devname, "mouse")) {
- dev = usb_mouse_init();
- } else if (!strcmp(devname, "tablet")) {
- dev = usb_tablet_init();
- } else if (!strcmp(devname, "keyboard")) {
- dev = usb_keyboard_init();
- } else if (strstart(devname, "disk:", &p)) {
- dev = usb_msd_init(p);
-#if 0
- } else if (!strcmp(devname, "wacom-tablet")) {
- dev = usb_wacom_init();
- } else if (strstart(devname, "serial:", &p)) {
- dev = usb_serial_init(p);
-#ifdef CONFIG_BRLAPI
- } else if (!strcmp(devname, "braille")) {
- dev = usb_baum_init();
-#endif
- } else if (strstart(devname, "net:", &p)) {
- int nic = nb_nics;
-
- if (net_client_init("nic", p) < 0)
- return -1;
- nd_table[nic].model = "usb";
- dev = usb_net_init(&nd_table[nic]);
-#endif
- } else {
- return -1;
- }
- if (!dev)
- return -1;
-
- return usb_device_add_dev(dev);
-}
-
-int usb_device_del_addr(int bus_num, int addr)
-{
- USBPort *port;
- USBPort **lastp;
- USBDevice *dev;
-
- if (!used_usb_ports)
- return -1;
-
- if (bus_num != 0)
- return -1;
-
- lastp = &used_usb_ports;
- port = used_usb_ports;
- while (port && port->dev->addr != addr) {
- lastp = &port->next;
- port = port->next;
- }
-
- if (!port)
- return -1;
-
- dev = port->dev;
- *lastp = port->next;
- usb_attach(port, NULL);
- dev->handle_destroy(dev);
- port->next = free_usb_ports;
- free_usb_ports = port;
- return 0;
-}
-
-static int usb_device_del(const char *devname)
-{
- int bus_num, addr;
- const char *p;
-
- if (strstart(devname, "host:", &p))
- return usb_host_device_close(p);
-
- if (!used_usb_ports)
- return -1;
-
- p = strchr(devname, '.');
- if (!p)
- return -1;
- bus_num = strtoul(devname, NULL, 0);
- addr = strtoul(p + 1, NULL, 0);
-
- return usb_device_del_addr(bus_num, addr);
-}
-
-void do_usb_add(const char *devname)
-{
- usb_device_add(devname);
-}
-
-void do_usb_del(const char *devname)
-{
- usb_device_del(devname);
-}
-
-void usb_info(void)
-{
- USBDevice *dev;
- USBPort *port;
- const char *speed_str;
-
- if (!usb_enabled) {
- term_printf("USB support not enabled\n");
- return;
- }
-
- for (port = used_usb_ports; port; port = port->next) {
- dev = port->dev;
- if (!dev)
- continue;
- switch(dev->speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
- term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
- 0, dev->addr, speed_str, dev->devname);
- }
-}
-
-/***********************************************************/
-/* pid file */
-
-static char *pid_filename;
-
-/* Remove PID file. Called on normal exit */
-
-static void remove_pidfile(void)
-{
- unlink (pid_filename);
-}
-
-static void create_pidfile(const char *filename)
-{
- struct stat pidstat;
- FILE *f;
-
- /* Try to write our PID to the named file */
- if (stat(filename, &pidstat) < 0) {
- if (errno == ENOENT) {
- if ((f = fopen (filename, "w")) == NULL) {
- perror("Opening pidfile");
- exit(1);
- }
- fprintf(f, "%d\n", getpid());
- fclose(f);
- pid_filename = qemu_strdup(filename);
- if (!pid_filename) {
- fprintf(stderr, "Could not save PID filename");
- exit(1);
- }
- atexit(remove_pidfile);
- }
- } else {
- fprintf(stderr, "%s already exists. Remove it and try again.\n",
- filename);
- exit(1);
- }
-}
-
-/***********************************************************/
-/* dumb display */
-
-static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
-{
-}
-
-static void dumb_resize(DisplayState *ds, int w, int h)
-{
-}
-
-static void dumb_refresh(DisplayState *ds)
-{
-#if defined(CONFIG_SDL)
- vga_hw_update();
-#endif
-}
-
-static void dumb_display_init(DisplayState *ds)
-{
- ds->data = NULL;
- ds->linesize = 0;
- ds->depth = 0;
- ds->dpy_update = dumb_update;
- ds->dpy_resize = dumb_resize;
- ds->dpy_refresh = dumb_refresh;
- ds->gui_timer_interval = 500;
- ds->idle = 1;
-}
-
-/***********************************************************/
-/* I/O handling */
-
-#define MAX_IO_HANDLERS 64
-
-typedef struct IOHandlerRecord {
- int fd;
- IOCanRWHandler *fd_read_poll;
- IOHandler *fd_read;
- IOHandler *fd_write;
- int deleted;
- void *opaque;
- /* temporary data */
- struct pollfd *ufd;
- struct IOHandlerRecord *next;
-} IOHandlerRecord;
-
-static IOHandlerRecord *first_io_handler;
-
-/* XXX: fd_read_poll should be suppressed, but an API change is
- necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
- IOCanRWHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- IOHandlerRecord **pioh, *ioh;
-
- if (!fd_read && !fd_write) {
- pioh = &first_io_handler;
- for(;;) {
- ioh = *pioh;
- if (ioh == NULL)
- break;
- if (ioh->fd == fd) {
- ioh->deleted = 1;
- break;
- }
- pioh = &ioh->next;
- }
- } else {
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (ioh->fd == fd)
- goto found;
- }
- ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- if (!ioh)
- return -1;
- ioh->next = first_io_handler;
- first_io_handler = ioh;
- found:
- ioh->fd = fd;
- ioh->fd_read_poll = fd_read_poll;
- ioh->fd_read = fd_read;
- ioh->fd_write = fd_write;
- ioh->opaque = opaque;
- ioh->deleted = 0;
- }
- return 0;
-}
-
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque)
-{
- return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
-}
-
-/***********************************************************/
-/* Polling handling */
-
-typedef struct PollingEntry {
- PollingFunc *func;
- void *opaque;
- struct PollingEntry *next;
-} PollingEntry;
-
-static PollingEntry *first_polling_entry;
-
-int qemu_add_polling_cb(PollingFunc *func, void *opaque)
-{
- PollingEntry **ppe, *pe;
- pe = qemu_mallocz(sizeof(PollingEntry));
- if (!pe)
- return -1;
- pe->func = func;
- pe->opaque = opaque;
- for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
- *ppe = pe;
- return 0;
-}
-
-void qemu_del_polling_cb(PollingFunc *func, void *opaque)
-{
- PollingEntry **ppe, *pe;
- for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
- pe = *ppe;
- if (pe->func == func && pe->opaque == opaque) {
- *ppe = pe->next;
- qemu_free(pe);
- break;
- }
- }
-}
-
-#ifdef _WIN32
-/***********************************************************/
-/* Wait objects support */
-typedef struct WaitObjects {
- int num;
- HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
- WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
- void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
-} WaitObjects;
-
-static WaitObjects wait_objects = {0};
-
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
-{
- WaitObjects *w = &wait_objects;
-
- if (w->num >= MAXIMUM_WAIT_OBJECTS)
- return -1;
- w->events[w->num] = handle;
- w->func[w->num] = func;
- w->opaque[w->num] = opaque;
- w->num++;
- return 0;
-}
-
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
-{
- int i, found;
- WaitObjects *w = &wait_objects;
-
- found = 0;
- for (i = 0; i < w->num; i++) {
- if (w->events[i] == handle)
- found = 1;
- if (found) {
- w->events[i] = w->events[i + 1];
- w->func[i] = w->func[i + 1];
- w->opaque[i] = w->opaque[i + 1];
- }
- }
- if (found)
- w->num--;
-}
-#endif
-
-/***********************************************************/
-/* savevm/loadvm support */
-
-#define IO_BUF_SIZE 32768
-
-struct QEMUFile {
- FILE *outfile;
- BlockDriverState *bs;
- int is_file;
- int is_writable;
- int64_t base_offset;
- int64_t buf_offset; /* start of buffer when writing, end of buffer
- when reading */
- int buf_index;
- int buf_size; /* 0 when writing */
- uint8_t buf[IO_BUF_SIZE];
-};
-
-QEMUFile *qemu_fopen(const char *filename, const char *mode)
-{
- QEMUFile *f;
-
- f = qemu_mallocz(sizeof(QEMUFile));
- if (!f)
- return NULL;
- if (!strcmp(mode, "wb")) {
- f->is_writable = 1;
- } else if (!strcmp(mode, "rb")) {
- f->is_writable = 0;
- } else {
- goto fail;
- }
- f->outfile = fopen(filename, mode);
- if (!f->outfile)
- goto fail;
- f->is_file = 1;
- return f;
- fail:
- if (f->outfile)
- fclose(f->outfile);
- qemu_free(f);
- return NULL;
-}
-
-static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
-{
- QEMUFile *f;
-
- f = qemu_mallocz(sizeof(QEMUFile));
- if (!f)
- return NULL;
- f->is_file = 0;
- f->bs = bs;
- f->is_writable = is_writable;
- f->base_offset = offset;
- return f;
-}
-
-void qemu_fflush(QEMUFile *f)
-{
- if (!f->is_writable)
- return;
- if (f->buf_index > 0) {
- if (f->is_file) {
- fseek(f->outfile, f->buf_offset, SEEK_SET);
- fwrite(f->buf, 1, f->buf_index, f->outfile);
- } else {
- bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
- f->buf, f->buf_index);
- }
- f->buf_offset += f->buf_index;
- f->buf_index = 0;
- }
-}
-
-static void qemu_fill_buffer(QEMUFile *f)
-{
- int len;
-
- if (f->is_writable)
- return;
- if (f->is_file) {
- fseek(f->outfile, f->buf_offset, SEEK_SET);
- len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
- if (len < 0)
- len = 0;
- } else {
- len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
- f->buf, IO_BUF_SIZE);
- if (len < 0)
- len = 0;
- }
- f->buf_index = 0;
- f->buf_size = len;
- f->buf_offset += len;
-}
-
-void qemu_fclose(QEMUFile *f)
-{
- if (f->is_writable)
- qemu_fflush(f);
- if (f->is_file) {
- fclose(f->outfile);
- }
- qemu_free(f);
-}
-
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
-{
- int l;
- while (size > 0) {
- l = IO_BUF_SIZE - f->buf_index;
- if (l > size)
- l = size;
- memcpy(f->buf + f->buf_index, buf, l);
- f->buf_index += l;
- buf += l;
- size -= l;
- if (f->buf_index >= IO_BUF_SIZE)
- qemu_fflush(f);
- }
-}
-
-void qemu_put_byte(QEMUFile *f, int v)
-{
- f->buf[f->buf_index++] = v;
- if (f->buf_index >= IO_BUF_SIZE)
- qemu_fflush(f);
-}
-
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
-{
- int size, l;
-
- size = size1;
- while (size > 0) {
- l = f->buf_size - f->buf_index;
- if (l == 0) {
- qemu_fill_buffer(f);
- l = f->buf_size - f->buf_index;
- if (l == 0)
- break;
- }
- if (l > size)
- l = size;
- memcpy(buf, f->buf + f->buf_index, l);
- f->buf_index += l;
- buf += l;
- size -= l;
- }
- return size1 - size;
-}
-
-int qemu_get_byte(QEMUFile *f)
-{
- if (f->buf_index >= f->buf_size) {
- qemu_fill_buffer(f);
- if (f->buf_index >= f->buf_size)
- return 0;
- }
- return f->buf[f->buf_index++];
-}
-
-int64_t qemu_ftell(QEMUFile *f)
-{
- return f->buf_offset - f->buf_size + f->buf_index;
-}
-
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
-{
- if (whence == SEEK_SET) {
- /* nothing to do */
- } else if (whence == SEEK_CUR) {
- pos += qemu_ftell(f);
- } else {
- /* SEEK_END not supported */
- return -1;
- }
- if (f->is_writable) {
- qemu_fflush(f);
- f->buf_offset = pos;
- } else {
- f->buf_offset = pos;
- f->buf_index = 0;
- f->buf_size = 0;
- }
- return pos;
-}
-
-void qemu_put_be16(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, v >> 8);
- qemu_put_byte(f, v);
-}
-
-void qemu_put_be32(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, v >> 24);
- qemu_put_byte(f, v >> 16);
- qemu_put_byte(f, v >> 8);
- qemu_put_byte(f, v);
-}
-
-void qemu_put_be64(QEMUFile *f, uint64_t v)
-{
- qemu_put_be32(f, v >> 32);
- qemu_put_be32(f, v);
-}
-
-unsigned int qemu_get_be16(QEMUFile *f)
-{
- unsigned int v;
- v = qemu_get_byte(f) << 8;
- v |= qemu_get_byte(f);
- return v;
-}
-
-unsigned int qemu_get_be32(QEMUFile *f)
-{
- unsigned int v;
- v = qemu_get_byte(f) << 24;
- v |= qemu_get_byte(f) << 16;
- v |= qemu_get_byte(f) << 8;
- v |= qemu_get_byte(f);
- return v;
-}
-
-uint64_t qemu_get_be64(QEMUFile *f)
-{
- uint64_t v;
- v = (uint64_t)qemu_get_be32(f) << 32;
- v |= qemu_get_be32(f);
- return v;
-}
-
-void qemu_put_struct(QEMUFile* f, const QField* fields, const void* s)
-{
- const QField* qf = fields;
-
- for (;;) {
- uint8_t* p = (uint8_t*)s + qf->offset;
-
- switch (qf->type) {
- case Q_FIELD_END:
- break;
- case Q_FIELD_BYTE:
- qemu_put_byte(f, p[0]);
- break;
- case Q_FIELD_INT16:
- qemu_put_be16(f, ((uint16_t*)p)[0]);
- break;
- case Q_FIELD_INT32:
- qemu_put_be32(f, ((uint32_t*)p)[0]);
- break;
- case Q_FIELD_INT64:
- qemu_put_be64(f, ((uint64_t*)p)[0]);
- break;
- case Q_FIELD_BUFFER:
- if (fields[1].type != Q_FIELD_BUFFER_SIZE ||
- fields[2].type != Q_FIELD_BUFFER_SIZE)
- {
- fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument. aborting\n",
- __FUNCTION__ );
- exit(1);
- }
- else
- {
- uint32_t size = ((uint32_t)fields[1].offset << 16) | (uint32_t)fields[2].offset;
-
- qemu_put_buffer(f, p, size);
- qf += 2;
- }
- break;
- default:
- fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
- exit(1);
- }
- qf++;
- }
-}
-
-int qemu_get_struct(QEMUFile* f, const QField* fields, void* s)
-{
- const QField* qf = fields;
-
- for (;;) {
- uint8_t* p = (uint8_t*)s + qf->offset;
-
- switch (qf->type) {
- case Q_FIELD_END:
- break;
- case Q_FIELD_BYTE:
- p[0] = qemu_get_byte(f);
- break;
- case Q_FIELD_INT16:
- ((uint16_t*)p)[0] = qemu_get_be16(f);
- break;
- case Q_FIELD_INT32:
- ((uint32_t*)p)[0] = qemu_get_be32(f);
- break;
- case Q_FIELD_INT64:
- ((uint64_t*)p)[0] = qemu_get_be64(f);
- break;
- case Q_FIELD_BUFFER:
- if (fields[1].type != Q_FIELD_BUFFER_SIZE ||
- fields[2].type != Q_FIELD_BUFFER_SIZE)
- {
- fprintf(stderr, "%s: invalid QFIELD_BUFFER item passed as argument.\n",
- __FUNCTION__ );
- return -1;
- }
- else
- {
- uint32_t size = ((uint32_t)fields[1].offset << 16) | (uint32_t)fields[2].offset;
- int ret = qemu_get_buffer(f, p, size);
-
- if (ret != size) {
- fprintf(stderr, "%s: not enough bytes to load structure\n", __FUNCTION__);
- return -1;
- }
- qf += 2;
- }
- break;
- default:
- fprintf(stderr, "%s: invalid fields list passed as argument. aborting\n", __FUNCTION__);
- exit(1);
- }
- qf++;
- }
- return 0;
-}
-
-typedef struct SaveStateEntry {
- char idstr[256];
- int instance_id;
- int version_id;
- SaveStateHandler *save_state;
- LoadStateHandler *load_state;
- void *opaque;
- struct SaveStateEntry *next;
-} SaveStateEntry;
-
-static SaveStateEntry *first_se;
-
-/* TODO: Individual devices generally have very little idea about the rest
- of the system, so instance_id should be removed/replaced.
- Meanwhile pass -1 as instance_id if you do not already have a clearly
- distinguishing id for all instances of your device class. */
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque)
-{
- SaveStateEntry *se, **pse;
-
- se = qemu_malloc(sizeof(SaveStateEntry));
- if (!se)
- return -1;
- pstrcpy(se->idstr, sizeof(se->idstr), idstr);
- se->instance_id = (instance_id == -1) ? 0 : instance_id;
- se->version_id = version_id;
- se->save_state = save_state;
- se->load_state = load_state;
- se->opaque = opaque;
- se->next = NULL;
-
- /* add at the end of list */
- pse = &first_se;
- while (*pse != NULL) {
- if (instance_id == -1
- && strcmp(se->idstr, (*pse)->idstr) == 0
- && se->instance_id <= (*pse)->instance_id)
- se->instance_id = (*pse)->instance_id + 1;
- pse = &(*pse)->next;
- }
- *pse = se;
- return 0;
-}
-
-#define QEMU_VM_FILE_MAGIC 0x5145564d
-#define QEMU_VM_FILE_VERSION 0x00000002
-
-static int qemu_savevm_state(QEMUFile *f)
-{
- SaveStateEntry *se;
- int len, ret;
- int64_t cur_pos, len_pos, total_len_pos;
-
- qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
- qemu_put_be32(f, QEMU_VM_FILE_VERSION);
- total_len_pos = qemu_ftell(f);
- qemu_put_be64(f, 0); /* total size */
-
- for(se = first_se; se != NULL; se = se->next) {
- if (se->save_state == NULL)
- /* this one has a loader only, for backwards compatibility */
- continue;
-
- /* ID string */
- len = strlen(se->idstr);
- qemu_put_byte(f, len);
- qemu_put_buffer(f, (uint8_t *)se->idstr, len);
-
- qemu_put_be32(f, se->instance_id);
- qemu_put_be32(f, se->version_id);
-
- /* record size: filled later */
- len_pos = qemu_ftell(f);
- qemu_put_be32(f, 0);
- se->save_state(f, se->opaque);
-
- /* fill record size */
- cur_pos = qemu_ftell(f);
- len = cur_pos - len_pos - 4;
- qemu_fseek(f, len_pos, SEEK_SET);
- qemu_put_be32(f, len);
- qemu_fseek(f, cur_pos, SEEK_SET);
- }
- cur_pos = qemu_ftell(f);
- qemu_fseek(f, total_len_pos, SEEK_SET);
- qemu_put_be64(f, cur_pos - total_len_pos - 8);
- qemu_fseek(f, cur_pos, SEEK_SET);
-
- ret = 0;
- return ret;
-}
-
-static SaveStateEntry *find_se(const char *idstr, int instance_id)
-{
- SaveStateEntry *se;
-
- for(se = first_se; se != NULL; se = se->next) {
- if (!strcmp(se->idstr, idstr) &&
- instance_id == se->instance_id)
- return se;
- }
- return NULL;
-}
-
-static int qemu_loadvm_state(QEMUFile *f)
-{
- SaveStateEntry *se;
- int len, ret, instance_id, record_len, version_id;
- int64_t total_len, end_pos, cur_pos;
- unsigned int v;
- char idstr[256];
-
- v = qemu_get_be32(f);
- if (v != QEMU_VM_FILE_MAGIC)
- goto fail;
- v = qemu_get_be32(f);
- if (v != QEMU_VM_FILE_VERSION) {
- fail:
- ret = -1;
- goto the_end;
- }
- total_len = qemu_get_be64(f);
- end_pos = total_len + qemu_ftell(f);
- for(;;) {
- if (qemu_ftell(f) >= end_pos)
- break;
- len = qemu_get_byte(f);
- qemu_get_buffer(f, (uint8_t *)idstr, len);
- idstr[len] = '\0';
- instance_id = qemu_get_be32(f);
- version_id = qemu_get_be32(f);
- record_len = qemu_get_be32(f);
-#if 0
- printf("idstr=%s instance=0x%x version=%d len=%d\n",
- idstr, instance_id, version_id, record_len);
-#endif
- cur_pos = qemu_ftell(f);
- se = find_se(idstr, instance_id);
- if (!se) {
- fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
- instance_id, idstr);
- } else {
- ret = se->load_state(f, se->opaque, version_id);
- if (ret < 0) {
- fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
- instance_id, idstr);
- }
- }
- /* always seek to exact end of record */
- qemu_fseek(f, cur_pos + record_len, SEEK_SET);
- }
- ret = 0;
- the_end:
- return ret;
-}
-
-/* device can contain snapshots */
-static int bdrv_can_snapshot(BlockDriverState *bs)
-{
- return (bs &&
- !bdrv_is_removable(bs) &&
- !bdrv_is_read_only(bs));
-}
-
-/* device must be snapshots in order to have a reliable snapshot */
-static int bdrv_has_snapshot(BlockDriverState *bs)
-{
- return (bs &&
- !bdrv_is_removable(bs) &&
- !bdrv_is_read_only(bs));
-}
-
-static BlockDriverState *get_bs_snapshots(void)
-{
- BlockDriverState *bs;
- int i;
-
- if (bs_snapshots)
- return bs_snapshots;
- for(i = 0; i <= nb_drives; i++) {
- bs = drives_table[i].bdrv;
- if (bdrv_can_snapshot(bs))
- goto ok;
- }
- return NULL;
- ok:
- bs_snapshots = bs;
- return bs;
-}
-
-static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
- const char *name)
-{
- QEMUSnapshotInfo *sn_tab, *sn;
- int nb_sns, i, ret;
-
- ret = -ENOENT;
- nb_sns = bdrv_snapshot_list(bs, &sn_tab);
- if (nb_sns < 0)
- return ret;
- for(i = 0; i < nb_sns; i++) {
- sn = &sn_tab[i];
- if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
- *sn_info = *sn;
- ret = 0;
- break;
- }
- }
- qemu_free(sn_tab);
- return ret;
-}
-
-void do_savevm(const char *name)
-{
- BlockDriverState *bs, *bs1;
- QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
- int must_delete, ret, i;
- BlockDriverInfo bdi1, *bdi = &bdi1;
- QEMUFile *f;
- int saved_vm_running;
-#ifdef _WIN32
- struct _timeb tb;
-#else
- struct timeval tv;
-#endif
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No block device can accept snapshots\n");
- return;
- }
-
- /* ??? Should this occur after vm_stop? */
- qemu_aio_flush();
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- must_delete = 0;
- if (name) {
- ret = bdrv_snapshot_find(bs, old_sn, name);
- if (ret >= 0) {
- must_delete = 1;
- }
- }
- memset(sn, 0, sizeof(*sn));
- if (must_delete) {
- pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
- pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
- } else {
- if (name)
- pstrcpy(sn->name, sizeof(sn->name), name);
- }
-
- /* fill auxiliary fields */
-#ifdef _WIN32
- _ftime(&tb);
- sn->date_sec = tb.time;
- sn->date_nsec = tb.millitm * 1000000;
-#else
- gettimeofday(&tv, NULL);
- sn->date_sec = tv.tv_sec;
- sn->date_nsec = tv.tv_usec * 1000;
-#endif
- sn->vm_clock_nsec = qemu_get_clock(vm_clock);
-
- if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
- term_printf("Device %s does not support VM state snapshots\n",
- bdrv_get_device_name(bs));
- goto the_end;
- }
-
- /* save the VM state */
- f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
- if (!f) {
- term_printf("Could not open VM state file\n");
- goto the_end;
- }
- ret = qemu_savevm_state(f);
- sn->vm_state_size = qemu_ftell(f);
- qemu_fclose(f);
- if (ret < 0) {
- term_printf("Error %d while writing VM\n", ret);
- goto the_end;
- }
-
- /* create the snapshots */
-
- for(i = 0; i < nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
- if (bdrv_has_snapshot(bs1)) {
- if (must_delete) {
- ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
- if (ret < 0) {
- term_printf("Error while deleting snapshot on '%s'\n",
- bdrv_get_device_name(bs1));
- }
- }
- ret = bdrv_snapshot_create(bs1, sn);
- if (ret < 0) {
- term_printf("Error while creating snapshot on '%s'\n",
- bdrv_get_device_name(bs1));
- }
- }
- }
-
- the_end:
- if (saved_vm_running)
- vm_start();
-}
-
-void do_loadvm(const char *name)
-{
- BlockDriverState *bs, *bs1;
- BlockDriverInfo bdi1, *bdi = &bdi1;
- QEMUFile *f;
- int i, ret;
- int saved_vm_running;
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No block device supports snapshots\n");
- return;
- }
-
- /* Flush all IO requests so they don't interfere with the new state. */
- qemu_aio_flush();
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- for(i = 0; i <= nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
- if (bdrv_has_snapshot(bs1)) {
- ret = bdrv_snapshot_goto(bs1, name);
- if (ret < 0) {
- if (bs != bs1)
- term_printf("Warning: ");
- switch(ret) {
- case -ENOTSUP:
- term_printf("Snapshots not supported on device '%s'\n",
- bdrv_get_device_name(bs1));
- break;
- case -ENOENT:
- term_printf("Could not find snapshot '%s' on device '%s'\n",
- name, bdrv_get_device_name(bs1));
- break;
- default:
- term_printf("Error %d while activating snapshot on '%s'\n",
- ret, bdrv_get_device_name(bs1));
- break;
- }
- /* fatal on snapshot block device */
- if (bs == bs1)
- goto the_end;
- }
- }
- }
-
- if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
- term_printf("Device %s does not support VM state snapshots\n",
- bdrv_get_device_name(bs));
- return;
- }
-
- /* restore the VM state */
- f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
- if (!f) {
- term_printf("Could not open VM state file\n");
- goto the_end;
- }
- ret = qemu_loadvm_state(f);
- qemu_fclose(f);
- if (ret < 0) {
- term_printf("Error %d while loading VM state\n", ret);
- }
- the_end:
- if (saved_vm_running)
- vm_start();
-}
-
-void do_delvm(const char *name)
-{
- BlockDriverState *bs, *bs1;
- int i, ret;
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No block device supports snapshots\n");
- return;
- }
-
- for(i = 0; i <= nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
- if (bdrv_has_snapshot(bs1)) {
- ret = bdrv_snapshot_delete(bs1, name);
- if (ret < 0) {
- if (ret == -ENOTSUP)
- term_printf("Snapshots not supported on device '%s'\n",
- bdrv_get_device_name(bs1));
- else
- term_printf("Error %d while deleting snapshot on '%s'\n",
- ret, bdrv_get_device_name(bs1));
- }
- }
- }
-}
-
-void do_info_snapshots(void)
-{
- BlockDriverState *bs, *bs1;
- QEMUSnapshotInfo *sn_tab, *sn;
- int nb_sns, i;
- char buf[256];
-
- bs = get_bs_snapshots();
- if (!bs) {
- term_printf("No available block device supports snapshots\n");
- return;
- }
- term_printf("Snapshot devices:");
- for(i = 0; i <= nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
- if (bdrv_has_snapshot(bs1)) {
- if (bs == bs1)
- term_printf(" %s", bdrv_get_device_name(bs1));
- }
- }
- term_printf("\n");
-
- nb_sns = bdrv_snapshot_list(bs, &sn_tab);
- if (nb_sns < 0) {
- term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
- return;
- }
- term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
- term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
- for(i = 0; i < nb_sns; i++) {
- sn = &sn_tab[i];
- term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
- }
- qemu_free(sn_tab);
-}
-
-/***********************************************************/
-/* ram save/restore */
-/* we just avoid storing empty pages */
-static void ram_put_page(QEMUFile *f, const uint8_t *buf, int len)
-{
- int i, v;
-
- v = buf[0];
- for(i = 1; i < len; i++) {
- if (buf[i] != v)
- goto normal_save;
- }
- qemu_put_byte(f, 1);
- qemu_put_byte(f, v);
- return;
- normal_save:
- qemu_put_byte(f, 0);
- qemu_put_buffer(f, buf, len);
-}
-
-static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
-{
- int v;
-
- v = qemu_get_byte(f);
- switch(v) {
- case 0:
- if (qemu_get_buffer(f, buf, len) != len)
- return -EIO;
- break;
- case 1:
- v = qemu_get_byte(f);
- memset(buf, v, len);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ram_load_v1(QEMUFile *f, void *opaque)
-{
- int ret;
- ram_addr_t i;
-
- if (qemu_get_be32(f) != phys_ram_size)
- return -EINVAL;
- for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
- ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-#define BDRV_HASH_BLOCK_SIZE 1024
-#define IOBUF_SIZE 4096
-#define RAM_CBLOCK_MAGIC 0xfabe
-
-typedef struct RamCompressState {
- z_stream zstream;
- QEMUFile *f;
- uint8_t buf[IOBUF_SIZE];
-} RamCompressState;
-
-static int ram_compress_open(RamCompressState *s, QEMUFile *f)
-{
- int ret;
- memset(s, 0, sizeof(*s));
- s->f = f;
- ret = deflateInit2(&s->zstream, 1,
- Z_DEFLATED, 15,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != Z_OK)
- return -1;
- s->zstream.avail_out = IOBUF_SIZE;
- s->zstream.next_out = s->buf;
- return 0;
-}
-
-static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
-{
- qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
- qemu_put_be16(s->f, len);
- qemu_put_buffer(s->f, buf, len);
-}
-
-static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
-{
- int ret;
-
- s->zstream.avail_in = len;
- s->zstream.next_in = (uint8_t *)buf;
- while (s->zstream.avail_in > 0) {
- ret = deflate(&s->zstream, Z_NO_FLUSH);
- if (ret != Z_OK)
- return -1;
- if (s->zstream.avail_out == 0) {
- ram_put_cblock(s, s->buf, IOBUF_SIZE);
- s->zstream.avail_out = IOBUF_SIZE;
- s->zstream.next_out = s->buf;
- }
- }
- return 0;
-}
-
-static void ram_compress_close(RamCompressState *s)
-{
- int len, ret;
-
- /* compress last bytes */
- for(;;) {
- ret = deflate(&s->zstream, Z_FINISH);
- if (ret == Z_OK || ret == Z_STREAM_END) {
- len = IOBUF_SIZE - s->zstream.avail_out;
- if (len > 0) {
- ram_put_cblock(s, s->buf, len);
- }
- s->zstream.avail_out = IOBUF_SIZE;
- s->zstream.next_out = s->buf;
- if (ret == Z_STREAM_END)
- break;
- } else {
- goto fail;
- }
- }
-fail:
- deflateEnd(&s->zstream);
-}
-
-typedef struct RamDecompressState {
- z_stream zstream;
- QEMUFile *f;
- uint8_t buf[IOBUF_SIZE];
-} RamDecompressState;
-
-static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
-{
- int ret;
- memset(s, 0, sizeof(*s));
- s->f = f;
- ret = inflateInit(&s->zstream);
- if (ret != Z_OK)
- return -1;
- return 0;
-}
-
-static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
-{
- int ret, clen;
-
- s->zstream.avail_out = len;
- s->zstream.next_out = buf;
- while (s->zstream.avail_out > 0) {
- if (s->zstream.avail_in == 0) {
- if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
- return -1;
- clen = qemu_get_be16(s->f);
- if (clen > IOBUF_SIZE)
- return -1;
- qemu_get_buffer(s->f, s->buf, clen);
- s->zstream.avail_in = clen;
- s->zstream.next_in = s->buf;
- }
- ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END) {
- return -1;
- }
- }
- return 0;
-}
-
-static void ram_decompress_close(RamDecompressState *s)
-{
- inflateEnd(&s->zstream);
-}
-
-static void ram_save(QEMUFile *f, void *opaque)
-{
- ram_addr_t i;
- RamCompressState s1, *s = &s1;
- uint8_t buf[10];
-
- qemu_put_be32(f, phys_ram_size);
- if (ram_compress_open(s, f) < 0)
- return;
- for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
-#if 0
- if (tight_savevm_enabled) {
- int64_t sector_num;
- int j;
-
- /* find if the memory block is available on a virtual
- block device */
- sector_num = -1;
- for(j = 0; j < nb_drives; j++) {
- sector_num = bdrv_hash_find(drives_table[j].bdrv,
- phys_ram_base + i,
- BDRV_HASH_BLOCK_SIZE);
- if (sector_num >= 0)
- break;
- }
- if (j == nb_drives)
- goto normal_compress;
- buf[0] = 1;
- buf[1] = j;
- cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
- ram_compress_buf(s, buf, 10);
- } else
-#endif
- {
- // normal_compress:
- buf[0] = 0;
- ram_compress_buf(s, buf, 1);
- ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
- }
- }
- ram_compress_close(s);
-}
-
-static int ram_load(QEMUFile *f, void *opaque, int version_id)
-{
- RamDecompressState s1, *s = &s1;
- uint8_t buf[10];
- ram_addr_t i;
-
- if (version_id == 1)
- return ram_load_v1(f, opaque);
- if (version_id != 2)
- return -EINVAL;
- if (qemu_get_be32(f) != phys_ram_size)
- return -EINVAL;
- if (ram_decompress_open(s, f) < 0)
- return -EINVAL;
- for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
- if (ram_decompress_buf(s, buf, 1) < 0) {
- fprintf(stderr, "Error while reading ram block header\n");
- goto error;
- }
- if (buf[0] == 0) {
- if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
- fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
- goto error;
- }
- } else
-#if 0
- if (buf[0] == 1) {
- int bs_index;
- int64_t sector_num;
-
- ram_decompress_buf(s, buf + 1, 9);
- bs_index = buf[1];
- sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
- if (bs_index >= nb_drives) {
- fprintf(stderr, "Invalid block device index %d\n", bs_index);
- goto error;
- }
- if (bdrv_read(drives_table[bs_index].bdrv, sector_num,
- phys_ram_base + i,
- BDRV_HASH_BLOCK_SIZE / 512) < 0) {
- fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
- bs_index, sector_num);
- goto error;
- }
- } else
-#endif
- {
- error:
- printf("Error block header\n");
- return -EINVAL;
- }
- }
- ram_decompress_close(s);
- return 0;
-}
-
-/***********************************************************/
-/* bottom halves (can be seen as timers which expire ASAP) */
-
-struct QEMUBH {
- QEMUBHFunc *cb;
- void *opaque;
- int scheduled;
- QEMUBH *next;
-};
-
-static QEMUBH *first_bh = NULL;
-
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
-{
- QEMUBH *bh;
- bh = qemu_mallocz(sizeof(QEMUBH));
- if (!bh)
- return NULL;
- bh->cb = cb;
- bh->opaque = opaque;
- return bh;
-}
-
-int qemu_bh_poll(void)
-{
- QEMUBH *bh, **pbh;
- int ret;
-
- ret = 0;
- for(;;) {
- pbh = &first_bh;
- bh = *pbh;
- if (!bh)
- break;
- ret = 1;
- *pbh = bh->next;
- bh->scheduled = 0;
- bh->cb(bh->opaque);
- }
- return ret;
-}
-
-void qemu_bh_schedule(QEMUBH *bh)
-{
- CPUState *env = cpu_single_env;
- if (bh->scheduled)
- return;
- bh->scheduled = 1;
- bh->next = first_bh;
- first_bh = bh;
-
- /* stop the currently executing CPU to execute the BH ASAP */
- if (env) {
- cpu_interrupt(env, CPU_INTERRUPT_EXIT);
- }
-}
-
-void qemu_bh_cancel(QEMUBH *bh)
-{
- QEMUBH **pbh;
- if (bh->scheduled) {
- pbh = &first_bh;
- while (*pbh != bh)
- pbh = &(*pbh)->next;
- *pbh = bh->next;
- bh->scheduled = 0;
- }
-}
-
-void qemu_bh_delete(QEMUBH *bh)
-{
- qemu_bh_cancel(bh);
- qemu_free(bh);
-}
-
-/***********************************************************/
-/* machine registration */
-
-QEMUMachine *first_machine = NULL;
-
-int qemu_register_machine(QEMUMachine *m)
-{
- QEMUMachine **pm;
- pm = &first_machine;
- while (*pm != NULL)
- pm = &(*pm)->next;
- m->next = NULL;
- *pm = m;
- return 0;
-}
-
-static QEMUMachine *find_machine(const char *name)
-{
- QEMUMachine *m;
-
- for(m = first_machine; m != NULL; m = m->next) {
- if (!strcmp(m->name, name))
- return m;
- }
- return NULL;
-}
-
-/***********************************************************/
-/* main execution loop */
-
-static void gui_update(void *opaque)
-{
- DisplayState *ds = opaque;
- ds->dpy_refresh(ds);
- qemu_mod_timer(ds->gui_timer,
- (ds->gui_timer_interval ?
- ds->gui_timer_interval :
- GUI_REFRESH_INTERVAL)
- + qemu_get_clock(rt_clock));
-}
-
-struct vm_change_state_entry {
- VMChangeStateHandler *cb;
- void *opaque;
- LIST_ENTRY (vm_change_state_entry) entries;
-};
-
-static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque)
-{
- VMChangeStateEntry *e;
-
- e = qemu_mallocz(sizeof (*e));
- if (!e)
- return NULL;
-
- e->cb = cb;
- e->opaque = opaque;
- LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
- return e;
-}
-
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
-{
- LIST_REMOVE (e, entries);
- qemu_free (e);
-}
-
-static void vm_state_notify(int running)
-{
- VMChangeStateEntry *e;
-
- for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
- e->cb(e->opaque, running);
- }
-}
-
-/* XXX: support several handlers */
-static VMStopHandler *vm_stop_cb;
-static void *vm_stop_opaque;
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
-{
- vm_stop_cb = cb;
- vm_stop_opaque = opaque;
- return 0;
-}
-
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
-{
- vm_stop_cb = NULL;
-}
-
-void vm_start(void)
-{
- if (!vm_running) {
- cpu_enable_ticks();
- vm_running = 1;
- vm_state_notify(1);
- qemu_rearm_alarm_timer(alarm_timer);
- }
-}
-
-void vm_stop(int reason)
-{
- if (vm_running) {
- cpu_disable_ticks();
- vm_running = 0;
- if (reason != 0) {
- if (vm_stop_cb) {
- vm_stop_cb(vm_stop_opaque, reason);
- }
- }
- vm_state_notify(0);
- }
-}
-
-/* reset/shutdown handler */
-
-typedef struct QEMUResetEntry {
- QEMUResetHandler *func;
- void *opaque;
- struct QEMUResetEntry *next;
-} QEMUResetEntry;
-
-static QEMUResetEntry *first_reset_entry;
-static int reset_requested;
-static int shutdown_requested;
-static int powerdown_requested;
-
-int qemu_shutdown_requested(void)
-{
- int r = shutdown_requested;
- shutdown_requested = 0;
- return r;
-}
-
-int qemu_reset_requested(void)
-{
- int r = reset_requested;
- reset_requested = 0;
- return r;
-}
-
-int qemu_powerdown_requested(void)
-{
- int r = powerdown_requested;
- powerdown_requested = 0;
- return r;
-}
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque)
-{
- QEMUResetEntry **pre, *re;
-
- pre = &first_reset_entry;
- while (*pre != NULL)
- pre = &(*pre)->next;
- re = qemu_mallocz(sizeof(QEMUResetEntry));
- re->func = func;
- re->opaque = opaque;
- re->next = NULL;
- *pre = re;
-}
-
-void qemu_system_reset(void)
-{
- QEMUResetEntry *re;
-
- /* reset all devices */
- for(re = first_reset_entry; re != NULL; re = re->next) {
- re->func(re->opaque);
- }
-}
-
-void qemu_system_reset_request(void)
-{
- if (no_reboot) {
- shutdown_requested = 1;
- } else {
- reset_requested = 1;
- }
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-#ifdef HAS_AUDIO
-extern void AUD_cleanup();
-#endif
-
-void qemu_system_shutdown_request(void)
-{
- shutdown_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void qemu_system_powerdown_request(void)
-{
- powerdown_requested = 1;
- if (cpu_single_env)
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-#define MAIN_LOOP_STATS 0
-
-#if MAIN_LOOP_STATS
-typedef struct {
- int counter;
- int64_t reset_time; // time when counter is reset
- int64_t spent_time_total; // total time spent since last counter reset
- int64_t spent_time_min; // minimum time spent in call
- int64_t spent_time_max; // maximum time spent in call
- int64_t wait_time_total; // total time spent waiting for select()
-} MainLoopStats;
-
-static __inline__ int64_t
-mainloopstats_now( void )
-{
- return qemu_get_clock( vm_clock );
-}
-
-static __inline__ double
-mainloopstats_to_ms( int64_t duration )
-{
- return duration / 1000000.;
-}
-
-static void
-mainloopstats_reset( MainLoopStats* s )
-{
- int64_t now = qemu_get_clock( vm_clock );
-
- s->counter = 0;
- s->reset_time = now;
- s->spent_time_total = 0;
- s->wait_time_total = 0;
- s->spent_time_min = INT_MAX;
- s->spent_time_max = 0;
-}
-
-static MainLoopStats main_loop_stats;
-#endif /* MAIN_LOOP_STATS */
-
-void main_loop_wait(int timeout)
-{
- IOHandlerRecord *ioh;
- fd_set rfds, wfds, xfds;
- int ret, nfds;
-#ifdef _WIN32
- int ret2, i;
-#endif
- struct timeval tv;
- PollingEntry *pe;
-
-#if MAIN_LOOP_STATS
- int64 time_before = mainloopstats_now();
- int64 time_after_select;
-#endif
-
- /* XXX: need to suppress polling by better using win32 events */
- ret = 0;
- for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
- ret |= pe->func(pe->opaque);
- }
-#ifdef _WIN32
- if (ret == 0) {
- int err;
- WaitObjects *w = &wait_objects;
-
- ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
- if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
- if (w->func[ret - WAIT_OBJECT_0])
- w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
-
- /* Check for additional signaled events */
- for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
-
- /* Check if event is signaled */
- ret2 = WaitForSingleObject(w->events[i], 0);
- if(ret2 == WAIT_OBJECT_0) {
- if (w->func[i])
- w->func[i](w->opaque[i]);
- } else if (ret2 == WAIT_TIMEOUT) {
- } else {
- err = GetLastError();
- fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
- }
- }
- } else if (ret == WAIT_TIMEOUT) {
- } else {
- err = GetLastError();
- fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
- }
- }
-#endif
- /* poll any events */
- /* XXX: separate device handlers from system ones */
- nfds = -1;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&xfds);
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (ioh->deleted)
- continue;
- if (ioh->fd_read &&
- (!ioh->fd_read_poll ||
- ioh->fd_read_poll(ioh->opaque) != 0)) {
- FD_SET(ioh->fd, &rfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- if (ioh->fd_write) {
- FD_SET(ioh->fd, &wfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- }
-
- tv.tv_sec = 0;
-#ifdef _WIN32
- tv.tv_usec = 0;
-#else
- tv.tv_usec = timeout * 1000;
-#endif
-#if defined(CONFIG_SLIRP)
- if (slirp_inited) {
- slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
- }
-#endif
- ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
-#if MAIN_LOOP_STATS
- time_after_select = mainloopstats_now();
-#endif
- if (ret > 0) {
- IOHandlerRecord **pioh;
-
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
- ioh->fd_read(ioh->opaque);
- }
- if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
- ioh->fd_write(ioh->opaque);
- }
- }
-
- /* remove deleted IO handlers */
- pioh = &first_io_handler;
- while (*pioh) {
- ioh = *pioh;
- if (ioh->deleted) {
- *pioh = ioh->next;
- qemu_free(ioh);
- } else
- pioh = &ioh->next;
- }
- }
-#if defined(CONFIG_SLIRP)
- if (slirp_inited) {
- if (ret < 0) {
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&xfds);
- }
- slirp_select_poll(&rfds, &wfds, &xfds);
- }
-#endif
- charpipe_poll();
-
- if (vm_running) {
- if (likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
- qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock));
- /* run dma transfers, if any */
- DMA_run();
- }
-
- /* real time timers */
- qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock));
-
- if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
- alarm_timer->flags &= ~(ALARM_FLAG_EXPIRED);
- qemu_rearm_alarm_timer(alarm_timer);
- }
-
- /* Check bottom-halves last in case any of the earlier events triggered
- them. */
- qemu_bh_poll();
-
-#if MAIN_LOOP_STATS
- {
- MainLoopStats* s = &main_loop_stats;
- int64_t time_after = mainloopstats_now();
- int64_t time_diff = time_after - time_before;
-
- s->spent_time_total += time_diff;
- if (time_diff < s->spent_time_min)
- s->spent_time_min = time_diff;
- if (time_diff > s->spent_time_max)
- s->spent_time_max = time_diff;
-
- time_diff = time_after_select - time_before;
- s->wait_time_total += time_diff;
-
- if (++s->counter == 1000) {
- double period = time_after - s->reset_time;
- double average_spent = s->spent_time_total * 1. / s->counter;
- double average_wait = s->wait_time_total * 1. / s->counter;
-
- printf( "main loop stats: iterations: %8ld, period: %10.2f ms, avg wait time: %10.2f ms (%.3f %%), avg exec time %10.2f ms (%.3f %%)\n",
- s->counter,
- mainloopstats_to_ms(period),
- mainloopstats_to_ms(average_wait),
- s->wait_time_total * 100. / period,
- mainloopstats_to_ms(average_spent),
- s->spent_time_total * 100. / period );
-
- mainloopstats_reset( s );
- }
- }
-#endif /* MAIN_LOOP_STATS */
-}
-
-static int main_loop(void)
-{
- int ret, timeout;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
- CPUState *env;
-
- cur_cpu = first_cpu;
- next_cpu = cur_cpu->next_cpu ?: first_cpu;
- for(;;) {
- if (vm_running) {
-
- for(;;) {
- /* get next cpu */
- env = next_cpu;
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
- if (use_icount) {
- int64_t count;
- int decr;
- qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
- env->icount_decr.u16.low = 0;
- env->icount_extra = 0;
- count = qemu_next_deadline();
- count = (count + (1 << icount_time_shift) - 1)
- >> icount_time_shift;
- qemu_icount += count;
- decr = (count > 0xffff) ? 0xffff : count;
- count -= decr;
- env->icount_decr.u16.low = decr;
- env->icount_extra = count;
- }
- ret = cpu_exec(env);
-#ifdef CONFIG_PROFILER
- qemu_time += profile_getclock() - ti;
-#endif
- if (use_icount) {
- /* Fold pending instructions back into the
- instruction counter, and clear the interrupt flag. */
- qemu_icount -= (env->icount_decr.u16.low
- + env->icount_extra);
- env->icount_decr.u32 = 0;
- env->icount_extra = 0;
- }
- next_cpu = env->next_cpu ?: first_cpu;
- if (event_pending && likely(ret != EXCP_DEBUG)) {
- ret = EXCP_INTERRUPT;
- event_pending = 0;
- break;
- }
- if (ret == EXCP_HLT) {
- /* Give the next CPU a chance to run. */
- cur_cpu = env;
- continue;
- }
- if (ret != EXCP_HALTED)
- break;
- /* all CPUs are halted ? */
- if (env == cur_cpu)
- break;
- }
- cur_cpu = env;
-
-#ifdef CONFIG_TRACE
- if (tbflush_requested) {
- tbflush_requested = 0;
- tb_flush(env);
- ret = EXCP_INTERRUPT;
- } else if (exit_requested)
- goto ExitRequested;
-#endif
-
- if (shutdown_requested) {
- ret = EXCP_INTERRUPT;
- if (no_shutdown) {
- vm_stop(0);
- no_shutdown = 0;
- }
- else
- break;
- }
- if (reset_requested) {
- reset_requested = 0;
- qemu_system_reset();
- ret = EXCP_INTERRUPT;
- }
- if (powerdown_requested) {
- powerdown_requested = 0;
- qemu_system_powerdown();
- ret = EXCP_INTERRUPT;
- }
- if (unlikely(ret == EXCP_DEBUG)) {
- vm_stop(EXCP_DEBUG);
- }
- /* If all cpus are halted then wait until the next IRQ */
- /* XXX: use timeout computed from timers */
- if (ret == EXCP_HALTED) {
- if (use_icount) {
- int64_t add;
- int64_t delta;
- /* Advance virtual time to the next event. */
- if (use_icount == 1) {
- /* When not using an adaptive execution frequency
- we tend to get badly out of sync with real time,
- so just delay for a reasonable amount of time. */
- delta = 0;
- } else {
- delta = cpu_get_icount() - cpu_get_clock();
- }
- if (delta > 0) {
- /* If virtual time is ahead of real time then just
- wait for IO. */
- timeout = (delta / 1000000) + 1;
- } else {
- /* Wait for either IO to occur or the next
- timer event. */
- add = qemu_next_deadline();
- /* We advance the timer before checking for IO.
- Limit the amount we advance so that early IO
- activity won't get the guest too far ahead. */
- if (add > 10000000)
- add = 10000000;
- delta += add;
- add = (add + (1 << icount_time_shift) - 1)
- >> icount_time_shift;
- qemu_icount += add;
- timeout = delta / 1000000;
- if (timeout < 0)
- timeout = 0;
- }
- } else {
- timeout = 10;
- }
- } else {
- timeout = 0;
- }
- } else {
- if (shutdown_requested)
- break;
- timeout = 10;
- }
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
- main_loop_wait(timeout);
-#ifdef CONFIG_PROFILER
- dev_time += profile_getclock() - ti;
-#endif
- }
- cpu_disable_ticks();
- return ret;
-
-#ifdef CONFIG_TRACE
-ExitRequested:
-# ifdef HAS_AUDIO
- AUD_cleanup();
-# endif
- exit(1);
- return 0;
-#endif
-}
-
-static void help(int exitcode)
-{
- printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
- "usage: %s [options] [disk_image]\n"
- "\n"
- "'disk_image' is a raw hard image image for IDE hard disk 0\n"
- "\n"
- "Standard options:\n"
- "-M machine select emulated machine (-M ? for list)\n"
- "-cpu cpu select CPU (-cpu ? for list)\n"
- "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
- "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
- "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
- "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
- "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
- " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
- " [,cache=on|off][,format=f]\n"
- " use 'file' as a drive image\n"
- "-mtdblock file use 'file' as on-board Flash memory image\n"
- "-sd file use 'file' as SecureDigital card image\n"
- "-pflash file use 'file' as a parallel flash image\n"
- "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
- "-snapshot write to temporary files instead of disk image files\n"
-#ifdef CONFIG_SDL
- "-no-frame open SDL window without a frame and window decorations\n"
- "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
- "-no-quit disable SDL window close capability\n"
-#endif
-#ifdef TARGET_I386
- "-no-fd-bootchk disable boot signature checking for floppy disks\n"
-#endif
- "-m megs set virtual RAM size to megs MB [default=%d]\n"
- "-smp n set the number of CPUs to 'n' [default=1]\n"
- "-nographic disable graphical output and redirect serial I/Os to console\n"
- "-portrait rotate graphical output 90 deg left (only PXA LCD)\n"
-#ifndef _WIN32
- "-k language use keyboard layout (for example \"fr\" for French)\n"
-#endif
-#ifdef HAS_AUDIO
- "-audio-help print list of audio drivers and their options\n"
- "-soundhw c1,... enable audio support\n"
- " and only specified sound cards (comma separated list)\n"
- " use -soundhw ? to get the list of supported cards\n"
- " use -soundhw all to enable all of them\n"
-#endif
- "-localtime set the real time clock to local time [default=utc]\n"
- "-full-screen start in full screen\n"
-#ifdef TARGET_I386
- "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
-#endif
- "-usb enable the USB driver (will be the default soon)\n"
- "-usbdevice name add the host or guest USB device 'name'\n"
-#if defined(TARGET_PPC) || defined(TARGET_SPARC)
- "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
-#endif
- "-name string set the name of the guest\n"
- "\n"
- "Network options:\n"
- "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
- " create a new Network Interface Card and connect it to VLAN 'n'\n"
-#ifdef CONFIG_SLIRP
- "-net user[,vlan=n][,hostname=host]\n"
- " connect the user mode network stack to VLAN 'n' and send\n"
- " hostname 'host' to DHCP clients\n"
-#endif
-#ifdef _WIN32
- "-net tap[,vlan=n],ifname=name\n"
- " connect the host TAP network interface to VLAN 'n'\n"
-#else
- "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
- " connect the host TAP network interface to VLAN 'n' and use the\n"
- " network scripts 'file' (default=%s)\n"
- " and 'dfile' (default=%s);\n"
- " use '[down]script=no' to disable script execution;\n"
- " use 'fd=h' to connect to an already opened TAP interface\n"
-#endif
- "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
- " connect the vlan 'n' to another VLAN using a socket connection\n"
- "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
- " connect the vlan 'n' to multicast maddr and port\n"
- "-net none use it alone to have zero network devices; if no -net option\n"
- " is provided, the default is '-net nic -net user'\n"
- "\n"
-#ifdef CONFIG_SLIRP
- "-tftp dir allow tftp access to files in dir [-net user]\n"
- "-bootp file advertise file in BOOTP replies\n"
-#ifndef _WIN32
- "-smb dir allow SMB access to files in 'dir' [-net user]\n"
-#endif
- "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
- " redirect TCP or UDP connections from host to guest [-net user]\n"
-#endif
- "\n"
- "Linux boot specific:\n"
- "-kernel bzImage use 'bzImage' as kernel image\n"
- "-append cmdline use 'cmdline' as kernel command line\n"
- "-initrd file use 'file' as initial ram disk\n"
- "\n"
- "Debug/Expert options:\n"
- "-monitor dev redirect the monitor to char device 'dev'\n"
- "-serial dev redirect the serial port to char device 'dev'\n"
- "-parallel dev redirect the parallel port to char device 'dev'\n"
- "-pidfile file Write PID to 'file'\n"
- "-S freeze CPU at startup (use 'c' to start execution)\n"
- "-s wait gdb connection to port\n"
- "-p port set gdb connection port [default=%s]\n"
- "-d item1,... output log to %s (use -d ? for a list of log items)\n"
- "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
- " translation (t=none or lba) (usually qemu can guess them)\n"
- "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
-#ifdef USE_KQEMU
- "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
- "-no-kqemu disable KQEMU kernel module usage\n"
-#endif
-#ifdef TARGET_I386
- "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
- " (default is CL-GD5446 PCI VGA)\n"
- "-no-acpi disable ACPI\n"
-#endif
-#ifdef CONFIG_CURSES
- "-curses use a curses/ncurses interface instead of SDL\n"
-#endif
- "-no-reboot exit instead of rebooting\n"
- "-no-shutdown stop before shutdown\n"
- "-loadvm [tag|id] start right away with a saved state (loadvm in monitor)\n"
- "-vnc display start a VNC server on display\n"
-#ifdef CONFIG_TRACE
- "-trace file create an execution trace in 'file' (implies -tracing on)\n"
- "-tracing off start with tracing off\n"
- "-trace_miss include tracing of cache miss addresses\n"
- "-trace_addr include tracing of all load/store addresses\n"
- "-dcache_load_miss cycles\n"
- " set the dcache load miss penalty to 'cycles'\n"
- "-dcache_store_miss cycles\n"
- " set the dcache store miss penalty to 'cycles'\n"
-#endif
-#ifdef CONFIG_NAND
- "-nand name[,readonly][,size=size][,pagesize=size][,extrasize=size][,erasepages=pages][,initfile=file][,file=file]"
-#endif
-#ifndef _WIN32
- "-daemonize daemonize QEMU after initializing\n"
-#endif
- "-option-rom rom load a file, rom, into the option ROM space\n"
-#ifdef TARGET_SPARC
- "-prom-env variable=value set OpenBIOS nvram variables\n"
-#endif
- "-clock force the use of the given methods for timer alarm.\n"
- " To see what timers are available use -clock ?\n"
- "-startdate select initial date of the clock\n"
- "-icount [N|auto]\n"
- " Enable virtual instruction counter with 2^N clock ticks per instruction\n"
- "\n"
- "During emulation, the following keys are useful:\n"
- "ctrl-alt-f toggle full screen\n"
- "ctrl-alt-n switch to virtual console 'n'\n"
- "ctrl-alt toggle mouse and keyboard grab\n"
- "\n"
- "When using -nographic, press 'ctrl-a h' to get some help.\n"
- ,
- "qemu",
- DEFAULT_RAM_SIZE,
-#ifndef _WIN32
- DEFAULT_NETWORK_SCRIPT,
- DEFAULT_NETWORK_DOWN_SCRIPT,
-#endif
- DEFAULT_GDBSTUB_PORT,
- "/tmp/qemu.log");
- exit(exitcode);
-}
-
-#define HAS_ARG 0x0001
-
-enum {
- QEMU_OPTION_h,
-
- QEMU_OPTION_M,
- QEMU_OPTION_cpu,
- QEMU_OPTION_fda,
- QEMU_OPTION_fdb,
- QEMU_OPTION_hda,
- QEMU_OPTION_hdb,
- QEMU_OPTION_hdc,
- QEMU_OPTION_hdd,
- QEMU_OPTION_drive,
- QEMU_OPTION_cdrom,
- QEMU_OPTION_mtdblock,
- QEMU_OPTION_sd,
- QEMU_OPTION_pflash,
- QEMU_OPTION_boot,
- QEMU_OPTION_snapshot,
-#ifdef TARGET_I386
- QEMU_OPTION_no_fd_bootchk,
-#endif
- QEMU_OPTION_m,
- QEMU_OPTION_nographic,
- QEMU_OPTION_portrait,
-#ifdef HAS_AUDIO
- QEMU_OPTION_audio_help,
- QEMU_OPTION_soundhw,
-#endif
-
- QEMU_OPTION_net,
- QEMU_OPTION_tftp,
- QEMU_OPTION_bootp,
- QEMU_OPTION_smb,
- QEMU_OPTION_redir,
-
- QEMU_OPTION_kernel,
- QEMU_OPTION_append,
- QEMU_OPTION_initrd,
-
- QEMU_OPTION_S,
- QEMU_OPTION_s,
- QEMU_OPTION_p,
- QEMU_OPTION_d,
- QEMU_OPTION_hdachs,
- QEMU_OPTION_L,
- QEMU_OPTION_bios,
- QEMU_OPTION_k,
- QEMU_OPTION_localtime,
- QEMU_OPTION_cirrusvga,
- QEMU_OPTION_vmsvga,
- QEMU_OPTION_g,
- QEMU_OPTION_std_vga,
- QEMU_OPTION_echr,
- QEMU_OPTION_monitor,
- QEMU_OPTION_serial,
- QEMU_OPTION_parallel,
- QEMU_OPTION_loadvm,
- QEMU_OPTION_full_screen,
- QEMU_OPTION_no_frame,
- QEMU_OPTION_alt_grab,
- QEMU_OPTION_no_quit,
- QEMU_OPTION_pidfile,
- QEMU_OPTION_no_kqemu,
- QEMU_OPTION_kernel_kqemu,
- QEMU_OPTION_win2k_hack,
- QEMU_OPTION_usb,
- QEMU_OPTION_usbdevice,
- QEMU_OPTION_smp,
- QEMU_OPTION_vnc,
- QEMU_OPTION_no_acpi,
- QEMU_OPTION_curses,
- QEMU_OPTION_no_reboot,
- QEMU_OPTION_no_shutdown,
- QEMU_OPTION_show_cursor,
- QEMU_OPTION_daemonize,
- QEMU_OPTION_option_rom,
- QEMU_OPTION_semihosting,
- QEMU_OPTION_name,
- QEMU_OPTION_prom_env,
- QEMU_OPTION_old_param,
- QEMU_OPTION_noaudio,
- QEMU_OPTION_mic,
-#ifdef CONFIG_TRACE
- QEMU_OPTION_trace_file,
- QEMU_OPTION_tracing,
- QEMU_OPTION_trace_miss,
- QEMU_OPTION_trace_addr,
- QEMU_OPTION_dcache_load_miss,
- QEMU_OPTION_dcache_store_miss,
-#endif
-#ifdef CONFIG_NAND
- QEMU_OPTION_nand,
-#endif
- QEMU_OPTION_clock,
- QEMU_OPTION_startdate,
- QEMU_OPTION_tb_size,
- QEMU_OPTION_icount,
-};
-
-typedef struct QEMUOption {
- const char *name;
- int flags;
- int index;
-} QEMUOption;
-
-const QEMUOption qemu_options[] = {
- { "h", 0, QEMU_OPTION_h },
- { "help", 0, QEMU_OPTION_h },
-
- { "M", HAS_ARG, QEMU_OPTION_M },
- { "cpu", HAS_ARG, QEMU_OPTION_cpu },
- { "fda", HAS_ARG, QEMU_OPTION_fda },
- { "fdb", HAS_ARG, QEMU_OPTION_fdb },
- { "hda", HAS_ARG, QEMU_OPTION_hda },
- { "hdb", HAS_ARG, QEMU_OPTION_hdb },
- { "hdc", HAS_ARG, QEMU_OPTION_hdc },
- { "hdd", HAS_ARG, QEMU_OPTION_hdd },
- { "drive", HAS_ARG, QEMU_OPTION_drive },
- { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
- { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
- { "sd", HAS_ARG, QEMU_OPTION_sd },
- { "pflash", HAS_ARG, QEMU_OPTION_pflash },
- { "boot", HAS_ARG, QEMU_OPTION_boot },
- { "snapshot", 0, QEMU_OPTION_snapshot },
-#ifdef TARGET_I386
- { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
-#endif
- { "m", HAS_ARG, QEMU_OPTION_m },
- { "nographic", 0, QEMU_OPTION_nographic },
- { "portrait", 0, QEMU_OPTION_portrait },
- { "k", HAS_ARG, QEMU_OPTION_k },
-#ifdef HAS_AUDIO
- { "audio-help", 0, QEMU_OPTION_audio_help },
- { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
-#endif
-
- { "net", HAS_ARG, QEMU_OPTION_net},
-#ifdef CONFIG_SLIRP
- { "tftp", HAS_ARG, QEMU_OPTION_tftp },
- { "bootp", HAS_ARG, QEMU_OPTION_bootp },
-#ifndef _WIN32
- { "smb", HAS_ARG, QEMU_OPTION_smb },
-#endif
- { "redir", HAS_ARG, QEMU_OPTION_redir },
-#endif
-
- { "kernel", HAS_ARG, QEMU_OPTION_kernel },
- { "append", HAS_ARG, QEMU_OPTION_append },
- { "initrd", HAS_ARG, QEMU_OPTION_initrd },
-
- { "S", 0, QEMU_OPTION_S },
- { "s", 0, QEMU_OPTION_s },
- { "p", HAS_ARG, QEMU_OPTION_p },
- { "d", HAS_ARG, QEMU_OPTION_d },
- { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
- { "L", HAS_ARG, QEMU_OPTION_L },
- { "bios", HAS_ARG, QEMU_OPTION_bios },
-#ifdef USE_KQEMU
- { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
- { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-#endif
-#if defined(TARGET_PPC) || defined(TARGET_SPARC)
- { "g", HAS_ARG, QEMU_OPTION_g },
-#endif
- { "localtime", 0, QEMU_OPTION_localtime },
- { "std-vga", 0, QEMU_OPTION_std_vga },
- { "echr", HAS_ARG, QEMU_OPTION_echr },
- { "monitor", HAS_ARG, QEMU_OPTION_monitor },
- { "serial", HAS_ARG, QEMU_OPTION_serial },
- { "parallel", HAS_ARG, QEMU_OPTION_parallel },
- { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
- { "full-screen", 0, QEMU_OPTION_full_screen },
-#ifdef CONFIG_SDL
- { "no-frame", 0, QEMU_OPTION_no_frame },
- { "alt-grab", 0, QEMU_OPTION_alt_grab },
- { "no-quit", 0, QEMU_OPTION_no_quit },
-#endif
- { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
- { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
- { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
- { "smp", HAS_ARG, QEMU_OPTION_smp },
- { "vnc", HAS_ARG, QEMU_OPTION_vnc },
-#ifdef CONFIG_CURSES
- { "curses", 0, QEMU_OPTION_curses },
-#endif
-
- /* temporary options */
- { "usb", 0, QEMU_OPTION_usb },
- { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
- { "vmwarevga", 0, QEMU_OPTION_vmsvga },
- { "no-acpi", 0, QEMU_OPTION_no_acpi },
- { "no-reboot", 0, QEMU_OPTION_no_reboot },
- { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
- { "show-cursor", 0, QEMU_OPTION_show_cursor },
- { "daemonize", 0, QEMU_OPTION_daemonize },
- { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
- { "semihosting", 0, QEMU_OPTION_semihosting },
-#endif
- { "name", HAS_ARG, QEMU_OPTION_name },
-#if defined(TARGET_SPARC)
- { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
-#endif
-#if defined(TARGET_ARM)
- { "old-param", 0, QEMU_OPTION_old_param },
-#endif
-
- /* android stuff */
- { "noaudio", 0, QEMU_OPTION_noaudio },
- { "mic", HAS_ARG, QEMU_OPTION_mic },
-#ifdef CONFIG_TRACE
- { "trace", HAS_ARG, QEMU_OPTION_trace_file },
- { "tracing", HAS_ARG, QEMU_OPTION_tracing },
- { "trace_miss", 0, QEMU_OPTION_trace_miss },
- { "trace_addr", 0, QEMU_OPTION_trace_addr },
- { "dcache_load_miss", HAS_ARG, QEMU_OPTION_dcache_load_miss },
- { "dcache_store_miss", HAS_ARG, QEMU_OPTION_dcache_store_miss },
-#endif
-#ifdef CONFIG_NAND
- { "nand", HAS_ARG, QEMU_OPTION_nand },
-#endif
- { "clock", HAS_ARG, QEMU_OPTION_clock },
- { NULL, 0, 0 },
-};
-
-/* password input */
-
-int qemu_key_check(BlockDriverState *bs, const char *name)
-{
- char password[256];
- int i;
-
- if (!bdrv_is_encrypted(bs))
- return 0;
-
- term_printf("%s is encrypted.\n", name);
- for(i = 0; i < 3; i++) {
- monitor_readline("Password: ", 1, password, sizeof(password));
- if (bdrv_set_key(bs, password) == 0)
- return 0;
- term_printf("invalid password\n");
- }
- return -EPERM;
-}
-
-static BlockDriverState *get_bdrv(int index)
-{
- if (index > nb_drives)
- return NULL;
- return drives_table[index].bdrv;
-}
-
-static void read_passwords(void)
-{
- BlockDriverState *bs;
- int i;
-
- for(i = 0; i < 6; i++) {
- bs = get_bdrv(i);
- if (bs)
- qemu_key_check(bs, bdrv_get_device_name(bs));
- }
-}
-
-#ifdef HAS_AUDIO
-struct soundhw soundhw[] = {
-#if 0 /* ANDROID */
-#ifdef TARGET_I386
- {
- "pcspk",
- "PC speaker",
- 0,
- 1,
- { .init_isa = pcspk_audio_init }
- },
-#endif
- {
- "sb16",
- "Creative Sound Blaster 16",
- 0,
- 1,
- { .init_isa = SB16_init }
- },
-
-#ifdef CONFIG_CS4231A
- {
- "cs4231a",
- "CS4231A",
- 0,
- 1,
- { .init_isa = cs4231a_init }
- },
-#endif
-
-#ifdef CONFIG_ADLIB
- {
- "adlib",
-#ifdef HAS_YMF262
- "Yamaha YMF262 (OPL3)",
-#else
- "Yamaha YM3812 (OPL2)",
-#endif
- 0,
- 1,
- { .init_isa = Adlib_init }
- },
-#endif
-
-#ifdef CONFIG_GUS
- {
- "gus",
- "Gravis Ultrasound GF1",
- 0,
- 1,
- { .init_isa = GUS_init }
- },
-#endif
-
-#ifdef CONFIG_AC97
- {
- "ac97",
- "Intel 82801AA AC97 Audio",
- 0,
- 0,
- { .init_pci = ac97_init }
- },
-#endif
-
- {
- "es1370",
- "ENSONIQ AudioPCI ES1370",
- 0,
- 0,
- { .init_pci = es1370_init }
- },
-#endif /* ANDROID */
-
- { NULL, NULL, 0, 0, { NULL } }
-};
-
-static void select_soundhw (const char *optarg)
-{
- struct soundhw *c;
-
- if (*optarg == '?') {
- show_valid_cards:
-
- printf ("Valid sound card names (comma separated):\n");
- for (c = soundhw; c->name; ++c) {
- printf ("%-11s %s\n", c->name, c->descr);
- }
- printf ("\n-soundhw all will enable all of the above\n");
- exit (*optarg != '?');
- }
- else {
- size_t l;
- const char *p;
- char *e;
- int bad_card = 0;
-
- if (!strcmp (optarg, "all")) {
- for (c = soundhw; c->name; ++c) {
- c->enabled = 1;
- }
- return;
- }
-
- p = optarg;
- while (*p) {
- e = strchr (p, ',');
- l = !e ? strlen (p) : (size_t) (e - p);
-
- for (c = soundhw; c->name; ++c) {
- if (!strncmp (c->name, p, l)) {
- c->enabled = 1;
- break;
- }
- }
-
- if (!c->name) {
- if (l > 80) {
- fprintf (stderr,
- "Unknown sound card name (too big to show)\n");
- }
- else {
- fprintf (stderr, "Unknown sound card name `%.*s'\n",
- (int) l, p);
- }
- bad_card = 1;
- }
- p += l + (e != NULL);
- }
-
- if (bad_card)
- goto show_valid_cards;
- }
-}
-#endif
-
-#ifdef _WIN32
-static BOOL WINAPI qemu_ctrl_handler(DWORD type)
-{
- exit(STATUS_CONTROL_C_EXIT);
- return TRUE;
-}
-#endif
-
-#define MAX_NET_CLIENTS 32
-
-#ifndef _WIN32
-
-static void termsig_handler(int signal)
-{
- qemu_system_shutdown_request();
-}
-
-static void termsig_setup(void)
-{
- struct sigaction act;
-
- memset(&act, 0, sizeof(act));
- act.sa_handler = termsig_handler;
- sigaction(SIGINT, &act, NULL);
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGTERM, &act, NULL);
-}
-
-#endif
-
-int main(int argc, char **argv)
-{
-#ifdef CONFIG_GDBSTUB
- int use_gdbstub;
- const char *gdbstub_port;
-#endif
- uint32_t boot_devices_bitmap = 0;
- int i;
- int snapshot, linux_boot, net_boot;
- const char *initrd_filename;
- const char *kernel_filename, *kernel_cmdline;
- const char *boot_devices = "";
- DisplayState *ds = &display_state;
- int cyls, heads, secs, translation;
- const char *net_clients[MAX_NET_CLIENTS];
- int nb_net_clients;
- int hda_index;
- int optind;
- const char *r, *optarg;
- CharDriverState *monitor_hd;
- const char *monitor_device;
- const char *serial_devices[MAX_SERIAL_PORTS];
- int serial_device_index;
- const char *parallel_devices[MAX_PARALLEL_PORTS];
- int parallel_device_index;
- const char *loadvm = NULL;
- QEMUMachine *machine;
- const char *cpu_model;
- const char *usb_devices[MAX_USB_CMDLINE];
- int usb_devices_index;
- int fds[2];
- int tb_size;
- const char *pid_file = NULL;
- VLANState *vlan;
-
- LIST_INIT (&vm_change_state_head);
-#ifndef _WIN32
- {
- struct sigaction act;
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &act, NULL);
- }
-#else
- SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
- /* Note: cpu_interrupt() is currently not SMP safe, so we force
- QEMU to run on a single CPU */
- {
- HANDLE h;
- DWORD mask, smask;
- int i;
- h = GetCurrentProcess();
- if (GetProcessAffinityMask(h, &mask, &smask)) {
- for(i = 0; i < 32; i++) {
- if (mask & (1 << i))
- break;
- }
- if (i != 32) {
- mask = 1 << i;
- SetProcessAffinityMask(h, mask);
- }
- }
- }
-#endif
-
- register_machines();
- machine = first_machine;
- cpu_model = NULL;
- initrd_filename = NULL;
- ram_size = 0;
- vga_ram_size = VGA_RAM_SIZE;
-#ifdef CONFIG_GDBSTUB
- use_gdbstub = 0;
- gdbstub_port = DEFAULT_GDBSTUB_PORT;
-#endif
- snapshot = 0;
- nographic = 0;
- curses = 0;
- kernel_filename = NULL;
- kernel_cmdline = "";
- cyls = heads = secs = 0;
- translation = BIOS_ATA_TRANSLATION_AUTO;
- monitor_device = "vc";
-
- serial_devices[0] = "vc:80Cx24C";
- for(i = 1; i < MAX_SERIAL_PORTS; i++)
- serial_devices[i] = NULL;
- serial_device_index = 0;
-
- parallel_devices[0] = "vc:640x480";
- for(i = 1; i < MAX_PARALLEL_PORTS; i++)
- parallel_devices[i] = NULL;
- parallel_device_index = 0;
-
- usb_devices_index = 0;
-
- nb_net_clients = 0;
- nb_drives = 0;
- nb_drives_opt = 0;
- hda_index = -1;
-
- nb_nics = 0;
-
- tb_size = 0;
- android_audio_enabled = 1;
-
- optind = 1;
- for(;;) {
- if (optind >= argc)
- break;
- r = argv[optind];
- if (r[0] != '-') {
- hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
- } else {
- const QEMUOption *popt;
-
- optind++;
- /* Treat --foo the same as -foo. */
- if (r[1] == '-')
- r++;
- popt = qemu_options;
- for(;;) {
- if (!popt->name) {
- fprintf(stderr, "%s: invalid option -- '%s'\n",
- argv[0], r);
- exit(1);
- }
- if (!strcmp(popt->name, r + 1))
- break;
- popt++;
- }
- if (popt->flags & HAS_ARG) {
- if (optind >= argc) {
- fprintf(stderr, "%s: option '%s' requires an argument\n",
- argv[0], r);
- exit(1);
- }
- optarg = argv[optind++];
- } else {
- optarg = NULL;
- }
-
- switch(popt->index) {
- case QEMU_OPTION_M:
- machine = find_machine(optarg);
- if (!machine) {
- QEMUMachine *m;
- printf("Supported machines are:\n");
- for(m = first_machine; m != NULL; m = m->next) {
- printf("%-10s %s%s\n",
- m->name, m->desc,
- m == first_machine ? " (default)" : "");
- }
- exit(*optarg != '?');
- }
- break;
- case QEMU_OPTION_cpu:
- /* hw initialization will check this */
- if (*optarg == '?') {
-/* XXX: implement xxx_cpu_list for targets that still miss it */
-#if defined(cpu_list)
- cpu_list(stdout, &fprintf);
-#endif
- exit(0);
- } else {
- cpu_model = optarg;
- }
- break;
- case QEMU_OPTION_initrd:
- initrd_filename = optarg;
- break;
- case QEMU_OPTION_hda:
- if (cyls == 0)
- hda_index = drive_add(optarg, HD_ALIAS, 0);
- else
- hda_index = drive_add(optarg, HD_ALIAS
- ",cyls=%d,heads=%d,secs=%d%s",
- 0, cyls, heads, secs,
- translation == BIOS_ATA_TRANSLATION_LBA ?
- ",trans=lba" :
- translation == BIOS_ATA_TRANSLATION_NONE ?
- ",trans=none" : "");
- break;
- case QEMU_OPTION_hdb:
- case QEMU_OPTION_hdc:
- case QEMU_OPTION_hdd:
- drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
- break;
- case QEMU_OPTION_drive:
- drive_add(NULL, "%s", optarg);
- break;
- case QEMU_OPTION_mtdblock:
- drive_add(optarg, MTD_ALIAS);
- break;
- case QEMU_OPTION_sd:
- drive_add(optarg, SD_ALIAS);
- break;
- case QEMU_OPTION_pflash:
- drive_add(optarg, PFLASH_ALIAS);
- break;
- case QEMU_OPTION_snapshot:
- snapshot = 1;
- break;
- case QEMU_OPTION_hdachs:
- {
- const char *p;
- p = optarg;
- cyls = strtol(p, (char **)&p, 0);
- if (cyls < 1 || cyls > 16383)
- goto chs_fail;
- if (*p != ',')
- goto chs_fail;
- p++;
- heads = strtol(p, (char **)&p, 0);
- if (heads < 1 || heads > 16)
- goto chs_fail;
- if (*p != ',')
- goto chs_fail;
- p++;
- secs = strtol(p, (char **)&p, 0);
- if (secs < 1 || secs > 63)
- goto chs_fail;
- if (*p == ',') {
- p++;
- if (!strcmp(p, "none"))
- translation = BIOS_ATA_TRANSLATION_NONE;
- else if (!strcmp(p, "lba"))
- translation = BIOS_ATA_TRANSLATION_LBA;
- else if (!strcmp(p, "auto"))
- translation = BIOS_ATA_TRANSLATION_AUTO;
- else
- goto chs_fail;
- } else if (*p != '\0') {
- chs_fail:
- fprintf(stderr, "qemu: invalid physical CHS format\n");
- exit(1);
- }
- if (hda_index != -1)
- snprintf(drives_opt[hda_index].opt,
- sizeof(drives_opt[hda_index].opt),
- HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
- 0, cyls, heads, secs,
- translation == BIOS_ATA_TRANSLATION_LBA ?
- ",trans=lba" :
- translation == BIOS_ATA_TRANSLATION_NONE ?
- ",trans=none" : "");
- }
- break;
- case QEMU_OPTION_nographic:
- nographic = 1;
- break;
-#ifdef CONFIG_CURSES
- case QEMU_OPTION_curses:
- curses = 1;
- break;
-#endif
- case QEMU_OPTION_portrait:
- graphic_rotate = 1;
- break;
- case QEMU_OPTION_kernel:
- kernel_filename = optarg;
- break;
- case QEMU_OPTION_append:
- kernel_cmdline = optarg;
- break;
- case QEMU_OPTION_cdrom:
- drive_add(optarg, CDROM_ALIAS);
- break;
- case QEMU_OPTION_boot:
- boot_devices = optarg;
- /* We just do some generic consistency checks */
- {
- /* Could easily be extended to 64 devices if needed */
- const char *p;
-
- boot_devices_bitmap = 0;
- for (p = boot_devices; *p != '\0'; p++) {
- /* Allowed boot devices are:
- * a b : floppy disk drives
- * c ... f : IDE disk drives
- * g ... m : machine implementation dependant drives
- * n ... p : network devices
- * It's up to each machine implementation to check
- * if the given boot devices match the actual hardware
- * implementation and firmware features.
- */
- if (*p < 'a' || *p > 'q') {
- fprintf(stderr, "Invalid boot device '%c'\n", *p);
- exit(1);
- }
- if (boot_devices_bitmap & (1 << (*p - 'a'))) {
- fprintf(stderr,
- "Boot device '%c' was given twice\n",*p);
- exit(1);
- }
- boot_devices_bitmap |= 1 << (*p - 'a');
- }
- }
- break;
- case QEMU_OPTION_fda:
- case QEMU_OPTION_fdb:
- drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
- break;
-#ifdef TARGET_I386
- case QEMU_OPTION_no_fd_bootchk:
- fd_bootchk = 0;
- break;
-#endif
- case QEMU_OPTION_net:
- if (nb_net_clients >= MAX_NET_CLIENTS) {
- fprintf(stderr, "qemu: too many network clients\n");
- exit(1);
- }
- net_clients[nb_net_clients] = optarg;
- nb_net_clients++;
- break;
-#ifdef CONFIG_SLIRP
- case QEMU_OPTION_tftp:
- tftp_prefix = optarg;
- break;
- case QEMU_OPTION_bootp:
- bootp_filename = optarg;
- break;
-#if 0 /* ANDROID disabled */
- case QEMU_OPTION_smb:
- net_slirp_smb(optarg);
- break;
-#endif
- case QEMU_OPTION_redir:
- net_slirp_redir(optarg);
- break;
-#endif
-#ifdef HAS_AUDIO
- case QEMU_OPTION_audio_help:
- AUD_help ();
- exit (0);
- break;
- case QEMU_OPTION_soundhw:
- select_soundhw (optarg);
- break;
-#endif
- case QEMU_OPTION_h:
- help(0);
- break;
- case QEMU_OPTION_m: {
- uint64_t value;
- char *ptr;
-
- value = strtoul(optarg, &ptr, 10);
- switch (*ptr) {
- case 0: case 'M': case 'm':
- value <<= 20;
- break;
- case 'G': case 'g':
- value <<= 30;
- break;
- default:
- fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
- exit(1);
- }
-
- /* On 32-bit hosts, QEMU is limited by virtual address space */
- if (value > (2047 << 20)
-#ifndef USE_KQEMU
- && HOST_LONG_BITS == 32
-#endif
- ) {
- fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
- exit(1);
- }
- if (value != (uint64_t)(ram_addr_t)value) {
- fprintf(stderr, "qemu: ram size too large\n");
- exit(1);
- }
- ram_size = value;
- break;
- }
- case QEMU_OPTION_d:
- {
- int mask;
- CPULogItem *item;
-
- mask = cpu_str_to_log_mask(optarg);
- if (!mask) {
- printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
- }
- cpu_set_log(mask);
- }
- break;
-#ifdef CONFIG_GDBSTUB
- case QEMU_OPTION_s:
- use_gdbstub = 1;
- break;
- case QEMU_OPTION_p:
- gdbstub_port = optarg;
- break;
-#endif
- case QEMU_OPTION_L:
- bios_dir = optarg;
- break;
- case QEMU_OPTION_S:
-#if 1 /* ANDROID */
- fprintf(stderr, "Sorry, stopped launch is not supported in the Android emulator\n" );
- exit(1);
-#else
- autostart = 0;
- break;
-#endif
- case QEMU_OPTION_k:
- keyboard_layout = optarg;
- break;
- case QEMU_OPTION_localtime:
- rtc_utc = 0;
- break;
- case QEMU_OPTION_cirrusvga:
- cirrus_vga_enabled = 1;
- vmsvga_enabled = 0;
- break;
- case QEMU_OPTION_vmsvga:
- cirrus_vga_enabled = 0;
- vmsvga_enabled = 1;
- break;
- case QEMU_OPTION_std_vga:
- cirrus_vga_enabled = 0;
- vmsvga_enabled = 0;
- break;
- case QEMU_OPTION_g:
- {
- const char *p;
- int w, h, depth;
- p = optarg;
- w = strtol(p, (char **)&p, 10);
- if (w <= 0) {
- graphic_error:
- fprintf(stderr, "qemu: invalid resolution or depth\n");
- exit(1);
- }
- if (*p != 'x')
- goto graphic_error;
- p++;
- h = strtol(p, (char **)&p, 10);
- if (h <= 0)
- goto graphic_error;
- if (*p == 'x') {
- p++;
- depth = strtol(p, (char **)&p, 10);
- if (depth != 8 && depth != 15 && depth != 16 &&
- depth != 24 && depth != 32)
- goto graphic_error;
- } else if (*p == '\0') {
- depth = graphic_depth;
- } else {
- goto graphic_error;
- }
-
- graphic_width = w;
- graphic_height = h;
- graphic_depth = depth;
- }
- break;
- case QEMU_OPTION_echr:
- {
- char *r;
- term_escape_char = strtol(optarg, &r, 0);
- if (r == optarg)
- printf("Bad argument to echr\n");
- break;
- }
- case QEMU_OPTION_monitor:
- monitor_device = optarg;
- break;
- case QEMU_OPTION_serial:
- if (serial_device_index >= MAX_SERIAL_PORTS) {
- fprintf(stderr, "qemu: too many serial ports\n");
- exit(1);
- }
- serial_devices[serial_device_index] = optarg;
- serial_device_index++;
- break;
- case QEMU_OPTION_parallel:
- if (parallel_device_index >= MAX_PARALLEL_PORTS) {
- fprintf(stderr, "qemu: too many parallel ports\n");
- exit(1);
- }
- parallel_devices[parallel_device_index] = optarg;
- parallel_device_index++;
- break;
- case QEMU_OPTION_loadvm:
- loadvm = optarg;
- break;
- case QEMU_OPTION_full_screen:
- full_screen = 1;
- break;
-#ifdef CONFIG_SDL
- case QEMU_OPTION_no_frame:
- no_frame = 1;
- break;
- case QEMU_OPTION_alt_grab:
- alt_grab = 1;
- break;
- case QEMU_OPTION_no_quit:
- no_quit = 1;
- break;
-#endif
- case QEMU_OPTION_pidfile:
- pid_file = optarg;
- break;
-#ifdef TARGET_I386
- case QEMU_OPTION_win2k_hack:
- win2k_install_hack = 1;
- break;
-#endif
-#ifdef USE_KQEMU
- case QEMU_OPTION_no_kqemu:
- kqemu_allowed = 0;
- break;
- case QEMU_OPTION_kernel_kqemu:
- kqemu_allowed = 2;
- break;
-#endif
- case QEMU_OPTION_usb:
- usb_enabled = 1;
- break;
- case QEMU_OPTION_usbdevice:
- usb_enabled = 1;
- if (usb_devices_index >= MAX_USB_CMDLINE) {
- fprintf(stderr, "Too many USB devices\n");
- exit(1);
- }
- usb_devices[usb_devices_index] = optarg;
- usb_devices_index++;
- break;
- case QEMU_OPTION_smp:
- smp_cpus = atoi(optarg);
- if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
- fprintf(stderr, "Invalid number of CPUs\n");
- exit(1);
- }
- break;
- case QEMU_OPTION_vnc:
- vnc_display = optarg;
- break;
- case QEMU_OPTION_no_acpi:
- acpi_enabled = 0;
- break;
- case QEMU_OPTION_no_reboot:
- no_reboot = 1;
- break;
- case QEMU_OPTION_no_shutdown:
- no_shutdown = 1;
- break;
- case QEMU_OPTION_show_cursor:
- cursor_hide = 0;
- break;
- case QEMU_OPTION_daemonize:
- daemonize = 1;
- break;
- case QEMU_OPTION_option_rom:
- if (nb_option_roms >= MAX_OPTION_ROMS) {
- fprintf(stderr, "Too many option ROMs\n");
- exit(1);
- }
- option_rom[nb_option_roms] = optarg;
- nb_option_roms++;
- break;
- case QEMU_OPTION_semihosting:
- semihosting_enabled = 1;
- break;
- case QEMU_OPTION_name:
- qemu_name = optarg;
- break;
-#ifdef TARGET_SPARC
- case QEMU_OPTION_prom_env:
- if (nb_prom_envs >= MAX_PROM_ENVS) {
- fprintf(stderr, "Too many prom variables\n");
- exit(1);
- }
- prom_envs[nb_prom_envs] = optarg;
- nb_prom_envs++;
- break;
-#endif
-#ifdef TARGET_ARM
- case QEMU_OPTION_old_param:
- old_param = 1;
- break;
-#endif
- case QEMU_OPTION_clock:
- configure_alarms(optarg);
- break;
- case QEMU_OPTION_startdate:
- {
- struct tm tm;
- time_t rtc_start_date;
- if (!strcmp(optarg, "now")) {
- rtc_date_offset = -1;
- } else {
- if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
- &tm.tm_year,
- &tm.tm_mon,
- &tm.tm_mday,
- &tm.tm_hour,
- &tm.tm_min,
- &tm.tm_sec) == 6) {
- /* OK */
- } else if (sscanf(optarg, "%d-%d-%d",
- &tm.tm_year,
- &tm.tm_mon,
- &tm.tm_mday) == 3) {
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- } else {
- goto date_fail;
- }
- tm.tm_year -= 1900;
- tm.tm_mon--;
- rtc_start_date = mktimegm(&tm);
- if (rtc_start_date == -1) {
- date_fail:
- fprintf(stderr, "Invalid date format. Valid format are:\n"
- "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
- exit(1);
- }
- rtc_date_offset = time(NULL) - rtc_start_date;
- }
- }
- break;
- case QEMU_OPTION_tb_size:
- tb_size = strtol(optarg, NULL, 0);
- if (tb_size < 0)
- tb_size = 0;
- break;
- case QEMU_OPTION_icount:
- use_icount = 1;
- if (strcmp(optarg, "auto") == 0) {
- icount_time_shift = -1;
- } else {
- icount_time_shift = strtol(optarg, NULL, 0);
- }
- break;
-
- case QEMU_OPTION_noaudio:
- android_audio_enabled = 0;
- break;
- case QEMU_OPTION_mic:
- audio_input_source = (char*)optarg;
- break;
-#ifdef CONFIG_TRACE
- case QEMU_OPTION_trace_file:
- trace_filename = optarg;
- tracing = 1;
- break;
- case QEMU_OPTION_trace_miss:
- trace_cache_miss = 1;
- break;
- case QEMU_OPTION_trace_addr:
- trace_all_addr = 1;
- break;
- case QEMU_OPTION_tracing:
- if (strcmp(optarg, "off") == 0)
- tracing = 0;
- else if (strcmp(optarg, "on") == 0 && trace_filename)
- tracing = 1;
- else {
- fprintf(stderr, "Unexpected option to -tracing ('%s')\n",
- optarg);
- exit(1);
- }
- break;
- case QEMU_OPTION_dcache_load_miss:
- dcache_load_miss_penalty = atoi(optarg);
- break;
- case QEMU_OPTION_dcache_store_miss:
- dcache_store_miss_penalty = atoi(optarg);
- break;
-#endif
-#ifdef CONFIG_NAND
- case QEMU_OPTION_nand:
- nand_add_dev(optarg);
- break;
-#endif
- }
- }
- }
-
- if (nographic) {
- if (serial_device_index == 0)
- serial_devices[0] = "stdio";
- if (parallel_device_index == 0)
- parallel_devices[0] = "null";
- if (strncmp(monitor_device, "vc", 2) == 0)
- monitor_device = "stdio";
- }
-
-#ifndef _WIN32
- if (daemonize) {
- pid_t pid;
-
- if (pipe(fds) == -1)
- exit(1);
-
- pid = fork();
- if (pid > 0) {
- uint8_t status;
- ssize_t len;
-
- close(fds[1]);
-
- again:
- len = read(fds[0], &status, 1);
- if (len == -1 && (errno == EINTR))
- goto again;
-
- if (len != 1)
- exit(1);
- else if (status == 1) {
- fprintf(stderr, "Could not acquire pidfile\n");
- exit(1);
- } else
- exit(0);
- } else if (pid < 0)
- exit(1);
-
- setsid();
-
- pid = fork();
- if (pid > 0)
- exit(0);
- else if (pid < 0)
- exit(1);
-
- umask(027);
-
- signal(SIGTSTP, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
- signal(SIGTTIN, SIG_IGN);
- }
-#endif
-
- if (pid_file && qemu_create_pidfile(pid_file) != 0) {
- if (daemonize) {
- uint8_t status = 1;
- write(fds[1], &status, 1);
- } else
- fprintf(stderr, "Could not acquire pid file\n");
- exit(1);
- }
-
-#ifdef USE_KQEMU
- if (smp_cpus > 1)
- kqemu_allowed = 0;
-#endif
- linux_boot = (kernel_filename != NULL);
- net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
-
- if (!linux_boot && net_boot == 0 &&
- !machine->nodisk_ok && nb_drives_opt == 0)
- help(1);
-
- if (!linux_boot && *kernel_cmdline != '\0') {
- fprintf(stderr, "-append only allowed with -kernel option\n");
- exit(1);
- }
-
- if (!linux_boot && initrd_filename != NULL) {
- fprintf(stderr, "-initrd only allowed with -kernel option\n");
- exit(1);
- }
-
- /* boot to floppy or the default cd if no hard disk defined yet */
- if (!boot_devices[0]) {
- boot_devices = "cad";
- }
- setvbuf(stdout, NULL, _IOLBF, 0);
-
- init_timers();
- init_timer_alarm();
- qemu_aio_init();
- if (use_icount && icount_time_shift < 0) {
- use_icount = 2;
- /* 125MIPS seems a reasonable initial guess at the guest speed.
- It will be corrected fairly quickly anyway. */
- icount_time_shift = 3;
- init_icount_adjust();
- }
-
-#ifdef _WIN32
- socket_init();
-#endif
-
- /* init network clients */
- if (nb_net_clients == 0) {
- /* if no clients, we use a default config */
- net_clients[nb_net_clients++] = "nic";
-#ifdef CONFIG_SLIRP
- net_clients[nb_net_clients++] = "user";
-#endif
- }
-
- for(i = 0;i < nb_net_clients; i++) {
- if (net_client_parse(net_clients[i]) < 0)
- exit(1);
- }
- for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
- if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
- continue;
- if (vlan->nb_guest_devs == 0)
- fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
- if (vlan->nb_host_devs == 0)
- fprintf(stderr,
- "Warning: vlan %d is not connected to host network\n",
- vlan->id);
- }
-
-#ifdef TARGET_I386
- /* XXX: this should be moved in the PC machine instantiation code */
- if (net_boot != 0) {
- int netroms = 0;
- for (i = 0; i < nb_nics && i < 4; i++) {
- const char *model = nd_table[i].model;
- char buf[1024];
- if (net_boot & (1 << i)) {
- if (model == NULL)
- model = "ne2k_pci";
- snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
- if (get_image_size(buf) > 0) {
- if (nb_option_roms >= MAX_OPTION_ROMS) {
- fprintf(stderr, "Too many option ROMs\n");
- exit(1);
- }
- option_rom[nb_option_roms] = strdup(buf);
- nb_option_roms++;
- netroms++;
- }
- }
- }
- if (netroms == 0) {
- fprintf(stderr, "No valid PXE rom found for network device\n");
- exit(1);
- }
- }
-#endif
-
- /* init the memory */
- phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;
-
- if (machine->ram_require & RAMSIZE_FIXED) {
- if (ram_size > 0) {
- if (ram_size < phys_ram_size) {
- fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n",
- machine->name, (unsigned long long) phys_ram_size);
- exit(-1);
- }
-
- phys_ram_size = ram_size;
- } else
- ram_size = phys_ram_size;
- } else {
- if (ram_size == 0)
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-
- phys_ram_size += ram_size;
- }
-
- phys_ram_base = qemu_vmalloc(phys_ram_size);
- if (!phys_ram_base) {
- fprintf(stderr, "Could not allocate physical memory\n");
- exit(1);
- }
-
- /* init the dynamic translator */
- cpu_exec_init_all(tb_size * 1024 * 1024);
-
- bdrv_init();
-
- /* we always create the cdrom drive, even if no disk is there */
-
- if (nb_drives_opt < MAX_DRIVES)
- drive_add(NULL, CDROM_ALIAS);
-
- /* we always create at least one floppy */
-
- if (nb_drives_opt < MAX_DRIVES)
- drive_add(NULL, FD_ALIAS, 0);
-
- /* we always create one sd slot, even if no card is in it */
-
- if (nb_drives_opt < MAX_DRIVES)
- drive_add(NULL, SD_ALIAS);
-
- /* open the virtual block devices */
-
- for(i = 0; i < nb_drives_opt; i++)
- if (drive_init(&drives_opt[i], snapshot, machine) == -1)
- exit(1);
-
- register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
- register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
-
- /* terminal init */
- memset(&display_state, 0, sizeof(display_state));
- if (nographic) {
- if (curses) {
- fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
- exit(1);
- }
- /* nearly nothing to do */
- dumb_display_init(ds);
- } else if (vnc_display != NULL) {
- vnc_display_init(ds);
- if (vnc_display_open(ds, vnc_display) < 0)
- exit(1);
- } else
-#if defined(CONFIG_CURSES)
- if (curses) {
- curses_display_init(ds, full_screen);
- } else
-#endif
- {
-#if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen, no_frame);
-#elif defined(CONFIG_COCOA)
- cocoa_display_init(ds, full_screen);
-#else
- dumb_display_init(ds);
-#endif
- }
-
-#ifndef _WIN32
- /* must be after terminal init, SDL library changes signal handlers */
- termsig_setup();
-#endif
-
- /* Maintain compatibility with multiple stdio monitors */
- if (!strcmp(monitor_device,"stdio")) {
- for (i = 0; i < MAX_SERIAL_PORTS; i++) {
- const char *devname = serial_devices[i];
- if (devname && !strcmp(devname,"mon:stdio")) {
- monitor_device = NULL;
- break;
- } else if (devname && !strcmp(devname,"stdio")) {
- monitor_device = NULL;
- serial_devices[i] = "mon:stdio";
- break;
- }
- }
- }
- if (monitor_device) {
- monitor_hd = qemu_chr_open(monitor_device);
- if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
- }
- monitor_init(monitor_hd, !nographic);
- }
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- const char *devname = serial_devices[i];
- if (devname && strcmp(devname, "none")) {
- serial_hds[i] = qemu_chr_open(devname);
- if (!serial_hds[i]) {
- fprintf(stderr, "qemu: could not open serial device '%s'\n",
- devname);
- exit(1);
- }
- if (strstart(devname, "vc", 0))
- qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
- }
- }
-
- for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
- const char *devname = parallel_devices[i];
- if (devname && strcmp(devname, "none")) {
- parallel_hds[i] = qemu_chr_open(devname);
- if (!parallel_hds[i]) {
- fprintf(stderr, "qemu: could not open parallel device '%s'\n",
- devname);
- exit(1);
- }
- if (strstart(devname, "vc", 0))
- qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
- }
- }
-
-#ifdef CONFIG_TRACE
- if (trace_filename) {
- trace_init(trace_filename);
- dcache_init(dcache_size, dcache_ways, dcache_line_size,
- dcache_replace_policy, dcache_load_miss_penalty,
- dcache_store_miss_penalty);
- fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
- }
-#endif
-
- machine->init(ram_size, vga_ram_size, boot_devices, ds,
- kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
-
- /* init USB devices */
- if (usb_enabled) {
- for(i = 0; i < usb_devices_index; i++) {
- if (usb_device_add(usb_devices[i]) < 0) {
- fprintf(stderr, "Warning: could not add USB device %s\n",
- usb_devices[i]);
- }
- }
- }
-
- if (display_state.dpy_refresh) {
- display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
- qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
- }
-
-#ifdef CONFIG_GDBSTUB
- if (use_gdbstub) {
- /* XXX: use standard host:port notation and modify options
- accordingly. */
- if (gdbserver_start(gdbstub_port) < 0) {
- fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
- gdbstub_port);
- exit(1);
- }
- }
-#endif
-
- if (loadvm)
- do_loadvm(loadvm);
-
- /* call android-specific setup function */
- android_emulation_setup();
-
- {
- /* XXX: simplify init */
- read_passwords();
- if (autostart) {
- vm_start();
- }
- }
-
- if (daemonize) {
- uint8_t status = 0;
- ssize_t len;
- int fd;
-
- again1:
- len = write(fds[1], &status, 1);
- if (len == -1 && (errno == EINTR))
- goto again1;
-
- if (len != 1)
- exit(1);
-
- chdir("/");
- TFR(fd = open("/dev/null", O_RDWR));
- if (fd == -1)
- exit(1);
-
- dup2(fd, 0);
- dup2(fd, 1);
- dup2(fd, 2);
-
- close(fd);
- }
-
- main_loop();
- quit_timers();
-
-#if !defined(_WIN32)
- /* close network clients */
- for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
- VLANClientState *vc;
-
- for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
- if (vc->fd_read == tap_receive) {
- char ifname[64];
- TAPState *s = vc->opaque;
-
- if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
- s->down_script[0])
- launch_script(s->down_script, ifname, s->fd);
- }
-#if defined(CONFIG_VDE)
- if (vc->fd_read == vde_from_qemu) {
- VDEState *s = vc->opaque;
- vde_close(s->vde);
- }
-#endif
- }
- }
-#endif
-
- android_emulation_teardown();
- return 0;
-}
diff --git a/vnc.c b/vnc.c
deleted file mode 100644
index 8b7d19f..0000000
--- a/vnc.c
+++ /dev/null
@@ -1,2446 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "console.h"
-#include "sysemu.h"
-#include "qemu_socket.h"
-#include "qemu-timer.h"
-
-#define VNC_REFRESH_INTERVAL (1000 / 30)
-
-#include "vnc_keysym.h"
-#include "keymaps.c"
-#include "d3des.h"
-
-#ifdef CONFIG_VNC_TLS
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-#endif /* CONFIG_VNC_TLS */
-
-// #define _VNC_DEBUG 1
-
-#ifdef _VNC_DEBUG
-#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-
-#if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
-/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
-static void vnc_debug_gnutls_log(int level, const char* str) {
- VNC_DEBUG("%d %s", level, str);
-}
-#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
-#else
-#define VNC_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-
-typedef struct Buffer
-{
- size_t capacity;
- size_t offset;
- uint8_t *buffer;
-} Buffer;
-
-typedef struct VncState VncState;
-
-typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
-
-typedef void VncWritePixels(VncState *vs, void *data, int size);
-
-typedef void VncSendHextileTile(VncState *vs,
- int x, int y, int w, int h,
- void *last_bg,
- void *last_fg,
- int *has_bg, int *has_fg);
-
-#define VNC_MAX_WIDTH 2048
-#define VNC_MAX_HEIGHT 2048
-#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
-
-#define VNC_AUTH_CHALLENGE_SIZE 16
-
-enum {
- VNC_AUTH_INVALID = 0,
- VNC_AUTH_NONE = 1,
- VNC_AUTH_VNC = 2,
- VNC_AUTH_RA2 = 5,
- VNC_AUTH_RA2NE = 6,
- VNC_AUTH_TIGHT = 16,
- VNC_AUTH_ULTRA = 17,
- VNC_AUTH_TLS = 18,
- VNC_AUTH_VENCRYPT = 19
-};
-
-#ifdef CONFIG_VNC_TLS
-enum {
- VNC_WIREMODE_CLEAR,
- VNC_WIREMODE_TLS,
-};
-
-enum {
- VNC_AUTH_VENCRYPT_PLAIN = 256,
- VNC_AUTH_VENCRYPT_TLSNONE = 257,
- VNC_AUTH_VENCRYPT_TLSVNC = 258,
- VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
- VNC_AUTH_VENCRYPT_X509NONE = 260,
- VNC_AUTH_VENCRYPT_X509VNC = 261,
- VNC_AUTH_VENCRYPT_X509PLAIN = 262,
-};
-
-#define X509_CA_CERT_FILE "ca-cert.pem"
-#define X509_CA_CRL_FILE "ca-crl.pem"
-#define X509_SERVER_KEY_FILE "server-key.pem"
-#define X509_SERVER_CERT_FILE "server-cert.pem"
-
-#endif /* CONFIG_VNC_TLS */
-
-struct VncState
-{
- QEMUTimer *timer;
- int lsock;
- int csock;
- DisplayState *ds;
- int need_update;
- int width;
- int height;
- uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
- char *old_data;
- int depth; /* internal VNC frame buffer byte per pixel */
- int has_resize;
- int has_hextile;
- int has_pointer_type_change;
- int has_WMVi;
- int absolute;
- int last_x;
- int last_y;
-
- int major;
- int minor;
-
- char *display;
- char *password;
- int auth;
-#ifdef CONFIG_VNC_TLS
- int subauth;
- int x509verify;
-
- char *x509cacert;
- char *x509cacrl;
- char *x509cert;
- char *x509key;
-#endif
- char challenge[VNC_AUTH_CHALLENGE_SIZE];
-
-#ifdef CONFIG_VNC_TLS
- int wiremode;
- gnutls_session_t tls_session;
-#endif
-
- Buffer output;
- Buffer input;
- kbd_layout_t *kbd_layout;
- /* current output mode information */
- VncWritePixels *write_pixels;
- VncSendHextileTile *send_hextile_tile;
- int pix_bpp, pix_big_endian;
- int client_red_shift, client_red_max, server_red_shift, server_red_max;
- int client_green_shift, client_green_max, server_green_shift, server_green_max;
- int client_blue_shift, client_blue_max, server_blue_shift, server_blue_max;
-
- VncReadEvent *read_handler;
- size_t read_handler_expect;
- /* input */
- uint8_t modifiers_state[256];
-};
-
-static VncState *vnc_state; /* needed for info vnc */
-
-void do_info_vnc(void)
-{
- if (vnc_state == NULL)
- term_printf("VNC server disabled\n");
- else {
- term_printf("VNC server active on: ");
- term_print_filename(vnc_state->display);
- term_printf("\n");
-
- if (vnc_state->csock == -1)
- term_printf("No client connected\n");
- else
- term_printf("Client connected\n");
- }
-}
-
-/* TODO
- 1) Get the queue working for IO.
- 2) there is some weirdness when using the -S option (the screen is grey
- and not totally invalidated
- 3) resolutions > 1024
-*/
-
-static void vnc_write(VncState *vs, const void *data, size_t len);
-static void vnc_write_u32(VncState *vs, uint32_t value);
-static void vnc_write_s32(VncState *vs, int32_t value);
-static void vnc_write_u16(VncState *vs, uint16_t value);
-static void vnc_write_u8(VncState *vs, uint8_t value);
-static void vnc_flush(VncState *vs);
-static void vnc_update_client(void *opaque);
-static void vnc_client_read(void *opaque);
-
-static void vnc_colordepth(DisplayState *ds, int depth);
-
-static inline void vnc_set_bit(uint32_t *d, int k)
-{
- d[k >> 5] |= 1 << (k & 0x1f);
-}
-
-static inline void vnc_clear_bit(uint32_t *d, int k)
-{
- d[k >> 5] &= ~(1 << (k & 0x1f));
-}
-
-static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
-{
- int j;
-
- j = 0;
- while (n >= 32) {
- d[j++] = -1;
- n -= 32;
- }
- if (n > 0)
- d[j++] = (1 << n) - 1;
- while (j < nb_words)
- d[j++] = 0;
-}
-
-static inline int vnc_get_bit(const uint32_t *d, int k)
-{
- return (d[k >> 5] >> (k & 0x1f)) & 1;
-}
-
-static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
- int nb_words)
-{
- int i;
- for(i = 0; i < nb_words; i++) {
- if ((d1[i] & d2[i]) != 0)
- return 1;
- }
- return 0;
-}
-
-static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
-{
- VncState *vs = ds->opaque;
- int i;
-
- h += y;
-
- /* round x down to ensure the loop only spans one 16-pixel block per,
- iteration. otherwise, if (x % 16) != 0, the last iteration may span
- two 16-pixel blocks but we only mark the first as dirty
- */
- w += (x % 16);
- x -= (x % 16);
-
- x = MIN(x, vs->width);
- y = MIN(y, vs->height);
- w = MIN(x + w, vs->width) - x;
- h = MIN(h, vs->height);
-
- for (; y < h; y++)
- for (i = 0; i < w; i += 16)
- vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
-}
-
-static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding)
-{
- vnc_write_u16(vs, x);
- vnc_write_u16(vs, y);
- vnc_write_u16(vs, w);
- vnc_write_u16(vs, h);
-
- vnc_write_s32(vs, encoding);
-}
-
-static void vnc_dpy_resize(DisplayState *ds, int w, int h)
-{
- int size_changed;
- VncState *vs = ds->opaque;
-
- ds->data = qemu_realloc(ds->data, w * h * vs->depth);
- vs->old_data = qemu_realloc(vs->old_data, w * h * vs->depth);
-
- if (ds->data == NULL || vs->old_data == NULL) {
- fprintf(stderr, "vnc: memory allocation failed\n");
- exit(1);
- }
-
- if (ds->depth != vs->depth * 8) {
- ds->depth = vs->depth * 8;
- console_color_init(ds);
- }
- size_changed = ds->width != w || ds->height != h;
- ds->width = w;
- ds->height = h;
- ds->linesize = w * vs->depth;
- if (size_changed) {
- vs->width = ds->width;
- vs->height = ds->height;
- if (vs->csock != -1 && vs->has_resize) {
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
- vnc_flush(vs);
- }
- }
-
- memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
- memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
-}
-
-/* fastest code */
-static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
-{
- vnc_write(vs, pixels, size);
-}
-
-/* slowest but generic code. */
-static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
-{
- uint8_t r, g, b;
-
- r = ((v >> vs->server_red_shift) & vs->server_red_max) * (vs->client_red_max + 1) /
- (vs->server_red_max + 1);
- g = ((v >> vs->server_green_shift) & vs->server_green_max) * (vs->client_green_max + 1) /
- (vs->server_green_max + 1);
- b = ((v >> vs->server_blue_shift) & vs->server_blue_max) * (vs->client_blue_max + 1) /
- (vs->server_blue_max + 1);
- v = (r << vs->client_red_shift) |
- (g << vs->client_green_shift) |
- (b << vs->client_blue_shift);
- switch(vs->pix_bpp) {
- case 1:
- buf[0] = v;
- break;
- case 2:
- if (vs->pix_big_endian) {
- buf[0] = v >> 8;
- buf[1] = v;
- } else {
- buf[1] = v >> 8;
- buf[0] = v;
- }
- break;
- default:
- case 4:
- if (vs->pix_big_endian) {
- buf[0] = v >> 24;
- buf[1] = v >> 16;
- buf[2] = v >> 8;
- buf[3] = v;
- } else {
- buf[3] = v >> 24;
- buf[2] = v >> 16;
- buf[1] = v >> 8;
- buf[0] = v;
- }
- break;
- }
-}
-
-static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
-{
- uint8_t buf[4];
-
- if (vs->depth == 4) {
- uint32_t *pixels = pixels1;
- int n, i;
- n = size >> 2;
- for(i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->pix_bpp);
- }
- } else if (vs->depth == 2) {
- uint16_t *pixels = pixels1;
- int n, i;
- n = size >> 1;
- for(i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->pix_bpp);
- }
- } else if (vs->depth == 1) {
- uint8_t *pixels = pixels1;
- int n, i;
- n = size;
- for(i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->pix_bpp);
- }
- } else {
- fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
- }
-}
-
-static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
-{
- int i;
- uint8_t *row;
-
- vnc_framebuffer_update(vs, x, y, w, h, 0);
-
- row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
- for (i = 0; i < h; i++) {
- vs->write_pixels(vs, row, w * vs->depth);
- row += vs->ds->linesize;
- }
-}
-
-static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
-{
- ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
- ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
-}
-
-#define BPP 8
-#include "vnchextile.h"
-#undef BPP
-
-#define BPP 16
-#include "vnchextile.h"
-#undef BPP
-
-#define BPP 32
-#include "vnchextile.h"
-#undef BPP
-
-#define GENERIC
-#define BPP 8
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 16
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 32
-#include "vnchextile.h"
-#undef BPP
-#undef GENERIC
-
-static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
-{
- int i, j;
- int has_fg, has_bg;
- uint8_t *last_fg, *last_bg;
-
- vnc_framebuffer_update(vs, x, y, w, h, 5);
-
- last_fg = (uint8_t *) malloc(vs->depth);
- last_bg = (uint8_t *) malloc(vs->depth);
- has_fg = has_bg = 0;
- for (j = y; j < (y + h); j += 16) {
- for (i = x; i < (x + w); i += 16) {
- vs->send_hextile_tile(vs, i, j,
- MIN(16, x + w - i), MIN(16, y + h - j),
- last_bg, last_fg, &has_bg, &has_fg);
- }
- }
- free(last_fg);
- free(last_bg);
-
-}
-
-static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- if (vs->has_hextile)
- send_framebuffer_update_hextile(vs, x, y, w, h);
- else
- send_framebuffer_update_raw(vs, x, y, w, h);
-}
-
-static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
-{
- int src, dst;
- uint8_t *src_row;
- uint8_t *dst_row;
- char *old_row;
- int y = 0;
- int pitch = ds->linesize;
- VncState *vs = ds->opaque;
-
- vnc_update_client(vs);
-
- if (dst_y > src_y) {
- y = h - 1;
- pitch = -pitch;
- }
-
- src = (ds->linesize * (src_y + y) + vs->depth * src_x);
- dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
-
- src_row = ds->data + src;
- dst_row = ds->data + dst;
- old_row = vs->old_data + dst;
-
- for (y = 0; y < h; y++) {
- memmove(old_row, src_row, w * vs->depth);
- memmove(dst_row, src_row, w * vs->depth);
- src_row += pitch;
- dst_row += pitch;
- old_row += pitch;
- }
-
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
- vnc_write_u16(vs, src_x);
- vnc_write_u16(vs, src_y);
- vnc_flush(vs);
-}
-
-static int find_dirty_height(VncState *vs, int y, int last_x, int x)
-{
- int h;
-
- for (h = 1; h < (vs->height - y); h++) {
- int tmp_x;
- if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
- break;
- for (tmp_x = last_x; tmp_x < x; tmp_x++)
- vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
- }
-
- return h;
-}
-
-static void vnc_update_client(void *opaque)
-{
- VncState *vs = opaque;
-
- if (vs->need_update && vs->csock != -1) {
- int y;
- uint8_t *row;
- char *old_row;
- uint32_t width_mask[VNC_DIRTY_WORDS];
- int n_rectangles;
- int saved_offset;
- int has_dirty = 0;
-
- vga_hw_update();
-
- vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
-
- /* Walk through the dirty map and eliminate tiles that
- really aren't dirty */
- row = vs->ds->data;
- old_row = vs->old_data;
-
- for (y = 0; y < vs->height; y++) {
- if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
- int x;
- uint8_t *ptr;
- char *old_ptr;
-
- ptr = row;
- old_ptr = (char*)old_row;
-
- for (x = 0; x < vs->ds->width; x += 16) {
- if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
- vnc_clear_bit(vs->dirty_row[y], (x / 16));
- } else {
- has_dirty = 1;
- memcpy(old_ptr, ptr, 16 * vs->depth);
- }
-
- ptr += 16 * vs->depth;
- old_ptr += 16 * vs->depth;
- }
- }
-
- row += vs->ds->linesize;
- old_row += vs->ds->linesize;
- }
-
- if (!has_dirty) {
- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
- return;
- }
-
- /* Count rectangles */
- n_rectangles = 0;
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- saved_offset = vs->output.offset;
- vnc_write_u16(vs, 0);
-
- for (y = 0; y < vs->height; y++) {
- int x;
- int last_x = -1;
- for (x = 0; x < vs->width / 16; x++) {
- if (vnc_get_bit(vs->dirty_row[y], x)) {
- if (last_x == -1) {
- last_x = x;
- }
- vnc_clear_bit(vs->dirty_row[y], x);
- } else {
- if (last_x != -1) {
- int h = find_dirty_height(vs, y, last_x, x);
- send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
- n_rectangles++;
- }
- last_x = -1;
- }
- }
- if (last_x != -1) {
- int h = find_dirty_height(vs, y, last_x, x);
- send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
- n_rectangles++;
- }
- }
- vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
- vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
- vnc_flush(vs);
-
- }
-
- if (vs->csock != -1) {
- qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
- }
-
-}
-
-static int vnc_listen_poll(void *opaque)
-{
- VncState *vs = opaque;
- if (vs->csock == -1)
- return 1;
- return 0;
-}
-
-static void buffer_reserve(Buffer *buffer, size_t len)
-{
- if ((buffer->capacity - buffer->offset) < len) {
- buffer->capacity += (len + 1024);
- buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
- if (buffer->buffer == NULL) {
- fprintf(stderr, "vnc: out of memory\n");
- exit(1);
- }
- }
-}
-
-static int buffer_empty(Buffer *buffer)
-{
- return buffer->offset == 0;
-}
-
-static uint8_t *buffer_end(Buffer *buffer)
-{
- return buffer->buffer + buffer->offset;
-}
-
-static void buffer_reset(Buffer *buffer)
-{
- buffer->offset = 0;
-}
-
-static void buffer_append(Buffer *buffer, const void *data, size_t len)
-{
- memcpy(buffer->buffer + buffer->offset, data, len);
- buffer->offset += len;
-}
-
-static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
-{
- if (ret == 0 || ret == -1) {
- if (ret == -1) {
- switch (last_errno) {
- case EINTR:
- case EAGAIN:
-#ifdef _WIN32
- case EWOULDBLOCK:
-#endif
- return 0;
- default:
- break;
- }
- }
-
- VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
- qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
- socket_close(vs->csock);
- vs->csock = -1;
- vs->ds->idle = 1;
- buffer_reset(&vs->input);
- buffer_reset(&vs->output);
- vs->need_update = 0;
-#ifdef CONFIG_VNC_TLS
- if (vs->tls_session) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- }
- vs->wiremode = VNC_WIREMODE_CLEAR;
-#endif /* CONFIG_VNC_TLS */
- return 0;
- }
- return ret;
-}
-
-static void vnc_client_error(VncState *vs)
-{
- vnc_client_io_error(vs, -1, EINVAL);
-}
-
-static void vnc_client_write(void *opaque)
-{
- long ret;
- VncState *vs = opaque;
-
-#ifdef CONFIG_VNC_TLS
- if (vs->tls_session) {
- ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
- if (ret < 0) {
- if (ret == GNUTLS_E_AGAIN)
- errno = EAGAIN;
- else
- errno = EIO;
- ret = -1;
- }
- } else
-#endif /* CONFIG_VNC_TLS */
- ret = socket_send(vs->csock, vs->output.buffer, vs->output.offset);
- ret = vnc_client_io_error(vs, ret, errno_str);
- if (!ret)
- return;
-
- memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
- vs->output.offset -= ret;
-
- if (vs->output.offset == 0) {
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
- }
-}
-
-static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-{
- vs->read_handler = func;
- vs->read_handler_expect = expecting;
-}
-
-static void vnc_client_read(void *opaque)
-{
- VncState *vs = opaque;
- long ret;
-
- buffer_reserve(&vs->input, 4096);
-
-#ifdef CONFIG_VNC_TLS
- if (vs->tls_session) {
- ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
- if (ret < 0) {
- if (ret == GNUTLS_E_AGAIN)
- errno = EAGAIN;
- else
- errno = EIO;
- ret = -1;
- }
- } else
-#endif /* CONFIG_VNC_TLS */
- ret = socket_recv(vs->csock, buffer_end(&vs->input), 4096);
- ret = vnc_client_io_error(vs, ret, errno_str);
- if (!ret)
- return;
-
- vs->input.offset += ret;
-
- while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
- size_t len = vs->read_handler_expect;
- int ret;
-
- ret = vs->read_handler(vs, vs->input.buffer, len);
- if (vs->csock == -1)
- return;
-
- if (!ret) {
- memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
- vs->input.offset -= len;
- } else {
- vs->read_handler_expect = ret;
- }
- }
-}
-
-static void vnc_write(VncState *vs, const void *data, size_t len)
-{
- buffer_reserve(&vs->output, len);
-
- if (buffer_empty(&vs->output)) {
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
- }
-
- buffer_append(&vs->output, data, len);
-}
-
-static void vnc_write_s32(VncState *vs, int32_t value)
-{
- vnc_write_u32(vs, *(uint32_t *)&value);
-}
-
-static void vnc_write_u32(VncState *vs, uint32_t value)
-{
- uint8_t buf[4];
-
- buf[0] = (value >> 24) & 0xFF;
- buf[1] = (value >> 16) & 0xFF;
- buf[2] = (value >> 8) & 0xFF;
- buf[3] = value & 0xFF;
-
- vnc_write(vs, buf, 4);
-}
-
-static void vnc_write_u16(VncState *vs, uint16_t value)
-{
- uint8_t buf[2];
-
- buf[0] = (value >> 8) & 0xFF;
- buf[1] = value & 0xFF;
-
- vnc_write(vs, buf, 2);
-}
-
-static void vnc_write_u8(VncState *vs, uint8_t value)
-{
- vnc_write(vs, (char *)&value, 1);
-}
-
-static void vnc_flush(VncState *vs)
-{
- if (vs->output.offset)
- vnc_client_write(vs);
-}
-
-static uint8_t read_u8(uint8_t *data, size_t offset)
-{
- return data[offset];
-}
-
-static uint16_t read_u16(uint8_t *data, size_t offset)
-{
- return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
-}
-
-static int32_t read_s32(uint8_t *data, size_t offset)
-{
- return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3]);
-}
-
-static uint32_t read_u32(uint8_t *data, size_t offset)
-{
- return ((data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3]);
-}
-
-#ifdef CONFIG_VNC_TLS
-static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
- const void *data,
- size_t len) {
- struct VncState *vs = (struct VncState *)transport;
-
- return socket_send(vs->csock, data, len);
-}
-
-
-static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
- void *data,
- size_t len) {
- struct VncState *vs = (struct VncState *)transport;
-
- return socket_recv(vs->csock, data, len);
-}
-#endif /* CONFIG_VNC_TLS */
-
-static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
-{
-}
-
-static void check_pointer_type_change(VncState *vs, int absolute)
-{
- if (vs->has_pointer_type_change && vs->absolute != absolute) {
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, absolute, 0,
- vs->ds->width, vs->ds->height, -257);
- vnc_flush(vs);
- }
- vs->absolute = absolute;
-}
-
-static void pointer_event(VncState *vs, int button_mask, int x, int y)
-{
- int buttons = 0;
- int dz = 0;
-
- if (button_mask & 0x01)
- buttons |= MOUSE_EVENT_LBUTTON;
- if (button_mask & 0x02)
- buttons |= MOUSE_EVENT_MBUTTON;
- if (button_mask & 0x04)
- buttons |= MOUSE_EVENT_RBUTTON;
- if (button_mask & 0x08)
- dz = -1;
- if (button_mask & 0x10)
- dz = 1;
-
- if (vs->absolute) {
- kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
- y * 0x7FFF / (vs->ds->height - 1),
- dz, buttons);
- } else if (vs->has_pointer_type_change) {
- x -= 0x7FFF;
- y -= 0x7FFF;
-
- kbd_mouse_event(x, y, dz, buttons);
- } else {
- if (vs->last_x != -1)
- kbd_mouse_event(x - vs->last_x,
- y - vs->last_y,
- dz, buttons);
- vs->last_x = x;
- vs->last_y = y;
- }
-
- check_pointer_type_change(vs, kbd_mouse_is_absolute());
-}
-
-static void reset_keys(VncState *vs)
-{
- int i;
- for(i = 0; i < 256; i++) {
- if (vs->modifiers_state[i]) {
- if (i & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(i | 0x80);
- vs->modifiers_state[i] = 0;
- }
- }
-}
-
-static void press_key(VncState *vs, int keysym)
-{
- kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
- kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
-}
-
-static void do_key_event(VncState *vs, int down, int keycode, int sym)
-{
- /* QEMU console switch */
- switch(keycode) {
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (down)
- vs->modifiers_state[keycode] = 1;
- else
- vs->modifiers_state[keycode] = 0;
- break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
- /* Reset the modifiers sent to the current console */
- reset_keys(vs);
- console_select(keycode - 0x02);
- return;
- }
- break;
- case 0x3a: /* CapsLock */
- case 0x45: /* NumLock */
- if (!down)
- vs->modifiers_state[keycode] ^= 1;
- break;
- }
-
- if (keycode_is_keypad(vs->kbd_layout, keycode)) {
- /* If the numlock state needs to change then simulate an additional
- keypress before sending this one. This will happen if the user
- toggles numlock away from the VNC window.
- */
- if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
- if (!vs->modifiers_state[0x45]) {
- vs->modifiers_state[0x45] = 1;
- press_key(vs, 0xff7f);
- }
- } else {
- if (vs->modifiers_state[0x45]) {
- vs->modifiers_state[0x45] = 0;
- press_key(vs, 0xff7f);
- }
- }
- }
-
- if (is_graphic_console()) {
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (down)
- kbd_put_keycode(keycode & 0x7f);
- else
- kbd_put_keycode(keycode | 0x80);
- } else {
- /* QEMU console emulation */
- if (down) {
- switch (keycode) {
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- break;
- case 0xc8:
- kbd_put_keysym(QEMU_KEY_UP);
- break;
- case 0xd0:
- kbd_put_keysym(QEMU_KEY_DOWN);
- break;
- case 0xcb:
- kbd_put_keysym(QEMU_KEY_LEFT);
- break;
- case 0xcd:
- kbd_put_keysym(QEMU_KEY_RIGHT);
- break;
- case 0xd3:
- kbd_put_keysym(QEMU_KEY_DELETE);
- break;
- case 0xc7:
- kbd_put_keysym(QEMU_KEY_HOME);
- break;
- case 0xcf:
- kbd_put_keysym(QEMU_KEY_END);
- break;
- case 0xc9:
- kbd_put_keysym(QEMU_KEY_PAGEUP);
- break;
- case 0xd1:
- kbd_put_keysym(QEMU_KEY_PAGEDOWN);
- break;
- default:
- kbd_put_keysym(sym);
- break;
- }
- }
- }
-}
-
-static void key_event(VncState *vs, int down, uint32_t sym)
-{
- int keycode;
-
- if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
- sym = sym - 'A' + 'a';
-
- keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
- do_key_event(vs, down, keycode, sym);
-}
-
-static void ext_key_event(VncState *vs, int down,
- uint32_t sym, uint16_t keycode)
-{
- /* if the user specifies a keyboard layout, always use it */
- if (keyboard_layout)
- key_event(vs, down, sym);
- else
- do_key_event(vs, down, keycode, sym);
-}
-
-static void framebuffer_update_request(VncState *vs, int incremental,
- int x_position, int y_position,
- int w, int h)
-{
- if (x_position > vs->ds->width)
- x_position = vs->ds->width;
- if (y_position > vs->ds->height)
- y_position = vs->ds->height;
- if (x_position + w >= vs->ds->width)
- w = vs->ds->width - x_position;
- if (y_position + h >= vs->ds->height)
- h = vs->ds->height - y_position;
-
- int i;
- vs->need_update = 1;
- if (!incremental) {
- char *old_row = vs->old_data + y_position * vs->ds->linesize;
-
- for (i = 0; i < h; i++) {
- vnc_set_bits(vs->dirty_row[y_position + i],
- (vs->ds->width / 16), VNC_DIRTY_WORDS);
- memset(old_row, 42, vs->ds->width * vs->depth);
- old_row += vs->ds->linesize;
- }
- }
-}
-
-static void send_ext_key_event_ack(VncState *vs)
-{
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0, vs->ds->width, vs->ds->height, -258);
- vnc_flush(vs);
-}
-
-static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
-{
- int i;
-
- vs->has_hextile = 0;
- vs->has_resize = 0;
- vs->has_pointer_type_change = 0;
- vs->has_WMVi = 0;
- vs->absolute = -1;
- vs->ds->dpy_copy = NULL;
-
- for (i = n_encodings - 1; i >= 0; i--) {
- switch (encodings[i]) {
- case 0: /* Raw */
- vs->has_hextile = 0;
- break;
- case 1: /* CopyRect */
- vs->ds->dpy_copy = vnc_copy;
- break;
- case 5: /* Hextile */
- vs->has_hextile = 1;
- break;
- case -223: /* DesktopResize */
- vs->has_resize = 1;
- break;
- case -257:
- vs->has_pointer_type_change = 1;
- break;
- case -258:
- send_ext_key_event_ack(vs);
- break;
- case 0x574D5669:
- vs->has_WMVi = 1;
- break;
- default:
- break;
- }
- }
-
- check_pointer_type_change(vs, kbd_mouse_is_absolute());
-}
-
-static void set_pixel_format(VncState *vs,
- int bits_per_pixel, int depth,
- int big_endian_flag, int true_color_flag,
- int red_max, int green_max, int blue_max,
- int red_shift, int green_shift, int blue_shift)
-{
- int host_big_endian_flag;
-
-#ifdef WORDS_BIGENDIAN
- host_big_endian_flag = 1;
-#else
- host_big_endian_flag = 0;
-#endif
- if (!true_color_flag) {
- fail:
- vnc_client_error(vs);
- return;
- }
- if (bits_per_pixel == 32 &&
- bits_per_pixel == vs->depth * 8 &&
- host_big_endian_flag == big_endian_flag &&
- red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
- red_shift == 16 && green_shift == 8 && blue_shift == 0) {
- vs->depth = 4;
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_32;
- } else
- if (bits_per_pixel == 16 &&
- bits_per_pixel == vs->depth * 8 &&
- host_big_endian_flag == big_endian_flag &&
- red_max == 31 && green_max == 63 && blue_max == 31 &&
- red_shift == 11 && green_shift == 5 && blue_shift == 0) {
- vs->depth = 2;
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_16;
- } else
- if (bits_per_pixel == 8 &&
- bits_per_pixel == vs->depth * 8 &&
- red_max == 7 && green_max == 7 && blue_max == 3 &&
- red_shift == 5 && green_shift == 2 && blue_shift == 0) {
- vs->depth = 1;
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_8;
- } else
- {
- /* generic and slower case */
- if (bits_per_pixel != 8 &&
- bits_per_pixel != 16 &&
- bits_per_pixel != 32)
- goto fail;
- if (vs->depth == 4) {
- vs->send_hextile_tile = send_hextile_tile_generic_32;
- } else if (vs->depth == 2) {
- vs->send_hextile_tile = send_hextile_tile_generic_16;
- } else {
- vs->send_hextile_tile = send_hextile_tile_generic_8;
- }
-
- vs->pix_big_endian = big_endian_flag;
- vs->write_pixels = vnc_write_pixels_generic;
- }
-
- vs->client_red_shift = red_shift;
- vs->client_red_max = red_max;
- vs->client_green_shift = green_shift;
- vs->client_green_max = green_max;
- vs->client_blue_shift = blue_shift;
- vs->client_blue_max = blue_max;
- vs->pix_bpp = bits_per_pixel / 8;
-
- vga_hw_invalidate();
- vga_hw_update();
-}
-
-static void pixel_format_message (VncState *vs) {
- char pad[3] = { 0, 0, 0 };
-
- vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
- if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */
- else vnc_write_u8(vs, vs->depth * 8); /* depth */
-
-#ifdef WORDS_BIGENDIAN
- vnc_write_u8(vs, 1); /* big-endian-flag */
-#else
- vnc_write_u8(vs, 0); /* big-endian-flag */
-#endif
- vnc_write_u8(vs, 1); /* true-color-flag */
- if (vs->depth == 4) {
- vnc_write_u16(vs, 0xFF); /* red-max */
- vnc_write_u16(vs, 0xFF); /* green-max */
- vnc_write_u16(vs, 0xFF); /* blue-max */
- vnc_write_u8(vs, 16); /* red-shift */
- vnc_write_u8(vs, 8); /* green-shift */
- vnc_write_u8(vs, 0); /* blue-shift */
- vs->send_hextile_tile = send_hextile_tile_32;
- } else if (vs->depth == 2) {
- vnc_write_u16(vs, 31); /* red-max */
- vnc_write_u16(vs, 63); /* green-max */
- vnc_write_u16(vs, 31); /* blue-max */
- vnc_write_u8(vs, 11); /* red-shift */
- vnc_write_u8(vs, 5); /* green-shift */
- vnc_write_u8(vs, 0); /* blue-shift */
- vs->send_hextile_tile = send_hextile_tile_16;
- } else if (vs->depth == 1) {
- /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
- vnc_write_u16(vs, 7); /* red-max */
- vnc_write_u16(vs, 7); /* green-max */
- vnc_write_u16(vs, 3); /* blue-max */
- vnc_write_u8(vs, 5); /* red-shift */
- vnc_write_u8(vs, 2); /* green-shift */
- vnc_write_u8(vs, 0); /* blue-shift */
- vs->send_hextile_tile = send_hextile_tile_8;
- }
- vs->client_red_max = vs->server_red_max;
- vs->client_green_max = vs->server_green_max;
- vs->client_blue_max = vs->server_blue_max;
- vs->client_red_shift = vs->server_red_shift;
- vs->client_green_shift = vs->server_green_shift;
- vs->client_blue_shift = vs->server_blue_shift;
- vs->pix_bpp = vs->depth * 8;
- vs->write_pixels = vnc_write_pixels_copy;
-
- vnc_write(vs, pad, 3); /* padding */
-}
-
-static void vnc_colordepth(DisplayState *ds, int depth)
-{
- int host_big_endian_flag;
- struct VncState *vs = ds->opaque;
-
- switch (depth) {
- case 24:
- if (ds->depth == 32) return;
- depth = 32;
- break;
- case 15:
- case 8:
- case 0:
- return;
- default:
- break;
- }
-
-#ifdef WORDS_BIGENDIAN
- host_big_endian_flag = 1;
-#else
- host_big_endian_flag = 0;
-#endif
-
- switch (depth) {
- case 8:
- vs->depth = depth / 8;
- vs->server_red_max = 7;
- vs->server_green_max = 7;
- vs->server_blue_max = 3;
- vs->server_red_shift = 5;
- vs->server_green_shift = 2;
- vs->server_blue_shift = 0;
- break;
- case 16:
- vs->depth = depth / 8;
- vs->server_red_max = 31;
- vs->server_green_max = 63;
- vs->server_blue_max = 31;
- vs->server_red_shift = 11;
- vs->server_green_shift = 5;
- vs->server_blue_shift = 0;
- break;
- case 32:
- vs->depth = 4;
- vs->server_red_max = 255;
- vs->server_green_max = 255;
- vs->server_blue_max = 255;
- vs->server_red_shift = 16;
- vs->server_green_shift = 8;
- vs->server_blue_shift = 0;
- break;
- default:
- return;
- }
-
- if (vs->csock != -1 && vs->has_WMVi) {
- /* Sending a WMVi message to notify the client*/
- vnc_write_u8(vs, 0); /* msg id */
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
- pixel_format_message(vs);
- vnc_flush(vs);
- } else {
- if (vs->pix_bpp == 4 && vs->depth == 4 &&
- host_big_endian_flag == vs->pix_big_endian &&
- vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff &&
- vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_32;
- } else if (vs->pix_bpp == 2 && vs->depth == 2 &&
- host_big_endian_flag == vs->pix_big_endian &&
- vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 &&
- vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_16;
- } else if (vs->pix_bpp == 1 && vs->depth == 1 &&
- host_big_endian_flag == vs->pix_big_endian &&
- vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 &&
- vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) {
- vs->write_pixels = vnc_write_pixels_copy;
- vs->send_hextile_tile = send_hextile_tile_8;
- } else {
- if (vs->depth == 4) {
- vs->send_hextile_tile = send_hextile_tile_generic_32;
- } else if (vs->depth == 2) {
- vs->send_hextile_tile = send_hextile_tile_generic_16;
- } else {
- vs->send_hextile_tile = send_hextile_tile_generic_8;
- }
- vs->write_pixels = vnc_write_pixels_generic;
- }
- }
-}
-
-static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
-{
- int i;
- uint16_t limit;
-
- switch (data[0]) {
- case 0:
- if (len == 1)
- return 20;
-
- set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
- read_u8(data, 6), read_u8(data, 7),
- read_u16(data, 8), read_u16(data, 10),
- read_u16(data, 12), read_u8(data, 14),
- read_u8(data, 15), read_u8(data, 16));
- break;
- case 2:
- if (len == 1)
- return 4;
-
- if (len == 4)
- return 4 + (read_u16(data, 2) * 4);
-
- limit = read_u16(data, 2);
- for (i = 0; i < limit; i++) {
- int32_t val = read_s32(data, 4 + (i * 4));
- memcpy(data + 4 + (i * 4), &val, sizeof(val));
- }
-
- set_encodings(vs, (int32_t *)(data + 4), limit);
- break;
- case 3:
- if (len == 1)
- return 10;
-
- framebuffer_update_request(vs,
- read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
- read_u16(data, 6), read_u16(data, 8));
- break;
- case 4:
- if (len == 1)
- return 8;
-
- key_event(vs, read_u8(data, 1), read_u32(data, 4));
- break;
- case 5:
- if (len == 1)
- return 6;
-
- pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
- break;
- case 6:
- if (len == 1)
- return 8;
-
- if (len == 8) {
- uint32_t dlen = read_u32(data, 4);
- if (dlen > 0)
- return 8 + dlen;
- }
-
- client_cut_text(vs, read_u32(data, 4), data + 8);
- break;
- case 255:
- if (len == 1)
- return 2;
-
- switch (read_u8(data, 1)) {
- case 0:
- if (len == 2)
- return 12;
-
- ext_key_event(vs, read_u16(data, 2),
- read_u32(data, 4), read_u32(data, 8));
- break;
- default:
- printf("Msg: %d\n", read_u16(data, 0));
- vnc_client_error(vs);
- break;
- }
- break;
- default:
- printf("Msg: %d\n", data[0]);
- vnc_client_error(vs);
- break;
- }
-
- vnc_read_when(vs, protocol_client_msg, 1);
- return 0;
-}
-
-static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
-{
- char buf[1024];
- int size;
-
- vs->width = vs->ds->width;
- vs->height = vs->ds->height;
- vnc_write_u16(vs, vs->ds->width);
- vnc_write_u16(vs, vs->ds->height);
-
- pixel_format_message(vs);
-
- if (qemu_name)
- size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
- else
- size = snprintf(buf, sizeof(buf), "QEMU");
-
- vnc_write_u32(vs, size);
- vnc_write(vs, buf, size);
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_msg, 1);
-
- return 0;
-}
-
-static void make_challenge(VncState *vs)
-{
- int i;
-
- srand(time(NULL)+getpid()+getpid()*987654+rand());
-
- for (i = 0 ; i < sizeof(vs->challenge) ; i++)
- vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-}
-
-static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
-{
- unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
- int i, j, pwlen;
- unsigned char key[8];
-
- if (!vs->password || !vs->password[0]) {
- VNC_DEBUG("No password configured on server");
- vnc_write_u32(vs, 1); /* Reject auth */
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_flush(vs);
- vnc_client_error(vs);
- return 0;
- }
-
- memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
-
- /* Calculate the expected challenge response */
- pwlen = strlen(vs->password);
- for (i=0; i<sizeof(key); i++)
- key[i] = i<pwlen ? vs->password[i] : 0;
- deskey(key, EN0);
- for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
- des(response+j, response+j);
-
- /* Compare expected vs actual challenge response */
- if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
- VNC_DEBUG("Client challenge reponse did not match\n");
- vnc_write_u32(vs, 1); /* Reject auth */
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Accepting VNC challenge response\n");
- vnc_write_u32(vs, 0); /* Accept auth */
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_init, 1);
- }
- return 0;
-}
-
-static int start_auth_vnc(VncState *vs)
-{
- make_challenge(vs);
- /* Send client a 'random' challenge */
- vnc_write(vs, vs->challenge, sizeof(vs->challenge));
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
- return 0;
-}
-
-
-#ifdef CONFIG_VNC_TLS
-#define DH_BITS 1024
-static gnutls_dh_params_t dh_params;
-
-static int vnc_tls_initialize(void)
-{
- static int tlsinitialized = 0;
-
- if (tlsinitialized)
- return 1;
-
- if (gnutls_global_init () < 0)
- return 0;
-
- /* XXX ought to re-generate diffie-hellmen params periodically */
- if (gnutls_dh_params_init (&dh_params) < 0)
- return 0;
- if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
- return 0;
-
-#if _VNC_DEBUG == 2
- gnutls_global_set_log_level(10);
- gnutls_global_set_log_function(vnc_debug_gnutls_log);
-#endif
-
- tlsinitialized = 1;
-
- return 1;
-}
-
-static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
-{
- gnutls_anon_server_credentials anon_cred;
- int ret;
-
- if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
- VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
- return NULL;
- }
-
- gnutls_anon_set_server_dh_params(anon_cred, dh_params);
-
- return anon_cred;
-}
-
-
-static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
-{
- gnutls_certificate_credentials_t x509_cred;
- int ret;
-
- if (!vs->x509cacert) {
- VNC_DEBUG("No CA x509 certificate specified\n");
- return NULL;
- }
- if (!vs->x509cert) {
- VNC_DEBUG("No server x509 certificate specified\n");
- return NULL;
- }
- if (!vs->x509key) {
- VNC_DEBUG("No server private key specified\n");
- return NULL;
- }
-
- if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
- VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
- return NULL;
- }
- if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
- vs->x509cacert,
- GNUTLS_X509_FMT_PEM)) < 0) {
- VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
- gnutls_certificate_free_credentials(x509_cred);
- return NULL;
- }
-
- if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
- vs->x509cert,
- vs->x509key,
- GNUTLS_X509_FMT_PEM)) < 0) {
- VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
- gnutls_certificate_free_credentials(x509_cred);
- return NULL;
- }
-
- if (vs->x509cacrl) {
- if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
- vs->x509cacrl,
- GNUTLS_X509_FMT_PEM)) < 0) {
- VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
- gnutls_certificate_free_credentials(x509_cred);
- return NULL;
- }
- }
-
- gnutls_certificate_set_dh_params (x509_cred, dh_params);
-
- return x509_cred;
-}
-
-static int vnc_validate_certificate(struct VncState *vs)
-{
- int ret;
- unsigned int status;
- const gnutls_datum_t *certs;
- unsigned int nCerts, i;
- time_t now;
-
- VNC_DEBUG("Validating client certificate\n");
- if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
- VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
- return -1;
- }
-
- if ((now = time(NULL)) == ((time_t)-1)) {
- return -1;
- }
-
- if (status != 0) {
- if (status & GNUTLS_CERT_INVALID)
- VNC_DEBUG("The certificate is not trusted.\n");
-
- if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
- VNC_DEBUG("The certificate hasn't got a known issuer.\n");
-
- if (status & GNUTLS_CERT_REVOKED)
- VNC_DEBUG("The certificate has been revoked.\n");
-
- if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
- VNC_DEBUG("The certificate uses an insecure algorithm\n");
-
- return -1;
- } else {
- VNC_DEBUG("Certificate is valid!\n");
- }
-
- /* Only support x509 for now */
- if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
- return -1;
-
- if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
- return -1;
-
- for (i = 0 ; i < nCerts ; i++) {
- gnutls_x509_crt_t cert;
- VNC_DEBUG ("Checking certificate chain %d\n", i);
- if (gnutls_x509_crt_init (&cert) < 0)
- return -1;
-
- if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- if (gnutls_x509_crt_get_expiration_time (cert) < now) {
- VNC_DEBUG("The certificate has expired\n");
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- if (gnutls_x509_crt_get_activation_time (cert) > now) {
- VNC_DEBUG("The certificate is not yet activated\n");
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- if (gnutls_x509_crt_get_activation_time (cert) > now) {
- VNC_DEBUG("The certificate is not yet activated\n");
- gnutls_x509_crt_deinit (cert);
- return -1;
- }
-
- gnutls_x509_crt_deinit (cert);
- }
-
- return 0;
-}
-
-
-static int start_auth_vencrypt_subauth(VncState *vs)
-{
- switch (vs->subauth) {
- case VNC_AUTH_VENCRYPT_TLSNONE:
- case VNC_AUTH_VENCRYPT_X509NONE:
- VNC_DEBUG("Accept TLS auth none\n");
- vnc_write_u32(vs, 0); /* Accept auth completion */
- vnc_read_when(vs, protocol_client_init, 1);
- break;
-
- case VNC_AUTH_VENCRYPT_TLSVNC:
- case VNC_AUTH_VENCRYPT_X509VNC:
- VNC_DEBUG("Start TLS auth VNC\n");
- return start_auth_vnc(vs);
-
- default: /* Should not be possible, but just in case */
- VNC_DEBUG("Reject auth %d\n", vs->auth);
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Unsupported authentication type";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- }
-
- return 0;
-}
-
-static void vnc_handshake_io(void *opaque);
-
-static int vnc_continue_handshake(struct VncState *vs) {
- int ret;
-
- if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
- if (!gnutls_error_is_fatal(ret)) {
- VNC_DEBUG("Handshake interrupted (blocking)\n");
- if (!gnutls_record_get_direction(vs->tls_session))
- qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
- else
- qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
- return 0;
- }
- VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
- vnc_client_error(vs);
- return -1;
- }
-
- if (vs->x509verify) {
- if (vnc_validate_certificate(vs) < 0) {
- VNC_DEBUG("Client verification failed\n");
- vnc_client_error(vs);
- return -1;
- } else {
- VNC_DEBUG("Client verification passed\n");
- }
- }
-
- VNC_DEBUG("Handshake done, switching to TLS data mode\n");
- vs->wiremode = VNC_WIREMODE_TLS;
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
-
- return start_auth_vencrypt_subauth(vs);
-}
-
-static void vnc_handshake_io(void *opaque) {
- struct VncState *vs = (struct VncState *)opaque;
-
- VNC_DEBUG("Handshake IO continue\n");
- vnc_continue_handshake(vs);
-}
-
-#define NEED_X509_AUTH(vs) \
- ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
- (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
- (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
-
-
-static int vnc_start_tls(struct VncState *vs) {
- static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
- static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
- static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
- static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
-
- VNC_DEBUG("Do TLS setup\n");
- if (vnc_tls_initialize() < 0) {
- VNC_DEBUG("Failed to init TLS\n");
- vnc_client_error(vs);
- return -1;
- }
- if (vs->tls_session == NULL) {
- if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_set_default_priority(vs->tls_session) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
-
- if (NEED_X509_AUTH(vs)) {
- gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
- if (!x509_cred) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
- if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- gnutls_certificate_free_credentials(x509_cred);
- vnc_client_error(vs);
- return -1;
- }
- if (vs->x509verify) {
- VNC_DEBUG("Requesting a client certificate\n");
- gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
- }
-
- } else {
- gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
- if (!anon_cred) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- vnc_client_error(vs);
- return -1;
- }
- if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- gnutls_anon_free_server_credentials(anon_cred);
- vnc_client_error(vs);
- return -1;
- }
- }
-
- gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
- gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
- gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
- }
-
- VNC_DEBUG("Start TLS handshake process\n");
- return vnc_continue_handshake(vs);
-}
-
-static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
-{
- int auth = read_u32(data, 0);
-
- if (auth != vs->subauth) {
- VNC_DEBUG("Rejecting auth %d\n", auth);
- vnc_write_u8(vs, 0); /* Reject auth */
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
- vnc_write_u8(vs, 1); /* Accept auth */
- vnc_flush(vs);
-
- if (vnc_start_tls(vs) < 0) {
- VNC_DEBUG("Failed to complete TLS\n");
- return 0;
- }
-
- if (vs->wiremode == VNC_WIREMODE_TLS) {
- VNC_DEBUG("Starting VeNCrypt subauth\n");
- return start_auth_vencrypt_subauth(vs);
- } else {
- VNC_DEBUG("TLS handshake blocked\n");
- return 0;
- }
- }
- return 0;
-}
-
-static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
-{
- if (data[0] != 0 ||
- data[1] != 2) {
- VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
- vnc_write_u8(vs, 1); /* Reject version */
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
- vnc_write_u8(vs, 0); /* Accept version */
- vnc_write_u8(vs, 1); /* Number of sub-auths */
- vnc_write_u32(vs, vs->subauth); /* The supported auth */
- vnc_flush(vs);
- vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
- }
- return 0;
-}
-
-static int start_auth_vencrypt(VncState *vs)
-{
- /* Send VeNCrypt version 0.2 */
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 2);
-
- vnc_read_when(vs, protocol_client_vencrypt_init, 2);
- return 0;
-}
-#endif /* CONFIG_VNC_TLS */
-
-static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
-{
- /* We only advertise 1 auth scheme at a time, so client
- * must pick the one we sent. Verify this */
- if (data[0] != vs->auth) { /* Reject auth */
- VNC_DEBUG("Reject auth %d\n", (int)data[0]);
- vnc_write_u32(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- } else { /* Accept requested auth */
- VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
- switch (vs->auth) {
- case VNC_AUTH_NONE:
- VNC_DEBUG("Accept auth none\n");
- if (vs->minor >= 8) {
- vnc_write_u32(vs, 0); /* Accept auth completion */
- vnc_flush(vs);
- }
- vnc_read_when(vs, protocol_client_init, 1);
- break;
-
- case VNC_AUTH_VNC:
- VNC_DEBUG("Start VNC auth\n");
- return start_auth_vnc(vs);
-
-#ifdef CONFIG_VNC_TLS
- case VNC_AUTH_VENCRYPT:
- VNC_DEBUG("Accept VeNCrypt auth\n");;
- return start_auth_vencrypt(vs);
-#endif /* CONFIG_VNC_TLS */
-
- default: /* Should not be possible, but just in case */
- VNC_DEBUG("Reject auth %d\n", vs->auth);
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- }
- }
- return 0;
-}
-
-static int protocol_version(VncState *vs, uint8_t *version, size_t len)
-{
- char local[13];
-
- memcpy(local, version, 12);
- local[12] = 0;
-
- if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
- VNC_DEBUG("Malformed protocol version %s\n", local);
- vnc_client_error(vs);
- return 0;
- }
- VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
- if (vs->major != 3 ||
- (vs->minor != 3 &&
- vs->minor != 4 &&
- vs->minor != 5 &&
- vs->minor != 7 &&
- vs->minor != 8)) {
- VNC_DEBUG("Unsupported client version\n");
- vnc_write_u32(vs, VNC_AUTH_INVALID);
- vnc_flush(vs);
- vnc_client_error(vs);
- return 0;
- }
- /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
- * as equivalent to v3.3 by servers
- */
- if (vs->minor == 4 || vs->minor == 5)
- vs->minor = 3;
-
- if (vs->minor == 3) {
- if (vs->auth == VNC_AUTH_NONE) {
- VNC_DEBUG("Tell client auth none\n");
- vnc_write_u32(vs, vs->auth);
- vnc_flush(vs);
- vnc_read_when(vs, protocol_client_init, 1);
- } else if (vs->auth == VNC_AUTH_VNC) {
- VNC_DEBUG("Tell client VNC auth\n");
- vnc_write_u32(vs, vs->auth);
- vnc_flush(vs);
- start_auth_vnc(vs);
- } else {
- VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
- vnc_write_u32(vs, VNC_AUTH_INVALID);
- vnc_flush(vs);
- vnc_client_error(vs);
- }
- } else {
- VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
- vnc_write_u8(vs, 1); /* num auth */
- vnc_write_u8(vs, vs->auth);
- vnc_read_when(vs, protocol_client_auth, 1);
- vnc_flush(vs);
- }
-
- return 0;
-}
-
-static void vnc_connect(VncState *vs)
-{
- VNC_DEBUG("New client on socket %d\n", vs->csock);
- vs->ds->idle = 0;
- socket_set_nonblock(vs->csock);
- qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
- vnc_write(vs, "RFB 003.008\n", 12);
- vnc_flush(vs);
- vnc_read_when(vs, protocol_version, 12);
- memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
- memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
- vs->has_resize = 0;
- vs->has_hextile = 0;
- vs->ds->dpy_copy = NULL;
- vnc_update_client(vs);
-}
-
-static void vnc_listen_read(void *opaque)
-{
- VncState *vs = opaque;
-
- /* Catch-up */
- vga_hw_update();
-
- vs->csock = socket_accept(vs->lsock, NULL);
- if (vs->csock != -1) {
- vnc_connect(vs);
- }
-}
-
-extern int parse_host_port(SockAddress* saddr, const char *str);
-
-void vnc_display_init(DisplayState *ds)
-{
- VncState *vs;
-
- vs = qemu_mallocz(sizeof(VncState));
- if (!vs)
- exit(1);
-
- ds->opaque = vs;
- ds->idle = 1;
- vnc_state = vs;
- vs->display = NULL;
- vs->password = NULL;
-
- vs->lsock = -1;
- vs->csock = -1;
- vs->last_x = -1;
- vs->last_y = -1;
-
- vs->ds = ds;
-
- if (keyboard_layout)
- vs->kbd_layout = init_keyboard_layout(keyboard_layout);
- else
- vs->kbd_layout = init_keyboard_layout("en-us");
-
- if (!vs->kbd_layout)
- exit(1);
-
- vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
-
- vs->ds->data = NULL;
- vs->ds->dpy_update = vnc_dpy_update;
- vs->ds->dpy_resize = vnc_dpy_resize;
- vs->ds->dpy_refresh = NULL;
-
- vnc_colordepth(vs->ds, 32);
- vnc_dpy_resize(vs->ds, 640, 400);
-}
-
-#ifdef CONFIG_VNC_TLS
-static int vnc_set_x509_credential(VncState *vs,
- const char *certdir,
- const char *filename,
- char **cred,
- int ignoreMissing)
-{
- struct stat sb;
-
- if (*cred) {
- qemu_free(*cred);
- *cred = NULL;
- }
-
- if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
- return -1;
-
- strcpy(*cred, certdir);
- strcat(*cred, "/");
- strcat(*cred, filename);
-
- VNC_DEBUG("Check %s\n", *cred);
- if (stat(*cred, &sb) < 0) {
- qemu_free(*cred);
- *cred = NULL;
- if (ignoreMissing && errno == ENOENT)
- return 0;
- return -1;
- }
-
- return 0;
-}
-
-static int vnc_set_x509_credential_dir(VncState *vs,
- const char *certdir)
-{
- if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
- goto cleanup;
- if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
- goto cleanup;
- if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
- goto cleanup;
- if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
- goto cleanup;
-
- return 0;
-
- cleanup:
- qemu_free(vs->x509cacert);
- qemu_free(vs->x509cacrl);
- qemu_free(vs->x509cert);
- qemu_free(vs->x509key);
- vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
- return -1;
-}
-#endif /* CONFIG_VNC_TLS */
-
-void vnc_display_close(DisplayState *ds)
-{
- VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
-
- if (vs->display) {
- qemu_free(vs->display);
- vs->display = NULL;
- }
- if (vs->lsock != -1) {
- qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
- close(vs->lsock);
- vs->lsock = -1;
- }
- if (vs->csock != -1) {
- qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
- socket_close(vs->csock);
- vs->csock = -1;
- buffer_reset(&vs->input);
- buffer_reset(&vs->output);
- vs->need_update = 0;
-#ifdef CONFIG_VNC_TLS
- if (vs->tls_session) {
- gnutls_deinit(vs->tls_session);
- vs->tls_session = NULL;
- }
- vs->wiremode = VNC_WIREMODE_CLEAR;
-#endif /* CONFIG_VNC_TLS */
- }
- vs->auth = VNC_AUTH_INVALID;
-#ifdef CONFIG_VNC_TLS
- vs->subauth = VNC_AUTH_INVALID;
- vs->x509verify = 0;
-#endif
-}
-
-int vnc_display_password(DisplayState *ds, const char *password)
-{
- VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
-
- if (vs->password) {
- qemu_free(vs->password);
- vs->password = NULL;
- }
- if (password && password[0]) {
- if (!(vs->password = qemu_strdup(password)))
- return -1;
- }
-
- return 0;
-}
-
-int vnc_display_open(DisplayState *ds, const char *display)
-{
- SockAddress addr;
-#ifndef _WIN32
- const char *p;
-#endif
- int ret;
- VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
- const char *options;
- int password = 0;
- int reverse = 0;
-#ifdef CONFIG_VNC_TLS
- int tls = 0, x509 = 0;
-#endif
-
- sock_address_init_inet( &addr, SOCK_ADDRESS_INET_ANY, 0 );
- vs->lsock = -1;
-
- vnc_display_close(ds);
- if (strcmp(display, "none") == 0)
- return 0;
-
- if (!(vs->display = strdup(display)))
- return -1;
-
- options = display;
- while ((options = strchr(options, ','))) {
- options++;
- if (strncmp(options, "password", 8) == 0) {
- password = 1; /* Require password auth */
- } else if (strncmp(options, "reverse", 7) == 0) {
- reverse = 1;
-#ifdef CONFIG_VNC_TLS
- } else if (strncmp(options, "tls", 3) == 0) {
- tls = 1; /* Require TLS */
- } else if (strncmp(options, "x509", 4) == 0) {
- char *start, *end;
- x509 = 1; /* Require x509 certificates */
- if (strncmp(options, "x509verify", 10) == 0)
- vs->x509verify = 1; /* ...and verify client certs */
-
- /* Now check for 'x509=/some/path' postfix
- * and use that to setup x509 certificate/key paths */
- start = strchr(options, '=');
- end = strchr(options, ',');
- if (start && (!end || (start < end))) {
- int len = end ? end-(start+1) : strlen(start+1);
- char *path = qemu_malloc(len+1);
- strncpy(path, start+1, len);
- path[len] = '\0';
- VNC_DEBUG("Trying certificate path '%s'\n", path);
- ret = vnc_set_x509_credential_dir(vs, path);
- qemu_free(path);
- if (ret < 0) {
- fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
- goto FAIL;
- }
- } else {
- fprintf(stderr, "No certificate path provided\n");
- goto FAIL;
- }
-#endif
- }
- }
-
- if (password) {
-#ifdef CONFIG_VNC_TLS
- if (tls) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (x509) {
- VNC_DEBUG("Initializing VNC server with x509 password auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
- } else {
- VNC_DEBUG("Initializing VNC server with TLS password auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
- }
- } else {
-#endif
- VNC_DEBUG("Initializing VNC server with password auth\n");
- vs->auth = VNC_AUTH_VNC;
-#ifdef CONFIG_VNC_TLS
- vs->subauth = VNC_AUTH_INVALID;
- }
-#endif
- } else {
-#ifdef CONFIG_VNC_TLS
- if (tls) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (x509) {
- VNC_DEBUG("Initializing VNC server with x509 no auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
- } else {
- VNC_DEBUG("Initializing VNC server with TLS no auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
- }
- } else {
-#endif
- VNC_DEBUG("Initializing VNC server with no auth\n");
- vs->auth = VNC_AUTH_NONE;
-#ifdef CONFIG_VNC_TLS
- vs->subauth = VNC_AUTH_INVALID;
- }
-#endif
- }
-#ifndef _WIN32
- if (strstart(display, "unix:", &p)) {
- sock_address_init_unix( &addr, p);
- vs->lsock = socket_create( SOCKET_UNIX, SOCKET_STREAM );
- if (vs->lsock == -1) {
- fprintf(stderr, "Could not create socket\n");
- goto FAIL;
- }
-
- if (!reverse) {
- unlink(p);
- }
- } else
-#endif
- {
- if (parse_host_port(&addr, display) < 0) {
- fprintf(stderr, "Could not parse VNC address\n");
- goto FAIL;
- }
-
- sock_address_set_port(&addr, reverse ? 0 : 5900);
-
- vs->lsock = socket_create_inet( SOCKET_STREAM );
- if (vs->lsock == -1) {
- fprintf(stderr, "Could not create socket\n");
- goto FAIL;
- }
-
- ret = socket_set_xreuseaddr(vs->lsock);
- if (ret == -1) {
- fprintf(stderr, "setsockopt() failed\n");
- goto FAIL;
- }
- }
-
- if (reverse) {
- if (socket_connect(vs->lsock, &addr) == -1) {
- fprintf(stderr, "Connection to VNC client failed\n");
- goto FAIL;
- }
- vs->csock = vs->lsock;
- vs->lsock = -1;
- vnc_connect(vs);
- return 0;
- }
-
- if (socket_bind(vs->lsock, &addr) == -1) {
- fprintf(stderr, "bind() failed\n");
- goto FAIL;
- }
-
- if (socket_listen(vs->lsock, 1) == -1) {
- fprintf(stderr, "listen() failed\n");
- goto FAIL;
- }
-
- return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
-
-FAIL:
- sock_address_done(&addr);
-
- if (vs->lsock >= 0) {
- socket_close(vs->lsock);
- vs->lsock = -1;
- }
- free(vs->display);
- vs->display = NULL;
- return -1;
-}
diff --git a/vnc_keysym.h b/vnc_keysym.h
deleted file mode 100644
index b6a172d..0000000
--- a/vnc_keysym.h
+++ /dev/null
@@ -1,302 +0,0 @@
-typedef struct {
- const char* name;
- int keysym;
-} name2keysym_t;
-static name2keysym_t name2keysym[]={
-/* ascii */
- { "space", 0x020},
- { "exclam", 0x021},
- { "quotedbl", 0x022},
- { "numbersign", 0x023},
- { "dollar", 0x024},
- { "percent", 0x025},
- { "ampersand", 0x026},
- { "apostrophe", 0x027},
- { "parenleft", 0x028},
- { "parenright", 0x029},
- { "asterisk", 0x02a},
- { "plus", 0x02b},
- { "comma", 0x02c},
- { "minus", 0x02d},
- { "period", 0x02e},
- { "slash", 0x02f},
- { "0", 0x030},
- { "1", 0x031},
- { "2", 0x032},
- { "3", 0x033},
- { "4", 0x034},
- { "5", 0x035},
- { "6", 0x036},
- { "7", 0x037},
- { "8", 0x038},
- { "9", 0x039},
- { "colon", 0x03a},
- { "semicolon", 0x03b},
- { "less", 0x03c},
- { "equal", 0x03d},
- { "greater", 0x03e},
- { "question", 0x03f},
- { "at", 0x040},
- { "A", 0x041},
- { "B", 0x042},
- { "C", 0x043},
- { "D", 0x044},
- { "E", 0x045},
- { "F", 0x046},
- { "G", 0x047},
- { "H", 0x048},
- { "I", 0x049},
- { "J", 0x04a},
- { "K", 0x04b},
- { "L", 0x04c},
- { "M", 0x04d},
- { "N", 0x04e},
- { "O", 0x04f},
- { "P", 0x050},
- { "Q", 0x051},
- { "R", 0x052},
- { "S", 0x053},
- { "T", 0x054},
- { "U", 0x055},
- { "V", 0x056},
- { "W", 0x057},
- { "X", 0x058},
- { "Y", 0x059},
- { "Z", 0x05a},
- { "bracketleft", 0x05b},
- { "backslash", 0x05c},
- { "bracketright", 0x05d},
- { "asciicircum", 0x05e},
- { "underscore", 0x05f},
- { "grave", 0x060},
- { "a", 0x061},
- { "b", 0x062},
- { "c", 0x063},
- { "d", 0x064},
- { "e", 0x065},
- { "f", 0x066},
- { "g", 0x067},
- { "h", 0x068},
- { "i", 0x069},
- { "j", 0x06a},
- { "k", 0x06b},
- { "l", 0x06c},
- { "m", 0x06d},
- { "n", 0x06e},
- { "o", 0x06f},
- { "p", 0x070},
- { "q", 0x071},
- { "r", 0x072},
- { "s", 0x073},
- { "t", 0x074},
- { "u", 0x075},
- { "v", 0x076},
- { "w", 0x077},
- { "x", 0x078},
- { "y", 0x079},
- { "z", 0x07a},
- { "braceleft", 0x07b},
- { "bar", 0x07c},
- { "braceright", 0x07d},
- { "asciitilde", 0x07e},
-
-/* latin 1 extensions */
-{ "nobreakspace", 0x0a0},
-{ "exclamdown", 0x0a1},
-{ "cent", 0x0a2},
-{ "sterling", 0x0a3},
-{ "currency", 0x0a4},
-{ "yen", 0x0a5},
-{ "brokenbar", 0x0a6},
-{ "section", 0x0a7},
-{ "diaeresis", 0x0a8},
-{ "copyright", 0x0a9},
-{ "ordfeminine", 0x0aa},
-{ "guillemotleft", 0x0ab},
-{ "notsign", 0x0ac},
-{ "hyphen", 0x0ad},
-{ "registered", 0x0ae},
-{ "macron", 0x0af},
-{ "degree", 0x0b0},
-{ "plusminus", 0x0b1},
-{ "twosuperior", 0x0b2},
-{ "threesuperior", 0x0b3},
-{ "acute", 0x0b4},
-{ "mu", 0x0b5},
-{ "paragraph", 0x0b6},
-{ "periodcentered", 0x0b7},
-{ "cedilla", 0x0b8},
-{ "onesuperior", 0x0b9},
-{ "masculine", 0x0ba},
-{ "guillemotright", 0x0bb},
-{ "onequarter", 0x0bc},
-{ "onehalf", 0x0bd},
-{ "threequarters", 0x0be},
-{ "questiondown", 0x0bf},
-{ "Agrave", 0x0c0},
-{ "Aacute", 0x0c1},
-{ "Acircumflex", 0x0c2},
-{ "Atilde", 0x0c3},
-{ "Adiaeresis", 0x0c4},
-{ "Aring", 0x0c5},
-{ "AE", 0x0c6},
-{ "Ccedilla", 0x0c7},
-{ "Egrave", 0x0c8},
-{ "Eacute", 0x0c9},
-{ "Ecircumflex", 0x0ca},
-{ "Ediaeresis", 0x0cb},
-{ "Igrave", 0x0cc},
-{ "Iacute", 0x0cd},
-{ "Icircumflex", 0x0ce},
-{ "Idiaeresis", 0x0cf},
-{ "ETH", 0x0d0},
-{ "Eth", 0x0d0},
-{ "Ntilde", 0x0d1},
-{ "Ograve", 0x0d2},
-{ "Oacute", 0x0d3},
-{ "Ocircumflex", 0x0d4},
-{ "Otilde", 0x0d5},
-{ "Odiaeresis", 0x0d6},
-{ "multiply", 0x0d7},
-{ "Ooblique", 0x0d8},
-{ "Oslash", 0x0d8},
-{ "Ugrave", 0x0d9},
-{ "Uacute", 0x0da},
-{ "Ucircumflex", 0x0db},
-{ "Udiaeresis", 0x0dc},
-{ "Yacute", 0x0dd},
-{ "THORN", 0x0de},
-{ "Thorn", 0x0de},
-{ "ssharp", 0x0df},
-{ "agrave", 0x0e0},
-{ "aacute", 0x0e1},
-{ "acircumflex", 0x0e2},
-{ "atilde", 0x0e3},
-{ "adiaeresis", 0x0e4},
-{ "aring", 0x0e5},
-{ "ae", 0x0e6},
-{ "ccedilla", 0x0e7},
-{ "egrave", 0x0e8},
-{ "eacute", 0x0e9},
-{ "ecircumflex", 0x0ea},
-{ "ediaeresis", 0x0eb},
-{ "igrave", 0x0ec},
-{ "iacute", 0x0ed},
-{ "icircumflex", 0x0ee},
-{ "idiaeresis", 0x0ef},
-{ "eth", 0x0f0},
-{ "ntilde", 0x0f1},
-{ "ograve", 0x0f2},
-{ "oacute", 0x0f3},
-{ "ocircumflex", 0x0f4},
-{ "otilde", 0x0f5},
-{ "odiaeresis", 0x0f6},
-{ "division", 0x0f7},
-{ "oslash", 0x0f8},
-{ "ooblique", 0x0f8},
-{ "ugrave", 0x0f9},
-{ "uacute", 0x0fa},
-{ "ucircumflex", 0x0fb},
-{ "udiaeresis", 0x0fc},
-{ "yacute", 0x0fd},
-{ "thorn", 0x0fe},
-{ "ydiaeresis", 0x0ff},
-{"EuroSign", 0x20ac}, /* XK_EuroSign */
-
- /* modifiers */
-{"Control_L", 0xffe3}, /* XK_Control_L */
-{"Control_R", 0xffe4}, /* XK_Control_R */
-{"Alt_L", 0xffe9}, /* XK_Alt_L */
-{"Alt_R", 0xffea}, /* XK_Alt_R */
-{"Caps_Lock", 0xffe5}, /* XK_Caps_Lock */
-{"Meta_L", 0xffe7}, /* XK_Meta_L */
-{"Meta_R", 0xffe8}, /* XK_Meta_R */
-{"Shift_L", 0xffe1}, /* XK_Shift_L */
-{"Shift_R", 0xffe2}, /* XK_Shift_R */
-{"Super_L", 0xffeb}, /* XK_Super_L */
-{"Super_R", 0xffec}, /* XK_Super_R */
-
- /* special keys */
-{"BackSpace", 0xff08}, /* XK_BackSpace */
-{"Tab", 0xff09}, /* XK_Tab */
-{"Return", 0xff0d}, /* XK_Return */
-{"Right", 0xff53}, /* XK_Right */
-{"Left", 0xff51}, /* XK_Left */
-{"Up", 0xff52}, /* XK_Up */
-{"Down", 0xff54}, /* XK_Down */
-{"Page_Down", 0xff56}, /* XK_Page_Down */
-{"Page_Up", 0xff55}, /* XK_Page_Up */
-{"Insert", 0xff63}, /* XK_Insert */
-{"Delete", 0xffff}, /* XK_Delete */
-{"Home", 0xff50}, /* XK_Home */
-{"End", 0xff57}, /* XK_End */
-{"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
-{"KP_Home", 0xff95},
-{"KP_Left", 0xff96},
-{"KP_Up", 0xff97},
-{"KP_Right", 0xff98},
-{"KP_Down", 0xff99},
-{"KP_Prior", 0xff9a},
-{"KP_Page_Up", 0xff9a},
-{"KP_Next", 0xff9b},
-{"KP_Page_Down", 0xff9b},
-{"KP_End", 0xff9c},
-{"KP_Begin", 0xff9d},
-{"KP_Insert", 0xff9e},
-{"KP_Delete", 0xff9f},
-{"F1", 0xffbe}, /* XK_F1 */
-{"F2", 0xffbf}, /* XK_F2 */
-{"F3", 0xffc0}, /* XK_F3 */
-{"F4", 0xffc1}, /* XK_F4 */
-{"F5", 0xffc2}, /* XK_F5 */
-{"F6", 0xffc3}, /* XK_F6 */
-{"F7", 0xffc4}, /* XK_F7 */
-{"F8", 0xffc5}, /* XK_F8 */
-{"F9", 0xffc6}, /* XK_F9 */
-{"F10", 0xffc7}, /* XK_F10 */
-{"F11", 0xffc8}, /* XK_F11 */
-{"F12", 0xffc9}, /* XK_F12 */
-{"F13", 0xffca}, /* XK_F13 */
-{"F14", 0xffcb}, /* XK_F14 */
-{"F15", 0xffcc}, /* XK_F15 */
-{"Sys_Req", 0xff15}, /* XK_Sys_Req */
-{"KP_0", 0xffb0}, /* XK_KP_0 */
-{"KP_1", 0xffb1}, /* XK_KP_1 */
-{"KP_2", 0xffb2}, /* XK_KP_2 */
-{"KP_3", 0xffb3}, /* XK_KP_3 */
-{"KP_4", 0xffb4}, /* XK_KP_4 */
-{"KP_5", 0xffb5}, /* XK_KP_5 */
-{"KP_6", 0xffb6}, /* XK_KP_6 */
-{"KP_7", 0xffb7}, /* XK_KP_7 */
-{"KP_8", 0xffb8}, /* XK_KP_8 */
-{"KP_9", 0xffb9}, /* XK_KP_9 */
-{"KP_Add", 0xffab}, /* XK_KP_Add */
-{"KP_Separator", 0xffac},/* XK_KP_Separator */
-{"KP_Decimal", 0xffae}, /* XK_KP_Decimal */
-{"KP_Divide", 0xffaf}, /* XK_KP_Divide */
-{"KP_Enter", 0xff8d}, /* XK_KP_Enter */
-{"KP_Equal", 0xffbd}, /* XK_KP_Equal */
-{"KP_Multiply", 0xffaa}, /* XK_KP_Multiply */
-{"KP_Subtract", 0xffad}, /* XK_KP_Subtract */
-{"help", 0xff6a}, /* XK_Help */
-{"Menu", 0xff67}, /* XK_Menu */
-{"Print", 0xff61}, /* XK_Print */
-{"Mode_switch", 0xff7e}, /* XK_Mode_switch */
-{"Num_Lock", 0xff7f}, /* XK_Num_Lock */
-{"Pause", 0xff13}, /* XK_Pause */
-{"Escape", 0xff1b}, /* XK_Escape */
-
- /* localized keys */
-{"BackApostrophe", 0xff21},
-{"Muhenkan", 0xff22},
-{"Katakana", 0xff27},
-{"Hankaku", 0xff29},
-{"Zenkaku_Hankaku", 0xff2a},
-{"Henkan_Mode_Real", 0xff23},
-{"Henkan_Mode_Ultra", 0xff3e},
-{"backslash_ja", 0xffa5},
-{"Katakana_Real", 0xff25},
-{"Eisu_toggle", 0xff30},
-
-{0,0},
-};
diff --git a/vnchextile.h b/vnchextile.h
deleted file mode 100644
index eb05feb..0000000
--- a/vnchextile.h
+++ /dev/null
@@ -1,209 +0,0 @@
-#define CONCAT_I(a, b) a ## b
-#define CONCAT(a, b) CONCAT_I(a, b)
-#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
-#ifdef GENERIC
-#define NAME CONCAT(generic_, BPP)
-#else
-#define NAME BPP
-#endif
-
-static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
- int x, int y, int w, int h,
- void *last_bg_,
- void *last_fg_,
- int *has_bg, int *has_fg)
-{
- uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth);
- pixel_t *irow = (pixel_t *)row;
- int j, i;
- pixel_t *last_bg = (pixel_t *)last_bg_;
- pixel_t *last_fg = (pixel_t *)last_fg_;
- pixel_t bg = 0;
- pixel_t fg = 0;
- int n_colors = 0;
- int bg_count = 0;
- int fg_count = 0;
- int flags = 0;
- uint8_t data[(vs->pix_bpp + 2) * 16 * 16];
- int n_data = 0;
- int n_subtiles = 0;
-
- for (j = 0; j < h; j++) {
- for (i = 0; i < w; i++) {
- switch (n_colors) {
- case 0:
- bg = irow[i];
- n_colors = 1;
- break;
- case 1:
- if (irow[i] != bg) {
- fg = irow[i];
- n_colors = 2;
- }
- break;
- case 2:
- if (irow[i] != bg && irow[i] != fg) {
- n_colors = 3;
- } else {
- if (irow[i] == bg)
- bg_count++;
- else if (irow[i] == fg)
- fg_count++;
- }
- break;
- default:
- break;
- }
- }
- if (n_colors > 2)
- break;
- irow += vs->ds->linesize / sizeof(pixel_t);
- }
-
- if (n_colors > 1 && fg_count > bg_count) {
- pixel_t tmp = fg;
- fg = bg;
- bg = tmp;
- }
-
- if (!*has_bg || *last_bg != bg) {
- flags |= 0x02;
- *has_bg = 1;
- *last_bg = bg;
- }
-
- if (!*has_fg || *last_fg != fg) {
- flags |= 0x04;
- *has_fg = 1;
- *last_fg = fg;
- }
-
- switch (n_colors) {
- case 1:
- n_data = 0;
- break;
- case 2:
- flags |= 0x08;
-
- irow = (pixel_t *)row;
-
- for (j = 0; j < h; j++) {
- int min_x = -1;
- for (i = 0; i < w; i++) {
- if (irow[i] == fg) {
- if (min_x == -1)
- min_x = i;
- } else if (min_x != -1) {
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- min_x = -1;
- }
- }
- if (min_x != -1) {
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- }
- irow += vs->ds->linesize / sizeof(pixel_t);
- }
- break;
- case 3:
- flags |= 0x18;
-
- irow = (pixel_t *)row;
-
- if (!*has_bg || *last_bg != bg)
- flags |= 0x02;
-
- for (j = 0; j < h; j++) {
- int has_color = 0;
- int min_x = -1;
- pixel_t color = 0; /* shut up gcc */
-
- for (i = 0; i < w; i++) {
- if (!has_color) {
- if (irow[i] == bg)
- continue;
- color = irow[i];
- min_x = i;
- has_color = 1;
- } else if (irow[i] != color) {
- has_color = 0;
-#ifdef GENERIC
- vnc_convert_pixel(vs, data + n_data, color);
- n_data += vs->pix_bpp;
-#else
- memcpy(data + n_data, &color, sizeof(color));
- n_data += sizeof(pixel_t);
-#endif
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
-
- min_x = -1;
- if (irow[i] != bg) {
- color = irow[i];
- min_x = i;
- has_color = 1;
- }
- }
- }
- if (has_color) {
-#ifdef GENERIC
- vnc_convert_pixel(vs, data + n_data, color);
- n_data += vs->pix_bpp;
-#else
- memcpy(data + n_data, &color, sizeof(color));
- n_data += sizeof(pixel_t);
-#endif
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- }
- irow += vs->ds->linesize / sizeof(pixel_t);
- }
-
- /* A SubrectsColoured subtile invalidates the foreground color */
- *has_fg = 0;
- if (n_data > (w * h * sizeof(pixel_t))) {
- n_colors = 4;
- flags = 0x01;
- *has_bg = 0;
-
- /* we really don't have to invalidate either the bg or fg
- but we've lost the old values. oh well. */
- }
- default:
- break;
- }
-
- if (n_colors > 3) {
- flags = 0x01;
- *has_fg = 0;
- *has_bg = 0;
- n_colors = 4;
- }
-
- vnc_write_u8(vs, flags);
- if (n_colors < 4) {
- if (flags & 0x02)
- vs->write_pixels(vs, last_bg, sizeof(pixel_t));
- if (flags & 0x04)
- vs->write_pixels(vs, last_fg, sizeof(pixel_t));
- if (n_subtiles) {
- vnc_write_u8(vs, n_subtiles);
- vnc_write(vs, data, n_data);
- }
- } else {
- for (j = 0; j < h; j++) {
- vs->write_pixels(vs, row, w * vs->depth);
- row += vs->ds->linesize;
- }
- }
-}
-
-#undef NAME
-#undef pixel_t
-#undef CONCAT_I
-#undef CONCAT
diff --git a/x86_64.ld b/x86_64.ld
deleted file mode 100644
index 878dafb..0000000
--- a/x86_64.ld
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Default linker script, for normal executables */
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(_start)
-SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0x90909090
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x90909090
- .fini :
- {
- KEEP (*(.fini))
- } =0x90909090
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
- /* Ensure the __preinit_array_start label is properly aligned. We
- could instead move the label definition inside the section, but
- the linker would then create the section even if it turns out to
- be empty, which isn't pretty. */
- . = ALIGN(64 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
- .dynamic : { *(.dynamic) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .got : { *(.got.plt) *(.got) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
- . = ALIGN(64 / 8);
- }
- . = ALIGN(64 / 8);
- _end = .;
- PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-}