Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .github/workflows/build-recompile-dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Build recompile-dataset binaries with MSVC on Windows.
#
# Triggers on changes to the dataset sources. Compiles each source file
# with cl.exe at multiple optimisation levels for both x86 and x64,
# then commits the PE binaries back to the repository.
#
name: Build recompile-dataset (MSVC)

on:
push:
paths:
- 'tests_src/recompile_dataset/**'
workflow_dispatch: # manual trigger

permissions:
contents: write

jobs:
build-msvc:
runs-on: windows-latest
strategy:
matrix:
include:
- arch: x64
outdir: tests/x86_64/recompile_dataset_pe
- arch: x86
outdir: tests/i386/recompile_dataset_pe
steps:
- uses: actions/checkout@v4

- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{ matrix.arch }}

- name: Build binaries
shell: cmd
env:
OUTDIR: ${{ matrix.outdir }}
run: |
setlocal enabledelayedexpansion
mkdir "%OUTDIR%" 2>nul

set SRCS=t1_control_flow t2_types t3_memory t4_calling t5_patterns
set OPTS=/O1 /O2 /Os /Ox
set COUNT=0
set FAIL=0

for %%S in (!SRCS!) do (
for %%O in (!OPTS!) do (
set "TAG=%%O"
set "TAG=!TAG:/=!"
set "NAME=%%S_msvc_!TAG!.exe"
echo Building !NAME! ...

cl.exe /nologo %%O /Zi /Fe:"!OUTDIR!\!NAME!" ^
tests_src\recompile_dataset\%%S.c ^
tests_src\recompile_dataset\dummy_main.c ^
/link /DEBUG /PDB:"!OUTDIR!\%%S_msvc_!TAG!.pdb"
if !errorlevel! equ 0 (
set /a COUNT+=1
) else (
echo FAILED: !NAME!
set FAIL=1
)
)
)

rem Clean up intermediate files in working directory
del /q *.obj 2>nul
del /q "!OUTDIR!\*.ilk" 2>nul

echo.
echo Built !COUNT! binaries.
if !FAIL! neq 0 (
echo Some builds failed.
exit /b 1
)

- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: recompile-dataset-pe-${{ matrix.arch }}
path: ${{ matrix.outdir }}/

commit-binaries:
needs: build-msvc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Download x64 binaries
uses: actions/download-artifact@v4
with:
name: recompile-dataset-pe-x64
path: tests/x86_64/recompile_dataset_pe/

- name: Download x86 binaries
uses: actions/download-artifact@v4
with:
name: recompile-dataset-pe-x86
path: tests/i386/recompile_dataset_pe/

- name: Commit binaries
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add tests/x86_64/recompile_dataset_pe/ tests/i386/recompile_dataset_pe/
if git diff --cached --quiet; then
echo "No changes to commit."
else
git commit -m "ci: rebuild MSVC recompile-dataset binaries [skip ci]"
git push
fi
Binary file added tests/aarch64/ccop_triggers/ccop_arm_adc_sbb_O1
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_adc_sbb_O2
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_adc_sbb_Os
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_add_O1
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_add_O2
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_add_Os
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_logic_O1
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_logic_O2
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_logic_Os
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_sub_O1
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_sub_O2
Binary file not shown.
Binary file added tests/aarch64/ccop_triggers/ccop_arm_sub_Os
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_adc_sbb_O1
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_adc_sbb_O2
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_adc_sbb_Os
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_add_O1
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_add_O2
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_add_Os
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_logic_O1
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_logic_O2
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_logic_Os
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_sub_O1
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_sub_O2
Binary file not shown.
Binary file added tests/armhf/ccop_triggers/ccop_arm_sub_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_adc_sbb_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_adc_sbb_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_adc_sbb_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_add_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_add_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_add_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_copy_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_copy_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_copy_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_inc_dec_O1_incdec
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_inc_dec_O2_haswell
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_inc_dec_Os_incdec
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_logic_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_logic_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_logic_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_rflags_c_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_rflags_c_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_rflags_c_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_shl_shr_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_shl_shr_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_shl_shr_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_sub_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_sub_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_sub_Os
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_umul_smul_O1
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_umul_smul_O2
Binary file not shown.
Binary file added tests/i386/ccop_triggers/ccop_umul_smul_Os
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_adc_sbb_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_adc_sbb_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_adc_sbb_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_add_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_add_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_add_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_copy_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_copy_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_copy_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_inc_dec_O1_incdec
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_inc_dec_Os_incdec
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_logic_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_logic_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_logic_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_rflags_c_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_rflags_c_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_rflags_c_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_shl_shr_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_shl_shr_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_shl_shr_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_sub_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_sub_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_sub_Os
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_umul_smul_O1
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_umul_smul_O2
Binary file not shown.
Binary file added tests/x86_64/ccop_triggers/ccop_umul_smul_Os
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_clang_O0
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_clang_O1
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_clang_O2
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_clang_O3
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_clang_Os
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_gcc_O0
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_gcc_O1
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_gcc_O2
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_gcc_O3
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t2_types_gcc_Os
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_clang_O0
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_clang_O1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_clang_Os
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_gcc_O0
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_gcc_O1
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_gcc_O2
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_gcc_O3
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t3_memory_gcc_Os
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t4_calling_gcc_O0
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t4_calling_gcc_O2
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t4_calling_gcc_Os
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t5_patterns_gcc_O0
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t5_patterns_gcc_O1
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t5_patterns_gcc_O2
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t5_patterns_gcc_O3
Binary file not shown.
Binary file added tests/x86_64/recompile_dataset/t5_patterns_gcc_Os
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
259 changes: 259 additions & 0 deletions tests_src/ccop_triggers/STATUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# ccop_triggers Test Suite — Status

