Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
24c8a2e
cc: fix 7 CPython codegen bugs including inliner two-reg struct return
jgarzik Mar 15, 2026
ba94e8c
cc: update Bug F analysis — isolate PyTuple_SET_ITEM as inliner crash…
jgarzik Mar 15, 2026
79d7d73
cc: refine Bug F analysis — crash requires multi-caller PyTuple_SET_I…
jgarzik Mar 15, 2026
adafbb6
cc: fix inliner Bug F — disable multi-call-site aggressive inlining a…
jgarzik Mar 15, 2026
81c51da
cc: fix Bug F root cause — 32-bit Copy to stack leaves upper bytes un…
jgarzik Mar 15, 2026
546b659
cc: fix Bug F (argument widening) and Bug G (small struct assignment)
jgarzik Mar 15, 2026
e96d13c
cc: fix Bugs H+I — Zext sign-extends instead of zero-extending, stack…
jgarzik Mar 15, 2026
f31778e
cc: update bugs.md — Bug J identified as _Py_Instrument NULL deref du…
jgarzik Mar 15, 2026
7e5ba94
cc: update Bug J — segfault now in LOAD_BUILD_CLASS dict lookup
jgarzik Mar 15, 2026
e31b2be
cc: fix Bug J — implement __attribute__((packed)) for struct layout
jgarzik Mar 15, 2026
36e4ef4
cc: update bugs.md — Bug K is bytecode interpreter switch dispatch fa…
jgarzik Mar 15, 2026
dc6fa79
cc: fix Bug K — switch uint8_t loads 32-bit from 8-bit stack slot
jgarzik Mar 15, 2026
b720879
cc: design fix — zero-initialize stack frames to prevent stale bytes
jgarzik Mar 15, 2026
9cd4093
cc: fix Bug L — Deref of small struct/union returns pointer instead o…
jgarzik Mar 15, 2026
fb6f639
cc: revise Bug L — restrict Deref value-load to unions only
jgarzik Mar 15, 2026
049ea92
cc: fix Bug M root cause — add error check after linearization
jgarzik Mar 15, 2026
2f7d28a
cc: fix Bug M — global initializer static address + ternary + error c…
jgarzik Mar 15, 2026
1228092
cc: update Bug N analysis — systematic codegen issue, every file brea…
jgarzik Mar 15, 2026
e552e2b
cc: identify Bug N root cause — ABI mismatch for large struct parameters
jgarzik Mar 15, 2026
bcd65ed
cc: fix Bug N — large struct parameter ABI + store-widening clobber
jgarzik Mar 15, 2026
eea4a83
cc: update bugs.md — Bug N fixed
jgarzik Mar 15, 2026
fc759c6
cc: fix store-widening to be struct-aware + regalloc cleanup
jgarzik Mar 15, 2026
bc5db54
cc: update bugs.md — document Bug O (ceval regalloc/SSA)
jgarzik Mar 15, 2026
36a4efd
cc: introduce PhiSource opcode for explicit phi operand tracking
jgarzik Mar 16, 2026
d4ea7a5
cc: fix Bugs P, Q + -O flag handling for CPython build
jgarzik Mar 16, 2026
1203720
cc: fix ternary expression int-to-long promotion (Bug R partial)
jgarzik Mar 16, 2026
bd82d07
cc: fix 64-bit conditional branch test (Bug R — UTF-8 decoder)
jgarzik Mar 16, 2026
b668b97
cc: update bugs.md — Bugs R1, R2 fixed; R3, R4 remain
jgarzik Mar 16, 2026
53705d6
cc: widen 32-bit stores to 64-bit for all non-struct locals (Bug R3)
jgarzik Mar 16, 2026
c2d08ba
cc: update bugs.md — CPython builds and runs, finalization crash remains
jgarzik Mar 16, 2026
cadeb80
cc: update bugs.md — CPython builds, runs, but math module has FP bugs
jgarzik Mar 16, 2026
09f93e8
cc: update bugs.md — additional CPython bugs found (S, T)
jgarzik Mar 16, 2026
fd7b8ca
cc: fix 11 systemic 32/64-bit type-width bugs, add constraint-based a…
jgarzik Mar 17, 2026
7fe38bd
cc: port x86-64 32/64-bit type-width fixes to aarch64 backend
jgarzik Mar 17, 2026
1fe78e4
cc: fix aarch64 stp offset overflow and store-widening guard
jgarzik Mar 17, 2026
aa2fe97
cc: fix aarch64 large struct param ABI, DWARF label placement, test
jgarzik Mar 17, 2026
a631fd3
cc: fix aarch64 store-widening clobbering globals and statics
jgarzik Mar 17, 2026
69a94d3
cc: type-based size derivation audit for both backends, IR hardening
jgarzik Mar 17, 2026
9a1b02f
cc: remove frame_size parameter threading from aarch64 backend
jgarzik Mar 17, 2026
81e0fbc
more: fix race condition panic in reader thread on early exit
jgarzik Mar 17, 2026
6211b5e
cc: fix aarch64 compare result size, replace magic 32 with u32::BITS
jgarzik Mar 17, 2026
5518406
cc: fix string literal UTF-8 encoding, XMM spill, and double-to-bool …
jgarzik Mar 17, 2026
bd5fac1
cc: fix unsigned long-to-double conversion and XMM parameter spilling
jgarzik Mar 17, 2026
62341b5
bugs.md: update status after string literal, XMM, and ucvt fixes
jgarzik Mar 17, 2026
f248afb
cc: fix four codegen bugs blocking CPython make test
jgarzik Mar 17, 2026
cface09
cc: fix char literal signedness and static local struct placement
jgarzik Mar 17, 2026
6f82496
cc: fix IEEE 754 NaN comparison handling in FP codegen
jgarzik Mar 18, 2026
03d4d98
cc: fix PreInc on dereferenced PostInc (++*s++) store address
jgarzik Mar 18, 2026
110e168
cc: implement 2-SSE struct parameter passing per SysV AMD64 ABI
jgarzik Mar 18, 2026
acfabcb
bugs.md: update status — 13+ tests pass, stack overflow and 2-SSE str…
jgarzik Mar 18, 2026
eb9e750
cc: fix register allocator for 2-SSE struct params
jgarzik Mar 18, 2026
0abd56c
cc: implement stack slot reuse (stack coloring) in register allocator
jgarzik Mar 18, 2026
dbe7420
cc: restrict stack slot reuse to pseudos with reliable intervals
jgarzik Mar 18, 2026
d5084d4
bugs.md: update status — stack coloring reduces eval loop frame 118KB…
jgarzik Mar 18, 2026
29b314a
cc: rewrite liveness analysis to proper dataflow and improve stack co…
jgarzik Mar 18, 2026
18c49a9
cc: refactor cc/arch and cc/ir — O(1) lookups, dedup init walkers, sc…
jgarzik Mar 18, 2026
ac01f5a
cc: fix 6 codegen bugs — stack reuse, struct ABI, FP select, FP neg c…
jgarzik Mar 19, 2026
d345527
cc: fix 6 codegen bugs — stack coloring, RAX clobbers, two-SSE ABI, f…
jgarzik Mar 19, 2026
e7aedca
cc: fix small struct return — allocate local storage for <=64-bit str…
jgarzik Mar 19, 2026
2ae2e3c
cc: fix FP binop src2 clobber — save src2 when it shares dst register
jgarzik Mar 19, 2026
e49ee14
cc: fix va_start overflow_arg_area and FP binop src2 clobber
jgarzik Mar 19, 2026
c3e0f38
cc: fix long double→double narrowing for function arguments
jgarzik Mar 19, 2026
8bdb25c
cc: spill cross-block FP pseudos to stack — fix XMM register reuse bug
jgarzik Mar 19, 2026
c5071ed
bugs.md: update status — 70→19 CPython test failures (51 fixed)
jgarzik Mar 19, 2026
b50d38b
cc: fix 2D char array initializers — emit inline data, not pointers
jgarzik Mar 19, 2026
07794ad
cc: fix ternary div-by-zero and 2D char array initializers
jgarzik Mar 19, 2026
3efa50e
cc: fix implicit int→float argument conversion (uint32_t→double etc.)
jgarzik Mar 19, 2026
e48bc62
cc: fix unsigned comparison in constant expression evaluator
jgarzik Mar 19, 2026
913af02
cc: fix struct-typed array init — whole-struct copy instead of field …
jgarzik Mar 19, 2026
2a6d289
cc: fix __CHAR_UNSIGNED__ and struct-in-array initialization
jgarzik Mar 19, 2026
e93de7e
cc: fix double→unsigned int conversion overflow
jgarzik Mar 19, 2026
fdd08c5
cc: fix wide char in preprocessor, double→uint overflow, CHAR_UNSIGNED
jgarzik Mar 19, 2026
4edbcac
cc: fix sizeof(void)=0, wide char in #if, double→uint, CHAR_UNSIGNED
jgarzik Mar 20, 2026
216d0d3
cc: fix Sym pseudo liveness over-estimation, reduce stack frames
jgarzik Mar 20, 2026
583540d
cc: ir/ code quality refactoring — correctness fix, DRY, O(1) lookups…
jgarzik Mar 20, 2026
0064bb8
cc: fix inliner for two-SSE struct params (e.g. {double,double})
jgarzik Mar 21, 2026
2001af5
cc: update docs — mark completed features, document new builtins
jgarzik Mar 21, 2026
9923edd
cc: C11 alignment compliance + GCC aligned attribute
jgarzik Mar 21, 2026
a31eef6
cc: fix aarch64 x19-relative offset computation for over-aligned locals
jgarzik Mar 21, 2026
5831b8d
cc: fix 5 C99 preprocessor compliance gaps + digraph support
jgarzik Mar 21, 2026
62be35a
cc: fix 11 macOS/aarch64 CI test failures
jgarzik Mar 21, 2026
baaf9db
cc: fix 3 more macOS/aarch64 failures — HFA-2 return, nullability, test
jgarzik Mar 21, 2026
d34ea0b
cc: fix last 2 macOS/aarch64 failures — nullability DRY, inliner asm
jgarzik Mar 21, 2026
94b1ef8
cc: fix macOS parse error — skip_extensions before all decl semicolons
jgarzik Mar 21, 2026
c26a0de
cc: add diagnostic test for macOS stdlib.h parse error at line 540
jgarzik Mar 21, 2026
14a3361
cc: fix diag test to panic on macOS only, showing preprocessed output
jgarzik Mar 21, 2026
5af6fdd
c99 checklist
jgarzik Mar 21, 2026
934cfb7
cc: implement full __int128 / __uint128_t operational support
jgarzik Mar 22, 2026
8b2829e
cc: fix clippy large_enum_variant warning — Box BlockItem::Statement
jgarzik Mar 22, 2026
51b5e18
cc: rustfmt formatting fixes in test files
jgarzik Mar 22, 2026
663df53
cc: fix aarch64 int128 stack alignment — use natural type alignment
jgarzik Mar 22, 2026
6677869
cc: fix type alignment and __int128 ABI across both backends
jgarzik Mar 22, 2026
ef9f1aa
cc: fix aarch64 int128 shift amount loading and return/param ABI
jgarzik Mar 22, 2026
8bb5190
cc: dump generated assembly on test failure for CI diagnosis
jgarzik Mar 22, 2026
c774439
cc: fix aarch64 comparison result store/load size mismatch
jgarzik Mar 22, 2026
dcb7974
cc: fix aarch64 int128 call argument setup — load both halves
jgarzik Mar 22, 2026
576ece1
cc: fix aarch64 int128 param store — write to arg pseudo slot, not local
jgarzik Mar 22, 2026
ffedfb6
cc: fix int128 bugs — ternary, stack-spilled args, global loads + tests
jgarzik Mar 22, 2026
8ec3862
cc: fix struct/int128 store through spilled pointer on both archs
jgarzik Mar 22, 2026
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
104 changes: 104 additions & 0 deletions bugs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# pcc Bug Log — CPython Build Campaign

