├── .clang-format ├── .clang-tidy ├── .clang_complete ├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── dbrew.config ├── dbrew.creator ├── dbrew.files ├── dbrew.includes ├── docs ├── C++.md ├── README ├── TODO ├── pubs │ └── preprint-hips16.pdf └── related │ ├── Agner-CallingConventions.pdf │ ├── README.md │ └── SystemV-abi-amd64.pdf ├── examples ├── .gitignore ├── Makefile ├── matrix.c ├── simple.c ├── stencil.c ├── strcmp.c └── vector.c ├── include ├── dbrew.h └── priv │ ├── buffers.h │ ├── common.h │ ├── decode.h │ ├── emulate.h │ ├── engine.h │ ├── error.h │ ├── expr.h │ ├── generate.h │ ├── instr.h │ ├── printer.h │ └── vector.h ├── meson.build ├── src ├── buffers.c ├── config.c ├── dbrew.c ├── decode.c ├── emulate.c ├── engine.c ├── error.c ├── expr.c ├── generate.c ├── instr.c ├── meson.build ├── printer.c ├── snippets.c └── vector.c └── tests ├── Makefile ├── README.md ├── TODO.md ├── branchtest.c ├── cases ├── decode │ ├── avx.s │ ├── avx.s.expect │ ├── group-f7.s │ ├── group-f7.s.expect │ ├── it-adc.s │ ├── it-adc.s.expect │ ├── it-add-buferr.s │ ├── it-add-buferr.s.expect │ ├── it-add-buferr.s.expect_stderr │ ├── it-add.s │ ├── it-add.s.expect │ ├── it-and-imm.s │ ├── it-and-imm.s.expect │ ├── it-and.s │ ├── it-and.s.expect │ ├── it-bsf.s │ ├── it-bsf.s.expect │ ├── it-cltq.s │ ├── it-cltq.s.expect │ ├── it-cmovcc.s │ ├── it-cmovcc.s.expect │ ├── it-cmp.s │ ├── it-cmp.s.expect │ ├── it-inc-dec.s │ ├── it-inc-dec.s.expect │ ├── it-lea.s │ ├── it-lea.s.expect │ ├── it-leave.s │ ├── it-leave.s.expect │ ├── it-mov.s │ ├── it-mov.s.expect │ ├── it-movsx.s │ ├── it-movsx.s.expect │ ├── it-movzx.s │ ├── it-movzx.s.expect │ ├── it-mul-div.s │ ├── it-mul-div.s.expect │ ├── it-neg-not.s │ ├── it-neg-not.s.expect │ ├── it-nop.s │ ├── it-nop.s.expect │ ├── it-or.s │ ├── it-or.s.expect │ ├── it-push-pop.s │ ├── it-push-pop.s.expect │ ├── it-pxor.s │ ├── it-pxor.s.expect │ ├── it-sbb.s │ ├── it-sbb.s.expect │ ├── it-shift.s │ ├── it-shift.s.expect │ ├── it-sub.s │ ├── it-sub.s.expect │ ├── it-test.s │ ├── it-test.s.expect │ ├── it-ud2.s │ ├── it-ud2.s.expect │ ├── it-ud2.s.expect_stderr │ ├── it-xor.s │ ├── it-xor.s.expect │ ├── js-short.s │ ├── js-short.s.expect │ ├── js.s │ ├── js.s.expect │ ├── modrm.s │ ├── modrm.s.expect │ ├── movq.s │ ├── movq.s.expect │ ├── pop-word-ax.s │ ├── pop-word-ax.s.expect │ ├── pop-word-r10w.s │ ├── pop-word-r10w.s.expect │ ├── push-word-ax.s │ ├── push-word-ax.s.expect │ ├── push-word-r10w.s │ ├── push-word-r10w.s.expect │ ├── sse-arithmetic.s │ ├── sse-arithmetic.s.expect │ ├── sse.s │ └── sse.s.expect ├── examples │ ├── stencil-5-avx.c │ ├── stencil-5-avx.c.expect │ ├── stencil-5.c │ ├── stencil-5.c.expect │ ├── stencil-6-avx.c │ ├── stencil-6-avx.c.expect │ ├── stencil-6.c │ ├── stencil-6.c.expect │ ├── stencil-7-avx.c │ ├── stencil-7-avx.c.expect │ ├── stencil-7.c │ ├── stencil-7.c.expect │ ├── stencil-8-avx.c │ ├── stencil-8-avx.c.expect │ ├── stencil-8.c │ └── stencil-8.c.expect ├── generator │ ├── avx.s │ ├── avx.s.expect │ ├── it-add.s │ ├── it-add.s.expect │ ├── it-and-imm.s │ ├── it-and-imm.s.expect │ ├── it-pxor.s │ ├── it-pxor.s.expect │ ├── it-test.s │ ├── it-test.s.expect │ ├── it-undef.c │ ├── it-undef.c.expect │ ├── it-undef.c.expect_stderr │ ├── modrm.s │ ├── modrm.s.expect │ ├── op-ret.c │ ├── op-ret.c.expect │ ├── sse.s │ └── sse.s.expect └── integration │ ├── fp.s │ ├── fp.s.expect │ ├── it-and.s │ ├── it-and.s.expect │ ├── it-cltq.s │ ├── it-cltq.s.expect │ ├── op-call.s │ ├── op-call.s.expect │ ├── op-call.s.expect_filter │ ├── op-inc.s │ ├── op-inc.s.expect │ ├── op-ja.s │ ├── op-ja.s.expect │ ├── op-jbe.s │ ├── op-jbe.s.expect │ ├── op-je.s │ ├── op-je.s.expect │ ├── op-jo.s │ ├── op-jo.s.expect │ ├── op-jp.s │ ├── op-jp.s.expect │ ├── op-js-1.s │ ├── op-js-1.s.expect │ ├── op-js-2.s │ ├── op-js-2.s.expect │ ├── op-jz-dynamic.s │ ├── op-jz-dynamic.s.expect │ ├── op-jz.s │ ├── op-jz.s.expect │ ├── op-leave.s │ ├── op-leave.s.expect │ ├── op-mov-mem.s │ ├── op-mov-mem.s.expect │ ├── op-mov-r9d.s │ ├── op-mov-r9d.s.expect │ ├── op-push-pop.s │ ├── op-push-pop.s.expect │ ├── op-shl.s │ ├── op-shl.s.expect │ ├── segov.s │ └── segov.s.expect ├── stencil-apply-g-fp.s ├── test-driver-decode-buferr.c ├── test-driver-decode.c ├── test-driver-gen.c ├── test-driver-generate.c ├── test-driver.c ├── test.c ├── test.exp-O0 ├── test.exp-O2 ├── test.pl └── test.py /.clang-format: -------------------------------------------------------------------------------- 1 | DisableFormat: true 2 | -------------------------------------------------------------------------------- /.clang_complete: -------------------------------------------------------------------------------- 1 | -Iinclude 2 | -Iinclude/priv 3 | -std=gnu99 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.out 4 | *.d 5 | 6 | # ignore stuff from various IDEs 7 | dbrew.creator.user 8 | .vscode 9 | 10 | # ignore any local experiments in tmp/ 11 | tmp 12 | 13 | # ignore file generated by "bear" 14 | compile_commands.json 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caps-tum/dbrew/10a202f3f209d2f2ef5c08aba15d9b3e01b3a5ba/.gitmodules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | dist: bionic 3 | 4 | addons: 5 | apt: 6 | packages: &default_pkgs 7 | - libglib2.0-dev 8 | - python3-pip 9 | - python3-setuptools 10 | # - libstdc++6-4.9-dbg 11 | - ninja-build 12 | 13 | matrix: 14 | include: 15 | - compiler: gcc 16 | env: 17 | - COMPILERC=gcc-7 18 | - COMPILERCXX=g++-7 19 | addons: 20 | apt: 21 | packages: 22 | - *default_pkgs 23 | - gcc-7 24 | - g++-7 25 | - compiler: clang 26 | env: 27 | - COMPILERC=clang-8 28 | - COMPILERCXX=clang++-8 29 | addons: 30 | apt: 31 | packages: 32 | - *default_pkgs 33 | - clang-8 34 | 35 | install: 36 | # The meson included in the Xenial repositories is too old (0.29). 37 | - pip3 install meson 38 | # Hack to work around different versions of LLVM being installed and meson 39 | # always choosing the newest one, regardless of our specifications. 40 | - export CC=$COMPILERC 41 | - export CXX=$COMPILERCXX 42 | 43 | script: 44 | - mkdir build 45 | - meson build 46 | - ninja -v -C build 47 | - meson test -v -C build 48 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Can (and should) be specified via the command line. 3 | SUBDIRS=examples 4 | 5 | WFLAGS_BASE=-Wall -Wextra -Wmissing-field-initializers -Wunused-parameter \ 6 | -Wold-style-definition -Wmissing-declarations -Wmissing-prototypes \ 7 | -Wredundant-decls -Wmissing-noreturn -Wshadow -Wpointer-arith \ 8 | -Wwrite-strings -Winline -Wformat-nonliteral -Wformat-security \ 9 | -Wswitch-default -Winit-self -Wnested-externs -Wstrict-prototypes \ 10 | -Wmissing-include-dirs -Wundef -Wmissing-format-attribute 11 | ifeq ($(CI),1) 12 | WFLAGS=-Werror $(WFLAGS_BASE) 13 | else 14 | WFLAGS=$(WFLAGS_BASE) 15 | endif 16 | 17 | WFLAGS2=-Wswitch-enum -Wswitch -Waggregate-return 18 | 19 | CFLAGS=-g -std=gnu99 -Iinclude -Iinclude/priv -fPIC $(WFLAGS) 20 | LDFLAGS=-g 21 | 22 | # always compile examples and DBrew snippets with optimizations 23 | # this allows other DBrew code to still be debuggable 24 | OPTFLAGS=-O2 -mavx 25 | 26 | ## flags dependent on compiler 27 | CCNAME:=$(strip $(shell $(CC) --version | head -c 3)) 28 | ifeq ($(CCNAME),$(filter $(CCNAME),gcc cc icc)) 29 | # gcc/cc 30 | $(info ** gcc compatible compiler detected: $(CC)) 31 | 32 | # some snippets 'switch' to AVX mode. hack to avoid 32-byte stack alignment 33 | # FIXME: rewriter should move such stack alignment to outermost level 34 | # clang does not know these options 35 | SNIPPETSFLAGS=$(OPTFLAGS) -mno-vzeroupper -mpreferred-stack-boundary=5 36 | 37 | else ifeq ($(shell $(CC) -v 2>&1 | egrep -c "(clang version|Apple LLVM version)"), 1) 38 | # clang 39 | $(info ** clang detected: $(CC)) 40 | CFLAGS += -fno-pie 41 | SNIPPETSFLAGS=$(OPTFLAGS) 42 | else 43 | $(error Compiler $(CC) not supported) 44 | endif 45 | 46 | SRCS = $(wildcard src/*.c) 47 | HEADERS = $(wildcard include/*.h) 48 | OBJS = $(SRCS:.c=.o) 49 | DEPS = $(SRCS:.c=.d) 50 | 51 | # instruct GCC to produce dependency files 52 | CFLAGS += -MMD -MP 53 | 54 | 55 | # Build targets 56 | 57 | SUBDIRS_BUILD=$(addprefix build_, $(SUBDIRS)) 58 | .PHONY: $(SUBDIRS_BUILD) 59 | 60 | all: libdbrew.a $(SUBDIRS_BUILD) 61 | 62 | libdbrew.a: $(OBJS) $(HEADERS) 63 | ar rcs libdbrew.a $(OBJS) 64 | 65 | $(SUBDIRS_BUILD): build_%: libdbrew.a 66 | +$(MAKE) -C $* 67 | 68 | src/snippets.o: src/snippets.c 69 | $(CC) $(CFLAGS) $(SNIPPETSFLAGS) -c $< -o $@ 70 | 71 | 72 | ## Clean targets 73 | 74 | SUBDIRS_CLEAN=$(addprefix clean_, $(SUBDIRS)) 75 | .PHONY: $(SUBDIRS_CLEAN) 76 | 77 | clean: clean_dbrew $(SUBDIRS_CLEAN) 78 | 79 | clean_dbrew: 80 | rm -f *~ *.o $(OBJS) $(DEPS) libdbrew.a 81 | +$(MAKE) clean -C tests 82 | 83 | $(SUBDIRS_CLEAN): clean_%: 84 | +$(MAKE) clean -C $* 85 | 86 | 87 | ## Test targets 88 | 89 | SUBDIRS_TEST=$(addprefix test_, $(SUBDIRS)) 90 | .PHONY: $(SUBDIRS_TEST) 91 | 92 | test: libdbrew.a test_dbrew $(SUBDIRS_TEST) 93 | 94 | test_dbrew: libdbrew.a 95 | cd tests && ./test.py 96 | 97 | $(SUBDIRS_TEST): test_%: build_% 98 | +$(MAKE) test -C $* 99 | 100 | 101 | # include previously generated dependency rules if existing 102 | -include $(DEPS) 103 | 104 | tidy: compile_commands.json 105 | git ls-files '*.c' | xargs -P 1 -I{} clang-tidy -header-filter=.* -p . {}; fi 106 | 107 | compile_commands.json: 108 | bear make 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DBrew - a Library for Dynamic Binary Rewriting 2 | 3 | [![Build Status](https://travis-ci.org/caps-tum/dbrew.svg?branch=master)](https://travis-ci.org/caps-tum/dbrew) 4 | 5 | --- 6 | 7 | **REMARK:** This repository no longer contains an LLVM-based binary optimizer, which has been moved [here](https://github.com/aengelke/binopt). The name DBrew only refers to the tracing binary rewriter. 8 | 9 | --- 10 | 11 | This library allows application-controlled, explicit rewriting of functions 12 | at runtime on the binary level. The rewritten functions can be used instead 13 | of the original functions as drop-in replacements as they use the exact same 14 | function signature. 15 | 16 | Warning: DBrew is in a very early state with lots of features missing. 17 | 18 | 19 | ## Why is this useful? 20 | 21 | Performance improvement 22 | * specialization: if function parameters are known at runtime 23 | * optimization of common case by reordering and inline, e.g. when 24 | profiling/usage data is available 25 | 26 | Change functionality 27 | * redirect function calls, memory accesses 28 | * replace instructions 29 | * insert instrumentation for profiling 30 | 31 | 32 | # API 33 | 34 | DBrew provides best-effort and robustness. The API is designed in a way 35 | that rewriting may fail; however, it always can return the original 36 | function as fall-back. Thus, there is no need to strive for complete 37 | coverage of binary code. 38 | 39 | Rewriting configurations heavily rely on the C calling convention / ABI 40 | (Application Binary Interface) of the target architecture. This way, 41 | DBrew supports rewriting of compiled code from most languages (C, C++, ...) 42 | and makes the DBrew API itself architecture independent. 43 | 44 | 45 | 46 | ## Supported Architectures 47 | 48 | For now just one: 49 | * amd64 (that is, 64bit x86) 50 | 51 | 52 | ## Example 53 | 54 | To generate a spezialised version of strcmp which only can compare a given 55 | string with a fixed string, which should be faster than the generic strcmp: 56 | 57 | strcmpHW = dbrew_rewrite(strcmp, str, "Hello World!"); 58 | 59 | Use the returned function pointer to run the generated special comparison. 60 | The second parameter actually is not used in the rewritten code. However, 61 | if rewriting failed for whatever reason, the original strcmp may be returned 62 | (depending on configuration). So, it is better to use valid parameters. 63 | 64 | FIXME: This short example currently does not work because DBrew does not yet 65 | (1) catch/ignore the dynamic-linker part of 1st-time invocations of shared 66 | library functions and (2) specialize on (mixed) knowledge (known/unknown) about 67 | SSE/AVX registers contents, which the strcmp version in your glibc may use. 68 | 69 | 70 | ## Publications 71 | 72 | * Josef Weidendorfer and Jens Breitbart. The Case for Binary Rewriting at Runtime for Efficient Implementation of High-Level Programming Models in HPC. In *Proceedings of the 21st int. Workshop on High-Level Parallel Programming Models and Supportive Environments (HIPS 2016)*. Chicago, US, 2016. ([PDF of pre-print version](https://github.com/lrr-tum/dbrew/raw/master/docs/pubs/preprint-hips16.pdf)) 73 | 74 | * Alexis Engelke and Josef Weidendorfer. Using LLVM for Optimized Light-Weight Binary Re-Writing at Runtime. In Proceedings of the 22st int. Workshop on High-Level Parallel Programming Models and Supportive Environments (HIPS 2017). Orlando, US, 2017 ([PDF of pre-print version](http://wwwi10.lrr.in.tum.de/~weidendo/pubs/hips17.pdf)) *Note: the LLVM-based binary rewriter has been moved [here](https://github.com/aengelke/binopt).* 75 | 76 | ## License 77 | 78 | LGPLv2.1+ 79 | 80 | 81 | ## Remarks for Development 82 | 83 | * All features should have a test case, see tests/ subdirectory. Running the tests is done with "make test". Using travis on github, pushed commits automatically trigger compile and test. 84 | 85 | * Make heavy use of assertions. Any unsupported cases of partly implemented features should fail hard using "assert(0);", without trying to be smart on parsing input. 86 | 87 | * C is tricky. For better quality, (1) compilations fail on warnings, with a lot of warnings switched on, (2) travis compiles and runs the tests with a variety of compilers and compiler versions, and (3) use the linter "clang-tidy": "make tidy" 88 | -------------------------------------------------------------------------------- /dbrew.config: -------------------------------------------------------------------------------- 1 | // Add predefined macros for your project here. For example: 2 | // #define THE_ANSWER 42 3 | #define __AVX__ 4 | -------------------------------------------------------------------------------- /dbrew.creator: -------------------------------------------------------------------------------- 1 | [General] 2 | -------------------------------------------------------------------------------- /dbrew.files: -------------------------------------------------------------------------------- 1 | include/priv/buffers.h 2 | include/priv/common.h 3 | include/priv/decode.h 4 | include/priv/engine.h 5 | include/priv/emulate.h 6 | include/priv/expr.h 7 | include/priv/error.h 8 | include/priv/generate.h 9 | include/priv/instr.h 10 | include/priv/printer.h 11 | include/dbrew.h 12 | 13 | src/buffers.c 14 | src/dbrew.c 15 | src/decode.c 16 | src/emulate.c 17 | src/error.c 18 | src/expr.c 19 | src/generate.c 20 | src/instr.c 21 | src/printer.c 22 | src/engine.c 23 | src/config.c 24 | src/vector.c 25 | src/snippets.c 26 | 27 | deps/Makefile 28 | 29 | # test cases and expected files left out 30 | tests/README.md 31 | tests/TODO.md 32 | tests/Makefile 33 | tests/test-driver.c 34 | tests/test-driver-decode.c 35 | tests/test-driver-gen.c 36 | tests/test-driver-generate.c 37 | tests/op-tls.c 38 | tests/branchtest.c 39 | tests/test.c 40 | tests/test.py 41 | 42 | examples/stencil.c 43 | examples/simple.c 44 | examples/strcmp.c 45 | examples/matrix.c 46 | examples/vector.c 47 | examples/Makefile 48 | examples/.gitignore 49 | 50 | docs/README 51 | docs/TODO 52 | 53 | Makefile 54 | README.md 55 | .gitignore 56 | include/priv/vector.h 57 | -------------------------------------------------------------------------------- /dbrew.includes: -------------------------------------------------------------------------------- 1 | include 2 | include/priv 3 | src 4 | examples 5 | -------------------------------------------------------------------------------- /docs/C++.md: -------------------------------------------------------------------------------- 1 | The DBrew C API can be used from C++. 2 | However, there are some details to care about. 3 | 4 | We will provide a C++ API in the future. 5 | 6 | ## Reference Parameters 7 | 8 | Using C++ references as parameter type is not straight-forward, as the C API does not know about references. 9 | So, this does not work: 10 | 11 | ``` 12 | typedef int (*foo_t)(const int&, int); 13 | 14 | int foo(const int &i, int j) {...} 15 | 16 | foo_t f = (foo_t) dbrew_rewrite(r, 2, 3); 17 | ``` 18 | 19 | But you can cast dbrew_rewrite to the matching C++-signature. 20 | 21 | ``` 22 | typedef int64_t (*rewrite_foo_t)(Rewriter*, const int&, int); 23 | ... 24 | foo_t f = (foo_t) ((rewrite_foo_t)dbrew_rewrite)(r, 2, 3); 25 | ``` 26 | 27 | In binary code, C++ references are pointers. Now, if you mark 28 | a C++ reference as known, DBrew will interpret this as the 29 | corresponding pointer to be known. As the semantic of passing 30 | a pointer as known includes that all values reachable via that 31 | pointer also are handled as known, DBrew shows the expected 32 | behavior, i.e. the value behind the reference will be handled 33 | as known. 34 | -------------------------------------------------------------------------------- /docs/README: -------------------------------------------------------------------------------- 1 | This directory is for documenting the DBrew API 2 | (TODO: generate from source?) 3 | -------------------------------------------------------------------------------- /docs/TODO: -------------------------------------------------------------------------------- 1 | == Short-term TODOs 2 | 3 | Replace asserts with correct error handling for 4 | * decoder [done] 5 | * emulator 6 | * generator 7 | 8 | API: 9 | * rewriting function for arbitrary parameters 10 | 11 | Tests: 12 | * emulator 13 | * generator 14 | * [more details](../tests/TODO.md) 15 | 16 | Emulation 17 | * config to catch memory writes via hash table 18 | * config to error out on non-static branching 19 | * pure capturing (no need to emulate anything unknown) 20 | * track meta info for vector registers 21 | * callbacks during emulation 22 | * inlining of callbacks? 23 | 24 | Optimizations: 25 | * liveness analysis, remove unneeded instructions 26 | * register renaming, upgrade spilled stack-values into registers 27 | * vectorization? 28 | 29 | Multiple ISAs: 30 | * subdirs per ISA 31 | * simple one like RiscV ? 32 | -------------------------------------------------------------------------------- /docs/pubs/preprint-hips16.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caps-tum/dbrew/10a202f3f209d2f2ef5c08aba15d9b3e01b3a5ba/docs/pubs/preprint-hips16.pdf -------------------------------------------------------------------------------- /docs/related/Agner-CallingConventions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caps-tum/dbrew/10a202f3f209d2f2ef5c08aba15d9b3e01b3a5ba/docs/related/Agner-CallingConventions.pdf -------------------------------------------------------------------------------- /docs/related/README.md: -------------------------------------------------------------------------------- 1 | Currently PDFs around ABI specifications 2 | -------------------------------------------------------------------------------- /docs/related/SystemV-abi-amd64.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caps-tum/dbrew/10a202f3f209d2f2ef5c08aba15d9b3e01b3a5ba/docs/related/SystemV-abi-amd64.pdf -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | matrix 2 | stencil 3 | strcmp 4 | simple 5 | vector 6 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES = stencil matrix strcmp simple vector 2 | CPPFLAGS=-I../include 3 | #LDLIBS=-L.. -ldbrew # with libs, dependencies do not work 4 | 5 | # optimization flags should be the same as for DBrew snippets. 6 | # thus, the Makefile from the top directory overrides OPTS for this. 7 | # this is to avoid e.g. SSE/AVX transition penalties 8 | OPTS=-O2 -mavx 9 | CFLAGS=-std=gnu99 $(OPTS) 10 | 11 | ## no PIE: flags dependent on compiler/version 12 | CCNAME:=$(strip $(shell $(CC) --version | head -c 3)) 13 | ifeq ($(CCNAME),$(filter $(CCNAME),gcc cc icc)) 14 | $(info ** gcc compatible compiler detected: $(CC)) 15 | CFLAGS += -fno-pie 16 | ifeq ($(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 5),1) 17 | LDFLAGS += -no-pie 18 | endif 19 | else ifeq ($(shell $(CC) -v 2>&1 | egrep -c "(clang version|Apple LLVM version)"), 1) 20 | $(info ** clang detected: $(CC)) 21 | CFLAGS += -fno-pie 22 | else 23 | $(error Compiler $(CC) not supported) 24 | endif 25 | 26 | all: $(EXAMPLES) 27 | 28 | stencil: stencil.o ../libdbrew.a 29 | 30 | matrix: matrix.o ../libdbrew.a 31 | 32 | strcmp: strcmp.o ../libdbrew.a 33 | 34 | simple: simple.o ../libdbrew.a 35 | 36 | vector: vector.o ../libdbrew.a 37 | 38 | test: 39 | 40 | clean: 41 | rm -f *.o *~ $(EXAMPLES) 42 | -------------------------------------------------------------------------------- /examples/matrix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example for DBrew API 3 | * 4 | * Analysis of matrix multiplication kernel. 5 | */ 6 | 7 | #include 8 | #include 9 | #include "dbrew.h" 10 | 11 | typedef void (*mm_t)(int s, 12 | double a[][s], double b[][s], double c[][s], 13 | int i, int j, int k); 14 | 15 | void mm_kernel(int s, 16 | double a[][s], double b[][s], double c[][s], 17 | int i, int j, int k) 18 | { 19 | a[i][k] += b[i][j] * c[j][k]; 20 | } 21 | 22 | void init(int s, double m[][s], double v) 23 | { 24 | int i, j; 25 | 26 | for(i=0; i arg) && (argv[arg][0] == '-')) { 54 | if (argv[arg][1] == 'v') verbose++; 55 | if (argv[arg][2] == 'v') verbose++; 56 | arg++; 57 | } 58 | if (argc > arg) { s = atoi(argv[arg]); arg++; } 59 | if (s == 0) s = 102; 60 | 61 | a = (double*) malloc(sizeof(double) * s * s); 62 | b = (double*) malloc(sizeof(double) * s * s); 63 | c = (double*) malloc(sizeof(double) * s * s); 64 | 65 | init(s, (double(*)[s]) a, 0.0); 66 | init(s, (double(*)[s]) b, 2.0); 67 | init(s, (double(*)[s]) c, 3.0); 68 | 69 | for(i=0; i1) { 81 | dbrew_verbose(r, true, true, true); 82 | dbrew_optverbose(r, true); 83 | dbrew_config_function_setname(r, (uint64_t) mm_kernel, "mm"); 84 | } 85 | dbrew_set_function(r, (uint64_t) mm_kernel); 86 | dbrew_config_staticpar(r, 0); // size is constant 87 | dbrew_config_parcount(r, 7); 88 | mmf = (mm_t) dbrew_rewrite(r, s, a, b, c, 0, 0, 0); 89 | 90 | if (verbose > 0) { 91 | // use another rewriter to show generated code 92 | Rewriter* r2 = dbrew_new(); 93 | uint64_t genfunc = dbrew_generated_code(r); 94 | int gensize = dbrew_generated_size(r); 95 | dbrew_config_function_setname(r2, genfunc, "gmm"); 96 | dbrew_config_function_setsize(r2, genfunc, gensize); 97 | dbrew_decode_print(r2, genfunc, gensize); 98 | dbrew_free(r2); 99 | } 100 | 101 | init(s, (double(*)[s]) a, 0.0); 102 | for(i=0; i 8 | #include "dbrew.h" 9 | 10 | typedef int (*f_t)(char*); 11 | 12 | int isHello(char* s) 13 | { 14 | return strcmp(s, "Hello"); 15 | } 16 | 17 | int main(int argc, char* argv[]) 18 | { 19 | // force relocation of strcmp 20 | if (strcmp("Foo", argv[0])==0) return 0; 21 | 22 | dbrew_def_verbose(true, true, true); 23 | f_t f = (f_t) dbrew_rewrite_func((uint64_t) isHello, "Bla"); 24 | 25 | return f(argv[1]); 26 | } 27 | -------------------------------------------------------------------------------- /include/priv/buffers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #ifndef BUFFERS_H 21 | #define BUFFERS_H 22 | 23 | #include 24 | 25 | // XXX: Move Struct in C file after removing all direct dependencies! 26 | struct _CodeStorage { 27 | int size; 28 | int fullsize; /* rounded to multiple of a page size */ 29 | int used; 30 | uint8_t* buf; 31 | }; 32 | 33 | typedef struct _CodeStorage CodeStorage; 34 | 35 | CodeStorage* initCodeStorage(int size); 36 | void freeCodeStorage(CodeStorage* cs); 37 | 38 | /* this checks whether enough storage is available, but does 39 | * not change . 40 | */ 41 | uint8_t* reserveCodeStorage(CodeStorage* cs, int size); 42 | uint8_t* useCodeStorage(CodeStorage* cs, int size); 43 | 44 | #endif // BUFFERS_H 45 | -------------------------------------------------------------------------------- /include/priv/decode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #ifndef DECODE_H 21 | #define DECODE_H 22 | 23 | #include "common.h" 24 | 25 | #include 26 | 27 | typedef struct _DContext DContext; 28 | 29 | Instr* nextInstr(Rewriter* r, uint64_t a, int len); 30 | Instr* addSimple(Rewriter* r, DContext* c, InstrType it, ValType vt); 31 | Instr* addUnaryOp(Rewriter* r, DContext* c, InstrType it, Operand* o); 32 | 33 | Instr* addBinaryOp(Rewriter* r, DContext* c, 34 | InstrType it, ValType vt, Operand* o1, Operand* o2); 35 | 36 | Instr* addTernaryOp(Rewriter* r, DContext* c, 37 | InstrType it, ValType vt, 38 | Operand* o1, Operand* o2, Operand* o3); 39 | 40 | #endif // DECODE_H 41 | -------------------------------------------------------------------------------- /include/priv/emulate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #ifndef EMULATE_H 21 | #define EMULATE_H 22 | 23 | #include 24 | 25 | #include "common.h" 26 | #include "instr.h" 27 | #include "engine.h" 28 | #include "error.h" 29 | 30 | 31 | /*------------------------------------------------------------*/ 32 | /* x86_64 capturing emulator 33 | * trace execution in the emulator to capture code to generate 34 | * 35 | * We maintain states (known/static vs unknown/dynamic at capture time) 36 | * for registers and values on stack. To be able to do the latter, we 37 | * assume that the known values on stack do not get changed by 38 | * memory writes with dynamic address. This assumption should be fine, 39 | * as such behavior is dangerous and potentially a bug. 40 | * 41 | * At branches to multiple possible targets, we need to travers each path by 42 | * saving emulator state. After emulating one path, we roll back and 43 | * go the other path. As this may happen recursively, we do a kind of 44 | * back-tracking, with emulator states stored as stacks. 45 | * To allow for fast saving/restoring of emulator states, each part of 46 | * the emulation state (registers, bytes on stack) is given by a 47 | * EmuStateEntry (linked) list with the current value/state in front. 48 | * Saving copies the complete EmuState, inheriting the individual states. 49 | */ 50 | 51 | // exported functions 52 | 53 | // get a new emulator state with stack size 54 | EmuState* allocEmuState(int size); 55 | void freeEmuState(Rewriter* r); 56 | void resetEmuState(EmuState* es); 57 | // save current emulator state for later rollback, return ID 58 | int saveEmuState(RContext *c); 59 | // set current emulator state to previously saved state 60 | void restoreEmuState(Rewriter* r, int esID); 61 | void printEmuState(EmuState* es); 62 | void printStaticEmuState(EmuState* es, int esID); 63 | 64 | void resetCapturing(Rewriter* r); 65 | CBB* getCaptureBB(RContext* c, uint64_t f, int esID); 66 | int pushCaptureBB(RContext *c, CBB* bb); 67 | CBB* popCaptureBB(Rewriter* r); 68 | Instr* newCapInstr(RContext *c); 69 | void capture(RContext* c, Instr* instr); 70 | void captureRet(RContext* c, Instr* orig, EmuState* es); 71 | 72 | // clone a decoded BB as a CBB 73 | CBB* createCBBfromDBB(Rewriter* r, DBB* src); 74 | 75 | // emulate a given instruction in a given emulation state (in RContext). 76 | // Capture it if not static. Set exit variable in RContext on jump. 77 | // Returns 0 if no error, otherwise pointer to Error struct 78 | void processInstr(RContext*, Instr *instr); 79 | 80 | // process call or jump to known location 81 | uint64_t processKnownTargets(RContext* c, uint64_t f); 82 | 83 | #endif // EMULATE_H 84 | -------------------------------------------------------------------------------- /include/priv/engine.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #ifndef ENGINE_H 21 | #define ENGINE_H 22 | 23 | #include "common.h" 24 | #include "error.h" 25 | 26 | #include 27 | #include 28 | 29 | // rewriter context 30 | typedef struct _RContext RContext; 31 | struct _RContext 32 | { 33 | Rewriter* r; 34 | uint64_t exit; 35 | Error* e; 36 | }; 37 | 38 | Rewriter* allocRewriter(void); 39 | void initRewriter(Rewriter* r); 40 | void freeRewriter(Rewriter* r); 41 | 42 | // Rewrite engine 43 | Error* vEmulateAndCapture(Rewriter* r, va_list args); 44 | void runOptsOnCaptured(RContext *c); 45 | void generateBinaryFromCaptured(RContext* c); 46 | 47 | #endif // ENGINE_H 48 | -------------------------------------------------------------------------------- /include/priv/error.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | /** 21 | * Error processing in DBrew 22 | * 23 | * At any step, there may be a (recoverable) error situation 24 | * Any such situation is passed to callers using the defined Error struct 25 | */ 26 | 27 | #ifndef ERROR_H 28 | #define ERROR_H 29 | 30 | #include "dbrew.h" 31 | 32 | typedef struct _Error Error; 33 | typedef struct _DecodeError DecodeError; 34 | typedef struct _GenerateError GenerateError; 35 | typedef struct _RewriteError RewriteError; 36 | typedef struct _EmulationError EmulationError; 37 | 38 | typedef enum _ErrorModule { 39 | EM_Unknown, 40 | EM_Decoder, EM_Emulator, EM_Generator, EM_Capture, EM_Rewriter, 41 | EM_Max 42 | } ErrorModule; 43 | 44 | typedef enum _ErrorType { 45 | ET_NoError, 46 | ET_Unknown, 47 | ET_InvalidRequest, // Rewriter 48 | ET_BufferOverflow, // Decoder, Generator, Rewriter 49 | ET_UnsupportedInstr, ET_UnsupportedOperands, // Generator, Emulator 50 | // Decoder 51 | ET_BadPrefix, ET_BadOpcode, ET_BadOperands, 52 | // 53 | ET_Max 54 | } ErrorType; 55 | 56 | struct _Error { 57 | ErrorModule em; 58 | ErrorType et; 59 | Rewriter* r; 60 | 61 | const char* desc; // textual description 62 | }; 63 | 64 | void setErrorNone(Error* e); 65 | bool isErrorSet(Error*); 66 | void initError(Error* e); 67 | void setError(Error* e, ErrorType et, ErrorModule em, Rewriter* r, const char *d); 68 | const char* errorString(Error*); 69 | // add error to some log, with further description (e.g. recover action) 70 | // currently just to stderror 71 | void logError(Error* e, char* d); 72 | 73 | 74 | // extensions with more context info 75 | 76 | struct _DecodeError { 77 | Error e; // must be first 78 | 79 | // additional context 80 | DBB* dbb; 81 | int offset; 82 | }; 83 | 84 | void setDecodeError(DecodeError* de, Rewriter* r, char* d, 85 | ErrorType et, DBB* dbb, int off); 86 | const char* decodeErrorContext(Error*); // used by errorString() 87 | 88 | 89 | struct _GenerateError { 90 | Error e; // must be first 91 | 92 | // additional context 93 | CBB* cbb; 94 | int offset; 95 | }; 96 | 97 | void setGenerateError(GenerateError* ge, Rewriter* r, char* d, 98 | ErrorType et, CBB* cbb, int off); 99 | const char* generateErrorContext(Error*); // used by errorString() 100 | 101 | 102 | #endif // ERROR_H 103 | -------------------------------------------------------------------------------- /include/priv/expr.h: -------------------------------------------------------------------------------- 1 | /* Expression tree for analyzed information, 2 | * helps also with various optimizations. 3 | * 4 | * Examples for analying memory accesses: 5 | * - with "double a[50][50]": 6 | * for "a[i+1][j+1]" we see "a + 400*i + 8*j + 408" 7 | * with i par1, j par2: 8 | * Ref(a, Sum(Scaled(400, Par(1)), Sum(Scaled(8, Par(2)), Const(408))) 9 | * 10 | * If element/dimension sizes known, reconstruction is possible 11 | */ 12 | 13 | #ifndef EXPR_H 14 | #define EXPR_H 15 | 16 | #include 17 | 18 | typedef enum _NodeType { 19 | NT_Invalid, NT_Const, NT_Sum, NT_Scaled, NT_Par, NT_Ref 20 | } NodeType; 21 | 22 | typedef struct _ExprNode ExprNode; 23 | typedef struct _ExprPool ExprPool; 24 | 25 | #define EN_NAMELEN 8 26 | struct _ExprNode { 27 | ExprPool* p; 28 | NodeType type; 29 | 30 | int ival; // Const, Scaled: scaling factor, FuncPar: par no 31 | uint64_t ptr; // Ref: base pointer 32 | int left; // Sum: Op1, Ref: index 33 | int right; // Sum: Op2 34 | char name[EN_NAMELEN]; // Par: parameter name, Ref: array name 35 | }; 36 | 37 | struct _ExprPool { 38 | int size; 39 | int used; 40 | ExprNode n[1]; 41 | }; 42 | 43 | ExprPool* expr_allocPool(int s); 44 | void expr_freePool(ExprPool* p); 45 | ExprNode* expr_newNode(ExprPool* p, NodeType t); 46 | int expr_nodeIndex(ExprPool* p, ExprNode* n); 47 | 48 | ExprNode* expr_newConst(ExprPool* p, int val); 49 | ExprNode* expr_newPar(ExprPool* p, int no, char* n); 50 | ExprNode* expr_newScaled(ExprPool* p, int factor, ExprNode* e); 51 | ExprNode* expr_newRef(ExprPool* p, uint64_t ptr, char* n, ExprNode* idx); 52 | ExprNode* expr_newSum(ExprPool* p, ExprNode* left, ExprNode* right); 53 | 54 | char* expr_toString(ExprNode* e); 55 | 56 | 57 | #endif // EXPR_H 58 | 59 | -------------------------------------------------------------------------------- /include/priv/generate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #ifndef GENERATE_H 21 | #define GENERATE_H 22 | 23 | #include "common.h" 24 | #include "error.h" 25 | 26 | typedef struct _GContext GContext; 27 | 28 | // generate code for a captured BB 29 | // returns 0 on success 30 | GenerateError* generate(Rewriter* r, CBB* cbb); 31 | 32 | #endif // GENERATE_H 33 | -------------------------------------------------------------------------------- /include/priv/printer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #ifndef PRINTER_H 21 | #define PRINTER_H 22 | 23 | #include "common.h" 24 | 25 | const char* regNameI(RegType rt, RegIndex ri); 26 | const char* regName(Reg r); 27 | char* op2string(Operand* o, Instr* instr, FunctionConfig *fc); 28 | const char* instrName(InstrType it, int* pOpCount); 29 | char* instr2string(Instr* instr, int align, FunctionConfig *fc); 30 | char* bytes2string(Instr* instr, int start, int count); 31 | char* prettyAddress(uint64_t a, FunctionConfig* fc); 32 | void printDecodedBBs(Rewriter* r); 33 | 34 | #endif // PRINTER_H 35 | -------------------------------------------------------------------------------- /include/priv/vector.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #include "common.h" 21 | #include "engine.h" 22 | 23 | #include 24 | 25 | uint64_t handleVectorCall(Rewriter *r, uint64_t f, EmuState* es); 26 | void runVectorization(RContext* c); 27 | 28 | int maxVectorBytes(void); 29 | uint64_t expandedVectorVariant(uint64_t f, int s, VectorizeReq* vr); 30 | 31 | // replacement functions 32 | 33 | // for dbrew_apply4_R8V8 34 | void apply4_R8V8_X2(uint64_t f, double* ov, double* iv); 35 | void apply4_R8V8_X4(uint64_t f, double* ov, double* iv); 36 | 37 | // for dbrew_apply4_R8V8V8 38 | void apply4_R8V8V8_X2(uint64_t f, double* ov, double* i1v, double* i2v); 39 | void apply4_R8V8V8_X4(uint64_t f, double* ov, double* i1v, double* i2v); 40 | 41 | // for dbrew_apply4_R8P8 42 | void apply4_R8P8_X2(uint64_t f, double* ov, double* iv); 43 | void apply4_R8P8_X4(uint64_t f, double* ov, double* iv); 44 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('libdbrew', ['c', 'cpp'], default_options: ['buildtype=debugoptimized', 'warning_level=3', 'c_std=gnu99', 'cpp_std=c++17']) 2 | 3 | if get_option('warning_level').to_int() >= 3 4 | add_project_arguments(['-Wmissing-field-initializers', 5 | '-Wunused-parameter', 6 | '-Wold-style-definition', 7 | '-Wmissing-declarations', 8 | '-Wmissing-prototypes', 9 | '-Wredundant-decls', 10 | '-Wmissing-noreturn', 11 | '-Wshadow', 12 | '-Wpointer-arith', 13 | '-Wwrite-strings', 14 | '-Winline', 15 | '-Wformat-nonliteral', 16 | '-Wformat-security', 17 | '-Wswitch-default', 18 | '-Winit-self', 19 | '-Wnested-externs', 20 | '-Wstrict-prototypes', 21 | '-Wmissing-include-dirs', 22 | '-Wundef', 23 | '-Wmissing-format-attribute' 24 | ], language: 'c') 25 | endif 26 | 27 | add_project_arguments(['-Wno-unused-parameter'], language: 'cpp') 28 | 29 | subdir('src') 30 | dbrew = declare_dependency(include_directories: include_directories('include'), 31 | link_with: libdbrew) 32 | dbrew_priv = declare_dependency(include_directories: dbrew_includes, 33 | link_with: libdbrew) 34 | 35 | install_headers('include/dbrew.h') 36 | -------------------------------------------------------------------------------- /src/buffers.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of DBrew, the dynamic binary rewriting library. 3 | * 4 | * (c) 2015-2016, Josef Weidendorfer 5 | * 6 | * DBrew is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License (LGPL) 8 | * as published by the Free Software Foundation, either version 2.1 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * DBrew is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with DBrew. If not, see . 18 | */ 19 | 20 | #define _DEFAULT_SOURCE 21 | 22 | #include "buffers.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | 31 | CodeStorage* initCodeStorage(int size) 32 | { 33 | int fullsize; 34 | uint8_t* buf; 35 | CodeStorage* cs; 36 | 37 | /* round up size to multiple of a page size */ 38 | fullsize = (size + 4095) & ~4095; 39 | 40 | /* We do not want to use malloc as we need execute permission. 41 | * This will return an address aligned to a page boundary 42 | */ 43 | buf = (uint8_t*) mmap(0, fullsize, 44 | PROT_READ | PROT_WRITE | PROT_EXEC, 45 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 46 | if (buf == (uint8_t*)-1) { 47 | perror("Can not mmap code region."); 48 | exit(1); 49 | } 50 | 51 | cs = (CodeStorage*) malloc(sizeof(CodeStorage)); 52 | cs->size = size; 53 | cs->fullsize = fullsize; 54 | cs->buf = buf; 55 | cs->used = 0; 56 | 57 | //fprintf(stderr, "Allocated Code Storage (size %d)\n", fullsize); 58 | 59 | return cs; 60 | } 61 | 62 | void freeCodeStorage(CodeStorage* cs) 63 | { 64 | if (cs) 65 | munmap(cs->buf, cs->fullsize); 66 | free(cs); 67 | } 68 | 69 | /* this checks whether enough storage is available, but does 70 | * not change . 71 | */ 72 | uint8_t* reserveCodeStorage(CodeStorage* cs, int size) 73 | { 74 | if (cs->fullsize - cs->used < size) { 75 | fprintf(stderr, 76 | "Error: CodeStorage (size %d) too small: used %d, need %d\n", 77 | cs->fullsize, cs->used, size); 78 | exit(1); 79 | } 80 | return cs->buf + cs->used; 81 | } 82 | 83 | uint8_t* useCodeStorage(CodeStorage* cs, int size) 84 | { 85 | uint8_t* p = cs->buf + cs->used; 86 | assert(cs->fullsize - cs->used >= size); 87 | cs->used += size; 88 | return p; 89 | } 90 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | sources = [ 2 | 'buffers.c', 3 | 'config.c', 4 | 'dbrew.c', 5 | 'decode.c', 6 | 'emulate.c', 7 | 'engine.c', 8 | 'error.c', 9 | 'expr.c', 10 | 'generate.c', 11 | 'instr.c', 12 | 'printer.c', 13 | 'snippets.c', 14 | 'vector.c', 15 | ] 16 | 17 | dbrew_includes = include_directories('../include', '../include/priv') 18 | 19 | libdbrew = static_library('dbrew', sources, include_directories: dbrew_includes, install: true) 20 | 21 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | # can be overwritten 2 | CC=gcc 3 | 4 | .PHONY: all test store clean 5 | 6 | all: test 7 | 8 | test: 9 | CC=$(CC) ./test.py 10 | 11 | store: 12 | ./test.py --store 13 | 14 | clean: 15 | rm -f *.o cases/*/*.o cases/*/*.out *~ 16 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # DBrew Test Framework 2 | 3 | Testing is done by running the Python script `test.py`. If no specific test 4 | cases are specified as parameters, the script iterates over all tests in 5 | subdirectory `cases/` and prints for each test case the result, as well as a 6 | summary. The script returns 0 back to the shell if all tests pass, and 1 7 | otherwise. From the top source directory, you can do "make test" to run all 8 | tests. 9 | 10 | To run specific test cases, specify them on the command line. Providing 11 | directories will run all tests within these directories. Thus, assuming 12 | that the directory `cases/integration/` exists, 13 | 14 | ./test.py cases/decode/it-add.s cases/integration 15 | 16 | will run the test `cases/decode/it-add.s` and all tests below directory 17 | `cases/integration/`. 18 | 19 | Running a test will force the compilation of the test. 20 | Use "-v" for more verbose output on the test runs, such as printing 21 | the compile command. See below for further command line options. 22 | 23 | ## Specification of a Test Case 24 | 25 | A test case (denoted by $testcase in the following) is the name of a source 26 | file, ending in `.c`, `.s` or `.S`, for example `cases/decode/it-add.s`. 27 | However, such a file often will not be the complete source for a test, see 28 | *driver* configuration below. 29 | 30 | The test source will be compiled and linked with DBrew, and the stdout/stderr 31 | output of a run will be compared with the files $testcase.expect and 32 | $testcase.expect_stderr, respectively. If any file with expected output does 33 | not exist, the output will be ignored as being irrelevant for the test result. 34 | Before comparison, output will be passed through a filter script given as 35 | $testcase.expect_filter (or $testcase.expect_stderr_filter) if present. This 36 | allows to suppress variable parts of test outputs before comparing (e.g. 37 | absolute addresses). 38 | 39 | ### Test Case Configuration Options 40 | 41 | Specific test case configuration can be provided in the first lines of a test 42 | source using line comments starting with "//!config=value". The following 43 | configurations are supported (the 'config' string in comment): 44 | 45 | * "driver": a C source file relative to tests/ directory, to include in the 46 | compilation of this test case. Allows for small test files by splitting off 47 | same source parts of test sources (e.g. a main() function) 48 | * "cc": overrides the compiler to use. For .s/.c files, this defaults to 49 | "as"/$CC, respectively (if environment variable CC is not set, to "cc") 50 | * "ccflags": override compile flags to use, defaults to "-std=c99 -g" 51 | * "args": command line options to use when running the test. Default is empty 52 | 53 | To see if configuration options are applied correctly for a test case, use 54 | 55 | ./test.py -v $testcase 56 | 57 | ## Test Script Command Line Options 58 | 59 | * `--verbose`, `-v`: Show compile and run commands used for tests 60 | * `--debug`, `-d`: Pass `--debug` at the end of the arguments for the test 61 | script 62 | * `--run`, `-r`: Run the specified test cases only and print the output to the 63 | terminal 64 | - `--store`, `-s`: Store the standard output of a test in the corresponding 65 | expect file. This can be used when the expect file does not exist yet. 66 | However, this can be also used to update existing expect files. 67 | **Warning: verify the differences to the previous results twice!** 68 | -------------------------------------------------------------------------------- /tests/TODO.md: -------------------------------------------------------------------------------- 1 | TOOD 2 | 3 | * make tests out of examples 4 | * thread-local-storage: make op-tls.c into test 5 | 6 | Missing decode tests 7 | * IP-relative addressing 8 | 9 | Known Bugs 10 | * idiv: with "/ 1", rdx gets not set to constant 0 11 | * cmov: not correct with constants as input and unknown condition 12 | * RIP-relative addressing of data may need constant pool (FIX?) 13 | * push/pop of constant values still needs to capture rsp changes 14 | 15 | -------------------------------------------------------------------------------- /tests/branchtest.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple x86_64 emulator/re-generator 3 | * (c) 2015, Josef Weidendorfer, GPLv2+ 4 | * 5 | * Test branching 6 | */ 7 | 8 | #include 9 | #include "dbrew.h" 10 | 11 | typedef int (*i2_func)(int,int); 12 | 13 | __attribute__ ((noinline)) 14 | int test1(int a, int b) 15 | { 16 | if (a == 1) return b; 17 | return 0; 18 | } 19 | 20 | __attribute__ ((noinline)) 21 | int test2(int a, int b) 22 | { 23 | while(a > 0) { b++; a--; } 24 | return b; 25 | } 26 | 27 | __attribute__ ((noinline)) 28 | int test3(int a, int b) 29 | { 30 | int c = a; 31 | while(a > 0) { 32 | while(b > 0) { 33 | c++; 34 | b--; 35 | } 36 | b = c; 37 | a--; 38 | } 39 | return c; 40 | } 41 | 42 | __attribute__ ((noinline)) 43 | int test4(int a, int b) 44 | { 45 | // printf("HELLO\n"); 46 | int i = makeDynamic(0); 47 | for(; i < a; i++) 48 | b += i; 49 | return b; 50 | } 51 | 52 | // decode captured code from c1 into c2 53 | void emulateCaptureRun(char* t1, char* t2, 54 | int p1, uint64_t p2, int sp1, uint64_t sp2, 55 | Rewriter* r1, Rewriter* r2) 56 | { 57 | int res; 58 | 59 | printf("Tracing emulation of %s(%d,%ld) %s:\n", t1, sp1, sp2, t2); 60 | res = (int)dbrew_emulate_capture(r1, sp1, sp2); 61 | printf("Result from emulation: %d\n", res); 62 | 63 | printf("Rewritten code (size %d bytes):\n", dbrew_generated_size(r1)); 64 | dbrew_set_function(r2, dbrew_generated_code(r1)); 65 | dbrew_decode_print(r2, dbrew_generated_code(r1), dbrew_generated_size(r1)); 66 | 67 | i2_func f = (i2_func) dbrew_generated_code(r1); 68 | res = f(p1,p2); 69 | 70 | printf("Run rewritten code %s(%d,%ld) = %d\n", t1, p1, p2, res); 71 | } 72 | 73 | 74 | /* 75 | * Test different specializations of a given fucntion . 76 | * must have signature i2_func (2 int parameters, returns int) 77 | * or i2p_func (int/pointer parameter, int return), given by 78 | */ 79 | void runTest(char* fname, uint64_t f, int p1, int p2, int sp1) 80 | { 81 | Rewriter *c1, *c2; 82 | int res; 83 | 84 | printf(">>> Testing with function %s\n\n", fname); 85 | 86 | c1 = dbrew_new(); 87 | dbrew_verbose(c1, true, true, true); 88 | c2 = dbrew_new(); 89 | 90 | i2_func ff = (i2_func) f; 91 | res = ff(p1, p2); 92 | printf("Run native: %s(%d,%d) = %d\n", fname, p1, p2, res); 93 | 94 | dbrew_set_function(c1, f); 95 | 96 | emulateCaptureRun(fname, "unmodified", p1, p2, sp1, p2, c1, c2); 97 | 98 | dbrew_config_reset(c1); 99 | dbrew_config_staticpar(c1, 0); 100 | emulateCaptureRun(fname, "p1 fix", p1, p2, sp1, p2, c1, c2); 101 | 102 | dbrew_free(c1); 103 | dbrew_free(c2); 104 | } 105 | 106 | 107 | int main() 108 | { 109 | //runTest("test1", (uint64_t) test1, 1,7, 2); 110 | //runTest("test2", (uint64_t) test2, 4,7, 3); 111 | //runTest("test3", (uint64_t) test3, 4,7, 3); 112 | runTest("test4", (uint64_t) test4, 4,7, 3); 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /tests/cases/decode/avx.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | vaddss xmm2, xmm0, xmm1 8 | vaddsd xmm2, xmm0, xmm1 9 | vaddps xmm2, xmm0, xmm1 10 | vaddpd xmm2, xmm0, xmm1 11 | vaddss xmm2, xmm0, [rax] 12 | vaddsd xmm2, xmm0, [rax] 13 | vaddps xmm2, xmm0, [rax] 14 | vaddpd xmm2, xmm0, [rax] 15 | 16 | vaddps ymm2, ymm0, ymm1 17 | vaddpd ymm2, ymm0, ymm1 18 | vaddps ymm2, ymm0, [rax] 19 | vaddpd ymm2, ymm0, [rax] 20 | 21 | vmulss xmm2, xmm0, xmm1 22 | vmulsd xmm2, xmm0, xmm1 23 | vmulps xmm2, xmm0, xmm1 24 | vmulpd xmm2, xmm0, xmm1 25 | vmulss xmm2, xmm0, [rax] 26 | vmulsd xmm2, xmm0, [rax] 27 | vmulps xmm2, xmm0, [rax] 28 | vmulpd xmm2, xmm0, [rax] 29 | 30 | vmulps ymm2, ymm0, ymm1 31 | vmulpd ymm2, ymm0, ymm1 32 | vmulps ymm2, ymm0, [rax] 33 | vmulpd ymm2, ymm0, [rax] 34 | 35 | vxorps xmm2, xmm0, xmm1 36 | vxorpd xmm2, xmm0, xmm1 37 | vxorps xmm2, xmm0, [rax] 38 | vxorpd xmm2, xmm0, [rax] 39 | vxorps ymm2, ymm0, ymm1 40 | vxorpd ymm2, ymm0, ymm1 41 | vxorps ymm2, ymm0, [rax] 42 | vxorpd ymm2, ymm0, [rax] 43 | 44 | vmovss xmm0, [rax] 45 | vmovsd xmm0, [rax] 46 | vmovaps xmm0, [rax] 47 | vmovapd xmm0, [rax] 48 | vmovups xmm0, [rax] 49 | vmovupd xmm0, [rax] 50 | vmovdqu xmm0, [rax] 51 | vmovdqa xmm0, [rax] 52 | vmovss [rax], xmm0 53 | vmovsd [rax], xmm0 54 | vmovaps [rax], xmm0 55 | vmovapd [rax], xmm0 56 | vmovups [rax], xmm0 57 | vmovupd [rax], xmm0 58 | vmovdqu [rax], xmm0 59 | vmovdqa [rax], xmm0 60 | 61 | vmovaps ymm0, [rax] 62 | vmovapd ymm0, [rax] 63 | vmovups ymm0, [rax] 64 | vmovupd ymm0, [rax] 65 | vmovdqu ymm0, [rax] 66 | vmovdqa ymm0, [rax] 67 | vmovaps [rax], ymm0 68 | vmovapd [rax], ymm0 69 | vmovups [rax], ymm0 70 | vmovupd [rax], ymm0 71 | vmovdqu [rax], ymm0 72 | vmovdqa [rax], ymm0 73 | 74 | vmovntdq [rax], xmm0 75 | vmovntdq [rax], ymm0 76 | 77 | ret 78 | -------------------------------------------------------------------------------- /tests/cases/decode/group-f7.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | not eax 8 | not rax 9 | not dword ptr [rdi] 10 | not qword ptr [rdi] 11 | 12 | neg eax 13 | neg rax 14 | neg dword ptr [rdi] 15 | neg qword ptr [rdi] 16 | 17 | mul eax 18 | mul rax 19 | mul dword ptr [rdi] 20 | mul qword ptr [rdi] 21 | 22 | imul eax 23 | imul rax 24 | imul dword ptr [rdi] 25 | imul qword ptr [rdi] 26 | 27 | div eax 28 | div rax 29 | div dword ptr [rdi] 30 | div qword ptr [rdi] 31 | 32 | idiv eax 33 | idiv rax 34 | idiv dword ptr [rdi] 35 | idiv qword ptr [rdi] 36 | 37 | ret 38 | 39 | -------------------------------------------------------------------------------- /tests/cases/decode/group-f7.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: f7 d0 not %eax 3 | f1+2: 48 f7 d0 not %rax 4 | f1+5: f7 17 notl (%rdi) 5 | f1+7: 48 f7 17 notq (%rdi) 6 | f1+10: f7 d8 neg %eax 7 | f1+12: 48 f7 d8 neg %rax 8 | f1+15: f7 1f negl (%rdi) 9 | f1+17: 48 f7 1f negq (%rdi) 10 | f1+20: f7 e0 mul %eax 11 | f1+22: 48 f7 e0 mul %rax 12 | f1+25: f7 27 mull (%rdi) 13 | f1+27: 48 f7 27 mulq (%rdi) 14 | f1+30: f7 e8 imul %eax 15 | f1+32: 48 f7 e8 imul %rax 16 | f1+35: f7 2f imull (%rdi) 17 | f1+37: 48 f7 2f imulq (%rdi) 18 | f1+40: f7 f0 div %eax 19 | f1+42: 48 f7 f0 div %rax 20 | f1+45: f7 37 divl (%rdi) 21 | f1+47: 48 f7 37 divq (%rdi) 22 | f1+50: f7 f8 idiv %eax 23 | f1+52: 48 f7 f8 idiv %rax 24 | f1+55: f7 3f idivl (%rdi) 25 | f1+57: 48 f7 3f idivq (%rdi) 26 | f1+60: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-adc.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // ADC instructions, Intel Vol. 2A 3-24 8 | adc [rdi], rax 9 | adc [rdi], r9 10 | adc [rdi], eax 11 | adc [rdi], r9d 12 | adc [rdi], ax 13 | adc [rdi], r9w 14 | adc [rdi], al 15 | adc [rdi], r9b 16 | adc rax, [rdi] 17 | adc r9, [rdi] 18 | adc eax, [rdi] 19 | adc r9d, [rdi] 20 | adc ax, [rdi] 21 | adc r9w, [rdi] 22 | adc al, [rdi] 23 | adc r9b, [rdi] 24 | adc al, 0x10 25 | adc ax, 0x1000 26 | adc eax, 0xabcdef00 27 | adc rax, 0x0bcdef00 28 | adc byte ptr [rax], 0x10 29 | adc word ptr [rax], 0x310 30 | adc dword ptr [rax], 0x310 31 | adc qword ptr [rax], 0x310 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tests/cases/decode/it-adc.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 11 07 adc %rax,(%rdi) 3 | f1+3: 4c 11 0f adc %r9,(%rdi) 4 | f1+6: 11 07 adc %eax,(%rdi) 5 | f1+8: 44 11 0f adc %r9d,(%rdi) 6 | f1+11: 66 11 07 adc %ax,(%rdi) 7 | f1+14: 66 44 11 0f adc %r9w,(%rdi) 8 | f1+18: 10 07 adc %al,(%rdi) 9 | f1+20: 44 10 0f adc %r9b,(%rdi) 10 | f1+23: 48 13 07 adc (%rdi),%rax 11 | f1+26: 4c 13 0f adc (%rdi),%r9 12 | f1+29: 13 07 adc (%rdi),%eax 13 | f1+31: 44 13 0f adc (%rdi),%r9d 14 | f1+34: 66 13 07 adc (%rdi),%ax 15 | f1+37: 66 44 13 0f adc (%rdi),%r9w 16 | f1+41: 12 07 adc (%rdi),%al 17 | f1+43: 44 12 0f adc (%rdi),%r9b 18 | f1+46: 14 10 adc $0x10,%al 19 | f1+48: 66 15 00 10 adc $0x1000,%ax 20 | f1+52: 15 00 ef cd ab adc $0xabcdef00,%eax 21 | f1+57: 48 15 00 ef cd 0b adc $0xbcdef00,%rax 22 | f1+63: 80 10 10 adcb $0x10,(%rax) 23 | f1+66: 66 81 10 10 03 adcw $0x310,(%rax) 24 | f1+71: 81 10 10 03 00 00 adcl $0x310,(%rax) 25 | f1+77: 48 81 10 10 03 00 00 adcq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-add-buferr.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode-buferr.c 2 | //!cc = gcc 3 | .intel_syntax noprefix 4 | .text 5 | .globl f1 6 | .type f1, @function 7 | f1: 8 | // ADD instructions, Intel Vol. 2A 3-29 9 | add [rdi], rax 10 | add [rdi], r9 11 | add [rdi], eax 12 | add [rdi], r9d 13 | add [rdi], ax 14 | add [rdi], r9w 15 | add [rdi], al 16 | add [rdi], r9b 17 | add rax, [rdi] 18 | add r9, [rdi] 19 | add eax, [rdi] 20 | add r9d, [rdi] 21 | add ax, [rdi] 22 | add r9w, [rdi] 23 | add al, [rdi] 24 | add r9b, [rdi] 25 | add al, 0x10 26 | add ax, 0x1000 27 | add ax, 0x10 28 | add eax, 0xabcdef00 29 | add eax, 0x10 30 | add rax, 0x0bcdef00 31 | add rax, 0x10 32 | add byte ptr [rax], 0x10 33 | add word ptr [rax], 0x310 34 | add dword ptr [rax], 0x310 35 | add qword ptr [rax], 0x310 36 | 37 | ret 38 | -------------------------------------------------------------------------------- /tests/cases/decode/it-add-buferr.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (1 instructions): 2 | f1: 48 01 07 add %rax,(%rdi) 3 | -------------------------------------------------------------------------------- /tests/cases/decode/it-add-buferr.s.expect_stderr: -------------------------------------------------------------------------------- 1 | Decoder error at decoding BB f1+6: decode buffer full (size: 1 instrs). Stopped decoding 2 | -------------------------------------------------------------------------------- /tests/cases/decode/it-add.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // ADD instructions, Intel Vol. 2A 3-29 8 | add [rdi], rax 9 | add [rdi], r9 10 | add [rdi], eax 11 | add [rdi], r9d 12 | add [rdi], ax 13 | add [rdi], r9w 14 | add [rdi], al 15 | add [rdi], r9b 16 | 17 | add rax, [rdi] 18 | add r9, [rdi] 19 | add eax, [rdi] 20 | add r9d, [rdi] 21 | add ax, [rdi] 22 | add r9w, [rdi] 23 | add al, [rdi] 24 | add r9b, [rdi] 25 | 26 | add al, 0x10 27 | add ax, 0x1000 28 | add ax, 0x10 29 | add eax, 0xabcdef00 30 | add eax, 0x10 31 | add rax, 0x0bcdef00 32 | add rax, 0x10 33 | 34 | add byte ptr [rax], 0x10 35 | add word ptr [rax], 0x310 36 | add dword ptr [rax], 0x310 37 | add qword ptr [rax], 0x310 38 | 39 | add al, r9b 40 | add r10b, bl 41 | add cl, dl 42 | add sil, dil 43 | add eax, r9d 44 | add r10d, ebx 45 | add rax, r9 46 | add r10, rbx 47 | 48 | add al, sil 49 | add sil, al 50 | add al, ah 51 | add ah, bl 52 | add bl, bh 53 | add cl, ch 54 | add dl, dh 55 | 56 | add bl, 0x10 57 | add bx, 0x1000 58 | add bx, 0x10 59 | add ebx, 0xabcdef00 60 | add ebx, 0x10 61 | add rbx, 0x0bcdef00 62 | add rbx, 0x10 63 | 64 | add r9b, 0x10 65 | add r9w, 0x1000 66 | add r9w, 0x10 67 | add r9d, 0xabcdef00 68 | add r9d, 0x10 69 | add r9, 0x0bcdef00 70 | add r9, 0x10 71 | 72 | ret 73 | -------------------------------------------------------------------------------- /tests/cases/decode/it-add.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (57 instructions): 2 | f1: 48 01 07 add %rax,(%rdi) 3 | f1+3: 4c 01 0f add %r9,(%rdi) 4 | f1+6: 01 07 add %eax,(%rdi) 5 | f1+8: 44 01 0f add %r9d,(%rdi) 6 | f1+11: 66 01 07 add %ax,(%rdi) 7 | f1+14: 66 44 01 0f add %r9w,(%rdi) 8 | f1+18: 00 07 add %al,(%rdi) 9 | f1+20: 44 00 0f add %r9b,(%rdi) 10 | f1+23: 48 03 07 add (%rdi),%rax 11 | f1+26: 4c 03 0f add (%rdi),%r9 12 | f1+29: 03 07 add (%rdi),%eax 13 | f1+31: 44 03 0f add (%rdi),%r9d 14 | f1+34: 66 03 07 add (%rdi),%ax 15 | f1+37: 66 44 03 0f add (%rdi),%r9w 16 | f1+41: 02 07 add (%rdi),%al 17 | f1+43: 44 02 0f add (%rdi),%r9b 18 | f1+46: 04 10 add $0x10,%al 19 | f1+48: 66 05 00 10 add $0x1000,%ax 20 | f1+52: 66 83 c0 10 add $0x10,%ax 21 | f1+56: 05 00 ef cd ab add $0xabcdef00,%eax 22 | f1+61: 83 c0 10 add $0x10,%eax 23 | f1+64: 48 05 00 ef cd 0b add $0xbcdef00,%rax 24 | f1+70: 48 83 c0 10 add $0x10,%rax 25 | f1+74: 80 00 10 addb $0x10,(%rax) 26 | f1+77: 66 81 00 10 03 addw $0x310,(%rax) 27 | f1+82: 81 00 10 03 00 00 addl $0x310,(%rax) 28 | f1+88: 48 81 00 10 03 00 00 addq $0x310,(%rax) 29 | f1+95: 44 00 c8 add %r9b,%al 30 | f1+98: 41 00 da add %bl,%r10b 31 | f1+101: 00 d1 add %dl,%cl 32 | f1+103: 40 00 fe add %dil,%sil 33 | f1+106: 44 01 c8 add %r9d,%eax 34 | f1+109: 41 01 da add %ebx,%r10d 35 | f1+112: 4c 01 c8 add %r9,%rax 36 | f1+115: 49 01 da add %rbx,%r10 37 | f1+118: 40 00 f0 add %sil,%al 38 | f1+121: 40 00 c6 add %al,%sil 39 | f1+124: 00 e0 add %ah,%al 40 | f1+126: 00 dc add %bl,%ah 41 | f1+128: 00 fb add %bh,%bl 42 | f1+130: 00 e9 add %ch,%cl 43 | f1+132: 00 f2 add %dh,%dl 44 | f1+134: 80 c3 10 add $0x10,%bl 45 | f1+137: 66 81 c3 00 10 add $0x1000,%bx 46 | f1+142: 66 83 c3 10 add $0x10,%bx 47 | f1+146: 81 c3 00 ef cd ab add $0xabcdef00,%ebx 48 | f1+152: 83 c3 10 add $0x10,%ebx 49 | f1+155: 48 81 c3 00 ef cd 0b add $0xbcdef00,%rbx 50 | f1+162: 48 83 c3 10 add $0x10,%rbx 51 | f1+166: 41 80 c1 10 add $0x10,%r9b 52 | f1+170: 66 41 81 c1 00 10 add $0x1000,%r9w 53 | f1+176: 66 41 83 c1 10 add $0x10,%r9w 54 | f1+181: 41 81 c1 00 ef cd ab add $0xabcdef00,%r9d 55 | f1+188: 41 83 c1 10 add $0x10,%r9d 56 | f1+192: 49 81 c1 00 ef cd 0b add $0xbcdef00,%r9 57 | f1+199: 49 83 c1 10 add $0x10,%r9 58 | f1+203: c3 ret 59 | -------------------------------------------------------------------------------- /tests/cases/decode/it-and-imm.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | and al, 4 8 | and ax, 4 9 | and ax, 400 10 | and eax, 4 11 | and eax, 400 12 | and eax, 400000 13 | and rax, 4 14 | and rax, 400 15 | and rax, 400000 16 | 17 | and al, -4 18 | and ax, -4 19 | and ax, -400 20 | and eax, -4 21 | and eax, -400 22 | and eax, -400000 23 | and rax, -4 24 | and rax, -400 25 | and rax, -400000 26 | ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-and-imm.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (19 instructions): 2 | f1: 24 04 and $0x4,%al 3 | f1+2: 66 83 e0 04 and $0x4,%ax 4 | f1+6: 66 25 90 01 and $0x190,%ax 5 | f1+10: 83 e0 04 and $0x4,%eax 6 | f1+13: 25 90 01 00 00 and $0x190,%eax 7 | f1+18: 25 80 1a 06 00 and $0x61a80,%eax 8 | f1+23: 48 83 e0 04 and $0x4,%rax 9 | f1+27: 48 25 90 01 00 00 and $0x190,%rax 10 | f1+33: 48 25 80 1a 06 00 and $0x61a80,%rax 11 | f1+39: 24 fc and $0xfc,%al 12 | f1+41: 66 83 e0 fc and $0xfffc,%ax 13 | f1+45: 66 25 70 fe and $0xfe70,%ax 14 | f1+49: 83 e0 fc and $0xfffffffc,%eax 15 | f1+52: 25 70 fe ff ff and $0xfffffe70,%eax 16 | f1+57: 25 80 e5 f9 ff and $0xfff9e580,%eax 17 | f1+62: 48 83 e0 fc and $0xfffffffffffffffc,%rax 18 | f1+66: 48 25 70 fe ff ff and $0xfffffffffffffe70,%rax 19 | f1+72: 48 25 80 e5 f9 ff and $0xfffffffffff9e580,%rax 20 | f1+78: c3 ret 21 | -------------------------------------------------------------------------------- /tests/cases/decode/it-and.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // AND instructions, Intel Vol. 2A 3-55 8 | and [rdi], rax 9 | and [rdi], r9 10 | and [rdi], eax 11 | and [rdi], r9d 12 | and [rdi], ax 13 | and [rdi], r9w 14 | and [rdi], al 15 | and [rdi], r9b 16 | and rax, [rdi] 17 | and r9, [rdi] 18 | and eax, [rdi] 19 | and r9d, [rdi] 20 | and ax, [rdi] 21 | and r9w, [rdi] 22 | and al, [rdi] 23 | and r9b, [rdi] 24 | and al, 0x10 25 | and ax, 0x1000 26 | and eax, 0xabcdef00 27 | and rax, 0x0bcdef00 28 | and byte ptr [rax], 0x10 29 | and word ptr [rax], 0x310 30 | and dword ptr [rax], 0x310 31 | and qword ptr [rax], 0x310 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tests/cases/decode/it-and.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 21 07 and %rax,(%rdi) 3 | f1+3: 4c 21 0f and %r9,(%rdi) 4 | f1+6: 21 07 and %eax,(%rdi) 5 | f1+8: 44 21 0f and %r9d,(%rdi) 6 | f1+11: 66 21 07 and %ax,(%rdi) 7 | f1+14: 66 44 21 0f and %r9w,(%rdi) 8 | f1+18: 20 07 and %al,(%rdi) 9 | f1+20: 44 20 0f and %r9b,(%rdi) 10 | f1+23: 48 23 07 and (%rdi),%rax 11 | f1+26: 4c 23 0f and (%rdi),%r9 12 | f1+29: 23 07 and (%rdi),%eax 13 | f1+31: 44 23 0f and (%rdi),%r9d 14 | f1+34: 66 23 07 and (%rdi),%ax 15 | f1+37: 66 44 23 0f and (%rdi),%r9w 16 | f1+41: 22 07 and (%rdi),%al 17 | f1+43: 44 22 0f and (%rdi),%r9b 18 | f1+46: 24 10 and $0x10,%al 19 | f1+48: 66 25 00 10 and $0x1000,%ax 20 | f1+52: 25 00 ef cd ab and $0xabcdef00,%eax 21 | f1+57: 48 25 00 ef cd 0b and $0xbcdef00,%rax 22 | f1+63: 80 20 10 andb $0x10,(%rax) 23 | f1+66: 66 81 20 10 03 andw $0x310,(%rax) 24 | f1+71: 81 20 10 03 00 00 andl $0x310,(%rax) 25 | f1+77: 48 81 20 10 03 00 00 andq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-bsf.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // BSF instruction 8 | bsf rax, [rdi] 9 | bsf r9, [rdi] 10 | bsf eax, [rdi] 11 | bsf r9d, [rdi] 12 | bsf ax, [rdi] 13 | bsf r9w, [rdi] 14 | 15 | ret 16 | -------------------------------------------------------------------------------- /tests/cases/decode/it-bsf.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (7 instructions): 2 | f1: 48 0f bc 07 bsf (%rdi),%rax 3 | f1+4: 4c 0f bc 0f bsf (%rdi),%r9 4 | f1+8: 0f bc 07 bsf (%rdi),%eax 5 | f1+11: 44 0f bc 0f bsf (%rdi),%r9d 6 | f1+15: 66 0f bc 07 bsf (%rdi),%ax 7 | f1+19: 66 44 0f bc 0f bsf (%rdi),%r9w 8 | f1+24: c3 ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/it-cltq.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov %edi,%eax 7 | cltq 8 | mov %rax,%rdx 9 | mov %si,%ax 10 | cwtl 11 | add %rdx,%rax 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/decode/it-cltq.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (7 instructions): 2 | f1: 89 f8 mov %edi,%eax 3 | f1+2: 48 98 cltq 4 | f1+4: 48 89 c2 mov %rax,%rdx 5 | f1+7: 66 89 f0 mov %si,%ax 6 | f1+10: 98 cwtl 7 | f1+11: 48 01 d0 add %rdx,%rax 8 | f1+14: c3 ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/it-cmovcc.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // CMOVcc instructions, Intel Vol. 2A 3-319 8 | cmovo ax, [rax] 9 | cmovo eax, [rax] 10 | cmovo rax, [rax] 11 | cmovno ax, [rax] 12 | cmovno eax, [rax] 13 | cmovno rax, [rax] 14 | cmovc ax, [rax] 15 | cmovc eax, [rax] 16 | cmovc rax, [rax] 17 | cmovnc ax, [rax] 18 | cmovnc eax, [rax] 19 | cmovnc rax, [rax] 20 | cmovz ax, [rax] 21 | cmovz eax, [rax] 22 | cmovz rax, [rax] 23 | cmovnz ax, [rax] 24 | cmovnz eax, [rax] 25 | cmovnz rax, [rax] 26 | cmovbe ax, [rax] 27 | cmovbe eax, [rax] 28 | cmovbe rax, [rax] 29 | cmovnbe ax, [rax] 30 | cmovnbe eax, [rax] 31 | cmovnbe rax, [rax] 32 | cmovs ax, [rax] 33 | cmovs eax, [rax] 34 | cmovs rax, [rax] 35 | cmovns ax, [rax] 36 | cmovns eax, [rax] 37 | cmovns rax, [rax] 38 | cmovp ax, [rax] 39 | cmovp eax, [rax] 40 | cmovp rax, [rax] 41 | cmovnp ax, [rax] 42 | cmovnp eax, [rax] 43 | cmovnp rax, [rax] 44 | cmovl ax, [rax] 45 | cmovl eax, [rax] 46 | cmovl rax, [rax] 47 | cmovnl ax, [rax] 48 | cmovnl eax, [rax] 49 | cmovnl rax, [rax] 50 | cmovle ax, [rax] 51 | cmovle eax, [rax] 52 | cmovle rax, [rax] 53 | cmovnle ax, [rax] 54 | cmovnle eax, [rax] 55 | cmovnle rax, [rax] 56 | 57 | ret 58 | -------------------------------------------------------------------------------- /tests/cases/decode/it-cmovcc.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (49 instructions): 2 | f1: 66 0f 40 00 cmovo (%rax),%ax 3 | f1+4: 0f 40 00 cmovo (%rax),%eax 4 | f1+7: 48 0f 40 00 cmovo (%rax),%rax 5 | f1+11: 66 0f 41 00 cmovno (%rax),%ax 6 | f1+15: 0f 41 00 cmovno (%rax),%eax 7 | f1+18: 48 0f 41 00 cmovno (%rax),%rax 8 | f1+22: 66 0f 42 00 cmovc (%rax),%ax 9 | f1+26: 0f 42 00 cmovc (%rax),%eax 10 | f1+29: 48 0f 42 00 cmovc (%rax),%rax 11 | f1+33: 66 0f 43 00 cmovnc (%rax),%ax 12 | f1+37: 0f 43 00 cmovnc (%rax),%eax 13 | f1+40: 48 0f 43 00 cmovnc (%rax),%rax 14 | f1+44: 66 0f 44 00 cmovz (%rax),%ax 15 | f1+48: 0f 44 00 cmovz (%rax),%eax 16 | f1+51: 48 0f 44 00 cmovz (%rax),%rax 17 | f1+55: 66 0f 45 00 cmovnz (%rax),%ax 18 | f1+59: 0f 45 00 cmovnz (%rax),%eax 19 | f1+62: 48 0f 45 00 cmovnz (%rax),%rax 20 | f1+66: 66 0f 46 00 cmovbe (%rax),%ax 21 | f1+70: 0f 46 00 cmovbe (%rax),%eax 22 | f1+73: 48 0f 46 00 cmovbe (%rax),%rax 23 | f1+77: 66 0f 47 00 cmova (%rax),%ax 24 | f1+81: 0f 47 00 cmova (%rax),%eax 25 | f1+84: 48 0f 47 00 cmova (%rax),%rax 26 | f1+88: 66 0f 48 00 cmovs (%rax),%ax 27 | f1+92: 0f 48 00 cmovs (%rax),%eax 28 | f1+95: 48 0f 48 00 cmovs (%rax),%rax 29 | f1+99: 66 0f 49 00 cmovns (%rax),%ax 30 | f1+103: 0f 49 00 cmovns (%rax),%eax 31 | f1+106: 48 0f 49 00 cmovns (%rax),%rax 32 | f1+110: 66 0f 4a 00 cmovp (%rax),%ax 33 | f1+114: 0f 4a 00 cmovp (%rax),%eax 34 | f1+117: 48 0f 4a 00 cmovp (%rax),%rax 35 | f1+121: 66 0f 4b 00 cmovnp (%rax),%ax 36 | f1+125: 0f 4b 00 cmovnp (%rax),%eax 37 | f1+128: 48 0f 4b 00 cmovnp (%rax),%rax 38 | f1+132: 66 0f 4c 00 cmovl (%rax),%ax 39 | f1+136: 0f 4c 00 cmovl (%rax),%eax 40 | f1+139: 48 0f 4c 00 cmovl (%rax),%rax 41 | f1+143: 66 0f 4d 00 cmovge (%rax),%ax 42 | f1+147: 0f 4d 00 cmovge (%rax),%eax 43 | f1+150: 48 0f 4d 00 cmovge (%rax),%rax 44 | f1+154: 66 0f 4e 00 cmovle (%rax),%ax 45 | f1+158: 0f 4e 00 cmovle (%rax),%eax 46 | f1+161: 48 0f 4e 00 cmovle (%rax),%rax 47 | f1+165: 66 0f 4f 00 cmovg (%rax),%ax 48 | f1+169: 0f 4f 00 cmovg (%rax),%eax 49 | f1+172: 48 0f 4f 00 cmovg (%rax),%rax 50 | f1+176: c3 ret 51 | -------------------------------------------------------------------------------- /tests/cases/decode/it-cmp.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // CMP instructions, Intel Vol. 2A 3-143 8 | cmp [rdi], rax 9 | cmp [rdi], r9 10 | cmp [rdi], eax 11 | cmp [rdi], r9d 12 | cmp [rdi], ax 13 | cmp [rdi], r9w 14 | cmp [rdi], al 15 | cmp [rdi], r9b 16 | cmp rax, [rdi] 17 | cmp r9, [rdi] 18 | cmp eax, [rdi] 19 | cmp r9d, [rdi] 20 | cmp ax, [rdi] 21 | cmp r9w, [rdi] 22 | cmp al, [rdi] 23 | cmp r9b, [rdi] 24 | cmp al, 0x10 25 | cmp ax, 0x1000 26 | cmp eax, 0xabcdef00 27 | cmp rax, 0x0bcdef00 28 | cmp byte ptr [rax], 0x10 29 | cmp word ptr [rax], 0x310 30 | cmp dword ptr [rax], 0x310 31 | cmp qword ptr [rax], 0x310 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tests/cases/decode/it-cmp.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 39 07 cmp %rax,(%rdi) 3 | f1+3: 4c 39 0f cmp %r9,(%rdi) 4 | f1+6: 39 07 cmp %eax,(%rdi) 5 | f1+8: 44 39 0f cmp %r9d,(%rdi) 6 | f1+11: 66 39 07 cmp %ax,(%rdi) 7 | f1+14: 66 44 39 0f cmp %r9w,(%rdi) 8 | f1+18: 38 07 cmp %al,(%rdi) 9 | f1+20: 44 38 0f cmp %r9b,(%rdi) 10 | f1+23: 48 3b 07 cmp (%rdi),%rax 11 | f1+26: 4c 3b 0f cmp (%rdi),%r9 12 | f1+29: 3b 07 cmp (%rdi),%eax 13 | f1+31: 44 3b 0f cmp (%rdi),%r9d 14 | f1+34: 66 3b 07 cmp (%rdi),%ax 15 | f1+37: 66 44 3b 0f cmp (%rdi),%r9w 16 | f1+41: 3a 07 cmp (%rdi),%al 17 | f1+43: 44 3a 0f cmp (%rdi),%r9b 18 | f1+46: 3c 10 cmp $0x10,%al 19 | f1+48: 66 3d 00 10 cmp $0x1000,%ax 20 | f1+52: 3d 00 ef cd ab cmp $0xabcdef00,%eax 21 | f1+57: 48 3d 00 ef cd 0b cmp $0xbcdef00,%rax 22 | f1+63: 80 38 10 cmpb $0x10,(%rax) 23 | f1+66: 66 81 38 10 03 cmpw $0x310,(%rax) 24 | f1+71: 81 38 10 03 00 00 cmpl $0x310,(%rax) 25 | f1+77: 48 81 38 10 03 00 00 cmpq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-inc-dec.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // INC instructions, Intel Vol. 2A 3-422 8 | inc byte ptr [rdx] 9 | inc al 10 | inc r11b 11 | inc word ptr [rdx] 12 | inc ax 13 | inc r11w 14 | inc dword ptr [rdx] 15 | inc eax 16 | inc r11d 17 | inc qword ptr [rdx] 18 | inc rax 19 | inc r11 20 | 21 | // DEC instructions, Intel Vol. 2A 3-258 22 | dec byte ptr [rdx] 23 | dec al 24 | dec r11b 25 | dec word ptr [rdx] 26 | dec ax 27 | dec r11w 28 | dec dword ptr [rdx] 29 | dec eax 30 | dec r11d 31 | dec qword ptr [rdx] 32 | dec rax 33 | dec r11 34 | 35 | ret 36 | -------------------------------------------------------------------------------- /tests/cases/decode/it-inc-dec.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: fe 02 incb (%rdx) 3 | f1+2: fe c0 inc %al 4 | f1+4: 41 fe c3 inc %r11b 5 | f1+7: 66 ff 02 incw (%rdx) 6 | f1+10: 66 ff c0 inc %ax 7 | f1+13: 66 41 ff c3 inc %r11w 8 | f1+17: ff 02 incl (%rdx) 9 | f1+19: ff c0 inc %eax 10 | f1+21: 41 ff c3 inc %r11d 11 | f1+24: 48 ff 02 incq (%rdx) 12 | f1+27: 48 ff c0 inc %rax 13 | f1+30: 49 ff c3 inc %r11 14 | f1+33: fe 0a decb (%rdx) 15 | f1+35: fe c8 dec %al 16 | f1+37: 41 fe cb dec %r11b 17 | f1+40: 66 ff 0a decw (%rdx) 18 | f1+43: 66 ff c8 dec %ax 19 | f1+46: 66 41 ff cb dec %r11w 20 | f1+50: ff 0a decl (%rdx) 21 | f1+52: ff c8 dec %eax 22 | f1+54: 41 ff cb dec %r11d 23 | f1+57: 48 ff 0a decq (%rdx) 24 | f1+60: 48 ff c8 dec %rax 25 | f1+63: 49 ff cb dec %r11 26 | f1+66: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-lea.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // LEA instructions, Intel Vol. 2A 3-480 8 | lea rax, [rdi] 9 | lea r9, [rdi] 10 | lea eax, [rdi] 11 | lea r9d, [rdi] 12 | lea ax, [rdi] 13 | lea r9w, [rdi] 14 | 15 | ret 16 | -------------------------------------------------------------------------------- /tests/cases/decode/it-lea.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (7 instructions): 2 | f1: 48 8d 07 lea (%rdi),%rax 3 | f1+3: 4c 8d 0f lea (%rdi),%r9 4 | f1+6: 8d 07 lea (%rdi),%eax 5 | f1+8: 44 8d 0f lea (%rdi),%r9d 6 | f1+11: 66 8d 07 lea (%rdi),%ax 7 | f1+14: 66 44 8d 0f lea (%rdi),%r9w 8 | f1+18: c3 ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/it-leave.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | //!cc = gcc 3 | .intel_syntax noprefix 4 | .text 5 | .globl f1 6 | .type f1, @function 7 | f1: 8 | // LEAVE instructions, Intel Vol. 2A 3-483 9 | leave 10 | // leavew // no need to implement 16-bit address-mode 11 | 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/decode/it-leave.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (2 instructions): 2 | f1: c9 leave 3 | f1+1: c3 ret 4 | -------------------------------------------------------------------------------- /tests/cases/decode/it-mov.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // MOV instructions, Intel Vol. 2A 3-530 8 | mov [rsi], dl 9 | mov [rsi], ah 10 | mov [rsi], r10b 11 | mov [rsi], dx 12 | mov [rsi], r10w 13 | mov [rsi], edx 14 | mov [rsi], r10d 15 | mov [rsi], rdx 16 | mov [rsi], r10 17 | mov dl, [rsi] 18 | mov ah, [rsi] 19 | mov r10b, [rsi] 20 | mov dx, [rsi] 21 | mov r10w, [rsi] 22 | mov edx, [rsi] 23 | mov r10d, [rsi] 24 | mov rdx, [rsi] 25 | mov r10, [rsi] 26 | 27 | mov dl, 0x10 28 | mov ah, 0x10 29 | mov r10b, 0x10 30 | mov dx, 0x1000 31 | mov r10w, 0x1000 32 | mov edx, 0x10000000 33 | mov r10d, 0x10000000 34 | movabs rdx, 0x1000000000000000 35 | movabs r10, 0x1000000000000000 36 | mov byte ptr [rdi], 0x10 37 | mov byte ptr [r10], 0x10 38 | mov word ptr [rdi], 0x1000 39 | mov word ptr [r10], 0x1000 40 | mov dword ptr [rdi], 0x10000000 41 | mov dword ptr [r10], 0x10000000 42 | mov qword ptr [rdi], 0x10000000 43 | mov qword ptr [r10], 0x10000000 44 | 45 | ret 46 | -------------------------------------------------------------------------------- /tests/cases/decode/it-mov.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (36 instructions): 2 | f1: 88 16 mov %dl,(%rsi) 3 | f1+2: 88 26 mov %ah,(%rsi) 4 | f1+4: 44 88 16 mov %r10b,(%rsi) 5 | f1+7: 66 89 16 mov %dx,(%rsi) 6 | f1+10: 66 44 89 16 mov %r10w,(%rsi) 7 | f1+14: 89 16 mov %edx,(%rsi) 8 | f1+16: 44 89 16 mov %r10d,(%rsi) 9 | f1+19: 48 89 16 mov %rdx,(%rsi) 10 | f1+22: 4c 89 16 mov %r10,(%rsi) 11 | f1+25: 8a 16 mov (%rsi),%dl 12 | f1+27: 8a 26 mov (%rsi),%ah 13 | f1+29: 44 8a 16 mov (%rsi),%r10b 14 | f1+32: 66 8b 16 mov (%rsi),%dx 15 | f1+35: 66 44 8b 16 mov (%rsi),%r10w 16 | f1+39: 8b 16 mov (%rsi),%edx 17 | f1+41: 44 8b 16 mov (%rsi),%r10d 18 | f1+44: 48 8b 16 mov (%rsi),%rdx 19 | f1+47: 4c 8b 16 mov (%rsi),%r10 20 | f1+50: b2 10 mov $0x10,%dl 21 | f1+52: b4 10 mov $0x10,%ah 22 | f1+54: 41 b2 10 mov $0x10,%r10b 23 | f1+57: 66 ba 00 10 mov $0x1000,%dx 24 | f1+61: 66 41 ba 00 10 mov $0x1000,%r10w 25 | f1+66: ba 00 00 00 10 mov $0x10000000,%edx 26 | f1+71: 41 ba 00 00 00 10 mov $0x10000000,%r10d 27 | f1+77: 48 ba 00 00 00 00 00 mov $0x1000000000000000,%rdx 28 | f1+84: 00 00 10 29 | f1+87: 49 ba 00 00 00 00 00 mov $0x1000000000000000,%r10 30 | f1+94: 00 00 10 31 | f1+97: c6 07 10 movb $0x10,(%rdi) 32 | f1+100: 41 c6 02 10 movb $0x10,(%r10) 33 | f1+104: 66 c7 07 00 10 movw $0x1000,(%rdi) 34 | f1+109: 66 41 c7 02 00 10 movw $0x1000,(%r10) 35 | f1+115: c7 07 00 00 00 10 movl $0x10000000,(%rdi) 36 | f1+121: 41 c7 02 00 00 00 10 movl $0x10000000,(%r10) 37 | f1+128: 48 c7 07 00 00 00 10 movq $0x10000000,(%rdi) 38 | f1+135: 49 c7 02 00 00 00 10 movq $0x10000000,(%r10) 39 | f1+142: c3 ret 40 | -------------------------------------------------------------------------------- /tests/cases/decode/it-movsx.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | //!cc = gcc 3 | .intel_syntax noprefix 4 | .text 5 | .globl f1 6 | .type f1, @function 7 | f1: 8 | // MOVSX instructions, Intel Vol. 2A 3-598 9 | movsx bx, byte ptr [rdi] 10 | movsx ebx, byte ptr [rdi] 11 | movsx rcx, bl 12 | movsx ebx, word ptr [rdi] 13 | movsx rcx, bx 14 | movsx rcx, ebx 15 | 16 | ret 17 | -------------------------------------------------------------------------------- /tests/cases/decode/it-movsx.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (7 instructions): 2 | f1: 66 0f be 1f movsxb (%rdi),%bx 3 | f1+4: 0f be 1f movsxb (%rdi),%ebx 4 | f1+7: 48 0f be cb movsx %bl,%rcx 5 | f1+11: 0f bf 1f movsxw (%rdi),%ebx 6 | f1+14: 48 0f bf cb movsx %bx,%rcx 7 | f1+18: 48 63 cb movsx %ebx,%rcx 8 | f1+21: c3 ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/it-movzx.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | //!cc = gcc 3 | .intel_syntax noprefix 4 | .text 5 | .globl f1 6 | .type f1, @function 7 | f1: 8 | // MOVZX instructions, Intel Vol. 2A 3-604 9 | movzx bx, byte ptr [rdi] 10 | movzx ebx, byte ptr [rdi] 11 | movzx rcx, bl 12 | movzx ebx, word ptr [rdi] 13 | movzx rcx, bx 14 | 15 | ret 16 | -------------------------------------------------------------------------------- /tests/cases/decode/it-movzx.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (6 instructions): 2 | f1: 66 0f b6 1f movzxb (%rdi),%bx 3 | f1+4: 0f b6 1f movzxb (%rdi),%ebx 4 | f1+7: 48 0f b6 cb movzx %bl,%rcx 5 | f1+11: 0f b7 1f movzxw (%rdi),%ebx 6 | f1+14: 48 0f b7 cb movzx %bx,%rcx 7 | f1+18: c3 ret 8 | -------------------------------------------------------------------------------- /tests/cases/decode/it-mul-div.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // MUL instructions, Intel Vol. 2A 3-614 8 | mul al 9 | mul r9b 10 | mul ax 11 | mul eax 12 | mul rax 13 | 14 | // IMUL instructions, Intel Vol. 2A 3-415 15 | imul al 16 | imul r9b 17 | imul ax 18 | imul eax 19 | imul rax 20 | imul rax, rax 21 | imul eax, eax 22 | imul ax, ax 23 | imul rax, rax, 0x100 24 | imul eax, eax, 0x100 25 | imul ax, ax, 0x100 26 | imul rax, rax, 0x10 27 | imul eax, eax, 0x10 28 | imul ax, ax, 0x10 29 | 30 | // DIV instructions, Intel Vol. 2A 3-260 31 | div al 32 | div r9b 33 | div ax 34 | div eax 35 | div rax 36 | 37 | // DIV instructions, Intel Vol. 2A 3-412 38 | idiv al 39 | idiv r9b 40 | idiv ax 41 | idiv eax 42 | idiv rax 43 | 44 | ret 45 | -------------------------------------------------------------------------------- /tests/cases/decode/it-mul-div.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (30 instructions): 2 | f1: f6 e0 mul %al 3 | f1+2: 41 f6 e1 mul %r9b 4 | f1+5: 66 f7 e0 mul %ax 5 | f1+8: f7 e0 mul %eax 6 | f1+10: 48 f7 e0 mul %rax 7 | f1+13: f6 e8 imul %al 8 | f1+15: 41 f6 e9 imul %r9b 9 | f1+18: 66 f7 e8 imul %ax 10 | f1+21: f7 e8 imul %eax 11 | f1+23: 48 f7 e8 imul %rax 12 | f1+26: 48 0f af c0 imul %rax,%rax 13 | f1+30: 0f af c0 imul %eax,%eax 14 | f1+33: 66 0f af c0 imul %ax,%ax 15 | f1+37: 48 69 c0 00 01 00 00 imul $0x100,%rax,%rax 16 | f1+44: 69 c0 00 01 00 00 imul $0x100,%eax,%eax 17 | f1+50: 66 69 c0 00 01 imul $0x100,%ax,%ax 18 | f1+55: 48 6b c0 10 imul $0x10,%rax,%rax 19 | f1+59: 6b c0 10 imul $0x10,%eax,%eax 20 | f1+62: 66 6b c0 10 imul $0x10,%ax,%ax 21 | f1+66: f6 f0 div %al 22 | f1+68: 41 f6 f1 div %r9b 23 | f1+71: 66 f7 f0 div %ax 24 | f1+74: f7 f0 div %eax 25 | f1+76: 48 f7 f0 div %rax 26 | f1+79: f6 f8 idiv %al 27 | f1+81: 41 f6 f9 idiv %r9b 28 | f1+84: 66 f7 f8 idiv %ax 29 | f1+87: f7 f8 idiv %eax 30 | f1+89: 48 f7 f8 idiv %rax 31 | f1+92: c3 ret 32 | -------------------------------------------------------------------------------- /tests/cases/decode/it-neg-not.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // NEG instructions, Intel Vol. 2B 4-7 8 | neg byte ptr [rdx] 9 | neg al 10 | neg r11b 11 | neg word ptr [rdx] 12 | neg ax 13 | neg r11w 14 | neg dword ptr [rdx] 15 | neg eax 16 | neg r11d 17 | neg qword ptr [rdx] 18 | neg rax 19 | neg r11 20 | 21 | // NOT instructions, Intel Vol. 2B 4-10 22 | not byte ptr [rdx] 23 | not al 24 | not r11b 25 | not word ptr [rdx] 26 | not ax 27 | not r11w 28 | not dword ptr [rdx] 29 | not eax 30 | not r11d 31 | not qword ptr [rdx] 32 | not rax 33 | not r11 34 | 35 | ret 36 | -------------------------------------------------------------------------------- /tests/cases/decode/it-neg-not.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: f6 1a negb (%rdx) 3 | f1+2: f6 d8 neg %al 4 | f1+4: 41 f6 db neg %r11b 5 | f1+7: 66 f7 1a negw (%rdx) 6 | f1+10: 66 f7 d8 neg %ax 7 | f1+13: 66 41 f7 db neg %r11w 8 | f1+17: f7 1a negl (%rdx) 9 | f1+19: f7 d8 neg %eax 10 | f1+21: 41 f7 db neg %r11d 11 | f1+24: 48 f7 1a negq (%rdx) 12 | f1+27: 48 f7 d8 neg %rax 13 | f1+30: 49 f7 db neg %r11 14 | f1+33: f6 12 notb (%rdx) 15 | f1+35: f6 d0 not %al 16 | f1+37: 41 f6 d3 not %r11b 17 | f1+40: 66 f7 12 notw (%rdx) 18 | f1+43: 66 f7 d0 not %ax 19 | f1+46: 66 41 f7 d3 not %r11w 20 | f1+50: f7 12 notl (%rdx) 21 | f1+52: f7 d0 not %eax 22 | f1+54: 41 f7 d3 not %r11d 23 | f1+57: 48 f7 12 notq (%rdx) 24 | f1+60: 48 f7 d0 not %rax 25 | f1+63: 49 f7 d3 not %r11 26 | f1+66: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-nop.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | //!cc = gcc 3 | .intel_syntax noprefix 4 | .text 5 | .globl f1 6 | .type f1, @function 7 | f1: 8 | // NOP instructions, Intel Vol. 2B 4-9 9 | nop 10 | nop di 11 | nop edi 12 | 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/decode/it-nop.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (4 instructions): 2 | f1: 90 nop 3 | f1+1: 66 0f 1f c7 nop %di 4 | f1+5: 0f 1f c7 nop %edi 5 | f1+8: c3 ret 6 | -------------------------------------------------------------------------------- /tests/cases/decode/it-or.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // OR instructions, Intel Vol. 2B 4-12 8 | or [rdi], rax 9 | or [rdi], r9 10 | or [rdi], eax 11 | or [rdi], r9d 12 | or [rdi], ax 13 | or [rdi], r9w 14 | or [rdi], al 15 | or [rdi], r9b 16 | or rax, [rdi] 17 | or r9, [rdi] 18 | or eax, [rdi] 19 | or r9d, [rdi] 20 | or ax, [rdi] 21 | or r9w, [rdi] 22 | or al, [rdi] 23 | or r9b, [rdi] 24 | or al, 0x10 25 | or ax, 0x1000 26 | or eax, 0xabcdef00 27 | or rax, 0x0bcdef00 28 | or byte ptr [rax], 0x10 29 | or word ptr [rax], 0x310 30 | or dword ptr [rax], 0x310 31 | or qword ptr [rax], 0x310 32 | 33 | ret 34 | 35 | -------------------------------------------------------------------------------- /tests/cases/decode/it-or.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 09 07 or %rax,(%rdi) 3 | f1+3: 4c 09 0f or %r9,(%rdi) 4 | f1+6: 09 07 or %eax,(%rdi) 5 | f1+8: 44 09 0f or %r9d,(%rdi) 6 | f1+11: 66 09 07 or %ax,(%rdi) 7 | f1+14: 66 44 09 0f or %r9w,(%rdi) 8 | f1+18: 08 07 or %al,(%rdi) 9 | f1+20: 44 08 0f or %r9b,(%rdi) 10 | f1+23: 48 0b 07 or (%rdi),%rax 11 | f1+26: 4c 0b 0f or (%rdi),%r9 12 | f1+29: 0b 07 or (%rdi),%eax 13 | f1+31: 44 0b 0f or (%rdi),%r9d 14 | f1+34: 66 0b 07 or (%rdi),%ax 15 | f1+37: 66 44 0b 0f or (%rdi),%r9w 16 | f1+41: 0a 07 or (%rdi),%al 17 | f1+43: 44 0a 0f or (%rdi),%r9b 18 | f1+46: 0c 10 or $0x10,%al 19 | f1+48: 66 0d 00 10 or $0x1000,%ax 20 | f1+52: 0d 00 ef cd ab or $0xabcdef00,%eax 21 | f1+57: 48 0d 00 ef cd 0b or $0xbcdef00,%rax 22 | f1+63: 80 08 10 orb $0x10,(%rax) 23 | f1+66: 66 81 08 10 03 orw $0x310,(%rax) 24 | f1+71: 81 08 10 03 00 00 orl $0x310,(%rax) 25 | f1+77: 48 81 08 10 03 00 00 orq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-push-pop.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // PUSH instructions, Intel Vol. 2B 4-272 8 | push word ptr [rdx] 9 | push qword ptr [rdx] 10 | push dx 11 | push rdx 12 | // imm8/16/32, extended to 64bit pushed 13 | push 0x10 14 | push 0x1000 15 | push 0x10000000 16 | // imm8/16, 16bits pushed 17 | push word ptr 0x10 18 | push word ptr 0x1000 19 | 20 | // rex.W push $0x78563412: push imm32 extended to 64bit, rex.W ignored 21 | // .byte 0x48, 0x68, 0x12, 0x34, 0x56, 0x78 22 | 23 | // push fs 24 | // push gs 25 | 26 | // POP instructions, Intel Vol. 2B 4-183 27 | pop word ptr [rdx] 28 | pop qword ptr [rdx] 29 | pop dx 30 | pop rdx 31 | 32 | pushfw 33 | popfw 34 | pushfq 35 | popfq 36 | 37 | ret 38 | -------------------------------------------------------------------------------- /tests/cases/decode/it-push-pop.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (18 instructions): 2 | f1: 66 ff 32 pushw (%rdx) 3 | f1+3: ff 32 pushq (%rdx) 4 | f1+5: 66 52 push %dx 5 | f1+7: 52 push %rdx 6 | f1+8: 6a 10 pushq $0x10 7 | f1+10: 68 00 10 00 00 pushq $0x1000 8 | f1+15: 68 00 00 00 10 pushq $0x10000000 9 | f1+20: 66 6a 10 pushw $0x10 10 | f1+23: 66 68 00 10 pushw $0x1000 11 | f1+27: 66 8f 02 popw (%rdx) 12 | f1+30: 8f 02 popq (%rdx) 13 | f1+32: 66 5a pop %dx 14 | f1+34: 5a pop %rdx 15 | f1+35: 66 9c pushf 16 | f1+37: 66 9d popf 17 | f1+39: 9c pushfq 18 | f1+40: 9d popfq 19 | f1+41: c3 ret 20 | -------------------------------------------------------------------------------- /tests/cases/decode/it-pxor.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | pxor mm1, mm2 8 | pxor mm1, [rdi] 9 | pxor mm1, [r9] 10 | 11 | pxor xmm3, xmm4 12 | pxor xmm3, xmm9 13 | pxor xmm3, [rdi] 14 | pxor xmm9, [rdi] 15 | pxor xmm3, [r9] 16 | pxor xmm9, [r9] 17 | 18 | ret 19 | -------------------------------------------------------------------------------- /tests/cases/decode/it-pxor.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (10 instructions): 2 | f1: 0f ef ca pxor %mm2,%mm1 3 | f1+3: 0f ef 0f pxor (%rdi),%mm1 4 | f1+6: 41 0f ef 09 pxor (%r9),%mm1 5 | f1+10: 66 0f ef dc pxor %xmm4,%xmm3 6 | f1+14: 66 41 0f ef d9 pxor %xmm9,%xmm3 7 | f1+19: 66 0f ef 1f pxor (%rdi),%xmm3 8 | f1+23: 66 44 0f ef 0f pxor (%rdi),%xmm9 9 | f1+28: 66 41 0f ef 19 pxor (%r9),%xmm3 10 | f1+33: 66 45 0f ef 09 pxor (%r9),%xmm9 11 | f1+38: c3 ret 12 | -------------------------------------------------------------------------------- /tests/cases/decode/it-sbb.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // SBB instructions, Intel Vol. 2B 4-349 8 | sbb [rdi], rax 9 | sbb [rdi], r9 10 | sbb [rdi], eax 11 | sbb [rdi], r9d 12 | sbb [rdi], ax 13 | sbb [rdi], r9w 14 | sbb [rdi], al 15 | sbb [rdi], r9b 16 | sbb rax, [rdi] 17 | sbb r9, [rdi] 18 | sbb eax, [rdi] 19 | sbb r9d, [rdi] 20 | sbb ax, [rdi] 21 | sbb r9w, [rdi] 22 | sbb al, [rdi] 23 | sbb r9b, [rdi] 24 | sbb al, 0x10 25 | sbb ax, 0x1000 26 | sbb eax, 0xabcdef00 27 | sbb rax, 0x0bcdef00 28 | sbb byte ptr [rax], 0x10 29 | sbb word ptr [rax], 0x310 30 | sbb dword ptr [rax], 0x310 31 | sbb qword ptr [rax], 0x310 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tests/cases/decode/it-sbb.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 19 07 sbb %rax,(%rdi) 3 | f1+3: 4c 19 0f sbb %r9,(%rdi) 4 | f1+6: 19 07 sbb %eax,(%rdi) 5 | f1+8: 44 19 0f sbb %r9d,(%rdi) 6 | f1+11: 66 19 07 sbb %ax,(%rdi) 7 | f1+14: 66 44 19 0f sbb %r9w,(%rdi) 8 | f1+18: 18 07 sbb %al,(%rdi) 9 | f1+20: 44 18 0f sbb %r9b,(%rdi) 10 | f1+23: 48 1b 07 sbb (%rdi),%rax 11 | f1+26: 4c 1b 0f sbb (%rdi),%r9 12 | f1+29: 1b 07 sbb (%rdi),%eax 13 | f1+31: 44 1b 0f sbb (%rdi),%r9d 14 | f1+34: 66 1b 07 sbb (%rdi),%ax 15 | f1+37: 66 44 1b 0f sbb (%rdi),%r9w 16 | f1+41: 1a 07 sbb (%rdi),%al 17 | f1+43: 44 1a 0f sbb (%rdi),%r9b 18 | f1+46: 1c 10 sbb $0x10,%al 19 | f1+48: 66 1d 00 10 sbb $0x1000,%ax 20 | f1+52: 1d 00 ef cd ab sbb $0xabcdef00,%eax 21 | f1+57: 48 1d 00 ef cd 0b sbb $0xbcdef00,%rax 22 | f1+63: 80 18 10 sbbb $0x10,(%rax) 23 | f1+66: 66 81 18 10 03 sbbw $0x310,(%rax) 24 | f1+71: 81 18 10 03 00 00 sbbl $0x310,(%rax) 25 | f1+77: 48 81 18 10 03 00 00 sbbq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-shift.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // SHL/SAL instructions, Intel Vol. 2B 4-342 8 | shl al, 1 9 | shl r10b, 1 10 | shl byte ptr [rax], 1 11 | shl al, cl 12 | shl r10b, cl 13 | shl byte ptr [rax], cl 14 | shl al, 5 15 | shl r10b, 5 16 | shl byte ptr [rax], 5 17 | shl ax, 1 18 | shl r10w, 1 19 | shl word ptr [rax], 1 20 | shl ax, cl 21 | shl r10w, cl 22 | shl word ptr [rax], cl 23 | shl ax, 5 24 | shl r10w, 5 25 | shl word ptr [rax], 5 26 | shl eax, 1 27 | shl r10d, 1 28 | shl dword ptr [rax], 1 29 | shl eax, cl 30 | shl r10d, cl 31 | shl dword ptr [rax], cl 32 | shl eax, 5 33 | shl r10d, 5 34 | shl dword ptr [rax], 5 35 | shl rax, 1 36 | shl r10, 1 37 | shl qword ptr [rax], 1 38 | shl rax, cl 39 | shl r10, cl 40 | shl qword ptr [rax], cl 41 | shl rax, 5 42 | shl r10, 5 43 | shl qword ptr [rax], 5 44 | 45 | // SHR instructions, Intel Vol. 2B 4-342 46 | shr al, 1 47 | shr r10b, 1 48 | shr byte ptr [rax], 1 49 | shr al, cl 50 | shr r10b, cl 51 | shr byte ptr [rax], cl 52 | shr al, 5 53 | shr r10b, 5 54 | shr byte ptr [rax], 5 55 | shr ax, 1 56 | shr r10w, 1 57 | shr word ptr [rax], 1 58 | shr ax, cl 59 | shr r10w, cl 60 | shr word ptr [rax], cl 61 | shr ax, 5 62 | shr r10w, 5 63 | shr word ptr [rax], 5 64 | shr eax, 1 65 | shr r10d, 1 66 | shr dword ptr [rax], 1 67 | shr eax, cl 68 | shr r10d, cl 69 | shr dword ptr [rax], cl 70 | shr eax, 5 71 | shr r10d, 5 72 | shr dword ptr [rax], 5 73 | shr rax, 1 74 | shr r10, 1 75 | shr qword ptr [rax], 1 76 | shr rax, cl 77 | shr r10, cl 78 | shr qword ptr [rax], cl 79 | shr rax, 5 80 | shr r10, 5 81 | shr qword ptr [rax], 5 82 | 83 | // SAR instructions, Intel Vol. 2B 4-342 84 | sar al, 1 85 | sar r10b, 1 86 | sar byte ptr [rax], 1 87 | sar al, cl 88 | sar r10b, cl 89 | sar byte ptr [rax], cl 90 | sar al, 5 91 | sar r10b, 5 92 | sar byte ptr [rax], 5 93 | sar ax, 1 94 | sar r10w, 1 95 | sar word ptr [rax], 1 96 | sar ax, cl 97 | sar r10w, cl 98 | sar word ptr [rax], cl 99 | sar ax, 5 100 | sar r10w, 5 101 | sar word ptr [rax], 5 102 | sar eax, 1 103 | sar r10d, 1 104 | sar dword ptr [rax], 1 105 | sar eax, cl 106 | sar r10d, cl 107 | sar dword ptr [rax], cl 108 | sar eax, 5 109 | sar r10d, 5 110 | sar dword ptr [rax], 5 111 | sar rax, 1 112 | sar r10, 1 113 | sar qword ptr [rax], 1 114 | sar rax, cl 115 | sar r10, cl 116 | sar qword ptr [rax], cl 117 | sar rax, 5 118 | sar r10, 5 119 | sar qword ptr [rax], 5 120 | 121 | ret 122 | -------------------------------------------------------------------------------- /tests/cases/decode/it-sub.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // SUB instructions, Intel Vol. 2B 4-407 8 | sub [rdi], rax 9 | sub [rdi], r9 10 | sub [rdi], eax 11 | sub [rdi], r9d 12 | sub [rdi], ax 13 | sub [rdi], r9w 14 | sub [rdi], al 15 | sub [rdi], r9b 16 | sub rax, [rdi] 17 | sub r9, [rdi] 18 | sub eax, [rdi] 19 | sub r9d, [rdi] 20 | sub ax, [rdi] 21 | sub r9w, [rdi] 22 | sub al, [rdi] 23 | sub r9b, [rdi] 24 | sub al, 0x10 25 | sub ax, 0x1000 26 | sub eax, 0xabcdef00 27 | sub rax, 0x0bcdef00 28 | sub byte ptr [rax], 0x10 29 | sub word ptr [rax], 0x310 30 | sub dword ptr [rax], 0x310 31 | sub qword ptr [rax], 0x310 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tests/cases/decode/it-sub.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 29 07 sub %rax,(%rdi) 3 | f1+3: 4c 29 0f sub %r9,(%rdi) 4 | f1+6: 29 07 sub %eax,(%rdi) 5 | f1+8: 44 29 0f sub %r9d,(%rdi) 6 | f1+11: 66 29 07 sub %ax,(%rdi) 7 | f1+14: 66 44 29 0f sub %r9w,(%rdi) 8 | f1+18: 28 07 sub %al,(%rdi) 9 | f1+20: 44 28 0f sub %r9b,(%rdi) 10 | f1+23: 48 2b 07 sub (%rdi),%rax 11 | f1+26: 4c 2b 0f sub (%rdi),%r9 12 | f1+29: 2b 07 sub (%rdi),%eax 13 | f1+31: 44 2b 0f sub (%rdi),%r9d 14 | f1+34: 66 2b 07 sub (%rdi),%ax 15 | f1+37: 66 44 2b 0f sub (%rdi),%r9w 16 | f1+41: 2a 07 sub (%rdi),%al 17 | f1+43: 44 2a 0f sub (%rdi),%r9b 18 | f1+46: 2c 10 sub $0x10,%al 19 | f1+48: 66 2d 00 10 sub $0x1000,%ax 20 | f1+52: 2d 00 ef cd ab sub $0xabcdef00,%eax 21 | f1+57: 48 2d 00 ef cd 0b sub $0xbcdef00,%rax 22 | f1+63: 80 28 10 subb $0x10,(%rax) 23 | f1+66: 66 81 28 10 03 subw $0x310,(%rax) 24 | f1+71: 81 28 10 03 00 00 subl $0x310,(%rax) 25 | f1+77: 48 81 28 10 03 00 00 subq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/it-test.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | //!cc = gcc 3 | .intel_syntax noprefix 4 | .text 5 | .globl f1 6 | .type f1, @function 7 | f1: 8 | // TEST instructions, Intel Vol. 2B 4-428 9 | test [rdi], rax 10 | test [rdi], r9 11 | test [rdi], eax 12 | test [rdi], r9d 13 | test [rdi], ax 14 | test [rdi], r9w 15 | test [rdi], al 16 | test [rdi], r9b 17 | 18 | test al, r9b 19 | test r10b, bl 20 | test cl, dl 21 | test sil, dil 22 | test eax, r9d 23 | test r10d, ebx 24 | test rax, r9 25 | test r10, rbx 26 | 27 | test al, 0x10 28 | test ax, 0x1000 29 | test eax, 0xabcdef00 30 | test rax, 0x0bcdef00 31 | test bl, 0x10 32 | test bx, 0x1000 33 | test ebx, 0xabcdef00 34 | test rbx, 0x0bcdef00 35 | test r9b, 0x10 36 | test r9w, 0x1000 37 | test r9d, 0xabcdef00 38 | test r9, 0x0bcdef00 39 | test byte ptr [rax], 0x10 40 | test word ptr [rax], 0x310 41 | test dword ptr [rax], 0x310 42 | test qword ptr [rax], 0x310 43 | 44 | test al, sil 45 | test sil, al 46 | test al, ah 47 | test ah, bl 48 | test bl, bh 49 | test cl, ch 50 | test dl, dh 51 | 52 | test ax, 0x10 53 | test eax, 0x10 54 | test rax, 0x10 55 | ret 56 | -------------------------------------------------------------------------------- /tests/cases/decode/it-test.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (43 instructions): 2 | f1: 48 85 07 test %rax,(%rdi) 3 | f1+3: 4c 85 0f test %r9,(%rdi) 4 | f1+6: 85 07 test %eax,(%rdi) 5 | f1+8: 44 85 0f test %r9d,(%rdi) 6 | f1+11: 66 85 07 test %ax,(%rdi) 7 | f1+14: 66 44 85 0f test %r9w,(%rdi) 8 | f1+18: 84 07 test %al,(%rdi) 9 | f1+20: 44 84 0f test %r9b,(%rdi) 10 | f1+23: 44 84 c8 test %r9b,%al 11 | f1+26: 41 84 da test %bl,%r10b 12 | f1+29: 84 d1 test %dl,%cl 13 | f1+31: 40 84 fe test %dil,%sil 14 | f1+34: 44 85 c8 test %r9d,%eax 15 | f1+37: 41 85 da test %ebx,%r10d 16 | f1+40: 4c 85 c8 test %r9,%rax 17 | f1+43: 49 85 da test %rbx,%r10 18 | f1+46: a8 10 test $0x10,%al 19 | f1+48: 66 a9 00 10 test $0x1000,%ax 20 | f1+52: a9 00 ef cd ab test $0xabcdef00,%eax 21 | f1+57: 48 a9 00 ef cd 0b test $0xbcdef00,%rax 22 | f1+63: f6 c3 10 test $0x10,%bl 23 | f1+66: 66 f7 c3 00 10 test $0x1000,%bx 24 | f1+71: f7 c3 00 ef cd ab test $0xabcdef00,%ebx 25 | f1+77: 48 f7 c3 00 ef cd 0b test $0xbcdef00,%rbx 26 | f1+84: 41 f6 c1 10 test $0x10,%r9b 27 | f1+88: 66 41 f7 c1 00 10 test $0x1000,%r9w 28 | f1+94: 41 f7 c1 00 ef cd ab test $0xabcdef00,%r9d 29 | f1+101: 49 f7 c1 00 ef cd 0b test $0xbcdef00,%r9 30 | f1+108: f6 00 10 testb $0x10,(%rax) 31 | f1+111: 66 f7 00 10 03 testw $0x310,(%rax) 32 | f1+116: f7 00 10 03 00 00 testl $0x310,(%rax) 33 | f1+122: 48 f7 00 10 03 00 00 testq $0x310,(%rax) 34 | f1+129: 40 84 f0 test %sil,%al 35 | f1+132: 40 84 c6 test %al,%sil 36 | f1+135: 84 e0 test %ah,%al 37 | f1+137: 84 dc test %bl,%ah 38 | f1+139: 84 fb test %bh,%bl 39 | f1+141: 84 e9 test %ch,%cl 40 | f1+143: 84 f2 test %dh,%dl 41 | f1+145: 66 a9 10 00 test $0x10,%ax 42 | f1+149: a9 10 00 00 00 test $0x10,%eax 43 | f1+154: 48 a9 10 00 00 00 test $0x10,%rax 44 | f1+160: c3 ret 45 | -------------------------------------------------------------------------------- /tests/cases/decode/it-ud2.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | ud2 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/it-ud2.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (1 instructions): 2 | f1: 0f 0b 3 | -------------------------------------------------------------------------------- /tests/cases/decode/it-ud2.s.expect_stderr: -------------------------------------------------------------------------------- 1 | Decoder error at decoding BB f1+2: unsupported opcode 0x0f 0x0b. Stopped decoding 2 | -------------------------------------------------------------------------------- /tests/cases/decode/it-xor.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // XOR instructions, Intel Vol. 2B 4-593 8 | xor [rdi], rax 9 | xor [rdi], r9 10 | xor [rdi], eax 11 | xor [rdi], r9d 12 | xor [rdi], ax 13 | xor [rdi], r9w 14 | xor [rdi], al 15 | xor [rdi], r9b 16 | xor rax, [rdi] 17 | xor r9, [rdi] 18 | xor eax, [rdi] 19 | xor r9d, [rdi] 20 | xor ax, [rdi] 21 | xor r9w, [rdi] 22 | xor al, [rdi] 23 | xor r9b, [rdi] 24 | xor al, 0x10 25 | xor ax, 0x1000 26 | xor eax, 0xabcdef00 27 | xor rax, 0x0bcdef00 28 | xor byte ptr [rax], 0x10 29 | xor word ptr [rax], 0x310 30 | xor dword ptr [rax], 0x310 31 | xor qword ptr [rax], 0x310 32 | 33 | ret 34 | -------------------------------------------------------------------------------- /tests/cases/decode/it-xor.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (25 instructions): 2 | f1: 48 31 07 xor %rax,(%rdi) 3 | f1+3: 4c 31 0f xor %r9,(%rdi) 4 | f1+6: 31 07 xor %eax,(%rdi) 5 | f1+8: 44 31 0f xor %r9d,(%rdi) 6 | f1+11: 66 31 07 xor %ax,(%rdi) 7 | f1+14: 66 44 31 0f xor %r9w,(%rdi) 8 | f1+18: 30 07 xor %al,(%rdi) 9 | f1+20: 44 30 0f xor %r9b,(%rdi) 10 | f1+23: 48 33 07 xor (%rdi),%rax 11 | f1+26: 4c 33 0f xor (%rdi),%r9 12 | f1+29: 33 07 xor (%rdi),%eax 13 | f1+31: 44 33 0f xor (%rdi),%r9d 14 | f1+34: 66 33 07 xor (%rdi),%ax 15 | f1+37: 66 44 33 0f xor (%rdi),%r9w 16 | f1+41: 32 07 xor (%rdi),%al 17 | f1+43: 44 32 0f xor (%rdi),%r9b 18 | f1+46: 34 10 xor $0x10,%al 19 | f1+48: 66 35 00 10 xor $0x1000,%ax 20 | f1+52: 35 00 ef cd ab xor $0xabcdef00,%eax 21 | f1+57: 48 35 00 ef cd 0b xor $0xbcdef00,%rax 22 | f1+63: 80 30 10 xorb $0x10,(%rax) 23 | f1+66: 66 81 30 10 03 xorw $0x310,(%rax) 24 | f1+71: 81 30 10 03 00 00 xorl $0x310,(%rax) 25 | f1+77: 48 81 30 10 03 00 00 xorq $0x310,(%rax) 26 | f1+84: c3 ret 27 | -------------------------------------------------------------------------------- /tests/cases/decode/js-short.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | 1: 8 | js 1b 9 | -------------------------------------------------------------------------------- /tests/cases/decode/js-short.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (1 instructions): 2 | f1: 78 fe js $f1 3 | -------------------------------------------------------------------------------- /tests/cases/decode/js.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | //!cc = gcc 3 | // ^fragile test case: only gcc behavior as expected, force gcc 4 | .intel_syntax noprefix 5 | .text 6 | .globl f1 7 | .type f1, @function 8 | f1: 9 | js short f1 10 | -------------------------------------------------------------------------------- /tests/cases/decode/js.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (1 instructions): 2 | f1: 0f 88 fa ff ff ff js $f1 3 | -------------------------------------------------------------------------------- /tests/cases/decode/modrm.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | inc rax 8 | inc rbp 9 | inc r9 10 | inc qword ptr [r9] 11 | inc qword ptr [r9 + rax] 12 | inc qword ptr [r9 + 1 * rax] 13 | inc qword ptr [r9 + 2 * rdx] 14 | inc qword ptr [r9 + 4 * rdx] 15 | inc qword ptr [r9 + 8 * rdx] 16 | inc qword ptr [0x10 + r9] 17 | inc qword ptr [0x10 + r9 + r14] 18 | inc qword ptr [0x10 + r9 + 1 * r14] 19 | inc qword ptr [0x10 + r9 + 2 * r14] 20 | inc qword ptr [0x10 + r9 + 4 * r14] 21 | inc qword ptr [0x10 + r9 + 8 * r14] 22 | inc qword ptr [0x1000 + r9] 23 | inc qword ptr [0x1000 + r9 + rax] 24 | inc qword ptr [0x1000 + r9 + 1 * rax] 25 | inc qword ptr [0x1000 + r9 + 2 * rdx] 26 | inc qword ptr [0x1000 + r9 + 4 * rdx] 27 | inc qword ptr [0x1000 + r9 + 8 * rdx] 28 | inc qword ptr [0x1000 + 2 * rdx] 29 | inc qword ptr [0x1000 + 4 * rdx] 30 | inc qword ptr [0x1000 + 8 * rdx] 31 | inc qword ptr [f1 + rip] 32 | inc qword ptr [f1 + 0x100 + rip] 33 | 34 | add rbp, rax 35 | add rbp, rbp 36 | add rbp, r9 37 | add rbp, qword ptr [r9] 38 | add rbp, qword ptr [r9 + rax] 39 | add rbp, qword ptr [r9 + 1 * rax] 40 | add rbp, qword ptr [r9 + 2 * rdx] 41 | add rbp, qword ptr [r9 + 4 * rdx] 42 | add rbp, qword ptr [r9 + 8 * rdx] 43 | add rbp, qword ptr [0x10 + r9] 44 | add rbp, qword ptr [0x10 + r9 + r14] 45 | add rbp, qword ptr [0x10 + r9 + 1 * r14] 46 | add rbp, qword ptr [0x10 + r9 + 2 * r14] 47 | add rbp, qword ptr [0x10 + r9 + 4 * r14] 48 | add rbp, qword ptr [0x10 + r9 + 8 * r14] 49 | add rbp, qword ptr [0x1000 + r9] 50 | add rbp, qword ptr [0x1000 + r9 + rax] 51 | add rbp, qword ptr [0x1000 + r9 + 1 * rax] 52 | add rbp, qword ptr [0x1000 + r9 + 2 * rdx] 53 | add rbp, qword ptr [0x1000 + r9 + 4 * rdx] 54 | add rbp, qword ptr [0x1000 + r9 + 8 * rdx] 55 | add rbp, qword ptr [0x1000 + 2 * r15] 56 | add rbp, qword ptr [0x1000 + 4 * r15] 57 | add rbp, qword ptr [0x1000 + 8 * r15] 58 | add rbp, qword ptr [f1 + rip] 59 | add rbp, qword ptr [f1 + 0x100 + rip] 60 | 61 | add r9, rax 62 | add r9, rbp 63 | add r9, r9 64 | add r9, qword ptr [r9] 65 | add r9, qword ptr [r9 + rax] 66 | add r9, qword ptr [r9 + 1 * rax] 67 | add r9, qword ptr [r9 + 2 * rdx] 68 | add r9, qword ptr [r9 + 4 * rdx] 69 | add r9, qword ptr [r9 + 8 * rdx] 70 | add r9, qword ptr [0x10 + r9] 71 | add r9, qword ptr [0x10 + r9 + r14] 72 | add r9, qword ptr [0x10 + r9 + 1 * r14] 73 | add r9, qword ptr [0x10 + r9 + 2 * r14] 74 | add r9, qword ptr [0x10 + r9 + 4 * r14] 75 | add r9, qword ptr [0x10 + r9 + 8 * r14] 76 | add r9, qword ptr [0x1000 + r9] 77 | add r9, qword ptr [0x1000 + r9 + rax] 78 | add r9, qword ptr [0x1000 + r9 + 1 * rax] 79 | add r9, qword ptr [0x1000 + r9 + 2 * rdx] 80 | add r9, qword ptr [0x1000 + r9 + 4 * rdx] 81 | add r9, qword ptr [0x1000 + r9 + 8 * rdx] 82 | add r9, qword ptr [0x1000 + 2 * r15] 83 | add r9, qword ptr [0x1000 + 4 * r15] 84 | add r9, qword ptr [0x1000 + 8 * r15] 85 | add r9, qword ptr [f1 + rip] 86 | add r9, qword ptr [f1 + 0x100 + rip] 87 | 88 | mov r9, qword ptr [rsp + 8 * rax] 89 | mov r9, qword ptr [rbp + 8 * rax] 90 | mov r9, qword ptr [rsi + 8 * rax] 91 | mov r9, qword ptr [r12 + 8 * rax] 92 | mov r9, qword ptr [r13 + 8 * rax] 93 | mov r9, qword ptr [r14 + 8 * rax] 94 | mov r9, qword ptr [0x12345678 + 8 * rax] 95 | .byte 0x4d,0x8b,0x0c,0xc5,0x12,0x34,0x56,0x78 96 | 97 | add r9, [0x8 + rbx] 98 | add r9, [0x8 + rsp] 99 | add r9, [0x8 + rbp] 100 | add r9, [0x8 + r11] 101 | add r9, [0x8 + r12] 102 | add r9, [0x8 + r13] 103 | 104 | mov r9, qword ptr [rsp] 105 | mov r9, qword ptr [rbp] 106 | mov r9, qword ptr [rsi] 107 | mov r9, qword ptr [r12] 108 | mov r9, qword ptr [r13] 109 | mov r9, qword ptr [r14] 110 | 111 | lea r9, [0x1000 + r9 + 8 * r12] 112 | 113 | ret 114 | 115 | -------------------------------------------------------------------------------- /tests/cases/decode/movq.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | movq rax, xmm0 8 | movq rax, xmm1 9 | movq rcx, xmm0 10 | movq rcx, xmm1 11 | ret 12 | -------------------------------------------------------------------------------- /tests/cases/decode/movq.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (5 instructions): 2 | f1: 66 48 0f 7e c0 movq %xmm0,%rax 3 | f1+5: 66 48 0f 7e c8 movq %xmm1,%rax 4 | f1+10: 66 48 0f 7e c1 movq %xmm0,%rcx 5 | f1+15: 66 48 0f 7e c9 movq %xmm1,%rcx 6 | f1+20: c3 ret 7 | -------------------------------------------------------------------------------- /tests/cases/decode/pop-word-ax.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | pop ax 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/pop-word-ax.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (2 instructions): 2 | f1: 66 58 pop %ax 3 | f1+2: c3 ret 4 | -------------------------------------------------------------------------------- /tests/cases/decode/pop-word-r10w.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | pop r10w 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/pop-word-r10w.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (2 instructions): 2 | f1: 66 41 5a pop %r10w 3 | f1+3: c3 ret 4 | -------------------------------------------------------------------------------- /tests/cases/decode/push-word-ax.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | push ax 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/push-word-ax.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (2 instructions): 2 | f1: 66 50 push %ax 3 | f1+2: c3 ret 4 | -------------------------------------------------------------------------------- /tests/cases/decode/push-word-r10w.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | push r10w 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/decode/push-word-r10w.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (2 instructions): 2 | f1: 66 41 52 push %r10w 3 | f1+3: c3 ret 4 | -------------------------------------------------------------------------------- /tests/cases/decode/sse-arithmetic.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | addss xmm0, xmm1 8 | addsd xmm0, xmm1 9 | addps xmm0, xmm15 10 | addpd xmm0, xmm1 11 | addss xmm0, [rax] 12 | addsd xmm0, [rax] 13 | addps xmm0, [rax] 14 | addpd xmm0, [rax] 15 | addsubps xmm0, xmm15 16 | addsubpd xmm0, xmm1 17 | addsubps xmm0, [rax] 18 | addsubpd xmm0, [rax] 19 | subss xmm0, xmm1 20 | subsd xmm0, xmm1 21 | subps xmm0, xmm15 22 | subpd xmm0, xmm1 23 | subss xmm0, [rax] 24 | subsd xmm0, [rax] 25 | subps xmm0, [rax] 26 | subpd xmm0, [rax] 27 | haddps xmm0, xmm15 28 | haddpd xmm0, xmm1 29 | haddps xmm0, [rax] 30 | haddpd xmm0, [rax] 31 | hsubps xmm0, xmm15 32 | hsubpd xmm0, xmm1 33 | hsubps xmm0, [rax] 34 | hsubpd xmm0, [rax] 35 | mulss xmm0, xmm1 36 | mulsd xmm0, xmm1 37 | mulps xmm0, xmm15 38 | mulpd xmm0, xmm1 39 | mulss xmm0, [rax] 40 | mulsd xmm0, [rax] 41 | mulps xmm0, [rax] 42 | mulpd xmm0, [rax] 43 | divss xmm0, xmm1 44 | divsd xmm0, xmm1 45 | divps xmm0, xmm15 46 | divpd xmm0, xmm1 47 | divss xmm0, [rax] 48 | divsd xmm0, [rax] 49 | divps xmm0, [rax] 50 | divpd xmm0, [rax] 51 | rcpss xmm0, xmm1 52 | rcpps xmm0, xmm15 53 | rcpss xmm0, [rax] 54 | rcpps xmm0, [rax] 55 | sqrtss xmm0, xmm1 56 | sqrtsd xmm0, xmm1 57 | sqrtps xmm0, xmm15 58 | sqrtpd xmm0, xmm1 59 | sqrtss xmm0, [rax] 60 | sqrtsd xmm0, [rax] 61 | sqrtps xmm0, [rax] 62 | sqrtpd xmm0, [rax] 63 | rsqrtss xmm0, xmm1 64 | rsqrtps xmm0, xmm15 65 | rsqrtss xmm0, [rax] 66 | rsqrtps xmm0, [rax] 67 | maxss xmm0, xmm1 68 | maxsd xmm0, xmm1 69 | maxps xmm0, xmm15 70 | maxpd xmm0, xmm1 71 | maxss xmm0, [rax] 72 | maxsd xmm0, [rax] 73 | maxps xmm0, [rax] 74 | maxpd xmm0, [rax] 75 | minss xmm0, xmm1 76 | minsd xmm0, xmm1 77 | minps xmm0, xmm15 78 | minpd xmm0, xmm1 79 | minss xmm0, [rax] 80 | minsd xmm0, [rax] 81 | minps xmm0, [rax] 82 | minpd xmm0, [rax] 83 | xorps xmm0, xmm15 84 | xorpd xmm0, xmm1 85 | xorps xmm0, [rax] 86 | xorpd xmm0, [rax] 87 | orps xmm0, xmm15 88 | orpd xmm0, xmm1 89 | orps xmm0, [rax] 90 | orpd xmm0, [rax] 91 | andps xmm0, xmm15 92 | andpd xmm0, xmm1 93 | andps xmm0, [rax] 94 | andpd xmm0, [rax] 95 | andnps xmm0, xmm15 96 | andnpd xmm0, xmm1 97 | andnps xmm0, [rax] 98 | andnpd xmm0, [rax] 99 | 100 | ret 101 | 102 | -------------------------------------------------------------------------------- /tests/cases/decode/sse.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-decode.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | movq rax, xmm0 8 | movq rsi, xmm7 9 | movq rax, xmm15 10 | movq r15, xmm15 11 | movq xmm0, rax 12 | movq xmm7, r9 13 | movq xmm15, rax 14 | movq xmm15, r15 15 | movss xmm0, [rdi] 16 | movsd xmm0, [rdi] 17 | movups xmm0, [rdi] 18 | movupd xmm0, [rdi] 19 | movaps xmm0, [rdi] 20 | movapd xmm0, [rdi] 21 | movss [rdi], xmm0 22 | movsd [rdi], xmm0 23 | movups [rdi], xmm0 24 | movupd [rdi], xmm0 25 | movaps [rdi], xmm0 26 | movapd [rdi], xmm0 27 | movq xmm0, xmm1 28 | movq [rdx], xmm1 29 | movq xmm0, [rdx] 30 | movq mm0, [rdx] 31 | movdqu xmm0, [rdx] 32 | movdqu [rdx], xmm0 33 | movdqa xmm0, [rdx] 34 | movdqa [rdx], xmm0 35 | movd xmm0, [rdx] 36 | movd [rdx], xmm0 37 | movlpd [rsi], xmm10 38 | movlpd xmm0, [rdi] 39 | movlps [rsi], xmm10 40 | movlps xmm0, [rdi] 41 | movhpd [rsi], xmm10 42 | movhpd xmm0, [rdi] 43 | movhps [rsi], xmm10 44 | movhps xmm0, [rdi] 45 | 46 | unpcklpd xmm0, xmm1 47 | unpcklpd xmm0, [rdi] 48 | unpcklps xmm0, xmm1 49 | unpcklps xmm0, [rdi] 50 | unpckhpd xmm0, xmm1 51 | unpckhpd xmm0, [rdi] 52 | unpckhps xmm0, xmm1 53 | unpckhps xmm0, [rdi] 54 | 55 | paddq xmm0, xmm1 56 | paddq xmm0, [rax] 57 | 58 | ret 59 | 60 | -------------------------------------------------------------------------------- /tests/cases/decode/sse.s.expect: -------------------------------------------------------------------------------- 1 | BB f1 (49 instructions): 2 | f1: 66 48 0f 7e c0 movq %xmm0,%rax 3 | f1+5: 66 48 0f 7e fe movq %xmm7,%rsi 4 | f1+10: 66 4c 0f 7e f8 movq %xmm15,%rax 5 | f1+15: 66 4d 0f 7e ff movq %xmm15,%r15 6 | f1+20: 66 48 0f 6e c0 movq %rax,%xmm0 7 | f1+25: 66 49 0f 6e f9 movq %r9,%xmm7 8 | f1+30: 66 4c 0f 6e f8 movq %rax,%xmm15 9 | f1+35: 66 4d 0f 6e ff movq %r15,%xmm15 10 | f1+40: f3 0f 10 07 movss (%rdi),%xmm0 11 | f1+44: f2 0f 10 07 movsd (%rdi),%xmm0 12 | f1+48: 0f 10 07 movups (%rdi),%xmm0 13 | f1+51: 66 0f 10 07 movupd (%rdi),%xmm0 14 | f1+55: 0f 28 07 movaps (%rdi),%xmm0 15 | f1+58: 66 0f 28 07 movapd (%rdi),%xmm0 16 | f1+62: f3 0f 11 07 movss %xmm0,(%rdi) 17 | f1+66: f2 0f 11 07 movsd %xmm0,(%rdi) 18 | f1+70: 0f 11 07 movups %xmm0,(%rdi) 19 | f1+73: 66 0f 11 07 movupd %xmm0,(%rdi) 20 | f1+77: 0f 29 07 movaps %xmm0,(%rdi) 21 | f1+80: 66 0f 29 07 movapd %xmm0,(%rdi) 22 | f1+84: f3 0f 7e c1 movq %xmm1,%xmm0 23 | f1+88: 66 0f d6 0a movq %xmm1,(%rdx) 24 | f1+92: f3 0f 7e 02 movq (%rdx),%xmm0 25 | f1+96: 0f 6f 02 movq (%rdx),%xmm0 26 | f1+99: f3 0f 6f 02 movdqu (%rdx),%xmm0 27 | f1+103: f3 0f 7f 02 movdqu %xmm0,(%rdx) 28 | f1+107: 66 0f 6f 02 movdqa (%rdx),%xmm0 29 | f1+111: 66 0f 7f 02 movdqa %xmm0,(%rdx) 30 | f1+115: 66 0f 6e 02 movd (%rdx),%xmm0 31 | f1+119: 66 0f 7e 02 movd %xmm0,(%rdx) 32 | f1+123: 66 44 0f 13 16 movlpd %xmm10,(%rsi) 33 | f1+128: 66 0f 12 07 movlpd (%rdi),%xmm0 34 | f1+132: 44 0f 13 16 movlps %xmm10,(%rsi) 35 | f1+136: 0f 12 07 movlps (%rdi),%xmm0 36 | f1+139: 66 44 0f 17 16 movhpd %xmm10,(%rsi) 37 | f1+144: 66 0f 16 07 movhpd (%rdi),%xmm0 38 | f1+148: 44 0f 17 16 movhps %xmm10,(%rsi) 39 | f1+152: 0f 16 07 movhps (%rdi),%xmm0 40 | f1+155: 66 0f 14 c1 unpcklpd %xmm1,%xmm0 41 | f1+159: 66 0f 14 07 unpcklpd (%rdi),%xmm0 42 | f1+163: 0f 14 c1 unpcklps %xmm1,%xmm0 43 | f1+166: 0f 14 07 unpcklps (%rdi),%xmm0 44 | f1+169: 66 0f 15 c1 unpckhpd %xmm1,%xmm0 45 | f1+173: 66 0f 15 07 unpckhpd (%rdi),%xmm0 46 | f1+177: 0f 15 c1 unpckhps %xmm1,%xmm0 47 | f1+180: 0f 15 07 unpckhps (%rdi),%xmm0 48 | f1+183: 66 0f d4 c1 paddq %xmm1,%xmm0 49 | f1+187: 66 0f d4 00 paddq (%rax),%xmm0 50 | f1+191: c3 ret 51 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-5-avx.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 -mavx 3 | //!args=5 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-5-avx.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: generic, rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 5 3 | Residuum after 10 iterations: 784.83623743 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-5.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 3 | //!args=5 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-5.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: generic, rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 5 3 | Residuum after 10 iterations: 784.83623743 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-6-avx.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 -mavx 3 | //!args=6 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-6-avx.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: grouped generic, rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 6 3 | Residuum after 10 iterations: 784.83623743 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-6.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 3 | //!args=6 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-6.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: grouped generic, rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 6 3 | Residuum after 10 iterations: 784.83623743 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-7-avx.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 -mavx 3 | //!args=7 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-7-avx.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: manual, rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 7 3 | Residuum after 10 iterations: 784.83623743 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-7.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 3 | //!args=7 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-7.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: manual, rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 7 3 | Residuum after 10 iterations: 784.83623743 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-8-avx.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 -mavx 3 | //!args=8 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-8-avx.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: (center), rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 8 3 | Residuum after 10 iterations: 0.00000000 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-8.c: -------------------------------------------------------------------------------- 1 | //!driver=../examples/stencil.c 2 | //!ccflags=-std=c99 -O2 3 | //!args=8 1002 10 4 | -------------------------------------------------------------------------------- /tests/cases/examples/stencil-8.c.expect: -------------------------------------------------------------------------------- 1 | Stencil code version: (center), rewriting. 2 | Width 1002, matrix size 8032032, 10 iterations, apply V 8 3 | Residuum after 10 iterations: 0.00000000 4 | -------------------------------------------------------------------------------- /tests/cases/generator/avx.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | vaddss xmm2, xmm0, xmm1 8 | vaddsd xmm2, xmm0, xmm1 9 | vaddps xmm2, xmm0, xmm1 10 | vaddpd xmm2, xmm0, xmm1 11 | vaddss xmm2, xmm0, [rax] 12 | vaddsd xmm2, xmm0, [rax] 13 | vaddps xmm2, xmm0, [rax] 14 | vaddpd xmm2, xmm0, [rax] 15 | 16 | vaddps ymm2, ymm0, ymm1 17 | vaddpd ymm2, ymm0, ymm1 18 | vaddps ymm2, ymm0, [rax] 19 | vaddpd ymm2, ymm0, [rax] 20 | 21 | vmulss xmm2, xmm0, xmm1 22 | vmulsd xmm2, xmm0, xmm1 23 | vmulps xmm2, xmm0, xmm1 24 | vmulpd xmm2, xmm0, xmm1 25 | vmulss xmm2, xmm0, [rax] 26 | vmulsd xmm2, xmm0, [rax] 27 | vmulps xmm2, xmm0, [rax] 28 | vmulpd xmm2, xmm0, [rax] 29 | 30 | vmulps ymm2, ymm0, ymm1 31 | vmulpd ymm2, ymm0, ymm1 32 | vmulps ymm2, ymm0, [rax] 33 | vmulpd ymm2, ymm0, [rax] 34 | 35 | vxorps xmm2, xmm0, xmm1 36 | vxorpd xmm2, xmm0, xmm1 37 | vxorps xmm2, xmm0, [rax] 38 | vxorpd xmm2, xmm0, [rax] 39 | vxorps ymm2, ymm0, ymm1 40 | vxorpd ymm2, ymm0, ymm1 41 | vxorps ymm2, ymm0, [rax] 42 | vxorpd ymm2, ymm0, [rax] 43 | 44 | vmovss xmm0, [rax] 45 | vmovsd xmm0, [rax] 46 | vmovaps xmm0, [rax] 47 | vmovapd xmm0, [rax] 48 | vmovups xmm0, [rax] 49 | vmovupd xmm0, [rax] 50 | vmovdqu xmm0, [rax] 51 | vmovdqa xmm0, [rax] 52 | vmovss [rax], xmm0 53 | vmovsd [rax], xmm0 54 | vmovaps [rax], xmm0 55 | vmovapd [rax], xmm0 56 | vmovups [rax], xmm0 57 | vmovupd [rax], xmm0 58 | vmovdqu [rax], xmm0 59 | vmovdqa [rax], xmm0 60 | 61 | vmovaps ymm0, [rax] 62 | vmovapd ymm0, [rax] 63 | vmovups ymm0, [rax] 64 | vmovupd ymm0, [rax] 65 | vmovdqu ymm0, [rax] 66 | vmovdqa ymm0, [rax] 67 | vmovaps [rax], ymm0 68 | vmovapd [rax], ymm0 69 | vmovups [rax], ymm0 70 | vmovupd [rax], ymm0 71 | vmovdqu [rax], ymm0 72 | vmovdqa [rax], ymm0 73 | 74 | vmovntdq [rax], xmm0 75 | vmovntdq [rax], ymm0 76 | 77 | ret 78 | -------------------------------------------------------------------------------- /tests/cases/generator/it-add.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // ADD instructions, Intel Vol. 2A 3-29 8 | add [rdi], rax 9 | add [rdi], r9 10 | add [rdi], eax 11 | add [rdi], r9d 12 | add [rdi], ax 13 | add [rdi], r9w 14 | add [rdi], al 15 | add [rdi], r9b 16 | 17 | add rax, [rdi] 18 | add r9, [rdi] 19 | add eax, [rdi] 20 | add r9d, [rdi] 21 | add ax, [rdi] 22 | add r9w, [rdi] 23 | add al, [rdi] 24 | add r9b, [rdi] 25 | 26 | add al, 0x10 27 | add ax, 0x1000 28 | add ax, 0x10 29 | add eax, 0xabcdef00 30 | add eax, 0x10 31 | add rax, 0x0bcdef00 32 | add rax, 0x10 33 | 34 | add byte ptr [rax], 0x10 35 | add word ptr [rax], 0x310 36 | add dword ptr [rax], 0x310 37 | add qword ptr [rax], 0x310 38 | 39 | add al, r9b 40 | add r10b, bl 41 | add cl, dl 42 | add sil, dil 43 | add eax, r9d 44 | add r10d, ebx 45 | add rax, r9 46 | add r10, rbx 47 | 48 | add al, sil 49 | add sil, al 50 | add al, ah 51 | add ah, bl 52 | add bl, bh 53 | add cl, ch 54 | add dl, dh 55 | 56 | add bl, 0x10 57 | add bx, 0x1000 58 | add bx, 0x10 59 | add ebx, 0xabcdef00 60 | add ebx, 0x10 61 | add rbx, 0x0bcdef00 62 | add rbx, 0x10 63 | 64 | add r9b, 0x10 65 | add r9w, 0x1000 66 | add r9w, 0x10 67 | add r9d, 0xabcdef00 68 | add r9d, 0x10 69 | add r9, 0x0bcdef00 70 | add r9, 0x10 71 | 72 | ret 73 | -------------------------------------------------------------------------------- /tests/cases/generator/it-add.s.expect: -------------------------------------------------------------------------------- 1 | BB f1gen (57 instructions): 2 | f1gen: 48 01 07 add %rax,(%rdi) 3 | f1gen+3: 4c 01 0f add %r9,(%rdi) 4 | f1gen+6: 01 07 add %eax,(%rdi) 5 | f1gen+8: 44 01 0f add %r9d,(%rdi) 6 | f1gen+11: 66 01 07 add %ax,(%rdi) 7 | f1gen+14: 66 44 01 0f add %r9w,(%rdi) 8 | f1gen+18: 00 07 add %al,(%rdi) 9 | f1gen+20: 44 00 0f add %r9b,(%rdi) 10 | f1gen+23: 48 03 07 add (%rdi),%rax 11 | f1gen+26: 4c 03 0f add (%rdi),%r9 12 | f1gen+29: 03 07 add (%rdi),%eax 13 | f1gen+31: 44 03 0f add (%rdi),%r9d 14 | f1gen+34: 66 03 07 add (%rdi),%ax 15 | f1gen+37: 66 44 03 0f add (%rdi),%r9w 16 | f1gen+41: 02 07 add (%rdi),%al 17 | f1gen+43: 44 02 0f add (%rdi),%r9b 18 | f1gen+46: 04 10 add $0x10,%al 19 | f1gen+48: 66 05 00 10 add $0x1000,%ax 20 | f1gen+52: 66 83 c0 10 add $0x10,%ax 21 | f1gen+56: 05 00 ef cd ab add $0xabcdef00,%eax 22 | f1gen+61: 83 c0 10 add $0x10,%eax 23 | f1gen+64: 48 05 00 ef cd 0b add $0xbcdef00,%rax 24 | f1gen+70: 48 83 c0 10 add $0x10,%rax 25 | f1gen+74: 80 00 10 addb $0x10,(%rax) 26 | f1gen+77: 66 81 00 10 03 addw $0x310,(%rax) 27 | f1gen+82: 81 00 10 03 00 00 addl $0x310,(%rax) 28 | f1gen+88: 48 81 00 10 03 00 00 addq $0x310,(%rax) 29 | f1gen+95: 44 00 c8 add %r9b,%al 30 | f1gen+98: 41 00 da add %bl,%r10b 31 | f1gen+101: 00 d1 add %dl,%cl 32 | f1gen+103: 40 00 fe add %dil,%sil 33 | f1gen+106: 44 01 c8 add %r9d,%eax 34 | f1gen+109: 41 01 da add %ebx,%r10d 35 | f1gen+112: 4c 01 c8 add %r9,%rax 36 | f1gen+115: 49 01 da add %rbx,%r10 37 | f1gen+118: 40 00 f0 add %sil,%al 38 | f1gen+121: 40 00 c6 add %al,%sil 39 | f1gen+124: 00 e0 add %ah,%al 40 | f1gen+126: 00 dc add %bl,%ah 41 | f1gen+128: 00 fb add %bh,%bl 42 | f1gen+130: 00 e9 add %ch,%cl 43 | f1gen+132: 00 f2 add %dh,%dl 44 | f1gen+134: 80 c3 10 add $0x10,%bl 45 | f1gen+137: 66 81 c3 00 10 add $0x1000,%bx 46 | f1gen+142: 66 83 c3 10 add $0x10,%bx 47 | f1gen+146: 81 c3 00 ef cd ab add $0xabcdef00,%ebx 48 | f1gen+152: 83 c3 10 add $0x10,%ebx 49 | f1gen+155: 48 81 c3 00 ef cd 0b add $0xbcdef00,%rbx 50 | f1gen+162: 48 83 c3 10 add $0x10,%rbx 51 | f1gen+166: 41 80 c1 10 add $0x10,%r9b 52 | f1gen+170: 66 41 81 c1 00 10 add $0x1000,%r9w 53 | f1gen+176: 66 41 83 c1 10 add $0x10,%r9w 54 | f1gen+181: 41 81 c1 00 ef cd ab add $0xabcdef00,%r9d 55 | f1gen+188: 41 83 c1 10 add $0x10,%r9d 56 | f1gen+192: 49 81 c1 00 ef cd 0b add $0xbcdef00,%r9 57 | f1gen+199: 49 83 c1 10 add $0x10,%r9 58 | f1gen+203: c3 ret 59 | -------------------------------------------------------------------------------- /tests/cases/generator/it-and-imm.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | and al, 4 8 | and ax, 4 9 | and ax, 400 10 | and eax, 4 11 | and eax, 400 12 | and eax, 400000 13 | and rax, 4 14 | and rax, 400 15 | and rax, 400000 16 | 17 | and al, -4 18 | and ax, -4 19 | and ax, -400 20 | and eax, -4 21 | and eax, -400 22 | and eax, -400000 23 | and rax, -4 24 | and rax, -400 25 | and rax, -400000 26 | ret 27 | -------------------------------------------------------------------------------- /tests/cases/generator/it-and-imm.s.expect: -------------------------------------------------------------------------------- 1 | BB f1gen (19 instructions): 2 | f1gen: 24 04 and $0x4,%al 3 | f1gen+2: 66 83 e0 04 and $0x4,%ax 4 | f1gen+6: 66 25 90 01 and $0x190,%ax 5 | f1gen+10: 83 e0 04 and $0x4,%eax 6 | f1gen+13: 25 90 01 00 00 and $0x190,%eax 7 | f1gen+18: 25 80 1a 06 00 and $0x61a80,%eax 8 | f1gen+23: 48 83 e0 04 and $0x4,%rax 9 | f1gen+27: 48 25 90 01 00 00 and $0x190,%rax 10 | f1gen+33: 48 25 80 1a 06 00 and $0x61a80,%rax 11 | f1gen+39: 24 fc and $0xfc,%al 12 | f1gen+41: 66 83 e0 fc and $0xfffc,%ax 13 | f1gen+45: 66 25 70 fe and $0xfe70,%ax 14 | f1gen+49: 83 e0 fc and $0xfffffffc,%eax 15 | f1gen+52: 25 70 fe ff ff and $0xfffffe70,%eax 16 | f1gen+57: 25 80 e5 f9 ff and $0xfff9e580,%eax 17 | f1gen+62: 48 83 e0 fc and $0xfffffffffffffffc,%rax 18 | f1gen+66: 48 25 70 fe ff ff and $0xfffffffffffffe70,%rax 19 | f1gen+72: 48 25 80 e5 f9 ff and $0xfffffffffff9e580,%rax 20 | f1gen+78: c3 ret 21 | -------------------------------------------------------------------------------- /tests/cases/generator/it-pxor.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | pxor mm1, mm2 8 | pxor mm1, [rdi] 9 | pxor mm1, [r9] 10 | 11 | pxor xmm3, xmm4 12 | pxor xmm3, xmm9 13 | pxor xmm3, [rdi] 14 | pxor xmm9, [rdi] 15 | pxor xmm3, [r9] 16 | pxor xmm9, [r9] 17 | 18 | ret 19 | -------------------------------------------------------------------------------- /tests/cases/generator/it-pxor.s.expect: -------------------------------------------------------------------------------- 1 | BB f1gen (10 instructions): 2 | f1gen: 0f ef ca pxor %mm2,%mm1 3 | f1gen+3: 0f ef 0f pxor (%rdi),%mm1 4 | f1gen+6: 41 0f ef 09 pxor (%r9),%mm1 5 | f1gen+10: 66 0f ef dc pxor %xmm4,%xmm3 6 | f1gen+14: 66 41 0f ef d9 pxor %xmm9,%xmm3 7 | f1gen+19: 66 0f ef 1f pxor (%rdi),%xmm3 8 | f1gen+23: 66 44 0f ef 0f pxor (%rdi),%xmm9 9 | f1gen+28: 66 41 0f ef 19 pxor (%r9),%xmm3 10 | f1gen+33: 66 45 0f ef 09 pxor (%r9),%xmm9 11 | f1gen+38: c3 ret 12 | -------------------------------------------------------------------------------- /tests/cases/generator/it-test.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | // TEST instructions, Intel Vol. 2B 4-428 8 | test [rdi], rax 9 | test [rdi], r9 10 | test [rdi], eax 11 | test [rdi], r9d 12 | test [rdi], ax 13 | test [rdi], r9w 14 | test [rdi], al 15 | test [rdi], r9b 16 | 17 | test al, r9b 18 | test r10b, bl 19 | test cl, dl 20 | test sil, dil 21 | test eax, r9d 22 | test r10d, ebx 23 | test rax, r9 24 | test r10, rbx 25 | 26 | test al, 0x10 27 | test ax, 0x1000 28 | test eax, 0xabcdef00 29 | test rax, 0x0bcdef00 30 | test bl, 0x10 31 | test bx, 0x1000 32 | test ebx, 0xabcdef00 33 | test rbx, 0x0bcdef00 34 | test r9b, 0x10 35 | test r9w, 0x1000 36 | test r9d, 0xabcdef00 37 | test r9, 0x0bcdef00 38 | test byte ptr [rax], 0x10 39 | test word ptr [rax], 0x310 40 | test dword ptr [rax], 0x310 41 | test qword ptr [rax], 0x310 42 | 43 | test al, sil 44 | test sil, al 45 | test al, ah 46 | test ah, bl 47 | test bl, bh 48 | test cl, ch 49 | test dl, dh 50 | ret 51 | -------------------------------------------------------------------------------- /tests/cases/generator/it-test.s.expect: -------------------------------------------------------------------------------- 1 | BB f1gen (40 instructions): 2 | f1gen: 48 85 07 test %rax,(%rdi) 3 | f1gen+3: 4c 85 0f test %r9,(%rdi) 4 | f1gen+6: 85 07 test %eax,(%rdi) 5 | f1gen+8: 44 85 0f test %r9d,(%rdi) 6 | f1gen+11: 66 85 07 test %ax,(%rdi) 7 | f1gen+14: 66 44 85 0f test %r9w,(%rdi) 8 | f1gen+18: 84 07 test %al,(%rdi) 9 | f1gen+20: 44 84 0f test %r9b,(%rdi) 10 | f1gen+23: 44 84 c8 test %r9b,%al 11 | f1gen+26: 41 84 da test %bl,%r10b 12 | f1gen+29: 84 d1 test %dl,%cl 13 | f1gen+31: 40 84 fe test %dil,%sil 14 | f1gen+34: 44 85 c8 test %r9d,%eax 15 | f1gen+37: 41 85 da test %ebx,%r10d 16 | f1gen+40: 4c 85 c8 test %r9,%rax 17 | f1gen+43: 49 85 da test %rbx,%r10 18 | f1gen+46: a8 10 test $0x10,%al 19 | f1gen+48: 66 a9 00 10 test $0x1000,%ax 20 | f1gen+52: a9 00 ef cd ab test $0xabcdef00,%eax 21 | f1gen+57: 48 a9 00 ef cd 0b test $0xbcdef00,%rax 22 | f1gen+63: f6 c3 10 test $0x10,%bl 23 | f1gen+66: 66 f7 c3 00 10 test $0x1000,%bx 24 | f1gen+71: f7 c3 00 ef cd ab test $0xabcdef00,%ebx 25 | f1gen+77: 48 f7 c3 00 ef cd 0b test $0xbcdef00,%rbx 26 | f1gen+84: 41 f6 c1 10 test $0x10,%r9b 27 | f1gen+88: 66 41 f7 c1 00 10 test $0x1000,%r9w 28 | f1gen+94: 41 f7 c1 00 ef cd ab test $0xabcdef00,%r9d 29 | f1gen+101: 49 f7 c1 00 ef cd 0b test $0xbcdef00,%r9 30 | f1gen+108: f6 00 10 testb $0x10,(%rax) 31 | f1gen+111: 66 f7 00 10 03 testw $0x310,(%rax) 32 | f1gen+116: f7 00 10 03 00 00 testl $0x310,(%rax) 33 | f1gen+122: 48 f7 00 10 03 00 00 testq $0x310,(%rax) 34 | f1gen+129: 40 84 f0 test %sil,%al 35 | f1gen+132: 40 84 c6 test %al,%sil 36 | f1gen+135: 84 e0 test %ah,%al 37 | f1gen+137: 84 dc test %bl,%ah 38 | f1gen+139: 84 fb test %bh,%bl 39 | f1gen+141: 84 e9 test %ch,%cl 40 | f1gen+143: 84 f2 test %dh,%dl 41 | f1gen+145: c3 ret 42 | -------------------------------------------------------------------------------- /tests/cases/generator/it-undef.c: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-generate.c 2 | #include 3 | 4 | void test_fill_instruction(Instr*); 5 | 6 | void 7 | test_fill_instruction(Instr* instr) 8 | { 9 | initSimpleInstr(instr, IT_Invalid); 10 | } 11 | -------------------------------------------------------------------------------- /tests/cases/generator/it-undef.c.expect: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caps-tum/dbrew/10a202f3f209d2f2ef5c08aba15d9b3e01b3a5ba/tests/cases/generator/it-undef.c.expect -------------------------------------------------------------------------------- /tests/cases/generator/it-undef.c.expect_stderr: -------------------------------------------------------------------------------- 1 | Generator error at instr 0 '' in BB (0x0): unsupported instruction. Stopped 2 | -------------------------------------------------------------------------------- /tests/cases/generator/modrm.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | inc rax 8 | inc rbp 9 | inc r9 10 | inc qword ptr [r9] 11 | inc qword ptr [r9 + rax] 12 | inc qword ptr [r9 + 1 * rax] 13 | inc qword ptr [r9 + 2 * rdx] 14 | inc qword ptr [r9 + 4 * rdx] 15 | inc qword ptr [r9 + 8 * rdx] 16 | inc qword ptr [0x10 + r9] 17 | inc qword ptr [0x10 + r9 + r14] 18 | inc qword ptr [0x10 + r9 + 1 * r14] 19 | inc qword ptr [0x10 + r9 + 2 * r14] 20 | inc qword ptr [0x10 + r9 + 4 * r14] 21 | inc qword ptr [0x10 + r9 + 8 * r14] 22 | inc qword ptr [0x1000 + r9] 23 | inc qword ptr [0x1000 + r9 + rax] 24 | inc qword ptr [0x1000 + r9 + 1 * rax] 25 | inc qword ptr [0x1000 + r9 + 2 * rdx] 26 | inc qword ptr [0x1000 + r9 + 4 * rdx] 27 | inc qword ptr [0x1000 + r9 + 8 * rdx] 28 | inc qword ptr [0x1000 + 2 * rdx] 29 | inc qword ptr [0x1000 + 4 * rdx] 30 | inc qword ptr [0x1000 + 8 * rdx] 31 | // inc qword ptr [rip] 32 | // inc qword ptr [rip + 0x100] 33 | 34 | add rbp, rax 35 | add rbp, rbp 36 | add rbp, r9 37 | add rbp, qword ptr [r9] 38 | add rbp, qword ptr [r9 + rax] 39 | add rbp, qword ptr [r9 + 1 * rax] 40 | add rbp, qword ptr [r9 + 2 * rdx] 41 | add rbp, qword ptr [r9 + 4 * rdx] 42 | add rbp, qword ptr [r9 + 8 * rdx] 43 | add rbp, qword ptr [0x10 + r9] 44 | add rbp, qword ptr [0x10 + r9 + r14] 45 | add rbp, qword ptr [0x10 + r9 + 1 * r14] 46 | add rbp, qword ptr [0x10 + r9 + 2 * r14] 47 | add rbp, qword ptr [0x10 + r9 + 4 * r14] 48 | add rbp, qword ptr [0x10 + r9 + 8 * r14] 49 | add rbp, qword ptr [0x1000 + r9] 50 | add rbp, qword ptr [0x1000 + r9 + rax] 51 | add rbp, qword ptr [0x1000 + r9 + 1 * rax] 52 | add rbp, qword ptr [0x1000 + r9 + 2 * rdx] 53 | add rbp, qword ptr [0x1000 + r9 + 4 * rdx] 54 | add rbp, qword ptr [0x1000 + r9 + 8 * rdx] 55 | add rbp, qword ptr [0x1000 + 2 * r15] 56 | add rbp, qword ptr [0x1000 + 4 * r15] 57 | add rbp, qword ptr [0x1000 + 8 * r15] 58 | // add rbp, qword ptr [rip] 59 | // add rbp, qword ptr [rip + 0x100] 60 | 61 | add r9, rax 62 | add r9, rbp 63 | add r9, r9 64 | add r9, qword ptr [r9] 65 | add r9, qword ptr [r9 + rax] 66 | add r9, qword ptr [r9 + 1 * rax] 67 | add r9, qword ptr [r9 + 2 * rdx] 68 | add r9, qword ptr [r9 + 4 * rdx] 69 | add r9, qword ptr [r9 + 8 * rdx] 70 | add r9, qword ptr [0x10 + r9] 71 | add r9, qword ptr [0x10 + r9 + r14] 72 | add r9, qword ptr [0x10 + r9 + 1 * r14] 73 | add r9, qword ptr [0x10 + r9 + 2 * r14] 74 | add r9, qword ptr [0x10 + r9 + 4 * r14] 75 | add r9, qword ptr [0x10 + r9 + 8 * r14] 76 | add r9, qword ptr [0x1000 + r9] 77 | add r9, qword ptr [0x1000 + r9 + rax] 78 | add r9, qword ptr [0x1000 + r9 + 1 * rax] 79 | add r9, qword ptr [0x1000 + r9 + 2 * rdx] 80 | add r9, qword ptr [0x1000 + r9 + 4 * rdx] 81 | add r9, qword ptr [0x1000 + r9 + 8 * rdx] 82 | add r9, qword ptr [0x1000 + 2 * r15] 83 | add r9, qword ptr [0x1000 + 4 * r15] 84 | add r9, qword ptr [0x1000 + 8 * r15] 85 | // add r9, qword ptr [rip] 86 | // add r9, qword ptr [rip + 0x100] 87 | 88 | mov r9, qword ptr [rsp + 8 * rax] 89 | mov r9, qword ptr [rbp + 8 * rax] 90 | mov r9, qword ptr [rsi + 8 * rax] 91 | mov r9, qword ptr [r12 + 8 * rax] 92 | mov r9, qword ptr [r13 + 8 * rax] 93 | mov r9, qword ptr [r14 + 8 * rax] 94 | mov r9, qword ptr [0x12345678 + 8 * rax] 95 | // same as before, using r13 instead of rbp as base (marker for no base) 96 | .byte 0x4d,0x8b,0x0c,0xc5,0x12,0x34,0x56,0x78 97 | 98 | // test indirect with rsp/r12: needs SIB encoding 99 | add r9, [0x8 + rbx] 100 | add r9, [0x8 + rsp] 101 | add r9, [0x8 + rbp] 102 | add r9, [0x8 + r11] 103 | add r9, [0x8 + r12] 104 | add r9, [0x8 + r13] 105 | 106 | mov r9, qword ptr [rsp] 107 | mov r9, qword ptr [rbp] 108 | mov r9, qword ptr [rsi] 109 | mov r9, qword ptr [r12] 110 | mov r9, qword ptr [r13] 111 | mov r9, qword ptr [r14] 112 | 113 | lea r9, [0x1000 + r9 + 8 * r12] 114 | 115 | ret 116 | 117 | -------------------------------------------------------------------------------- /tests/cases/generator/op-ret.c: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-generate.c 2 | 3 | #include 4 | 5 | void test_fill_instruction(Instr*); 6 | 7 | void 8 | test_fill_instruction(Instr* instr) 9 | { 10 | initSimpleInstr(instr, IT_RET); 11 | } 12 | -------------------------------------------------------------------------------- /tests/cases/generator/op-ret.c.expect: -------------------------------------------------------------------------------- 1 | Instruction: ret 2 | Generated: c3 3 | -------------------------------------------------------------------------------- /tests/cases/generator/sse.s: -------------------------------------------------------------------------------- 1 | //!driver = test-driver-gen.c 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | movq rax, xmm0 8 | movq rsi, xmm7 9 | movq rax, xmm15 10 | movq r15, xmm15 11 | movq xmm0, rax 12 | movq xmm7, r9 13 | movq xmm15, rax 14 | movq xmm15, r15 15 | movss xmm0, [rdi] 16 | movsd xmm0, [rdi] 17 | movups xmm0, [rdi] 18 | movupd xmm0, [rdi] 19 | movaps xmm0, [rdi] 20 | movapd xmm0, [rdi] 21 | movss [rdi], xmm0 22 | movsd [rdi], xmm0 23 | movups [rdi], xmm0 24 | movupd [rdi], xmm0 25 | movaps [rdi], xmm0 26 | movapd [rdi], xmm0 27 | movq xmm0, xmm1 28 | movq [rdx], xmm1 29 | movq xmm0, [rdx] 30 | movq mm0, [rdx] 31 | movdqu xmm0, [rdx] 32 | movdqu [rdx], xmm0 33 | movdqa xmm0, [rdx] 34 | movdqa [rdx], xmm0 35 | movd xmm0, [rdx] 36 | movd [rdx], xmm0 37 | movlpd [rsi], xmm10 38 | movlpd xmm0, [rdi] 39 | movlps [rsi], xmm10 40 | movlps xmm0, [rdi] 41 | movhpd [rsi], xmm10 42 | movhpd xmm0, [rdi] 43 | movhps [rsi], xmm10 44 | movhps xmm0, [rdi] 45 | 46 | unpcklpd xmm0, xmm1 47 | unpcklpd xmm0, [rdi] 48 | unpcklps xmm0, xmm1 49 | unpcklps xmm0, [rdi] 50 | unpckhpd xmm0, xmm1 51 | unpckhpd xmm0, [rdi] 52 | unpckhps xmm0, xmm1 53 | unpckhps xmm0, [rdi] 54 | 55 | paddq xmm0, xmm1 56 | paddq xmm0, [rax] 57 | 58 | ret 59 | 60 | -------------------------------------------------------------------------------- /tests/cases/generator/sse.s.expect: -------------------------------------------------------------------------------- 1 | BB f1gen (49 instructions): 2 | f1gen: 66 48 0f 7e c0 movq %xmm0,%rax 3 | f1gen+5: 66 48 0f 7e fe movq %xmm7,%rsi 4 | f1gen+10: 66 4c 0f 7e f8 movq %xmm15,%rax 5 | f1gen+15: 66 4d 0f 7e ff movq %xmm15,%r15 6 | f1gen+20: 66 48 0f 6e c0 movq %rax,%xmm0 7 | f1gen+25: 66 49 0f 6e f9 movq %r9,%xmm7 8 | f1gen+30: 66 4c 0f 6e f8 movq %rax,%xmm15 9 | f1gen+35: 66 4d 0f 6e ff movq %r15,%xmm15 10 | f1gen+40: f3 0f 10 07 movss (%rdi),%xmm0 11 | f1gen+44: f2 0f 10 07 movsd (%rdi),%xmm0 12 | f1gen+48: 0f 10 07 movups (%rdi),%xmm0 13 | f1gen+51: 66 0f 10 07 movupd (%rdi),%xmm0 14 | f1gen+55: 0f 28 07 movaps (%rdi),%xmm0 15 | f1gen+58: 66 0f 28 07 movapd (%rdi),%xmm0 16 | f1gen+62: f3 0f 11 07 movss %xmm0,(%rdi) 17 | f1gen+66: f2 0f 11 07 movsd %xmm0,(%rdi) 18 | f1gen+70: 0f 11 07 movups %xmm0,(%rdi) 19 | f1gen+73: 66 0f 11 07 movupd %xmm0,(%rdi) 20 | f1gen+77: 0f 29 07 movaps %xmm0,(%rdi) 21 | f1gen+80: 66 0f 29 07 movapd %xmm0,(%rdi) 22 | f1gen+84: f3 0f 7e c1 movq %xmm1,%xmm0 23 | f1gen+88: 66 0f d6 0a movq %xmm1,(%rdx) 24 | f1gen+92: f3 0f 7e 02 movq (%rdx),%xmm0 25 | f1gen+96: 0f 6f 02 movq (%rdx),%xmm0 26 | f1gen+99: f3 0f 6f 02 movdqu (%rdx),%xmm0 27 | f1gen+103: f3 0f 7f 02 movdqu %xmm0,(%rdx) 28 | f1gen+107: 66 0f 6f 02 movdqa (%rdx),%xmm0 29 | f1gen+111: 66 0f 7f 02 movdqa %xmm0,(%rdx) 30 | f1gen+115: 66 0f 6e 02 movd (%rdx),%xmm0 31 | f1gen+119: 66 0f 7e 02 movd %xmm0,(%rdx) 32 | f1gen+123: 66 44 0f 13 16 movlpd %xmm10,(%rsi) 33 | f1gen+128: 66 0f 12 07 movlpd (%rdi),%xmm0 34 | f1gen+132: 44 0f 13 16 movlps %xmm10,(%rsi) 35 | f1gen+136: 0f 12 07 movlps (%rdi),%xmm0 36 | f1gen+139: 66 44 0f 17 16 movhpd %xmm10,(%rsi) 37 | f1gen+144: 66 0f 16 07 movhpd (%rdi),%xmm0 38 | f1gen+148: 44 0f 17 16 movhps %xmm10,(%rsi) 39 | f1gen+152: 0f 16 07 movhps (%rdi),%xmm0 40 | f1gen+155: 66 0f 14 c1 unpcklpd %xmm1,%xmm0 41 | f1gen+159: 66 0f 14 07 unpcklpd (%rdi),%xmm0 42 | f1gen+163: 0f 14 c1 unpcklps %xmm1,%xmm0 43 | f1gen+166: 0f 14 07 unpcklps (%rdi),%xmm0 44 | f1gen+169: 66 0f 15 c1 unpckhpd %xmm1,%xmm0 45 | f1gen+173: 66 0f 15 07 unpckhpd (%rdi),%xmm0 46 | f1gen+177: 0f 15 c1 unpckhps %xmm1,%xmm0 47 | f1gen+180: 0f 15 07 unpckhps (%rdi),%xmm0 48 | f1gen+183: 66 0f d4 c1 paddq %xmm1,%xmm0 49 | f1gen+187: 66 0f d4 00 paddq (%rax),%xmm0 50 | f1gen+191: c3 ret 51 | -------------------------------------------------------------------------------- /tests/cases/integration/fp.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | xor rax, rax 7 | movq xmm0, rdi 8 | movq xmm1, rsi 9 | addsd xmm0, xmm1 10 | movq rax, xmm0 11 | ret 12 | -------------------------------------------------------------------------------- /tests/cases/integration/fp.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 31 c0 xor %rax,%rax 11 | test+3: 66 48 0f 6e c7 movq %rdi,%xmm0 12 | test+8: 66 48 0f 6e ce movq %rsi,%xmm1 13 | test+13: f2 0f 58 c1 addsd %xmm1,%xmm0 14 | test+17: 66 48 0f 7e c0 movq %xmm0,%rax 15 | test+22: c3 ret 16 | Emulate 'test: xor %rax,%rax' 17 | Emulate 'test+3: movq %rdi,%xmm0' 18 | Capture 'movq %rdi,%xmm0' (into test|0 + 1) 19 | Emulate 'test+8: movq %rsi,%xmm1' 20 | Capture 'movq %rsi,%xmm1' (into test|0 + 2) 21 | Emulate 'test+13: addsd %xmm1,%xmm0' 22 | Capture 'addsd %xmm1,%xmm0' (into test|0 + 3) 23 | Emulate 'test+17: movq %xmm0,%rax' 24 | Capture 'movq %xmm0,%rax' (into test|0 + 4) 25 | Emulate 'test+22: ret' 26 | Capture 'H-ret' (into test|0 + 5) 27 | Capture 'ret' (into test|0 + 6) 28 | Generating code for BB test|0 (7 instructions) 29 | I 0 : H-call (test|0)+0 30 | I 1 : movq %rdi,%xmm0 (test|0)+0 66 48 0f 6e c7 31 | I 2 : movq %rsi,%xmm1 (test|0)+5 66 48 0f 6e ce 32 | I 3 : addsd %xmm1,%xmm0 (test|0)+10 f2 0f 58 c1 33 | I 4 : movq %xmm0,%rax (test|0)+14 66 48 0f 7e c0 34 | I 5 : H-ret (test|0)+19 35 | I 6 : ret (test|0)+19 c3 36 | Generated: 20 bytes (pass1: 46) 37 | BB gen (5 instructions): 38 | gen: 66 48 0f 6e c7 movq %rdi,%xmm0 39 | gen+5: 66 48 0f 6e ce movq %rsi,%xmm1 40 | gen+10: f2 0f 58 c1 addsd %xmm1,%xmm0 41 | gen+14: 66 48 0f 7e c0 movq %xmm0,%rax 42 | gen+19: c3 ret 43 | -------------------------------------------------------------------------------- /tests/cases/integration/it-and.s: -------------------------------------------------------------------------------- 1 | //!args=--var 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov %rdi,%rax 7 | and $0,%rax 8 | mov %rdi,%rbx 9 | and $0xffffffffffffffff,%rbx 10 | add %rbx,%rax 11 | ret 12 | -------------------------------------------------------------------------------- /tests/cases/integration/it-and.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase unknown par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 89 f8 mov %rdi,%rax 11 | test+3: 48 83 e0 00 and $0x0,%rax 12 | test+7: 48 89 fb mov %rdi,%rbx 13 | test+10: 48 83 e3 ff and $0xffffffffffffffff,%rbx 14 | test+14: 48 01 d8 add %rbx,%rax 15 | test+17: c3 ret 16 | Emulate 'test: mov %rdi,%rax' 17 | Capture 'mov %rdi,%rax' (into test|0 + 1) 18 | Emulate 'test+3: and $0x0,%rax' 19 | Emulate 'test+7: mov %rdi,%rbx' 20 | Capture 'mov %rdi,%rbx' (into test|0 + 2) 21 | Emulate 'test+10: and $0xffffffffffffffff,%rbx' 22 | Emulate 'test+14: add %rbx,%rax' 23 | Capture 'mov %rbx,%rax' (into test|0 + 3) 24 | Emulate 'test+17: ret' 25 | Capture 'H-ret' (into test|0 + 4) 26 | Capture 'ret' (into test|0 + 5) 27 | Generating code for BB test|0 (6 instructions) 28 | I 0 : H-call (test|0)+0 29 | I 1 : mov %rdi,%rax (test|0)+0 48 89 f8 30 | I 2 : mov %rdi,%rbx (test|0)+3 48 89 fb 31 | I 3 : mov %rbx,%rax (test|0)+6 48 89 d8 32 | I 4 : H-ret (test|0)+9 33 | I 5 : ret (test|0)+9 c3 34 | Generated: 10 bytes (pass1: 36) 35 | BB gen (4 instructions): 36 | gen: 48 89 f8 mov %rdi,%rax 37 | gen+3: 48 89 fb mov %rdi,%rbx 38 | gen+6: 48 89 d8 mov %rbx,%rax 39 | gen+9: c3 ret 40 | >>> Testcase known par = 1. 41 | Saving current emulator state: new with esID 0 42 | Capture 'H-call' (into test|0 + 0) 43 | Processing BB (test|0) 44 | Emulation Static State (esID 0, call depth 0): 45 | Registers: %rsp (R 0), %rdi (0x1) 46 | Flags: (none) 47 | Stack: (none) 48 | Decoding BB test ... 49 | test: 48 89 f8 mov %rdi,%rax 50 | test+3: 48 83 e0 00 and $0x0,%rax 51 | test+7: 48 89 fb mov %rdi,%rbx 52 | test+10: 48 83 e3 ff and $0xffffffffffffffff,%rbx 53 | test+14: 48 01 d8 add %rbx,%rax 54 | test+17: c3 ret 55 | Emulate 'test: mov %rdi,%rax' 56 | Emulate 'test+3: and $0x0,%rax' 57 | Emulate 'test+7: mov %rdi,%rbx' 58 | Emulate 'test+10: and $0xffffffffffffffff,%rbx' 59 | Emulate 'test+14: add %rbx,%rax' 60 | Emulate 'test+17: ret' 61 | Capture 'H-ret' (into test|0 + 1) 62 | Capture 'mov $0x1,%rax' (into test|0 + 2) 63 | Capture 'ret' (into test|0 + 3) 64 | Generating code for BB test|0 (4 instructions) 65 | I 0 : H-call (test|0)+0 66 | I 1 : H-ret (test|0)+0 67 | I 2 : mov $0x1,%rax (test|0)+0 48 c7 c0 01 00 00 00 68 | I 3 : ret (test|0)+7 c3 69 | Generated: 8 bytes (pass1: 34) 70 | BB gen (2 instructions): 71 | gen: 48 c7 c0 01 00 00 00 mov $0x1,%rax 72 | gen+7: c3 ret 73 | -------------------------------------------------------------------------------- /tests/cases/integration/it-cltq.s: -------------------------------------------------------------------------------- 1 | //!args=--var 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov %edi,%eax 7 | cltq 8 | mov %rax,%rdx 9 | mov %esi,%eax 10 | cwtl 11 | add %rdx,%rax 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/integration/it-cltq.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase unknown par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 89 f8 mov %edi,%eax 11 | test+2: 48 98 cltq 12 | test+4: 48 89 c2 mov %rax,%rdx 13 | test+7: 89 f0 mov %esi,%eax 14 | test+9: 98 cwtl 15 | test+10: 48 01 d0 add %rdx,%rax 16 | test+13: c3 ret 17 | Emulate 'test: mov %edi,%eax' 18 | Capture 'mov %edi,%eax' (into test|0 + 1) 19 | Emulate 'test+2: cltq' 20 | Capture 'cltq' (into test|0 + 2) 21 | Emulate 'test+4: mov %rax,%rdx' 22 | Capture 'mov %rax,%rdx' (into test|0 + 3) 23 | Emulate 'test+7: mov %esi,%eax' 24 | Capture 'mov %esi,%eax' (into test|0 + 4) 25 | Emulate 'test+9: cwtl' 26 | Capture 'cwtl' (into test|0 + 5) 27 | Emulate 'test+10: add %rdx,%rax' 28 | Capture 'add %rdx,%rax' (into test|0 + 6) 29 | Emulate 'test+13: ret' 30 | Capture 'H-ret' (into test|0 + 7) 31 | Capture 'ret' (into test|0 + 8) 32 | Generating code for BB test|0 (9 instructions) 33 | I 0 : H-call (test|0)+0 34 | I 1 : mov %edi,%eax (test|0)+0 89 f8 35 | I 2 : cltq (test|0)+2 48 98 36 | I 3 : mov %rax,%rdx (test|0)+4 48 89 c2 37 | I 4 : mov %esi,%eax (test|0)+7 89 f0 38 | I 5 : cwtl (test|0)+9 98 39 | I 6 : add %rdx,%rax (test|0)+10 48 01 d0 40 | I 7 : H-ret (test|0)+13 41 | I 8 : ret (test|0)+13 c3 42 | Generated: 14 bytes (pass1: 40) 43 | BB gen (7 instructions): 44 | gen: 89 f8 mov %edi,%eax 45 | gen+2: 48 98 cltq 46 | gen+4: 48 89 c2 mov %rax,%rdx 47 | gen+7: 89 f0 mov %esi,%eax 48 | gen+9: 98 cwtl 49 | gen+10: 48 01 d0 add %rdx,%rax 50 | gen+13: c3 ret 51 | >>> Testcase known par = 1. 52 | Saving current emulator state: new with esID 0 53 | Capture 'H-call' (into test|0 + 0) 54 | Processing BB (test|0) 55 | Emulation Static State (esID 0, call depth 0): 56 | Registers: %rsp (R 0), %rdi (0x1) 57 | Flags: (none) 58 | Stack: (none) 59 | Decoding BB test ... 60 | test: 89 f8 mov %edi,%eax 61 | test+2: 48 98 cltq 62 | test+4: 48 89 c2 mov %rax,%rdx 63 | test+7: 89 f0 mov %esi,%eax 64 | test+9: 98 cwtl 65 | test+10: 48 01 d0 add %rdx,%rax 66 | test+13: c3 ret 67 | Emulate 'test: mov %edi,%eax' 68 | Emulate 'test+2: cltq' 69 | Emulate 'test+4: mov %rax,%rdx' 70 | Emulate 'test+7: mov %esi,%eax' 71 | Capture 'mov %esi,%eax' (into test|0 + 1) 72 | Emulate 'test+9: cwtl' 73 | Capture 'cwtl' (into test|0 + 2) 74 | Emulate 'test+10: add %rdx,%rax' 75 | Capture 'add $0x1,%rax' (into test|0 + 3) 76 | Emulate 'test+13: ret' 77 | Capture 'H-ret' (into test|0 + 4) 78 | Capture 'ret' (into test|0 + 5) 79 | Generating code for BB test|0 (6 instructions) 80 | I 0 : H-call (test|0)+0 81 | I 1 : mov %esi,%eax (test|0)+0 89 f0 82 | I 2 : cwtl (test|0)+2 98 83 | I 3 : add $0x1,%rax (test|0)+3 48 83 c0 01 84 | I 4 : H-ret (test|0)+7 85 | I 5 : ret (test|0)+7 c3 86 | Generated: 8 bytes (pass1: 34) 87 | BB gen (4 instructions): 88 | gen: 89 f0 mov %esi,%eax 89 | gen+2: 98 cwtl 90 | gen+3: 48 83 c0 01 add $0x1,%rax 91 | gen+7: c3 ret 92 | -------------------------------------------------------------------------------- /tests/cases/integration/op-call.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl f1 3 | .type f1, @function 4 | f1: 5 | movabs $jtarget, %r14 6 | callq *%r14 7 | ret 8 | jtarget: 9 | mov $0, %eax 10 | ret 11 | -------------------------------------------------------------------------------- /tests/cases/integration/op-call.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: XX mov $test+14,%r14 11 | test+7: XX 12 | test+10: 41 ff d6 call %r14 13 | Emulate 'test: mov $test+14,%r14' 14 | Emulate 'test+10: call %r14' 15 | Capture 'H-call' (into test|0 + 1) 16 | Decoding BB test+14 ... 17 | test+14: b8 00 00 00 00 mov $0x0,%eax 18 | test+19: c3 ret 19 | Emulate 'test+14: mov $0x0,%eax' 20 | Emulate 'test+19: ret' 21 | Capture 'H-ret' (into test|0 + 2) 22 | Decoding BB test+13 ... 23 | test+13: c3 ret 24 | Emulate 'test+13: ret' 25 | Capture 'H-ret' (into test|0 + 3) 26 | Capture 'mov $0x0,%rax' (into test|0 + 4) 27 | Capture 'ret' (into test|0 + 5) 28 | Generating code for BB test|0 (6 instructions) 29 | I 0 : H-call (test|0)+0 30 | I 1 : H-call (test|0)+0 31 | I 2 : H-ret (test|0)+0 32 | I 3 : H-ret (test|0)+0 33 | I 4 : mov $0x0,%rax (test|0)+0 48 31 c0 34 | I 5 : ret (test|0)+3 c3 35 | Generated: 4 bytes (pass1: 30) 36 | BB gen (2 instructions): 37 | gen: 48 31 c0 xor %rax,%rax 38 | gen+3: c3 ret 39 | -------------------------------------------------------------------------------- /tests/cases/integration/op-call.s.expect_filter: -------------------------------------------------------------------------------- 1 | sed -e 's/test: [ 0-9a-f]*/test: XX /g' | sed -e 's/test+7: [ 0-9a-f]*/test+7: XX /g' 2 | -------------------------------------------------------------------------------- /tests/cases/integration/op-inc.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl f1 3 | .type f1, @function 4 | f1: 5 | mov %edi, %eax 6 | inc %eax 7 | dec %eax 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/integration/op-inc.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 89 f8 mov %edi,%eax 11 | test+2: ff c0 inc %eax 12 | test+4: ff c8 dec %eax 13 | test+6: c3 ret 14 | Emulate 'test: mov %edi,%eax' 15 | Emulate 'test+2: inc %eax' 16 | Emulate 'test+4: dec %eax' 17 | Emulate 'test+6: ret' 18 | Capture 'H-ret' (into test|0 + 1) 19 | Capture 'mov $0x1,%rax' (into test|0 + 2) 20 | Capture 'ret' (into test|0 + 3) 21 | Generating code for BB test|0 (4 instructions) 22 | I 0 : H-call (test|0)+0 23 | I 1 : H-ret (test|0)+0 24 | I 2 : mov $0x1,%rax (test|0)+0 48 c7 c0 01 00 00 00 25 | I 3 : ret (test|0)+7 c3 26 | Generated: 8 bytes (pass1: 34) 27 | BB gen (2 instructions): 28 | gen: 48 c7 c0 01 00 00 00 mov $0x1,%rax 29 | gen+7: c3 ret 30 | -------------------------------------------------------------------------------- /tests/cases/integration/op-ja.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov rax, 0xffffffffff123231 7 | cmp rax, rdi 8 | ja 1f 9 | xor eax, eax 10 | ret 11 | 1: 12 | mov eax, 1 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/integration/op-ja.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 c7 c0 31 32 12 ff mov $0xffffffffff123231,%rax 11 | test+7: 48 39 f8 cmp %rdi,%rax 12 | test+10: 77 03 ja $test+15 13 | Emulate 'test: mov $0xffffffffff123231,%rax' 14 | Emulate 'test+7: cmp %rdi,%rax' 15 | Emulate 'test+10: ja $test+15' 16 | Decoding BB test+15 ... 17 | test+15: b8 01 00 00 00 mov $0x1,%eax 18 | test+20: c3 ret 19 | Emulate 'test+15: mov $0x1,%eax' 20 | Emulate 'test+20: ret' 21 | Capture 'H-ret' (into test|0 + 1) 22 | Capture 'mov $0x1,%rax' (into test|0 + 2) 23 | Capture 'ret' (into test|0 + 3) 24 | Generating code for BB test|0 (4 instructions) 25 | I 0 : H-call (test|0)+0 26 | I 1 : H-ret (test|0)+0 27 | I 2 : mov $0x1,%rax (test|0)+0 48 c7 c0 01 00 00 00 28 | I 3 : ret (test|0)+7 c3 29 | Generated: 8 bytes (pass1: 34) 30 | BB gen (2 instructions): 31 | gen: 48 c7 c0 01 00 00 00 mov $0x1,%rax 32 | gen+7: c3 ret 33 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jbe.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov rax, 0xffffffffff123231 7 | cmp rax, rdi 8 | jbe 1f 9 | xor eax, eax 10 | ret 11 | 1: 12 | mov eax, 1 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jbe.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 c7 c0 31 32 12 ff mov $0xffffffffff123231,%rax 11 | test+7: 48 39 f8 cmp %rdi,%rax 12 | test+10: 76 03 jbe $test+15 13 | Emulate 'test: mov $0xffffffffff123231,%rax' 14 | Emulate 'test+7: cmp %rdi,%rax' 15 | Emulate 'test+10: jbe $test+15' 16 | Decoding BB test+12 ... 17 | test+12: 31 c0 xor %eax,%eax 18 | test+14: c3 ret 19 | Emulate 'test+12: xor %eax,%eax' 20 | Emulate 'test+14: ret' 21 | Capture 'H-ret' (into test|0 + 1) 22 | Capture 'mov $0x0,%rax' (into test|0 + 2) 23 | Capture 'ret' (into test|0 + 3) 24 | Generating code for BB test|0 (4 instructions) 25 | I 0 : H-call (test|0)+0 26 | I 1 : H-ret (test|0)+0 27 | I 2 : mov $0x0,%rax (test|0)+0 48 31 c0 28 | I 3 : ret (test|0)+3 c3 29 | Generated: 4 bytes (pass1: 30) 30 | BB gen (2 instructions): 31 | gen: 48 31 c0 xor %rax,%rax 32 | gen+3: c3 ret 33 | -------------------------------------------------------------------------------- /tests/cases/integration/op-je.s: -------------------------------------------------------------------------------- 1 | //!run = {outfile} --var 0 1 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | test %rdi, %rdi 7 | jz 1f 8 | xor %eax, %eax 9 | ret 10 | 1: 11 | mov $1, %eax 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jo.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | movabs rax, 0x7fffffffffffffff 7 | add rax, rdi 8 | jo 1f 9 | xor eax, eax 10 | ret 11 | 1: 12 | mov eax, 1 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jo.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 b8 ff ff ff ff ff mov $0x7fffffffffffffff,%rax 11 | test+7: ff ff 7f 12 | test+10: 48 01 f8 add %rdi,%rax 13 | test+13: 70 03 jo $test+18 14 | Emulate 'test: mov $0x7fffffffffffffff,%rax' 15 | Emulate 'test+10: add %rdi,%rax' 16 | Emulate 'test+13: jo $test+18' 17 | Decoding BB test+18 ... 18 | test+18: b8 01 00 00 00 mov $0x1,%eax 19 | test+23: c3 ret 20 | Emulate 'test+18: mov $0x1,%eax' 21 | Emulate 'test+23: ret' 22 | Capture 'H-ret' (into test|0 + 1) 23 | Capture 'mov $0x1,%rax' (into test|0 + 2) 24 | Capture 'ret' (into test|0 + 3) 25 | Generating code for BB test|0 (4 instructions) 26 | I 0 : H-call (test|0)+0 27 | I 1 : H-ret (test|0)+0 28 | I 2 : mov $0x1,%rax (test|0)+0 48 c7 c0 01 00 00 00 29 | I 3 : ret (test|0)+7 c3 30 | Generated: 8 bytes (pass1: 34) 31 | BB gen (2 instructions): 32 | gen: 48 c7 c0 01 00 00 00 mov $0x1,%rax 33 | gen+7: c3 ret 34 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jp.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | add rdi, 2 7 | jp 1f 8 | xor eax, eax 9 | ret 10 | 1: 11 | mov eax, 1 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jp.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 83 c7 02 add $0x2,%rdi 11 | test+4: 7a 03 jp $test+9 12 | Emulate 'test: add $0x2,%rdi' 13 | Emulate 'test+4: jp $test+9' 14 | Decoding BB test+9 ... 15 | test+9: b8 01 00 00 00 mov $0x1,%eax 16 | test+14: c3 ret 17 | Emulate 'test+9: mov $0x1,%eax' 18 | Emulate 'test+14: ret' 19 | Capture 'H-ret' (into test|0 + 1) 20 | Capture 'mov $0x1,%rax' (into test|0 + 2) 21 | Capture 'ret' (into test|0 + 3) 22 | Generating code for BB test|0 (4 instructions) 23 | I 0 : H-call (test|0)+0 24 | I 1 : H-ret (test|0)+0 25 | I 2 : mov $0x1,%rax (test|0)+0 48 c7 c0 01 00 00 00 26 | I 3 : ret (test|0)+7 c3 27 | Generated: 8 bytes (pass1: 34) 28 | BB gen (2 instructions): 29 | gen: 48 c7 c0 01 00 00 00 mov $0x1,%rax 30 | gen+7: c3 ret 31 | -------------------------------------------------------------------------------- /tests/cases/integration/op-js-1.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | xor eax, eax 7 | add rax, rdi 8 | js 1f 9 | xor eax, eax 10 | ret 11 | 1: 12 | mov eax, 1 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/integration/op-js-1.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 31 c0 xor %eax,%eax 11 | test+2: 48 01 f8 add %rdi,%rax 12 | test+5: 78 03 js $test+10 13 | Emulate 'test: xor %eax,%eax' 14 | Emulate 'test+2: add %rdi,%rax' 15 | Emulate 'test+5: js $test+10' 16 | Decoding BB test+7 ... 17 | test+7: 31 c0 xor %eax,%eax 18 | test+9: c3 ret 19 | Emulate 'test+7: xor %eax,%eax' 20 | Emulate 'test+9: ret' 21 | Capture 'H-ret' (into test|0 + 1) 22 | Capture 'mov $0x0,%rax' (into test|0 + 2) 23 | Capture 'ret' (into test|0 + 3) 24 | Generating code for BB test|0 (4 instructions) 25 | I 0 : H-call (test|0)+0 26 | I 1 : H-ret (test|0)+0 27 | I 2 : mov $0x0,%rax (test|0)+0 48 31 c0 28 | I 3 : ret (test|0)+3 c3 29 | Generated: 4 bytes (pass1: 30) 30 | BB gen (2 instructions): 31 | gen: 48 31 c0 xor %rax,%rax 32 | gen+3: c3 ret 33 | -------------------------------------------------------------------------------- /tests/cases/integration/op-js-2.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov rax, 0xffffffffff123231 7 | add rax, rdi 8 | js 1f 9 | xor eax, eax 10 | ret 11 | 1: 12 | mov eax, 1 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/integration/op-js-2.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 48 c7 c0 31 32 12 ff mov $0xffffffffff123231,%rax 11 | test+7: 48 01 f8 add %rdi,%rax 12 | test+10: 78 03 js $test+15 13 | Emulate 'test: mov $0xffffffffff123231,%rax' 14 | Emulate 'test+7: add %rdi,%rax' 15 | Emulate 'test+10: js $test+15' 16 | Decoding BB test+15 ... 17 | test+15: b8 01 00 00 00 mov $0x1,%eax 18 | test+20: c3 ret 19 | Emulate 'test+15: mov $0x1,%eax' 20 | Emulate 'test+20: ret' 21 | Capture 'H-ret' (into test|0 + 1) 22 | Capture 'mov $0x1,%rax' (into test|0 + 2) 23 | Capture 'ret' (into test|0 + 3) 24 | Generating code for BB test|0 (4 instructions) 25 | I 0 : H-call (test|0)+0 26 | I 1 : H-ret (test|0)+0 27 | I 2 : mov $0x1,%rax (test|0)+0 48 c7 c0 01 00 00 00 28 | I 3 : ret (test|0)+7 c3 29 | Generated: 8 bytes (pass1: 34) 30 | BB gen (2 instructions): 31 | gen: 48 c7 c0 01 00 00 00 mov $0x1,%rax 32 | gen+7: c3 ret 33 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jz-dynamic.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | xor eax, eax 7 | test esi, esi 8 | jz 1f 9 | ret 10 | 1: 11 | inc eax 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jz-dynamic.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 31 c0 xor %eax,%eax 11 | test+2: 85 f6 test %esi,%esi 12 | test+4: 74 01 je $test+7 13 | Emulate 'test: xor %eax,%eax' 14 | Emulate 'test+2: test %esi,%esi' 15 | Capture 'test %esi,%esi' (into test|0 + 1) 16 | Emulate 'test+4: je $test+7' 17 | Saving current emulator state: new with esID 1 18 | Processing BB (test+6|1), 1 BBs in queue 19 | Emulation Static State (esID 1, call depth 0): 20 | Registers: %rax (0x0), %rsp (R 0), %rdi (0x1) 21 | Flags: CF (0), OF (0) 22 | Stack: (none) 23 | Decoding BB test+6 ... 24 | test+6: c3 ret 25 | Emulate 'test+6: ret' 26 | Capture 'H-ret' (into test+6|1 + 0) 27 | Capture 'mov $0x0,%rax' (into test+6|1 + 1) 28 | Capture 'ret' (into test+6|1 + 2) 29 | Processing BB (test+7|1), 0 BBs in queue 30 | Emulation Static State (esID 1, call depth 0): 31 | Registers: %rax (0x0), %rsp (R 0), %rdi (0x1) 32 | Flags: CF (0), OF (0) 33 | Stack: (none) 34 | Decoding BB test+7 ... 35 | test+7: ff c0 inc %eax 36 | test+9: c3 ret 37 | Emulate 'test+7: inc %eax' 38 | Emulate 'test+9: ret' 39 | Capture 'H-ret' (into test+7|1 + 0) 40 | Capture 'mov $0x1,%rax' (into test+7|1 + 1) 41 | Capture 'ret' (into test+7|1 + 2) 42 | Generating code for BB test|0 (2 instructions) 43 | I 0 : H-call (test|0)+0 44 | I 1 : test %esi,%esi (test|0)+0 85 f6 45 | I 2 : je (test+7|1), fall-through to (test+6|1) 46 | Generating code for BB test+6|1 (3 instructions) 47 | I 0 : H-ret (test+6|1)+0 48 | I 1 : mov $0x0,%rax (test+6|1)+0 48 31 c0 49 | I 2 : ret (test+6|1)+3 c3 50 | Generating code for BB test+7|1 (3 instructions) 51 | I 0 : H-ret (test+7|1)+0 52 | I 1 : mov $0x1,%rax (test+7|1)+0 48 c7 c0 01 00 00 00 53 | I 2 : ret (test+7|1)+7 c3 54 | Generated: 16 bytes (pass1: 92) 55 | BB gen (2 instructions): 56 | gen: 85 f6 test %esi,%esi 57 | gen+2: 74 04 je $gen+8 58 | BB gen+4 (2 instructions): 59 | gen+4: 48 31 c0 xor %rax,%rax 60 | gen+7: c3 ret 61 | BB gen+8 (2 instructions): 62 | gen+8: 48 c7 c0 01 00 00 00 mov $0x1,%rax 63 | gen+15: c3 ret 64 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jz.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | xor eax, eax 7 | test edi, edi 8 | jz 1f 9 | ret 10 | 1: 11 | inc eax 12 | ret 13 | -------------------------------------------------------------------------------- /tests/cases/integration/op-jz.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 31 c0 xor %eax,%eax 11 | test+2: 85 ff test %edi,%edi 12 | test+4: 74 01 je $test+7 13 | Emulate 'test: xor %eax,%eax' 14 | Emulate 'test+2: test %edi,%edi' 15 | Emulate 'test+4: je $test+7' 16 | Decoding BB test+6 ... 17 | test+6: c3 ret 18 | Emulate 'test+6: ret' 19 | Capture 'H-ret' (into test|0 + 1) 20 | Capture 'mov $0x0,%rax' (into test|0 + 2) 21 | Capture 'ret' (into test|0 + 3) 22 | Generating code for BB test|0 (4 instructions) 23 | I 0 : H-call (test|0)+0 24 | I 1 : H-ret (test|0)+0 25 | I 2 : mov $0x0,%rax (test|0)+0 48 31 c0 26 | I 3 : ret (test|0)+3 c3 27 | Generated: 4 bytes (pass1: 30) 28 | BB gen (2 instructions): 29 | gen: 48 31 c0 xor %rax,%rax 30 | gen+3: c3 ret 31 | -------------------------------------------------------------------------------- /tests/cases/integration/op-leave.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl f1 3 | .type f1, @function 4 | f1: 5 | push %rbp 6 | mov %rsp, %rbp 7 | mov %rdi, %rax 8 | leave 9 | ret 10 | -------------------------------------------------------------------------------- /tests/cases/integration/op-leave.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 55 push %rbp 11 | test+1: 48 89 e5 mov %rsp,%rbp 12 | test+4: 48 89 f8 mov %rdi,%rax 13 | test+7: c9 leave 14 | test+8: c3 ret 15 | Emulate 'test: push %rbp' 16 | Capture 'push %rbp' (into test|0 + 1) 17 | Emulate 'test+1: mov %rsp,%rbp' 18 | Capture 'mov %rsp,%rbp' (into test|0 + 2) 19 | Emulate 'test+4: mov %rdi,%rax' 20 | Emulate 'test+7: leave' 21 | Capture 'mov %rbp,%rsp' (into test|0 + 3) 22 | Capture 'pop %rbp' (into test|0 + 4) 23 | Emulate 'test+8: ret' 24 | Capture 'H-ret' (into test|0 + 5) 25 | Capture 'mov $0x1,%rax' (into test|0 + 6) 26 | Capture 'ret' (into test|0 + 7) 27 | Generating code for BB test|0 (8 instructions) 28 | I 0 : H-call (test|0)+0 29 | I 1 : push %rbp (test|0)+0 55 30 | I 2 : mov %rsp,%rbp (test|0)+1 48 89 e5 31 | I 3 : mov %rbp,%rsp (test|0)+4 48 89 ec 32 | I 4 : pop %rbp (test|0)+7 5d 33 | I 5 : H-ret (test|0)+8 34 | I 6 : mov $0x1,%rax (test|0)+8 48 c7 c0 01 00 00 00 35 | I 7 : ret (test|0)+15 c3 36 | Generated: 16 bytes (pass1: 42) 37 | BB gen (6 instructions): 38 | gen: 55 push %rbp 39 | gen+1: 48 89 e5 mov %rsp,%rbp 40 | gen+4: 48 89 ec mov %rbp,%rsp 41 | gen+7: 5d pop %rbp 42 | gen+8: 48 c7 c0 01 00 00 00 mov $0x1,%rax 43 | gen+15: c3 ret 44 | -------------------------------------------------------------------------------- /tests/cases/integration/op-mov-mem.s: -------------------------------------------------------------------------------- 1 | //!args=--nobytes 2 | .intel_syntax noprefix 3 | .text 4 | .globl f1 5 | .type f1, @function 6 | f1: 7 | mov rbx, 0x1234567 8 | mov [wdata], rbx 9 | // rip-relative addressing, AT&T: lea wdata(%rip),%rdx 10 | lea rdx,[rip+wdata] 11 | mov qword ptr [rdx],1 12 | // TODO: add test with movabs + 64bit immediate 13 | // uncomment if accessing read-only mem range is handled 14 | // mov rax, [rdata+8] 15 | mov rax, [wdata] 16 | ret 17 | 18 | -------------------------------------------------------------------------------- /tests/cases/integration/op-mov-mem.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: mov $0x1234567,%rbx 11 | test+7: mov %rbx,wdata 12 | test+15: lea wdata(%rip),%rdx 13 | test+22: movq $0x1,(%rdx) 14 | test+29: mov wdata,%rax 15 | test+37: ret 16 | Emulate 'test: mov $0x1234567,%rbx' 17 | Emulate 'test+7: mov %rbx,wdata' 18 | Capture 'movq $0x1234567,wdata' (into test|0 + 1) 19 | Emulate 'test+15: lea wdata(%rip),%rdx' 20 | Emulate 'test+22: movq $0x1,(%rdx)' 21 | Capture 'movq $0x1,wdata' (into test|0 + 2) 22 | Emulate 'test+29: mov wdata,%rax' 23 | Capture 'mov wdata,%rax' (into test|0 + 3) 24 | Emulate 'test+37: ret' 25 | Capture 'H-ret' (into test|0 + 4) 26 | Capture 'ret' (into test|0 + 5) 27 | Generating code for BB test|0 (6 instructions) 28 | I 0 : H-call (test|0)+0 29 | I 1 : movq $0x1234567,wdata (test|0)+0 30 | I 2 : movq $0x1,wdata (test|0)+12 31 | I 3 : mov wdata,%rax (test|0)+24 32 | I 4 : H-ret (test|0)+32 33 | I 5 : ret (test|0)+32 34 | Generated: 33 bytes (pass1: 59) 35 | BB gen (4 instructions): 36 | gen: movq $0x1234567,wdata 37 | gen+12: movq $0x1,wdata 38 | gen+24: mov wdata,%rax 39 | gen+32: ret 40 | -------------------------------------------------------------------------------- /tests/cases/integration/op-mov-r9d.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | mov r10d, 0x12345678 7 | mov r11w, r10w 8 | mov r12b, r10b 9 | mov r9d, 1 10 | mov rax, r9 11 | add rax, r11 12 | add rax, r12 13 | ret 14 | -------------------------------------------------------------------------------- /tests/cases/integration/op-mov-r9d.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 41 ba 78 56 34 12 mov $0x12345678,%r10d 11 | test+6: 66 45 89 d3 mov %r10w,%r11w 12 | test+10: 45 88 d4 mov %r10b,%r12b 13 | test+13: 41 b9 01 00 00 00 mov $0x1,%r9d 14 | test+19: 4c 89 c8 mov %r9,%rax 15 | test+22: 4c 01 d8 add %r11,%rax 16 | test+25: 4c 01 e0 add %r12,%rax 17 | test+28: c3 ret 18 | Emulate 'test: mov $0x12345678,%r10d' 19 | Emulate 'test+6: mov %r10w,%r11w' 20 | Emulate 'test+10: mov %r10b,%r12b' 21 | Emulate 'test+13: mov $0x1,%r9d' 22 | Emulate 'test+19: mov %r9,%rax' 23 | Emulate 'test+22: add %r11,%rax' 24 | Emulate 'test+25: add %r12,%rax' 25 | Emulate 'test+28: ret' 26 | Capture 'H-ret' (into test|0 + 1) 27 | Capture 'mov $0x56f1,%rax' (into test|0 + 2) 28 | Capture 'ret' (into test|0 + 3) 29 | Generating code for BB test|0 (4 instructions) 30 | I 0 : H-call (test|0)+0 31 | I 1 : H-ret (test|0)+0 32 | I 2 : mov $0x56f1,%rax (test|0)+0 48 c7 c0 f1 56 00 00 33 | I 3 : ret (test|0)+7 c3 34 | Generated: 8 bytes (pass1: 34) 35 | BB gen (2 instructions): 36 | gen: 48 c7 c0 f1 56 00 00 mov $0x56f1,%rax 37 | gen+7: c3 ret 38 | -------------------------------------------------------------------------------- /tests/cases/integration/op-push-pop.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | push 0x5b 7 | push -0xAAAAAA 8 | push -0x10 9 | mov rbx, 0xBBB 10 | push bx 11 | .byte 0x66, 0x68, 0xCC, 0x0C # Manual assembly of pushw 0xCCC (couldn't get GNU as to generate it) 12 | movq rbx, 0xDDDDDDDDDDDD # clang assembler needs q postfix 13 | push rbx 14 | pop r9 15 | pop dx 16 | pop cx 17 | pop r10 18 | pop rbx 19 | pop rax 20 | add rax, r9 21 | add rax, rbx 22 | add rax, r10 23 | add rax, rcx 24 | add rax, rdx # rax should be 0xdddddd334c05 25 | ret 26 | -------------------------------------------------------------------------------- /tests/cases/integration/op-push-pop.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 6a 5b pushq $0x5b 11 | test+2: 68 56 55 55 ff pushq $0xffffffffff555556 12 | test+7: 6a f0 pushq $0xfffffffffffffff0 13 | test+9: 48 c7 c3 bb 0b 00 00 mov $0xbbb,%rbx 14 | test+16: 66 53 push %bx 15 | test+18: 66 68 cc 0c pushw $0xccc 16 | test+22: 48 bb dd dd dd dd dd mov $0xdddddddddddd,%rbx 17 | test+29: dd 00 00 18 | test+32: 53 push %rbx 19 | test+33: 41 59 pop %r9 20 | test+35: 66 5a pop %dx 21 | test+37: 66 59 pop %cx 22 | test+39: 41 5a pop %r10 23 | test+41: 5b pop %rbx 24 | test+42: 58 pop %rax 25 | test+43: 4c 01 c8 add %r9,%rax 26 | test+46: 48 01 d8 add %rbx,%rax 27 | test+49: 4c 01 d0 add %r10,%rax 28 | test+52: 48 01 c8 add %rcx,%rax 29 | test+55: 48 01 d0 add %rdx,%rax 30 | test+58: c3 ret 31 | Emulate 'test: pushq $0x5b' 32 | Emulate 'test+2: pushq $0xffffffffff555556' 33 | Emulate 'test+7: pushq $0xfffffffffffffff0' 34 | Emulate 'test+9: mov $0xbbb,%rbx' 35 | Emulate 'test+16: push %bx' 36 | Emulate 'test+18: pushw $0xccc' 37 | Emulate 'test+22: mov $0xdddddddddddd,%rbx' 38 | Emulate 'test+32: push %rbx' 39 | Emulate 'test+33: pop %r9' 40 | Emulate 'test+35: pop %dx' 41 | Emulate 'test+37: pop %cx' 42 | Emulate 'test+39: pop %r10' 43 | Emulate 'test+41: pop %rbx' 44 | Emulate 'test+42: pop %rax' 45 | Emulate 'test+43: add %r9,%rax' 46 | Emulate 'test+46: add %rbx,%rax' 47 | Emulate 'test+49: add %r10,%rax' 48 | Emulate 'test+52: add %rcx,%rax' 49 | Emulate 'test+55: add %rdx,%rax' 50 | Emulate 'test+58: ret' 51 | Capture 'H-ret' (into test|0 + 1) 52 | Capture 'mov $0xdddddd334c05,%rax' (into test|0 + 2) 53 | Capture 'ret' (into test|0 + 3) 54 | Generating code for BB test|0 (4 instructions) 55 | I 0 : H-call (test|0)+0 56 | I 1 : H-ret (test|0)+0 57 | I 2 : mov $0xdddddd334c05,%rax (test|0)+0 48 b8 05 4c 33 dd dd dd 00 00 58 | I 3 : ret (test|0)+10 c3 59 | Generated: 11 bytes (pass1: 37) 60 | BB gen (2 instructions): 61 | gen: 48 b8 05 4c 33 dd dd mov $0xdddddd334c05,%rax 62 | gen+7: dd 00 00 63 | gen+10: c3 ret 64 | -------------------------------------------------------------------------------- /tests/cases/integration/op-shl.s: -------------------------------------------------------------------------------- 1 | .intel_syntax noprefix 2 | .text 3 | .globl f1 4 | .type f1, @function 5 | f1: 6 | shl edi, 5 7 | mov rax, rdi 8 | ret 9 | -------------------------------------------------------------------------------- /tests/cases/integration/op-shl.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: c1 e7 05 shl $0x5,%edi 11 | test+3: 48 89 f8 mov %rdi,%rax 12 | test+6: c3 ret 13 | Emulate 'test: shl $0x5,%edi' 14 | Emulate 'test+3: mov %rdi,%rax' 15 | Emulate 'test+6: ret' 16 | Capture 'H-ret' (into test|0 + 1) 17 | Capture 'mov $0x20,%rax' (into test|0 + 2) 18 | Capture 'ret' (into test|0 + 3) 19 | Generating code for BB test|0 (4 instructions) 20 | I 0 : H-call (test|0)+0 21 | I 1 : H-ret (test|0)+0 22 | I 2 : mov $0x20,%rax (test|0)+0 48 c7 c0 20 00 00 00 23 | I 3 : ret (test|0)+7 c3 24 | Generated: 8 bytes (pass1: 34) 25 | BB gen (2 instructions): 26 | gen: 48 c7 c0 20 00 00 00 mov $0x20,%rax 27 | gen+7: c3 ret 28 | -------------------------------------------------------------------------------- /tests/cases/integration/segov.s: -------------------------------------------------------------------------------- 1 | // test for segment-overwrite prefix (fs:) 2 | // this is gcc-generated assembly of 3 | // 4 | // __thread int tls_i32 = 1; 5 | // __thread long long tls_i64 = 1; 6 | // 7 | // int f1(int i) 8 | // { 9 | // return tls_i32 + tls_i64 + i; 10 | // } 11 | 12 | .text 13 | .globl f1 14 | .type f1, @function 15 | f1: 16 | push %rbp 17 | mov %rsp,%rbp 18 | mov %edi,-0x4(%rbp) 19 | mov %fs:-0x8,%rax 20 | mov %eax,%edx 21 | mov %fs:-0x10,%eax 22 | add %eax,%edx 23 | mov -0x4(%rbp),%eax 24 | add %edx,%eax 25 | pop %rbp 26 | ret 27 | -------------------------------------------------------------------------------- /tests/cases/integration/segov.s.expect: -------------------------------------------------------------------------------- 1 | >>> Testcase known par = 1. 2 | Saving current emulator state: new with esID 0 3 | Capture 'H-call' (into test|0 + 0) 4 | Processing BB (test|0) 5 | Emulation Static State (esID 0, call depth 0): 6 | Registers: %rsp (R 0), %rdi (0x1) 7 | Flags: (none) 8 | Stack: (none) 9 | Decoding BB test ... 10 | test: 55 push %rbp 11 | test+1: 48 89 e5 mov %rsp,%rbp 12 | test+4: 89 7d fc mov %edi,-0x4(%rbp) 13 | test+7: 64 48 8b 04 25 f8 ff mov %fs:-0x8,%rax 14 | test+14: ff ff 15 | test+16: 89 c2 mov %eax,%edx 16 | test+18: 64 8b 04 25 f0 ff ff mov %fs:-0x10,%eax 17 | test+25: ff 18 | test+26: 01 c2 add %eax,%edx 19 | test+28: 8b 45 fc mov -0x4(%rbp),%eax 20 | test+31: 01 d0 add %edx,%eax 21 | test+33: 5d pop %rbp 22 | test+34: c3 ret 23 | Emulate 'test: push %rbp' 24 | Capture 'push %rbp' (into test|0 + 1) 25 | Emulate 'test+1: mov %rsp,%rbp' 26 | Capture 'mov %rsp,%rbp' (into test|0 + 2) 27 | Emulate 'test+4: mov %edi,-0x4(%rbp)' 28 | Emulate 'test+7: mov %fs:-0x8,%rax' 29 | Capture 'mov %fs:-0x8,%rax' (into test|0 + 3) 30 | Emulate 'test+16: mov %eax,%edx' 31 | Capture 'mov %eax,%edx' (into test|0 + 4) 32 | Emulate 'test+18: mov %fs:-0x10,%eax' 33 | Capture 'mov %fs:-0x10,%eax' (into test|0 + 5) 34 | Emulate 'test+26: add %eax,%edx' 35 | Capture 'add %eax,%edx' (into test|0 + 6) 36 | Emulate 'test+28: mov -0x4(%rbp),%eax' 37 | Emulate 'test+31: add %edx,%eax' 38 | Capture 'mov $0x1,%eax' (into test|0 + 7) 39 | Capture 'add %edx,%eax' (into test|0 + 8) 40 | Emulate 'test+33: pop %rbp' 41 | Capture 'pop %rbp' (into test|0 + 9) 42 | Emulate 'test+34: ret' 43 | Capture 'H-ret' (into test|0 + 10) 44 | Capture 'ret' (into test|0 + 11) 45 | Generating code for BB test|0 (12 instructions) 46 | I 0 : H-call (test|0)+0 47 | I 1 : push %rbp (test|0)+0 55 48 | I 2 : mov %rsp,%rbp (test|0)+1 48 89 e5 49 | I 3 : mov %fs:-0x8,%rax (test|0)+4 64 48 8b 04 25 f8 ff ff ff 50 | I 4 : mov %eax,%edx (test|0)+13 89 c2 51 | I 5 : mov %fs:-0x10,%eax (test|0)+15 64 8b 04 25 f0 ff ff ff 52 | I 6 : add %eax,%edx (test|0)+23 01 c2 53 | I 7 : mov $0x1,%eax (test|0)+25 c7 c0 01 00 00 00 54 | I 8 : add %edx,%eax (test|0)+31 01 d0 55 | I 9 : pop %rbp (test|0)+33 5d 56 | I10 : H-ret (test|0)+34 57 | I11 : ret (test|0)+34 c3 58 | Generated: 35 bytes (pass1: 61) 59 | BB gen (10 instructions): 60 | gen: 55 push %rbp 61 | gen+1: 48 89 e5 mov %rsp,%rbp 62 | gen+4: 64 48 8b 04 25 f8 ff mov %fs:-0x8,%rax 63 | gen+11: ff ff 64 | gen+13: 89 c2 mov %eax,%edx 65 | gen+15: 64 8b 04 25 f0 ff ff mov %fs:-0x10,%eax 66 | gen+22: ff 67 | gen+23: 01 c2 add %eax,%edx 68 | gen+25: c7 c0 01 00 00 00 mov $0x1,%eax 69 | gen+31: 01 d0 add %edx,%eax 70 | gen+33: 5d pop %rbp 71 | gen+34: c3 ret 72 | -------------------------------------------------------------------------------- /tests/stencil-apply-g-fp.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl f1 3 | .type f1, @function 4 | f1: 5 | pushq %rbp 6 | movq %rsp, %rbp 7 | movq %rdi, -24(%rbp) 8 | movl %esi, -28(%rbp) 9 | movq %rdx, -40(%rbp) 10 | pxor %xmm0, %xmm0 11 | movsd %xmm0, -16(%rbp) 12 | .L5: 13 | movq -40(%rbp), %rax 14 | movsd 8(%rax), %xmm0 15 | movsd %xmm0, -8(%rbp) 16 | pxor %xmm0, %xmm0 17 | ucomisd -8(%rbp), %xmm0 18 | jp .L2 19 | pxor %xmm0, %xmm0 20 | ucomisd -8(%rbp), %xmm0 21 | je .L7 22 | .L2: 23 | movq -40(%rbp), %rax 24 | movl (%rax), %edx 25 | movq -40(%rbp), %rax 26 | movl 4(%rax), %eax 27 | imull -28(%rbp), %eax 28 | addl %edx, %eax 29 | cltq 30 | leaq 0(,%rax,8), %rdx 31 | movq -24(%rbp), %rax 32 | addq %rdx, %rax 33 | movsd (%rax), %xmm0 34 | mulsd -8(%rbp), %xmm0 35 | movsd -16(%rbp), %xmm1 36 | addsd %xmm1, %xmm0 37 | movsd %xmm0, -16(%rbp) 38 | addq $16, -40(%rbp) 39 | jmp .L5 40 | .L7: 41 | movsd -16(%rbp), %xmm0 42 | popq %rbp 43 | ret 44 | 45 | -------------------------------------------------------------------------------- /tests/test-driver-decode-buferr.c: -------------------------------------------------------------------------------- 1 | //!compile = as -c -o {ofile} {infile} && {cc} {ccflags} -o {outfile} {ofile} {driver} ../libdbrew.a -I../include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dbrew.h" 9 | 10 | int f1(int); 11 | // possible jump target 12 | int f2(int x) { return x; } 13 | 14 | int main() 15 | { 16 | // Decode the function. 17 | Rewriter* r = dbrew_new(); 18 | dbrew_set_decoding_capacity(r,1,1); // force decode buffer overflow 19 | // to get rid of changing addresses, assume gen code to be 800 bytes max 20 | dbrew_config_function_setname(r, (uintptr_t) f1, "f1"); 21 | dbrew_config_function_setsize(r, (uintptr_t) f1, 800); 22 | dbrew_decode_print(r, (uintptr_t) f1, 1); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tests/test-driver-decode.c: -------------------------------------------------------------------------------- 1 | //!compile = as -c -o {ofile} {infile} && {cc} {ccflags} -o {outfile} {ofile} {driver} ../libdbrew.a -I../include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dbrew.h" 9 | 10 | int f1(int); 11 | // possible jump target 12 | int f2(int x) { return x; } 13 | 14 | int main() 15 | { 16 | // Decode the function. 17 | Rewriter* r = dbrew_new(); 18 | // to get rid of changing addresses, assume gen code to be 800 bytes max 19 | dbrew_config_function_setname(r, (uintptr_t) f1, "f1"); 20 | dbrew_config_function_setsize(r, (uintptr_t) f1, 800); 21 | dbrew_decode_print(r, (uintptr_t) f1, 1); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tests/test-driver-gen.c: -------------------------------------------------------------------------------- 1 | //!compile = as -c -o {ofile} {infile} && {cc} {ccflags} -o {outfile} {ofile} {driver} ../libdbrew.a -I../include -I../include/priv 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dbrew.h" 9 | #include "emulate.h" 10 | #include "generate.h" 11 | #include "error.h" 12 | 13 | int f1(int); 14 | 15 | int main(int argc, char* argv[]) 16 | { 17 | Rewriter* r = dbrew_new(); 18 | if ((argc>1) && (strcmp(argv[1],"-v")==0)) 19 | dbrew_verbose(r, true, true, true); 20 | dbrew_config_function_setname(r, (uintptr_t) f1, "f1"); 21 | dbrew_config_function_setsize(r, (uintptr_t) f1, 800); 22 | 23 | DBB* dbb = dbrew_decode(r, (uint64_t) f1); // decode 24 | CBB* cbb = createCBBfromDBB(r, dbb); // capture all instructions 25 | Error* e = (Error*) generate(r, cbb); 26 | if (e) 27 | logError(e, (char*) "Stopped"); 28 | else { 29 | // print generated instructions 30 | dbrew_config_function_setname(r, (uintptr_t) cbb->addr1, "f1gen"); 31 | dbrew_config_function_setsize(r, (uintptr_t) cbb->addr1, 800); 32 | dbrew_decode_print(r, (uintptr_t) cbb->addr1, cbb->size); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /tests/test-driver-generate.c: -------------------------------------------------------------------------------- 1 | //!compile = {cc} {ccflags} -std=c99 -g -o {outfile} {infile} {driver} ../libdbrew.a -I../include -I../include/priv 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dbrew.h" 9 | #include "emulate.h" 10 | #include "engine.h" 11 | #include "generate.h" 12 | #include "instr.h" 13 | #include "printer.h" 14 | 15 | void test_fill_instruction(Instr*); 16 | 17 | int main() 18 | { 19 | RContext c; 20 | c.e = 0; 21 | c.r = dbrew_new(); 22 | initRewriter(c.r); 23 | 24 | // Construct a test-CBB of one instruction. This CBB does not have a 25 | // terminator and is not runnable, we only want to ensure that the produced 26 | // instruction is correct. 27 | CBB* cbb = getCaptureBB(&c, 0, -1); 28 | Instr* instr = newCapInstr(&c); 29 | if ((cbb != 0) && (instr != 0)) { 30 | cbb->instr = instr; 31 | cbb->count++; 32 | test_fill_instruction(instr); 33 | c.e = (Error*) generate(c.r, cbb); 34 | } 35 | if (c.e) 36 | logError(c.e, (char*) "Stopped"); 37 | else { 38 | printf("Instruction: %s\n", instr2string(instr, 0, cbb->fc)); 39 | printf("Generated: %s\n", bytes2string(instr, 0, instr->len)); 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /tests/test-driver.c: -------------------------------------------------------------------------------- 1 | //!compile = {cc} {ccflags} -c -o {ofile} {infile} && {cc} {ccflags} -o {outfile} {ofile} {driver} ../libdbrew.a -I../include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "dbrew.h" 9 | 10 | typedef long (*f1_t)(long, long); 11 | long f1(long, long); 12 | 13 | // data which may be read/written by test 14 | const uint64_t rdata[2] = {1,2}; // read-only data section (16 bytes) 15 | long wdata[2]; // uninitialized data section (16 bytes) 16 | 17 | int runtest(Rewriter*r, long parameter, bool doRun, bool showBytes) 18 | { 19 | f1_t ff; 20 | 21 | if (parameter >= 0) 22 | printf(">>> Testcase known par = %ld.\n", parameter); 23 | else 24 | printf(">>> Testcase unknown par = %ld.\n", -parameter); 25 | 26 | 27 | dbrew_set_function(r, (uint64_t) f1); 28 | dbrew_config_parcount(r, 2); 29 | // to get rid of changing addresses, assume f1 code to be 100 bytes max 30 | dbrew_config_function_setname(r, (uint64_t) f1, "test"); 31 | dbrew_config_function_setsize(r, (uint64_t) f1, 100); 32 | dbrew_config_set_memrange(r, "rdata", false, (uint64_t) rdata, 16); 33 | dbrew_config_set_memrange(r, "wdata", true, (uint64_t) wdata, 16); 34 | if (parameter >= 0) 35 | dbrew_config_staticpar(r, 0); 36 | else 37 | parameter = -parameter; // make positive 38 | ff = (f1_t) dbrew_rewrite(r, parameter, 1); 39 | 40 | // print the generated function. 41 | Rewriter* r2 = dbrew_new(); 42 | dbrew_printer_showbytes(r2, showBytes); 43 | dbrew_config_function_setname(r2, (uint64_t) ff, "gen"); 44 | dbrew_config_function_setsize(r2, (uint64_t) ff, dbrew_generated_size(r)); 45 | dbrew_config_set_memrange(r2, "rdata", false, (uint64_t) rdata, 16); 46 | dbrew_config_set_memrange(r2, "wdata", true, (uint64_t) wdata, 16); 47 | dbrew_decode_print(r2, (uint64_t) ff, dbrew_generated_size(r)); 48 | 49 | if (!doRun) return 0; 50 | 51 | // Ensure that the program actually works. 52 | long orig = f1(parameter, 1); 53 | long rewritten = ff(parameter, 1); 54 | 55 | printf(">>> Run orig/rewritten: %ld/%ld\n", orig, rewritten); 56 | return (orig != rewritten) ? 1 : 0; 57 | } 58 | 59 | int main(int argc, char** argv) 60 | { 61 | int arg = 1; 62 | int res = 0; 63 | bool debug = false; 64 | bool run = false; 65 | bool var = false; // also generate version with variable parameter? 66 | bool showBytes = true; 67 | while((arg) { 4 | s/^(.*)\.s$/$1/; 5 | $cmd = "cc test-parser.c ../spec.c $_.s -o test-$_"; 6 | print "$cmd\n"; 7 | system $cmd; 8 | } 9 | 10 | --------------------------------------------------------------------------------