## What This Is

A set of C source files designed to trigger every VEX condition-code operation (ccop) type
handled by angr's decompiler ccall rewriters (`amd64_ccalls.py`, `x86_ccalls.py`). Each
function is `noinline`, uses a volatile sink to prevent dead-code elimination, and is compiled
with `-fno-if-conversion` to force real branches (not cmov).

Built binaries go into `bin/amd64/` and `bin/i386/` (gitignored). Run `bash build.sh` to
rebuild.

## Current State: All 9 source files complete, all P0/P1 gaps filled

### Complete — ~285 functions across 54 binaries (all build cleanly, all tests pass)

| File | Functions | Notes |
|------|-----------|-------|
| `ccop_sub.c` | 48 | SUB/CMP: CondZ/NZ/L/NL/LE/NLE/B/NB/BE/NBE/S/NS all at 8,16,32,64. Pure C comparisons. |
| `ccop_add.c` | 39 | ADD: CondZ/NZ/S/NS/O/NO/B (8,16,32,64), CondLE/NLE (8,16,32,64), CondBE (8,16,32). Uses `__builtin_add_overflow` for CondO; `asm goto` for CondLE/NLE/BE. 64-bit CondLE/NLE guarded by `__x86_64__`. |
| `ccop_logic.c` | 38 | LOGIC (test/and): CondZ/NZ/S/NS/L/NL (8,16,32,64), CondLE/NLE (8,16,32,64), CondB/BE (8,16,32 x86 only via `asm goto`). |
| `ccop_inc_dec.c` | 48 | INC: CondZ/NZ/S/NS (8,16,32,64), CondO/NO (8,16,32 via asm goto), CondLE/NLE (32 fallback). DEC: CondZ/NZ/S/NS/LE/NLE (8,16,32,64). All inline asm; built with `-mtune-ctrl=use_incdec`. |
| `ccop_shl_shr.c` | 32 | SHL: CondZ/NZ/S/NS (8,16,32,64). SHR: CondZ/NZ/S/NS (8,16,32,64). Pure C shifts; narrow widths use volatile + explicit casts. |
| `ccop_umul_smul.c` | 16 | UMUL/SMUL: CondO/NO (8,16,32,64). Uses `__builtin_*_overflow`. 64-bit UMUL CondNO guarded by `__x86_64__`. |
| `ccop_adc_sbb.c` | ~59 | ADC/SBB: comprehensive coverage. amd64 section (11 funcs via `__int128`), i386 section (48 funcs via pure C + asm goto). Covers CondZ/NZ/S/B/O/NO for ADC; CondZ/B/NB/BE/NBE/L/NL/S/O/NO for SBB at 8,16,32 widths. |
| `ccop_copy.c` | 4 | COPY: CondZ/NZ via `pushf`/`popf` + `asm goto`. amd64 uses `pushfq`/`popfq` (64-bit), i386 uses `pushfl`/`popfl` (32-bit). |
| `ccop_rflags_c.c` | 6 | rflags_c: carry flag extraction for ADD (32,64), SUB (32,64), DEC (32,64). amd64-only (`#ifdef __x86_64__`). Uses `adc $0` / `sbb $0` carry chains. |