## Status: CPython 3.12.9 builds and runs with pcc at -O0. Sym pseudo liveness fix — eval loop frame 118KB→61KB. 456/458 tests pass (ulimit -s unlimited). test_threading passes with default 8MB stack.

### Bugs A-N, P, Q, 1-6: ALL FIXED (see git history)

### Bug S: Floating-point codegen bugs — FIXED
- **Root cause 1:** XMM registers not spilled across function calls. x86-64 SysV ABI says ALL XMM regs are caller-saved, but the register allocator didn't check `crosses_call` for FP values. Float/double values in XMM8-XMM13 were silently clobbered by intervening calls.
- **Fix:** In `regalloc.rs`, spill FP values to stack when `crosses_call` is true.
- **Root cause 2:** `emit_cbr()` used `FpSize::Single` (ucomiss, 32-bit) for all float-to-bool conditions including doubles. Values like 0.5 have zero in their lower 32 bits, so `if(0.5)` evaluated to false.
- **Fix:** Derive `FpSize` from the condition type's bit width in both x86-64 and aarch64 backends.
- **Tests:** `codegen_xmm_spill_across_calls`, `codegen_double_to_bool`

### Bug T: chr()/string literals with bytes >= 0x80 — FIXED
- **Root cause:** pcc stored C string bytes as Rust `char` values in a Rust `String`. For bytes >= 0x80, Rust UTF-8 encodes them (e.g., `\x80` → 2-byte `\xC2\x80`), corrupting assembly output, sizeof, and zero-fill calculations.
- **Fix (5 locations):**
- `escape_string()` in `cc/arch/codegen.rs`: emit single octal byte for chars 0-255
- `emit_initializer_data()` in `cc/arch/codegen.rs`: use `chars().count()` for zero-fill
- `sizeof` in `cc/parse/expression.rs`: use `chars().count()` for array size
- Null terminator offsets in `cc/ir/linearize.rs` (2 places): use `chars().count()`
- **Test:** `codegen_string_literal_high_bytes`

