authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-18 21:30:06+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-03-20 13:34:04-07:00
logbfc554b542175bf21179804a269e3f65aff7fe18
tree01b3ef6131526a56f444ad304e9405889d83e410
parentfbdf64a7dac93dfcb5aa0240477689c174906695

compiler: Support more GCC code models and fix the mapping to LLVM code models.

Closes #22517.

3 files changed, 56 insertions(+), 15 deletions(-)

lib/std/builtin.zig+8-3
......@@ -141,11 +141,16 @@ pub const AtomicRmwOp = enum {
141141/// therefore must be kept in sync with the compiler implementation.
142142pub const CodeModel = enum {
143143 default,
144 tiny,
145 small,
144 extreme,
146145 kernel,
147 medium,
148146 large,
147 medany,
148 medium,
149 medlow,
150 medmid,
151 normal,
152 small,
153 tiny,
149154};
150155
151156/// This data structure is used by the Zig language code generation and
src/codegen/llvm.zig+36-9
......@@ -771,6 +771,30 @@ const DataLayoutBuilder = struct {
771771 }
772772};
773773
774// Avoid depending on `llvm.CodeModel` in the bitcode-only case.
775const CodeModel = enum {
776 default,
777 tiny,
778 small,
779 kernel,
780 medium,
781 large,
782};
783
784fn codeModel(model: std.builtin.CodeModel, target: std.Target) CodeModel {
785 // Roughly match Clang's mapping of GCC code models to LLVM code models.
786 return switch (model) {
787 .default => .default,
788 .extreme, .large => .large,
789 .kernel => .kernel,
790 .medany => if (target.cpu.arch.isRISCV()) .medium else .large,
791 .medium => if (target.os.tag == .aix) .large else .medium,
792 .medmid => .medium,
793 .normal, .medlow, .small => .small,
794 .tiny => .tiny,
795 };
796}
797
774798pub const Object = struct {
775799 gpa: Allocator,
776800 builder: Builder,
......@@ -1135,14 +1159,17 @@ pub const Object = struct {
11351159 module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag(
11361160 behavior_error,
11371161 try o.builder.metadataString("Code Model"),
1138 try o.builder.metadataConstant(try o.builder.intConst(.i32, @as(i32, switch (comp.root_mod.code_model) {
1139 .tiny => 0,
1140 .small => 1,
1141 .kernel => 2,
1142 .medium => 3,
1143 .large => 4,
1144 else => unreachable,
1145 }))),
1162 try o.builder.metadataConstant(try o.builder.intConst(.i32, @as(
1163 i32,
1164 switch (codeModel(comp.root_mod.code_model, comp.root_mod.resolved_target.result)) {
1165 .default => unreachable,
1166 .tiny => 0,
1167 .small => 1,
1168 .kernel => 2,
1169 .medium => 3,
1170 .large => 4,
1171 },
1172 ))),
11461173 ));
11471174 }
11481175
......@@ -1294,7 +1321,7 @@ pub const Object = struct {
12941321 else
12951322 .Static;
12961323
1297 const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) {
1324 const code_model: llvm.CodeModel = switch (codeModel(comp.root_mod.code_model, comp.root_mod.resolved_target.result)) {
12981325 .default => .Default,
12991326 .tiny => .Tiny,
13001327 .small => .Small,
src/main.zig+12-3
......@@ -499,9 +499,18 @@ const usage_build_generic =
499499 \\ hex (planned feature) Intel IHEX
500500 \\ raw (planned feature) Dump machine code directly
501501 \\ -mcpu [cpu] Specify target CPU and feature set
502 \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses
503 \\ small|kernel|
504 \\ medium|large]
502 \\ -mcmodel=[model] Limit range of code and data virtual addresses
503 \\ default
504 \\ extreme
505 \\ kernel
506 \\ large
507 \\ medany
508 \\ medium
509 \\ medlow
510 \\ medmid
511 \\ normal
512 \\ small
513 \\ tiny
505514 \\ -mred-zone Force-enable the "red-zone"
506515 \\ -mno-red-zone Force-disable the "red-zone"
507516 \\ -fomit-frame-pointer Omit the stack frame pointer