### Python Test Harness

`tests/analyses/decompiler/test_ccop_triggers.py` — parametrized pytest (54 test cases)
that decompiles every `ccop_*` function in every binary and asserts:

1. Decompilation succeeds (codegen is not None)
2. For rewriter-handled (op, cond, width) combos: no raw `calculate_condition` or
`calculate_rflags_c` in the output
3. For fallback-only combos (no rewriter): just checks decompilation doesn't crash

Run: `python -m pytest tests/analyses/decompiler/test_ccop_triggers.py -v`

---

## Comprehensive Rewriter Coverage vs Test Coverage

The tables below map every (ccop, condition) combination handled by the rewriters against
what the test suite covers. This was generated by reading every code path in
`amd64_ccalls.py` and `x86_ccalls.py`.

### Legend

- **A** = amd64 rewriter handles this (B/W/L/Q widths)
- **X** = x86 rewriter handles this (B/W/L widths)
- All listed conditions now have full width coverage

### SUB — `ccop_sub.c` (48 functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondL | A, X | 8, 16, 32, 64 |
| CondNL | A, X | 8, 16, 32, 64 |
| CondLE | A, X | 8, 16, 32, 64 |
| CondNLE | A, X | 8, 16, 32, 64 |
| CondB | A, X | 8, 16, 32, 64 |
| CondNB | A, X | 8, 16, 32, 64 |
| CondBE | A, X | 8, 16, 32, 64 |
| CondNBE | A, X | 8, 16, 32, 64 |
| CondS | A, X | 8, 16, 32, 64 |
| CondNS | A, X | 8, 16, 32, 64 |

### ADD — `ccop_add.c` (39 functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondS | A, X | 8, 16, 32, 64 |
| CondNS | A, X | 8, 16, 32, 64 |
| CondO | A, X | 8, 16, 32, 64 |
| CondNO | A, X | 8, 16, 32, 64 |
| CondB | A, X | 8, 16, 32, 64 |
| CondLE | X only | 8, 16, 32, 64 |
| CondNLE | X only | 8, 16, 32, 64 |
| CondBE | X only | 8, 16, 32 |

### LOGIC — `ccop_logic.c` (38 functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondS | A, X | 8, 16, 32, 64 |
| CondNS | A, X | 8, 16, 32, 64 |
| CondL | A, X | 8, 16, 32, 64 |
| CondNL | A, X | 8, 16, 32, 64 |
| CondLE | A, X | 8, 16, 32, 64 |
| CondNLE | A, X | 8, 16, 32, 64 |
| CondB | X only | 8, 16, 32 |
| CondBE | X only | 8, 16, 32 |

### INC — `ccop_inc_dec.c` (24 INC functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondS | A | 8, 16, 32, 64 |
| CondNS | A | 8, 16, 32, 64 |
| CondO | X only | 8, 16, 32 |
| CondNO | X only | 8, 16, 32 |

Note: INC CondLE/CondNLE (32) are in the test but neither rewriter handles this — those
test fallback behavior only.

### DEC — `ccop_inc_dec.c` (24 DEC functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondS | A | 8, 16, 32, 64 |
| CondNS | A | 8, 16, 32, 64 |
| CondLE | A, X | 8, 16, 32, 64 |
| CondNLE | A, X | 8, 16, 32, 64 |

### SHL — `ccop_shl_shr.c` (16 SHL functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondS | A, X | 8, 16, 32, 64 |
| CondNS | A, X | 8, 16, 32, 64 |

### SHR — `ccop_shl_shr.c` (16 SHR functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 8, 16, 32, 64 |
| CondNZ | A, X | 8, 16, 32, 64 |
| CondS | A, X | 8, 16, 32, 64 |
| CondNS | A, X | 8, 16, 32, 64 |

### UMUL — `ccop_umul_smul.c` (8 UMUL functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondO | A, X | 8, 16, 32, 64 |
| CondNO | A, X | 8, 16, 32, 64 |