### Bug U: unsigned long to double + XMM param spill — FIXED
- **Fixed:** `cvtsi2sdq` treated unsigned 64-bit values as signed. Values >= 2^63 produced negative doubles. Now uses the correct shift-convert-double sequence.
- **Fixed:** XMM function parameters not spilled to stack at function entry. Any float computation that reused the same XMM register would clobber the parameter.
- `int(37.5)` and `math.floor(37.5)` now work correctly in CPython.
- **Tests:** `codegen_unsigned_long_to_double`

### Bug W: FP compare Xmm0 clobber — FIXED
- **Root cause:** `emit_fp_compare()` loaded src1 into Xmm0, but if src2 was allocated to Xmm0, src2 was clobbered. Result: `ucomisd %xmm0, %xmm0` (self-compare, always equal), causing `d < -(double)_PyTime_MIN` to always be false.
- **Symptom:** `time.sleep(0.001)` raised `OverflowError: timestamp out of range for platform time_t`
- **Fix:** In `emit_fp_compare()`, check if src2 is in Xmm0 before loading src1; if so, save src2 to Xmm15 first.
- **Test:** `codegen_fp_compare_xmm0_clobber`

### Bug X: Inline asm 64-bit register constraints — FIXED
- **Root cause:** `format_reg_default()` in `AsmOperandFormatter` hardcoded 32-bit register names for all inline asm operands. For `uintptr_t` with `"+r"` constraint, `xchg %edx, (%r8)` was emitted instead of `xchg %rdx, (%r8)`, truncating 64-bit values to 32 bits.
- **Symptom:** CPython's `_Py_atomic_store` (seq_cst via xchg) truncated pointers. Signal handlers in `_PySignal_Fini` had corrupted addresses → segfault during finalization.
- **Fix:** Pass operand size through `substitute_asm_operands` → `format_reg_default(reg, size_bits)`. Select register width (b/w/k/q) based on operand type's bit width.
- **Test:** `codegen_inline_asm_64bit_constraint`

