aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/ir.cpp
diff options
context:
space:
mode:
authorBelhorma Bendebiche <amro@bndb.sh>2021-07-23 12:43:38 -0400
committerAndrew Kelley <andrew@ziglang.org>2021-07-28 18:13:17 -0400
commitf5d9d739d70f5d99756e277cc7c77484d60ddf42 (patch)
tree27c6691dccdc0a0c750eac384e362f5655f4d3e0 /src/stage1/ir.cpp
parent2f9e498c6fa0395e4318b2359291353b495a94e1 (diff)
downloadzig-f5d9d739d70f5d99756e277cc7c77484d60ddf42.tar.gz
zig-f5d9d739d70f5d99756e277cc7c77484d60ddf42.zip
stage1: Expand SysV C ABI support for small structs
While the SysV ABI is not that complicated, LLVM does not allow us direct access to enforce it. By mimicking the IR generated by clang, we can trick LLVM into doing the right thing. This involves two main additions: 1. `AGG` ABI class This is not part of the spec, but since we have to track class per eightbyte and not per struct, the current enum is not enough. I considered adding multiple classes like: `INTEGER_INTEGER`, `INTEGER_SSE`, `SSE_INTEGER`. However, all of those cases would trigger the same code path so it's simpler to collapse into one. This class is only used on SysV. 2. LLVM C ABI type Clang uses different types in C ABI function signatures than the original structs passed in, and does conversion. For example, this struct: `{ i8, i8, float }` would use `{ i16, float }` at ABI boundaries. When passed as an argument, it is instead split into two arguments `i16` and `float`. Therefore, for every struct that passes ABI boundaries we need to keep track of its corresponding ABI type. Here are some more examples: ``` | Struct | ABI equivalent | | { i8, i8, i8, i8 } | i32 | | { float, float } | double | | { float, i32, i8 } | { float, i64 } | ``` Then, we must update function calls, returns, parameter lists and inits to properly convert back and forth as needed.
Diffstat (limited to 'src/stage1/ir.cpp')
0 files changed, 0 insertions, 0 deletions