### SMUL — `ccop_umul_smul.c` (8 SMUL functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondO | A (B/W/L/Q), X (L only) | 8, 16, 32, 64 |
| CondNO | A (B/W/L/Q), X (L only) | 8, 16, 32, 64 |

### ADC — `ccop_adc_sbb.c`

The AMD64 rewriter does NOT handle ADC at all. Only x86 handles ADC.

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondO | X only | 8, 16, 32 |
| CondNO | X only | 8, 16, 32 |
| CondB | X only | 8, 16, 32 |

ADC CondZ/NZ/S are tested but NOT handled by any rewriter — they exercise fallback only.

### SBB — `ccop_adc_sbb.c`

AMD64 rewriter only handles SBB+CondB. x86 handles more conditions.

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondB | A, X | 8, 16, 32, 64 |
| CondBE | X only | 8, 16, 32 |
| CondNB | X only | 8, 16, 32 |
| CondNBE | X only | 8, 16, 32 |
| CondL | X only | 8, 16, 32 |
| CondNL | X only | 8, 16, 32 |
| CondO | X only | 8, 16, 32 |
| CondNO | X only | 8, 16, 32 |

SBB CondZ/S are tested but NOT handled by any rewriter — they exercise fallback only.

### COPY — `ccop_copy.c` (4 functions)

| Condition | Rewriter | Tested Widths |
|-----------|----------|---------------|
| CondZ | A, X | 32, 64 |
| CondNZ | A, X | 32, 64 |

### `amd64g_calculate_rflags_c` — `ccop_rflags_c.c` (6 functions, amd64-only)

| CCOP | Rewriter | Tested Widths |
|------|----------|---------------|
| ADD | A only | 32, 64 |
| SUB | A only | 32, 64 |
| DEC | A only | 32, 64 |

---

## Remaining Gaps (P2 — fallback-only, no rewriter exists)

These ccop+condition combos are NOT handled by either rewriter. Tests would only verify
the decompiler doesn't crash (produces a raw `_ccall`). Not urgent.

| Gap | Notes |
|-----|-------|
| ADC + CondZ/NZ/S | Tested already, no rewriter path exists |
| SBB + CondZ/S | Tested already, no rewriter path exists |
| INC + CondLE/NLE | Tested already, no rewriter path exists |
| CondP/CondNP (parity) | Not in any rewriter |
| ROL/ROR | Op types defined but no rewriter code |
| ANDN/BLSI/BLSMSK/BLSR | AMD64 BMI ops, no rewriter |
| ADCX/ADOX | AMD64 ADX ops, no rewriter |

---

## Build System

```
bash build.sh # builds 54 binaries (27 amd64, 27 i386)
```

Produces 3 optimization variants per source file x 2 arches:
- Standard sources: `-O1`, `-O2`, `-Os`
- INC/DEC: `-O1 -mtune-ctrl=use_incdec`, `-O2 -mtune=haswell`, `-Os -mtune-ctrl=use_incdec`
- ADC/SBB: same as standard

All with base flags: `-fno-if-conversion -fno-if-conversion2 -fno-tree-loop-if-convert -g`

Requires `gcc` and `gcc-multilib` (both installed on this system).

## File Layout

```
ccop_triggers/
├── build.sh # Build script
├── ccop_common.h # NOINLINE macro, volatile g_sink, sized typedefs
├── ccop_sub.c # 48 funcs — SUB/CMP conditions
├── ccop_add.c # 39 funcs — ADD conditions
├── ccop_logic.c # 38 funcs — LOGIC (test/and) conditions
├── ccop_inc_dec.c # 48 funcs — INC/DEC conditions (inline asm)
├── ccop_shl_shr.c # 32 funcs — SHL/SHR conditions
├── ccop_umul_smul.c # 16 funcs — multiply overflow
├── ccop_adc_sbb.c # ~59 funcs — ADC/SBB multi-precision (inline asm)
├── ccop_copy.c # 4 funcs — COPY (pushf/popf)
├── ccop_rflags_c.c # 6 funcs — rflags_c carry extraction (amd64)
├── .gitignore # Ignores bin/
├── STATUS.md # This file
└── bin/ # Compiled output (gitignored)
├── amd64/ # 27 binaries
└── i386/ # 27 binaries

../test_ccop_triggers.py # Pytest harness (54 parametrized test cases)
```
Loading