### Bug Y: XMM-to-GPR movd truncation — FIXED
- **Root cause:** `emit_move()` for `Loc::Xmm → Reg` hardcoded `OperandSize::B32` (movd) instead of using `op_size`. For doubles (64-bit), `movd %xmm, %r10d` copied only lower 32 bits. For `1.0` (0x3FF0000000000000), lower 32 bits = 0x00000000 → result 0.0.
- **Symptom:** `1/1` returned `0.0` in CPython (integer true division). Conditional select of double values (ternary, if/else returning double) produced 0.0.
- **Fix:** Use `op_size` instead of hardcoded `B32` in `MovXmmGp` instruction.
- **Test:** `codegen_double_xmm_to_gpr_movq`

### Bug Z: Ternary function pointer call return type — FIXED
- **Root cause:** `parse_conditional_expr()` used `self.types.pointer_to()` for function-to-pointer decay, but `pointer_to()` only does a lookup and falls back to `void*` when the type isn't in the table. This caused `(cond ? func_a : func_b)(arg)` to have type `void*`, and the Call expression handler couldn't determine the function return type, defaulting to `int` (32-bit).
- **Fix:** Use `self.types.intern(Type::pointer(...))` instead of `self.types.pointer_to(...)` in ternary decay, ensuring the pointer-to-function type is created if not found.
- **Symptom:** `string.Formatter().format()` segfaulted; indirect calls through ternary-selected function pointers returned truncated 32-bit values for pointer return types.
- **Test:** `codegen_ternary_fptr_return_type`

### Bug AA: Character literal signedness — FIXED
- **Root cause:** `'\x80'` produced 128 (unsigned) instead of -128 (signed). pcc cast `char` to `i64` via Rust `char` (unsigned), bypassing sign-extension. GCC treats `'\x80'` as -128 per implementation-defined behavior.
- **Fix:** Use `*c as u8 as i8 as i64` in all 4 CharLit-to-integer conversions (linearize.rs x3, parser.rs x1).
- **Symptom:** CPython's `_pickle` module failed — `enum { PROTO = '\x80' }` was 128, but `switch((enum)char_val)` saw -128. All opcodes >= 0x80 were unmatchable.
- **Test:** `codegen_char_literal_signedness`

### Bug AB: Static local struct variables on stack — FIXED
- **Root cause:** `linearize_local_decl()` checked `self.types.modifiers(typ)` for STATIC, but storage class modifiers are in `declarator.storage_class`, not the type system. For struct types, STATIC was never in the type, so static structs were allocated on the stack.
- **Fix:** Check `declarator.storage_class.contains(TypeModifiers::STATIC)` instead.
- **Symptom:** CPython's `_PyArg_Parser` structs (declared `static` in clinic-generated code) lived on the stack. When the function returned, the linked list in `_PyRuntime.getargs.static_parsers` contained dangling stack pointers → segfault in `_PyArg_Fini()` during finalization.
- **Test:** `codegen_static_local_struct`

### Bug R5/O: Previously listed bugs — FIXED by above fixes

### Bug AC: IEEE 754 NaN comparison — FIXED
- **Root cause:** `ucomisd` sets PF=1 for NaN, but `sete`/`setb`/`setbe`/`setne` don't check PF. All NaN comparisons gave wrong results.
- **Fix:** For ordered ==, <, <=: emit `setcc + setnp + AND`. For !=: `setne + setp + OR`. Added `CondCode::Np`/`P`.
- **Test:** `codegen_nan_comparison`, `codegen_nan_comparison_comprehensive`

### Bug AD: PreInc on dereferenced PostInc (++*s++) — FIXED
- **Root cause:** `++*s++` re-evaluated `s++` when storing back the incremented value, causing the store to go to the wrong address (s+1 instead of s). The deref operand's side effects were executed twice.
- **Fix:** Pre-compute the lvalue address via `linearize_lvalue` before loading the value, avoiding re-evaluation of PostInc side effects.
- **Symptom:** `_Py_dg_dtoa` (float-to-string) produced wrong digit strings. `'%.0f' % 1.5` returned "12" instead of "2", causing memset crash.
- **Test:** `codegen_preinc_deref_postinc`

### Bug AE: 2-SSE struct ABI param/return mismatch — PARTIALLY FIXED
- **Root cause:** struct { double, double } was passed via hidden pointer but returned in XMM0+XMM1. Crashes when return value passed directly as argument.
- **Fix:** Implemented 2-XMM parameter passing at call sites and function entry.
- **Remaining:** When a 2-SSE struct is the FIRST param followed by integer params, the callee's function entry code assigns integer args to the wrong registers (off by one). `powu(Complex x, long n)` reads `n` from rsi instead of rdi.
- **Workaround:** Complex tests work when struct is not first param, or with unlimited stack.

### Bug AF: Stack overflow from excessive frame sizes — FIXED
- `_PyEval_EvalFrameDefault` frame reduced from 118KB to 83KB to 61KB via stack slot reuse
- Stack coloring reuses slots for non-loop-spanning pseudos with non-overlapping intervals
- Sym pseudo liveness fix: kill Sym pseudos at their declaration blocks before gen/kill scan, preventing block-scoped locals from appearing simultaneously live across switch/case/computed-goto dispatch
- test_threading now passes without `ulimit -s unlimited` (previously SIGSEGV from thread stack overflow)
- 17 additional CPython tests now passing

### Bug AG-AK: See git log for recent fixes (small struct return, FP binop clobber, va_start overflow, long double narrowing, XMM cross-block spill)

### Test status: CPython 3.12.9 make test at -O0 (ulimit -s unlimited)
- 491 tests run (test_decimal skipped, hangs at -O0)
- 456 PASS, 2 FAIL (baseline was 70 FAIL, 68 tests fixed)
- Remaining 2: test.test_gdb.test_pretty_print (GCC-specific, expected), test_tools (parallel flake, passes individually)
- test_threading and test_statistics pass without `ulimit -s unlimited`

### CPython build setup at -O0
- configure CC=/tmp/pcc-bin/pcc, then fix pyconfig.h GETPGRP/SETPGRP
- Frozen deepfreeze.c generated by gcc build first, saved to /tmp
- Makefile: OPT= -DNDEBUG -g -O0 -Wall
- After make clean: restore deepfreeze.c, then make -j nproc
- Must delete all .pyc files after pcc rebuild
7 changes: 1 addition & 6 deletions cc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,8 @@ Supported:

Not yet implemented (features we want to add):
- -fverbose-asm
- top builtins to implement:
__builtin_expect
__sync_synchronize
__sync_fetch_and_add (and maybe a couple of its siblings)
- assembly peephole optimizations
- C11 atomics (_Atomic operations)
- Other C11 features: _Generic, anonymous structs
- C11 `_Generic` type-generic selection

## Code Quality

Expand Down
16 changes: 16 additions & 0 deletions cc/abi/aapcs64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ impl Abi for Aapcs64Abi {
return ArgClass::Extend { signed, size_bits };
}

// 128-bit integer types: two consecutive GP registers, 16-byte aligned
if kind == TypeKind::Int128 {
return ArgClass::Direct {
classes: vec![RegClass::Integer, RegClass::Integer],
size_bits,
};
}

// Integer and pointer types - pass in X registers
if is_integer(kind) || is_pointer(kind) {
return ArgClass::Direct {
Expand Down Expand Up @@ -273,6 +281,14 @@ impl Abi for Aapcs64Abi {
return ArgClass::Ignore;
}

// 128-bit integer types: return in X0+X1
if kind == TypeKind::Int128 {
return ArgClass::Direct {
classes: vec![RegClass::Integer, RegClass::Integer],
size_bits,
};
}

// Integer and pointer types - return in X0
if is_integer(kind) || is_pointer(kind) {
return ArgClass::Direct {
Expand Down
1 change: 1 addition & 0 deletions cc/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ fn is_integer(kind: TypeKind) -> bool {
| TypeKind::Int
| TypeKind::Long
| TypeKind::LongLong
| TypeKind::Int128
| TypeKind::Bool
| TypeKind::Enum
)
Expand Down
18 changes: 17 additions & 1 deletion cc/abi/sysv_amd64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// Key rules:
// - Arguments passed in RDI, RSI, RDX, RCX, R8, R9 (INTEGER) and XMM0-XMM7 (SSE)
// - Return values in RAX, RDX (INTEGER) or XMM0, XMM1 (SSE)
// - Structs > 16 bytes use sret (hidden pointer in RDI)
// - Structs > 16 bytes: returned via sret (hidden pointer in RDI), passed by value on stack
// - Structs 9-16 bytes may use two registers
// - Each eightbyte is classified independently, then merged
//
Expand Down Expand Up @@ -196,6 +196,14 @@ impl Abi for SysVAmd64Abi {
return ArgClass::Extend { signed, size_bits };
}

// 128-bit integer types: two GP registers
if kind == TypeKind::Int128 {
return ArgClass::Direct {
classes: vec![RegClass::Integer, RegClass::Integer],
size_bits,
};
}

// Integer and pointer types
if is_integer(kind) || is_pointer(kind) {
return ArgClass::Direct {
Expand Down Expand Up @@ -274,6 +282,14 @@ impl Abi for SysVAmd64Abi {
return ArgClass::Ignore;
}

// 128-bit integer types: return in RAX+RDX
if kind == TypeKind::Int128 {
return ArgClass::Direct {
classes: vec![RegClass::Integer, RegClass::Integer],
size_bits,
};
}

// Integer and pointer types - return in RAX
if is_integer(kind) || is_pointer(kind) {
return ArgClass::Direct {
Expand Down
Loading
Loading